src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/stax/StAXDocumentSerializer.java

Thu, 12 Oct 2017 19:44:07 +0800

author
aoqi
date
Thu, 12 Oct 2017 19:44:07 +0800
changeset 760
e530533619ec
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  *
    25  * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
    26  */
    28 package com.sun.xml.internal.fastinfoset.stax;
    30 import com.sun.xml.internal.fastinfoset.Encoder;
    31 import com.sun.xml.internal.fastinfoset.EncodingConstants;
    32 import com.sun.xml.internal.fastinfoset.util.NamespaceContextImplementation;
    33 import java.io.IOException;
    34 import java.io.OutputStream;
    35 import java.util.EmptyStackException;
    36 import javax.xml.namespace.NamespaceContext;
    37 import javax.xml.stream.XMLStreamException;
    38 import javax.xml.stream.XMLStreamWriter;
    39 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
    40 import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
    41 import com.sun.xml.internal.fastinfoset.QualifiedName;
    42 import com.sun.xml.internal.fastinfoset.util.LocalNameQualifiedNamesMap;
    43 import com.sun.xml.internal.org.jvnet.fastinfoset.stax.LowLevelFastInfosetStreamWriter;
    45 /**
    46  * The Fast Infoset StAX serializer.
    47  * <p>
    48  * Instantiate this serializer to serialize a fast infoset document in accordance
    49  * with the StAX API.
    50  *
    51  * <p>
    52  * More than one fast infoset document may be encoded to the
    53  * {@link java.io.OutputStream}.
    54  */
    55 public class StAXDocumentSerializer extends Encoder
    56         implements XMLStreamWriter, LowLevelFastInfosetStreamWriter {
    57     protected StAXManager _manager;
    59     protected String _encoding;
    60     /**
    61      * Local name of current element.
    62      */
    63     protected String _currentLocalName;
    65     /**
    66      * Namespace of current element.
    67      */
    68     protected String _currentUri;
    70     /**
    71      * Prefix of current element.
    72      */
    73     protected String _currentPrefix;
    75    /**
    76      * This flag indicates when there is a pending start element event.
    77      */
    78     protected boolean _inStartElement = false;
    80     /**
    81      * This flag indicates if the current element is empty.
    82      */
    83     protected boolean _isEmptyElement = false;
    85     /**
    86      * List of attributes qnames and values defined in the current element.
    87      */
    88     protected String[] _attributesArray = new String[4 * 16];
    89     protected int _attributesArrayIndex = 0;
    91     protected boolean[] _nsSupportContextStack = new boolean[32];
    92     protected int _stackCount = -1;
    94     /**
    95      * Mapping between uris and prefixes.
    96      */
    97     protected NamespaceContextImplementation _nsContext =
    98             new NamespaceContextImplementation();
   100     /**
   101      * List of namespaces defined in the current element.
   102      */
   103     protected String[] _namespacesArray = new String[2 * 8];
   104     protected int _namespacesArrayIndex = 0;
   106     public StAXDocumentSerializer() {
   107         super(true);
   108         _manager = new StAXManager(StAXManager.CONTEXT_WRITER);
   109     }
   111     public StAXDocumentSerializer(OutputStream outputStream) {
   112         super(true);
   113         setOutputStream(outputStream);
   114         _manager = new StAXManager(StAXManager.CONTEXT_WRITER);
   115     }
   117     public StAXDocumentSerializer(OutputStream outputStream, StAXManager manager) {
   118         super(true);
   119         setOutputStream(outputStream);
   120         _manager = manager;
   121     }
   123     public void reset() {
   124         super.reset();
   126         _attributesArrayIndex = 0;
   127         _namespacesArrayIndex = 0;
   129         _nsContext.reset();
   130         _stackCount = -1;
   132         _currentUri = _currentPrefix = null;
   133         _currentLocalName = null;
   135         _inStartElement = _isEmptyElement = false;
   136     }
   138     // -- XMLStreamWriter Interface -------------------------------------------
   140     public void writeStartDocument() throws XMLStreamException {
   141         writeStartDocument("finf", "1.0");
   142     }
   144     public void writeStartDocument(String version) throws XMLStreamException {
   145         writeStartDocument("finf", version);
   146     }
   148     public void writeStartDocument(String encoding, String version)
   149         throws XMLStreamException
   150     {
   151         reset();
   153         try {
   154             encodeHeader(false);
   155             encodeInitialVocabulary();
   156         } catch (IOException e) {
   157             throw new XMLStreamException(e);
   158         }
   159     }
   161     public void writeEndDocument() throws XMLStreamException {
   162         try {
   164             // terminate all elements not terminated
   165             // by writeEndElement
   166             for(;_stackCount >= 0; _stackCount--) {
   167                 writeEndElement();
   168             }
   170             encodeDocumentTermination();
   171         }
   172         catch (IOException e) {
   173             throw new XMLStreamException(e);
   174         }
   175     }
   177     public void close() throws XMLStreamException {
   178         reset();
   179     }
   181     public void flush() throws XMLStreamException {
   182         try {
   183             _s.flush();
   184         }
   185         catch (IOException e) {
   186             throw new XMLStreamException(e);
   187         }
   188     }
   190     public void writeStartElement(String localName)
   191         throws XMLStreamException
   192     {
   193         // TODO is it necessary for FI to obtain the default namespace in scope?
   194         writeStartElement("", localName, "");
   195     }
   197     public void writeStartElement(String namespaceURI, String localName)
   198         throws XMLStreamException
   199     {
   200         writeStartElement("", localName, namespaceURI);
   201     }
   203     public void writeStartElement(String prefix, String localName,
   204         String namespaceURI) throws XMLStreamException
   205     {
   206         encodeTerminationAndCurrentElement(false);
   208         _inStartElement = true;
   209         _isEmptyElement = false;
   211         _currentLocalName = localName;
   212         _currentPrefix = prefix;
   213         _currentUri = namespaceURI;
   215         _stackCount++;
   216         if (_stackCount == _nsSupportContextStack.length) {
   217             boolean[] nsSupportContextStack = new boolean[_stackCount * 2];
   218             System.arraycopy(_nsSupportContextStack, 0, nsSupportContextStack, 0, _nsSupportContextStack.length);
   219             _nsSupportContextStack = nsSupportContextStack;
   220         }
   222         _nsSupportContextStack[_stackCount] = false;
   223     }
   225     public void writeEmptyElement(String localName)
   226         throws XMLStreamException
   227     {
   228         writeEmptyElement("", localName, "");
   229     }
   231     public void writeEmptyElement(String namespaceURI, String localName)
   232         throws XMLStreamException
   233     {
   234         writeEmptyElement("", localName, namespaceURI);
   235     }
   237     public void writeEmptyElement(String prefix, String localName,
   238         String namespaceURI) throws XMLStreamException
   239     {
   240         encodeTerminationAndCurrentElement(false);
   242         _isEmptyElement = _inStartElement = true;
   244         _currentLocalName = localName;
   245         _currentPrefix = prefix;
   246         _currentUri = namespaceURI;
   248         _stackCount++;
   249         if (_stackCount == _nsSupportContextStack.length) {
   250             boolean[] nsSupportContextStack = new boolean[_stackCount * 2];
   251             System.arraycopy(_nsSupportContextStack, 0, nsSupportContextStack, 0, _nsSupportContextStack.length);
   252             _nsSupportContextStack = nsSupportContextStack;
   253         }
   255         _nsSupportContextStack[_stackCount] = false;
   256     }
   258     public void writeEndElement() throws XMLStreamException {
   259         if (_inStartElement) {
   260             encodeTerminationAndCurrentElement(false);
   261         }
   263         try {
   264             encodeElementTermination();
   265             if (_nsSupportContextStack[_stackCount--] == true) {
   266                 _nsContext.popContext();
   267             }
   268         }
   269         catch (IOException e) {
   270             throw new XMLStreamException(e);
   271         }
   272         catch (EmptyStackException e) {
   273             throw new XMLStreamException(e);
   274         }
   275     }
   278     public void writeAttribute(String localName, String value)
   279         throws XMLStreamException
   280     {
   281         writeAttribute("", "", localName, value);
   282     }
   284     public void writeAttribute(String namespaceURI, String localName,
   285         String value) throws XMLStreamException
   286     {
   287         String prefix = "";
   289         // Find prefix for attribute, ignoring default namespace
   290         if (namespaceURI.length() > 0) {
   291             prefix = _nsContext.getNonDefaultPrefix(namespaceURI);
   293             // Undeclared prefix or ignorable default ns?
   294             if (prefix == null || prefix.length() == 0) {
   295                 // Workaround for BUG in SAX NamespaceSupport helper
   296                 // which incorrectly defines namespace declaration URI
   297                 if (namespaceURI == EncodingConstants.XMLNS_NAMESPACE_NAME ||
   298                         namespaceURI.equals(EncodingConstants.XMLNS_NAMESPACE_NAME)) {
   299                     // TODO
   300                     // Need to check carefully the rule for the writing of
   301                     // namespaces in StAX. Is it safe to ignore such
   302                     // attributes, as declarations will be made using the
   303                     // writeNamespace method
   304                     return;
   305                 }
   306                 throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.URIUnbound", new Object[]{namespaceURI}));
   307             }
   308         }
   309         writeAttribute(prefix, namespaceURI, localName, value);
   310     }
   312     public void writeAttribute(String prefix, String namespaceURI,
   313         String localName, String value) throws XMLStreamException
   314     {
   315         if (!_inStartElement) {
   316             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed"));
   317         }
   319         // TODO
   320         // Need to check carefully the rule for the writing of
   321         // namespaces in StAX. Is it safe to ignore such
   322         // attributes, as declarations will be made using the
   323         // writeNamespace method
   324         if (namespaceURI == EncodingConstants.XMLNS_NAMESPACE_NAME ||
   325                 namespaceURI.equals(EncodingConstants.XMLNS_NAMESPACE_NAME)) {
   326             return;
   327         }
   329         if (_attributesArrayIndex == _attributesArray.length) {
   330             final String[] attributesArray = new String[_attributesArrayIndex * 2];
   331             System.arraycopy(_attributesArray, 0, attributesArray, 0, _attributesArrayIndex);
   332             _attributesArray = attributesArray;
   333         }
   335         _attributesArray[_attributesArrayIndex++] = namespaceURI;
   336         _attributesArray[_attributesArrayIndex++] = prefix;
   337         _attributesArray[_attributesArrayIndex++] = localName;
   338         _attributesArray[_attributesArrayIndex++] = value;
   339     }
   341     public void writeNamespace(String prefix, String namespaceURI)
   342         throws XMLStreamException
   343     {
   344         if (prefix == null || prefix.length() == 0 || prefix.equals(EncodingConstants.XMLNS_NAMESPACE_PREFIX)) {
   345             writeDefaultNamespace(namespaceURI);
   346         }
   347         else {
   348             if (!_inStartElement) {
   349                 throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed"));
   350             }
   352             if (_namespacesArrayIndex == _namespacesArray.length) {
   353                 final String[] namespacesArray = new String[_namespacesArrayIndex * 2];
   354                 System.arraycopy(_namespacesArray, 0, namespacesArray, 0, _namespacesArrayIndex);
   355                 _namespacesArray = namespacesArray;
   356             }
   358             _namespacesArray[_namespacesArrayIndex++] = prefix;
   359             _namespacesArray[_namespacesArrayIndex++] = namespaceURI;
   360             setPrefix(prefix, namespaceURI);
   361         }
   362     }
   364     public void writeDefaultNamespace(String namespaceURI)
   365         throws XMLStreamException
   366     {
   367         if (!_inStartElement) {
   368             throw new IllegalStateException(CommonResourceBundle.getInstance().getString("message.attributeWritingNotAllowed"));
   369         }
   371         if (_namespacesArrayIndex == _namespacesArray.length) {
   372             final String[] namespacesArray = new String[_namespacesArrayIndex * 2];
   373             System.arraycopy(_namespacesArray, 0, namespacesArray, 0, _namespacesArrayIndex);
   374             _namespacesArray = namespacesArray;
   375         }
   377         _namespacesArray[_namespacesArrayIndex++] = "";
   378         _namespacesArray[_namespacesArrayIndex++] = namespaceURI;
   379         setPrefix("", namespaceURI);
   380     }
   382     public void writeComment(String data) throws XMLStreamException {
   383         try {
   384             if (getIgnoreComments()) return;
   386             encodeTerminationAndCurrentElement(true);
   388             // TODO: avoid array copy here
   389             encodeComment(data.toCharArray(), 0, data.length());
   390         }
   391         catch (IOException e) {
   392             throw new XMLStreamException(e);
   393         }
   394     }
   396     public void writeProcessingInstruction(String target)
   397         throws XMLStreamException
   398     {
   399         writeProcessingInstruction(target, "");
   400     }
   402     public void writeProcessingInstruction(String target, String data)
   403         throws XMLStreamException
   404     {
   405         try {
   406             if (getIgnoreProcesingInstructions()) return;
   408             encodeTerminationAndCurrentElement(true);
   410             encodeProcessingInstruction(target, data);
   411         }
   412         catch (IOException e) {
   413             throw new XMLStreamException(e);
   414         }
   415     }
   417     public void writeCData(String text) throws XMLStreamException {
   418          try {
   419             final int length = text.length();
   420             if (length == 0) {
   421                 return;
   422             } else if (length < _charBuffer.length) {
   423                 if (getIgnoreWhiteSpaceTextContent() &&
   424                         isWhiteSpace(text)) return;
   426                 // Warning: this method must be called before any state
   427                 // is modified, such as the _charBuffer contents,
   428                 // so the characters of text cannot be copied to _charBuffer
   429                 // before this call
   430                 encodeTerminationAndCurrentElement(true);
   432                 text.getChars(0, length, _charBuffer, 0);
   433                 encodeCIIBuiltInAlgorithmDataAsCDATA(_charBuffer, 0, length);
   434             } else {
   435                 final char ch[] = text.toCharArray();
   436                 if (getIgnoreWhiteSpaceTextContent() &&
   437                         isWhiteSpace(ch, 0, length)) return;
   439                 encodeTerminationAndCurrentElement(true);
   441                 encodeCIIBuiltInAlgorithmDataAsCDATA(ch, 0, length);
   442             }
   443         } catch (Exception e) {
   444             throw new XMLStreamException(e);
   445         }
   446     }
   448     public void writeDTD(String dtd) throws XMLStreamException {
   449         throw new UnsupportedOperationException(CommonResourceBundle.getInstance().getString("message.notImplemented"));
   450     }
   452     public void writeEntityRef(String name) throws XMLStreamException {
   453         throw new UnsupportedOperationException(CommonResourceBundle.getInstance().getString("message.notImplemented"));
   454     }
   456     public void writeCharacters(String text) throws XMLStreamException {
   457          try {
   458             final int length = text.length();
   459             if (length == 0) {
   460                 return;
   461             } else if (length < _charBuffer.length) {
   462                 if (getIgnoreWhiteSpaceTextContent() &&
   463                         isWhiteSpace(text)) return;
   465                 // Warning: this method must be called before any state
   466                 // is modified, such as the _charBuffer contents,
   467                 // so the characters of text cannot be copied to _charBuffer
   468                 // before this call
   469                 encodeTerminationAndCurrentElement(true);
   471                 text.getChars(0, length, _charBuffer, 0);
   472                 encodeCharacters(_charBuffer, 0, length);
   473             } else {
   474                 final char ch[] = text.toCharArray();
   475                 if (getIgnoreWhiteSpaceTextContent() &&
   476                         isWhiteSpace(ch, 0, length)) return;
   478                 encodeTerminationAndCurrentElement(true);
   480                 encodeCharactersNoClone(ch, 0, length);
   481             }
   482         }
   483         catch (IOException e) {
   484             throw new XMLStreamException(e);
   485         }
   486     }
   488     public void writeCharacters(char[] text, int start, int len)
   489         throws XMLStreamException
   490     {
   491          try {
   492             if (len <= 0) {
   493                 return;
   494             }
   496             if (getIgnoreWhiteSpaceTextContent() &&
   497                     isWhiteSpace(text, start, len)) return;
   499             encodeTerminationAndCurrentElement(true);
   501             encodeCharacters(text, start, len);
   502         }
   503         catch (IOException e) {
   504             throw new XMLStreamException(e);
   505         }
   506     }
   508     public String getPrefix(String uri) throws XMLStreamException {
   509         return _nsContext.getPrefix(uri);
   510     }
   512     public void setPrefix(String prefix, String uri)
   513         throws XMLStreamException
   514     {
   515         if (_stackCount > -1 && _nsSupportContextStack[_stackCount] == false) {
   516             _nsSupportContextStack[_stackCount] = true;
   517             _nsContext.pushContext();
   518         }
   520         _nsContext.declarePrefix(prefix, uri);
   521     }
   523     public void setDefaultNamespace(String uri) throws XMLStreamException {
   524         setPrefix("", uri);
   525     }
   527     /**
   528      * Sets the current namespace context for prefix and uri bindings.
   529      * This context becomes the root namespace context for writing and
   530      * will replace the current root namespace context.  Subsequent calls
   531      * to setPrefix and setDefaultNamespace will bind namespaces using
   532      * the context passed to the method as the root context for resolving
   533      * namespaces.  This method may only be called once at the start of
   534      * the document.  It does not cause the namespaces to be declared.
   535      * If a namespace URI to prefix mapping is found in the namespace
   536      * context it is treated as declared and the prefix may be used
   537      * by the StreamWriter.
   538      * @param context the namespace context to use for this writer, may not be null
   539      * @throws XMLStreamException
   540      */
   541     public void setNamespaceContext(NamespaceContext context)
   542         throws XMLStreamException
   543     {
   544         throw new UnsupportedOperationException("setNamespaceContext");
   545     }
   547     public NamespaceContext getNamespaceContext() {
   548         return _nsContext;
   549     }
   551     public Object getProperty(java.lang.String name)
   552         throws IllegalArgumentException
   553     {
   554         if (_manager != null) {
   555             return _manager.getProperty(name);
   556         }
   557         return null;
   558     }
   560     public void setManager(StAXManager manager) {
   561         _manager = manager;
   562     }
   564     public void setEncoding(String encoding) {
   565         _encoding = encoding;
   566     }
   569     public void writeOctets(byte[] b, int start, int len)
   570         throws XMLStreamException
   571     {
   572          try {
   573             if (len == 0) {
   574                 return;
   575             }
   577             encodeTerminationAndCurrentElement(true);
   579             encodeCIIOctetAlgorithmData(EncodingAlgorithmIndexes.BASE64, b, start, len);
   580         }
   581         catch (IOException e) {
   582             throw new XMLStreamException(e);
   583         }
   584     }
   586     protected void encodeTerminationAndCurrentElement(boolean terminateAfter) throws XMLStreamException {
   587         try {
   588             encodeTermination();
   590             if (_inStartElement) {
   592                 _b = EncodingConstants.ELEMENT;
   593                 if (_attributesArrayIndex > 0) {
   594                     _b |= EncodingConstants.ELEMENT_ATTRIBUTE_FLAG;
   595                 }
   597                 // Encode namespace decls associated with this element
   598                 if (_namespacesArrayIndex > 0) {
   599                     write(_b | EncodingConstants.ELEMENT_NAMESPACES_FLAG);
   600                     for (int i = 0; i < _namespacesArrayIndex;) {
   601                         encodeNamespaceAttribute(_namespacesArray[i++], _namespacesArray[i++]);
   602                     }
   603                     _namespacesArrayIndex = 0;
   605                     write(EncodingConstants.TERMINATOR);
   607                     _b = 0;
   608                 }
   610                 // If element's prefix is empty - apply default scope namespace
   611                 if (_currentPrefix.length() == 0) {
   612                     if (_currentUri.length() == 0) {
   613                         _currentUri = _nsContext.getNamespaceURI("");
   614                     } else {
   615                         String tmpPrefix = getPrefix(_currentUri);
   616                         if (tmpPrefix != null) {
   617                             _currentPrefix = tmpPrefix;
   618                         }
   619                     }
   620                 }
   622                 encodeElementQualifiedNameOnThirdBit(_currentUri, _currentPrefix, _currentLocalName);
   624                 for (int i = 0; i < _attributesArrayIndex;) {
   625                     encodeAttributeQualifiedNameOnSecondBit(
   626                             _attributesArray[i++], _attributesArray[i++], _attributesArray[i++]);
   628                     final String value = _attributesArray[i];
   629                     _attributesArray[i++] = null;
   630                     final boolean addToTable = isAttributeValueLengthMatchesLimit(value.length());
   631                     encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, false);
   633                     _b = EncodingConstants.TERMINATOR;
   634                     _terminate = true;
   635                 }
   636                 _attributesArrayIndex = 0;
   637                 _inStartElement = false;
   639                 if (_isEmptyElement) {
   640                     encodeElementTermination();
   641                     if (_nsSupportContextStack[_stackCount--] == true) {
   642                         _nsContext.popContext();
   643                     }
   645                     _isEmptyElement = false;
   646                 }
   648                 if (terminateAfter) {
   649                     encodeTermination();
   650                 }
   651             }
   652         } catch (IOException e) {
   653             throw new XMLStreamException(e);
   654         }
   655     }
   658     // LowLevelFastInfosetSerializer
   660     public final void initiateLowLevelWriting() throws XMLStreamException {
   661         encodeTerminationAndCurrentElement(false);
   662     }
   664     public final int getNextElementIndex() {
   665         return _v.elementName.getNextIndex();
   666     }
   668     public final int getNextAttributeIndex() {
   669         return _v.attributeName.getNextIndex();
   670     }
   672     public final int getLocalNameIndex() {
   673         return _v.localName.getIndex();
   674     }
   676     public final int getNextLocalNameIndex() {
   677         return _v.localName.getNextIndex();
   678     }
   680     public final void writeLowLevelTerminationAndMark() throws IOException {
   681         encodeTermination();
   682         mark();
   683     }
   685     public final void writeLowLevelStartElementIndexed(int type, int index) throws IOException {
   686         _b = type;
   687         encodeNonZeroIntegerOnThirdBit(index);
   688     }
   690     public final boolean writeLowLevelStartElement(int type, String prefix, String localName,
   691             String namespaceURI) throws IOException {
   692         final boolean isIndexed = encodeElement(type, namespaceURI, prefix, localName);
   694         if (!isIndexed)
   695             encodeLiteral(type | EncodingConstants.ELEMENT_LITERAL_QNAME_FLAG,
   696                     namespaceURI, prefix, localName);
   698         return isIndexed;
   699     }
   701     public final void writeLowLevelStartNamespaces() throws IOException {
   702         write(EncodingConstants.ELEMENT | EncodingConstants.ELEMENT_NAMESPACES_FLAG);
   703     }
   705     public final void writeLowLevelNamespace(String prefix, String namespaceName)
   706         throws IOException {
   707         encodeNamespaceAttribute(prefix, namespaceName);
   708     }
   710     public final void writeLowLevelEndNamespaces() throws IOException {
   711         write(EncodingConstants.TERMINATOR);
   712     }
   714     public final void writeLowLevelStartAttributes() throws IOException {
   715         if (hasMark()) {
   716             _octetBuffer[_markIndex] |= EncodingConstants.ELEMENT_ATTRIBUTE_FLAG;
   717             resetMark();
   718         }
   719     }
   721     public final void writeLowLevelAttributeIndexed(int index) throws IOException {
   722         encodeNonZeroIntegerOnSecondBitFirstBitZero(index);
   723     }
   725     public final boolean writeLowLevelAttribute(String prefix, String namespaceURI, String localName) throws IOException {
   726         final boolean isIndexed = encodeAttribute(namespaceURI, prefix, localName);
   728         if (!isIndexed)
   729             encodeLiteral(EncodingConstants.ATTRIBUTE_LITERAL_QNAME_FLAG,
   730                     namespaceURI, prefix, localName);
   732         return isIndexed;
   733     }
   735     public final void writeLowLevelAttributeValue(String value) throws IOException
   736     {
   737         final boolean addToTable = isAttributeValueLengthMatchesLimit(value.length());
   738         encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, false);
   739     }
   741     public final void writeLowLevelStartNameLiteral(int type, String prefix, byte[] utf8LocalName,
   742             String namespaceURI) throws IOException {
   743         encodeLiteralHeader(type, namespaceURI, prefix);
   744         encodeNonZeroOctetStringLengthOnSecondBit(utf8LocalName.length);
   745         write(utf8LocalName, 0, utf8LocalName.length);
   746     }
   748     public final void writeLowLevelStartNameLiteral(int type, String prefix, int localNameIndex,
   749             String namespaceURI) throws IOException {
   750         encodeLiteralHeader(type, namespaceURI, prefix);
   751         encodeNonZeroIntegerOnSecondBitFirstBitOne(localNameIndex);
   752     }
   754     public final void writeLowLevelEndStartElement() throws IOException {
   755         if (hasMark()) {
   756             resetMark();
   757         } else {
   758             // Terminate the attributes
   759             _b = EncodingConstants.TERMINATOR;
   760             _terminate = true;
   761         }
   762     }
   764     public final void writeLowLevelEndElement() throws IOException {
   765         encodeElementTermination();
   766     }
   768     public final void writeLowLevelText(char[] text, int length) throws IOException {
   769         if (length == 0)
   770             return;
   772         encodeTermination();
   774         encodeCharacters(text, 0, length);
   775     }
   777     public final void writeLowLevelText(String text) throws IOException {
   778         final int length = text.length();
   779         if (length == 0)
   780             return;
   782         encodeTermination();
   784         if (length < _charBuffer.length) {
   785             text.getChars(0, length, _charBuffer, 0);
   786             encodeCharacters(_charBuffer, 0, length);
   787         } else {
   788             final char ch[] = text.toCharArray();
   789             encodeCharactersNoClone(ch, 0, length);
   790         }
   791     }
   793     public final void writeLowLevelOctets(byte[] octets, int length) throws IOException {
   794         if (length == 0)
   795             return;
   797         encodeTermination();
   799         encodeCIIOctetAlgorithmData(EncodingAlgorithmIndexes.BASE64, octets, 0, length);
   800     }
   802     private boolean encodeElement(int type, String namespaceURI, String prefix, String localName) throws IOException {
   803         final LocalNameQualifiedNamesMap.Entry entry = _v.elementName.obtainEntry(localName);
   804         for (int i = 0; i < entry._valueIndex; i++) {
   805             final QualifiedName name = entry._value[i];
   806             if ((prefix == name.prefix || prefix.equals(name.prefix))
   807                     && (namespaceURI == name.namespaceName || namespaceURI.equals(name.namespaceName))) {
   808                 _b = type;
   809                 encodeNonZeroIntegerOnThirdBit(name.index);
   810                 return true;
   811             }
   812         }
   814         entry.addQualifiedName(new QualifiedName(prefix, namespaceURI, localName, "", _v.elementName.getNextIndex()));
   815         return false;
   816     }
   818     private boolean encodeAttribute(String namespaceURI, String prefix, String localName) throws IOException {
   819         final LocalNameQualifiedNamesMap.Entry entry = _v.attributeName.obtainEntry(localName);
   820         for (int i = 0; i < entry._valueIndex; i++) {
   821             final QualifiedName name = entry._value[i];
   822             if ((prefix == name.prefix || prefix.equals(name.prefix))
   823                     && (namespaceURI == name.namespaceName || namespaceURI.equals(name.namespaceName))) {
   824                 encodeNonZeroIntegerOnSecondBitFirstBitZero(name.index);
   825                 return true;
   826             }
   827         }
   829         entry.addQualifiedName(new QualifiedName(prefix, namespaceURI, localName, "", _v.attributeName.getNextIndex()));
   830         return false;
   831     }
   833     private void encodeLiteralHeader(int type, String namespaceURI, String prefix) throws IOException {
   834         if (namespaceURI != "") {
   835             type |= EncodingConstants.LITERAL_QNAME_NAMESPACE_NAME_FLAG;
   836             if (prefix != "")
   837                 type |= EncodingConstants.LITERAL_QNAME_PREFIX_FLAG;
   839             write(type);
   840             if (prefix != "")
   841                 encodeNonZeroIntegerOnSecondBitFirstBitOne(_v.prefix.get(prefix));
   842             encodeNonZeroIntegerOnSecondBitFirstBitOne(_v.namespaceName.get(namespaceURI));
   843         } else
   844             write(type);
   845     }
   847     private void encodeLiteral(int type, String namespaceURI, String prefix, String localName) throws IOException {
   848         encodeLiteralHeader(type, namespaceURI, prefix);
   850         final int localNameIndex = _v.localName.obtainIndex(localName);
   851         if (localNameIndex == -1) {
   852             encodeNonEmptyOctetStringOnSecondBit(localName);
   853         } else
   854             encodeNonZeroIntegerOnSecondBitFirstBitOne(localNameIndex);
   855     }
   856 }

mercurial