1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/Decoder.java Tue Mar 06 16:09:35 2012 -0800 1.3 @@ -0,0 +1,2008 @@ 1.4 +/* 1.5 + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + * 1.28 + * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC. 1.29 + */ 1.30 + 1.31 +package com.sun.xml.internal.fastinfoset; 1.32 + 1.33 +import com.sun.xml.internal.fastinfoset.alphabet.BuiltInRestrictedAlphabets; 1.34 +import com.sun.xml.internal.fastinfoset.org.apache.xerces.util.XMLChar; 1.35 +import com.sun.xml.internal.fastinfoset.util.CharArray; 1.36 +import com.sun.xml.internal.fastinfoset.util.CharArrayArray; 1.37 +import com.sun.xml.internal.fastinfoset.util.CharArrayString; 1.38 +import com.sun.xml.internal.fastinfoset.util.ContiguousCharArrayArray; 1.39 +import com.sun.xml.internal.fastinfoset.util.DuplicateAttributeVerifier; 1.40 +import com.sun.xml.internal.fastinfoset.util.PrefixArray; 1.41 +import com.sun.xml.internal.fastinfoset.util.QualifiedNameArray; 1.42 +import com.sun.xml.internal.fastinfoset.util.StringArray; 1.43 +import com.sun.xml.internal.fastinfoset.vocab.ParserVocabulary; 1.44 +import java.io.EOFException; 1.45 +import java.io.IOException; 1.46 +import java.io.InputStream; 1.47 +import java.util.ArrayList; 1.48 +import java.util.HashMap; 1.49 +import java.util.List; 1.50 +import java.util.Map; 1.51 +import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException; 1.52 +import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetParser; 1.53 + 1.54 +/** 1.55 + * Abstract decoder for developing concrete encoders. 1.56 + * 1.57 + * Concrete implementations extending Decoder will utilize methods on Decoder 1.58 + * to decode XML infoset according to the Fast Infoset standard. It is the 1.59 + * responsibility of the concrete implementation to ensure that methods are 1.60 + * invoked in the correct order to correctly decode a valid fast infoset 1.61 + * document. 1.62 + * 1.63 + * <p> 1.64 + * This class extends org.sax.xml.DefaultHandler so that concrete SAX 1.65 + * implementations can be used with javax.xml.parsers.SAXParser and the parse 1.66 + * methods that take org.sax.xml.DefaultHandler as a parameter. 1.67 + * 1.68 + * <p> 1.69 + * Buffering of octets that are read from an {@link java.io.InputStream} is 1.70 + * supported in a similar manner to a {@link java.io.BufferedInputStream}. 1.71 + * Combining buffering with decoding enables better performance. 1.72 + * 1.73 + * <p> 1.74 + * More than one fast infoset document may be decoded from the 1.75 + * {@link java.io.InputStream}. 1.76 + */ 1.77 +public abstract class Decoder implements FastInfosetParser { 1.78 + 1.79 + private static final char[] XML_NAMESPACE_NAME_CHARS = 1.80 + EncodingConstants.XML_NAMESPACE_NAME.toCharArray(); 1.81 + 1.82 + private static final char[] XMLNS_NAMESPACE_PREFIX_CHARS = 1.83 + EncodingConstants.XMLNS_NAMESPACE_PREFIX.toCharArray(); 1.84 + 1.85 + private static final char[] XMLNS_NAMESPACE_NAME_CHARS = 1.86 + EncodingConstants.XMLNS_NAMESPACE_NAME.toCharArray(); 1.87 + 1.88 + /** 1.89 + * String interning system property. 1.90 + */ 1.91 + public static final String STRING_INTERNING_SYSTEM_PROPERTY = 1.92 + "com.sun.xml.internal.fastinfoset.parser.string-interning"; 1.93 + 1.94 + /** 1.95 + * Internal buffer size interning system property. 1.96 + */ 1.97 + public static final String BUFFER_SIZE_SYSTEM_PROPERTY = 1.98 + "com.sun.xml.internal.fastinfoset.parser.buffer-size"; 1.99 + 1.100 + private static boolean _stringInterningSystemDefault = false; 1.101 + 1.102 + private static int _bufferSizeSystemDefault = 1024; 1.103 + 1.104 + static { 1.105 + String p = System.getProperty(STRING_INTERNING_SYSTEM_PROPERTY, 1.106 + Boolean.toString(_stringInterningSystemDefault)); 1.107 + _stringInterningSystemDefault = Boolean.valueOf(p).booleanValue(); 1.108 + 1.109 + p = System.getProperty(BUFFER_SIZE_SYSTEM_PROPERTY, 1.110 + Integer.toString(_bufferSizeSystemDefault)); 1.111 + try { 1.112 + int i = Integer.valueOf(p).intValue(); 1.113 + if (i > 0) { 1.114 + _bufferSizeSystemDefault = i; 1.115 + } 1.116 + } catch (NumberFormatException e) { 1.117 + } 1.118 + } 1.119 + 1.120 + /** 1.121 + * True if string interning is performed by the decoder. 1.122 + */ 1.123 + private boolean _stringInterning = _stringInterningSystemDefault; 1.124 + 1.125 + /** 1.126 + * The input stream from which the fast infoset document is being read. 1.127 + */ 1.128 + private InputStream _s; 1.129 + 1.130 + /** 1.131 + * The map of URIs to referenced vocabularies. 1.132 + */ 1.133 + private Map _externalVocabularies; 1.134 + 1.135 + /** 1.136 + * True if can parse fragments. 1.137 + */ 1.138 + protected boolean _parseFragments; 1.139 + 1.140 + /** 1.141 + * True if needs to close underlying input stream. 1.142 + */ 1.143 + protected boolean _needForceStreamClose; 1.144 + 1.145 + /** 1.146 + * True if the vocabulary is internally created by decoder. 1.147 + */ 1.148 + private boolean _vIsInternal; 1.149 + 1.150 + /** 1.151 + * The list of Notation Information Items that are part of the 1.152 + * Document Information Item. 1.153 + */ 1.154 + protected List _notations; 1.155 + 1.156 + /** 1.157 + * The list of Unparsed Entity Information Items that are part of the 1.158 + * Document Information Item. 1.159 + */ 1.160 + protected List _unparsedEntities; 1.161 + 1.162 + /** 1.163 + * The map of URIs to registered encoding algorithms. 1.164 + */ 1.165 + protected Map _registeredEncodingAlgorithms = new HashMap(); 1.166 + 1.167 + /** 1.168 + * The vocabulary used for decoding. 1.169 + */ 1.170 + protected ParserVocabulary _v; 1.171 + 1.172 + /** 1.173 + * The prefix table of the vocabulary. 1.174 + */ 1.175 + protected PrefixArray _prefixTable; 1.176 + 1.177 + /** 1.178 + * The element name table of the vocabulary. 1.179 + */ 1.180 + protected QualifiedNameArray _elementNameTable; 1.181 + 1.182 + /** 1.183 + * The attribute name table of the vocabulary. 1.184 + */ 1.185 + protected QualifiedNameArray _attributeNameTable; 1.186 + 1.187 + /** 1.188 + * The character content chunk table of the vocabulary. 1.189 + */ 1.190 + protected ContiguousCharArrayArray _characterContentChunkTable; 1.191 + 1.192 + /** 1.193 + * The attribute value table of the vocabulary. 1.194 + */ 1.195 + protected StringArray _attributeValueTable; 1.196 + 1.197 + /** 1.198 + * The current octet that is being read 1.199 + */ 1.200 + protected int _b; 1.201 + 1.202 + /** 1.203 + * True if an information item is terminated. 1.204 + */ 1.205 + protected boolean _terminate; 1.206 + 1.207 + /** 1.208 + * True if two information item are terminated in direct sequence. 1.209 + */ 1.210 + protected boolean _doubleTerminate; 1.211 + 1.212 + /** 1.213 + * True if an entry is required to be added to a table 1.214 + */ 1.215 + protected boolean _addToTable; 1.216 + 1.217 + /** 1.218 + * The vocabulary table index to an indexed non identifying string. 1.219 + */ 1.220 + protected int _integer; 1.221 + 1.222 + /** 1.223 + * The vocabulary table index of identifying string or the identifier of 1.224 + * an encoding algorithm or restricted alphabet. 1.225 + */ 1.226 + protected int _identifier; 1.227 + 1.228 + /** 1.229 + * The size of the internal buffer. 1.230 + */ 1.231 + protected int _bufferSize = _bufferSizeSystemDefault; 1.232 + 1.233 + /** 1.234 + * The internal buffer used for decoding. 1.235 + */ 1.236 + protected byte[] _octetBuffer = new byte[_bufferSizeSystemDefault]; 1.237 + 1.238 + /** 1.239 + * A mark into the internal buffer used for decoding encoded algorithm 1.240 + * or restricted alphabet data. 1.241 + */ 1.242 + protected int _octetBufferStart; 1.243 + 1.244 + /** 1.245 + * The offset into the buffer to read the next byte. 1.246 + */ 1.247 + protected int _octetBufferOffset; 1.248 + 1.249 + /** 1.250 + * The end of the buffer. 1.251 + */ 1.252 + protected int _octetBufferEnd; 1.253 + 1.254 + /** 1.255 + * The length of some octets in the buffer that are to be read. 1.256 + */ 1.257 + protected int _octetBufferLength; 1.258 + 1.259 + /** 1.260 + * The internal buffer of characters. 1.261 + */ 1.262 + protected char[] _charBuffer = new char[512]; 1.263 + 1.264 + /** 1.265 + * The length of characters in the buffer of characters. 1.266 + */ 1.267 + protected int _charBufferLength; 1.268 + 1.269 + /** 1.270 + * Helper class that checks for duplicate attribute information items. 1.271 + */ 1.272 + protected DuplicateAttributeVerifier _duplicateAttributeVerifier = new DuplicateAttributeVerifier(); 1.273 + 1.274 + /** 1.275 + * Default constructor for the Decoder. 1.276 + */ 1.277 + protected Decoder() { 1.278 + _v = new ParserVocabulary(); 1.279 + _prefixTable = _v.prefix; 1.280 + _elementNameTable = _v.elementName; 1.281 + _attributeNameTable = _v.attributeName; 1.282 + _characterContentChunkTable = _v.characterContentChunk; 1.283 + _attributeValueTable = _v.attributeValue; 1.284 + _vIsInternal = true; 1.285 + } 1.286 + 1.287 + 1.288 + // FastInfosetParser interface 1.289 + 1.290 + /** 1.291 + * {@inheritDoc} 1.292 + */ 1.293 + public void setStringInterning(boolean stringInterning) { 1.294 + _stringInterning = stringInterning; 1.295 + } 1.296 + 1.297 + /** 1.298 + * {@inheritDoc} 1.299 + */ 1.300 + public boolean getStringInterning() { 1.301 + return _stringInterning; 1.302 + } 1.303 + 1.304 + /** 1.305 + * {@inheritDoc} 1.306 + */ 1.307 + public void setBufferSize(int bufferSize) { 1.308 + if (_bufferSize > _octetBuffer.length) { 1.309 + _bufferSize = bufferSize; 1.310 + } 1.311 + } 1.312 + 1.313 + /** 1.314 + * {@inheritDoc} 1.315 + */ 1.316 + public int getBufferSize() { 1.317 + return _bufferSize; 1.318 + } 1.319 + 1.320 + /** 1.321 + * {@inheritDoc} 1.322 + */ 1.323 + public void setRegisteredEncodingAlgorithms(Map algorithms) { 1.324 + _registeredEncodingAlgorithms = algorithms; 1.325 + if (_registeredEncodingAlgorithms == null) { 1.326 + _registeredEncodingAlgorithms = new HashMap(); 1.327 + } 1.328 + } 1.329 + 1.330 + /** 1.331 + * {@inheritDoc} 1.332 + */ 1.333 + public Map getRegisteredEncodingAlgorithms() { 1.334 + return _registeredEncodingAlgorithms; 1.335 + } 1.336 + 1.337 + /** 1.338 + * {@inheritDoc} 1.339 + */ 1.340 + public void setExternalVocabularies(Map referencedVocabualries) { 1.341 + if (referencedVocabualries != null) { 1.342 + // Clone the input map 1.343 + _externalVocabularies = new HashMap(); 1.344 + _externalVocabularies.putAll(referencedVocabualries); 1.345 + } else { 1.346 + _externalVocabularies = null; 1.347 + } 1.348 + } 1.349 + 1.350 + /** 1.351 + * {@inheritDoc} 1.352 + */ 1.353 + public Map getExternalVocabularies() { 1.354 + return _externalVocabularies; 1.355 + } 1.356 + 1.357 + /** 1.358 + * {@inheritDoc} 1.359 + */ 1.360 + public void setParseFragments(boolean parseFragments) { 1.361 + _parseFragments = parseFragments; 1.362 + } 1.363 + 1.364 + /** 1.365 + * {@inheritDoc} 1.366 + */ 1.367 + public boolean getParseFragments() { 1.368 + return _parseFragments; 1.369 + } 1.370 + 1.371 + /** 1.372 + * {@inheritDoc} 1.373 + */ 1.374 + public void setForceStreamClose(boolean needForceStreamClose) { 1.375 + _needForceStreamClose = needForceStreamClose; 1.376 + } 1.377 + 1.378 + /** 1.379 + * {@inheritDoc} 1.380 + */ 1.381 + public boolean getForceStreamClose() { 1.382 + return _needForceStreamClose; 1.383 + } 1.384 + 1.385 +// End FastInfosetParser interface 1.386 + 1.387 + /** 1.388 + * Reset the decoder for reuse decoding another XML infoset. 1.389 + */ 1.390 + public void reset() { 1.391 + _terminate = _doubleTerminate = false; 1.392 + } 1.393 + 1.394 + /** 1.395 + * Set the ParserVocabulary to be used for decoding. 1.396 + * 1.397 + * @param v the vocabulary to be used for decoding. 1.398 + */ 1.399 + public void setVocabulary(ParserVocabulary v) { 1.400 + _v = v; 1.401 + _prefixTable = _v.prefix; 1.402 + _elementNameTable = _v.elementName; 1.403 + _attributeNameTable = _v.attributeName; 1.404 + _characterContentChunkTable = _v.characterContentChunk; 1.405 + _attributeValueTable = _v.attributeValue; 1.406 + _vIsInternal = false; 1.407 + } 1.408 + 1.409 + /** 1.410 + * Set the InputStream to decode the fast infoset document. 1.411 + * 1.412 + * @param s the InputStream where the fast infoset document is decoded from. 1.413 + */ 1.414 + public void setInputStream(InputStream s) { 1.415 + _s = s; 1.416 + _octetBufferOffset = 0; 1.417 + _octetBufferEnd = 0; 1.418 + if (_vIsInternal == true) { 1.419 + _v.clear(); 1.420 + } 1.421 + } 1.422 + 1.423 + protected final void decodeDII() throws FastInfosetException, IOException { 1.424 + final int b = read(); 1.425 + if (b == EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) { 1.426 + decodeInitialVocabulary(); 1.427 + } else if (b != 0) { 1.428 + throw new IOException(CommonResourceBundle.getInstance(). 1.429 + getString("message.optinalValues")); 1.430 + } 1.431 + } 1.432 + 1.433 + protected final void decodeAdditionalData() throws FastInfosetException, IOException { 1.434 + final int noOfItems = decodeNumberOfItemsOfSequence(); 1.435 + 1.436 + for (int i = 0; i < noOfItems; i++) { 1.437 + String URI = decodeNonEmptyOctetStringOnSecondBitAsUtf8String(); 1.438 + 1.439 + decodeNonEmptyOctetStringLengthOnSecondBit(); 1.440 + ensureOctetBufferSize(); 1.441 + _octetBufferStart = _octetBufferOffset; 1.442 + _octetBufferOffset += _octetBufferLength; 1.443 + } 1.444 + } 1.445 + 1.446 + protected final void decodeInitialVocabulary() throws FastInfosetException, IOException { 1.447 + // First 5 optionals of 13 bit optional field 1.448 + int b = read(); 1.449 + // Next 8 optionals of 13 bit optional field 1.450 + int b2 = read(); 1.451 + 1.452 + // Optimize for the most common case 1.453 + if (b == EncodingConstants.INITIAL_VOCABULARY_EXTERNAL_VOCABULARY_FLAG && b2 == 0) { 1.454 + decodeExternalVocabularyURI(); 1.455 + return; 1.456 + } 1.457 + 1.458 + if ((b & EncodingConstants.INITIAL_VOCABULARY_EXTERNAL_VOCABULARY_FLAG) > 0) { 1.459 + decodeExternalVocabularyURI(); 1.460 + } 1.461 + 1.462 + if ((b & EncodingConstants.INITIAL_VOCABULARY_RESTRICTED_ALPHABETS_FLAG) > 0) { 1.463 + decodeTableItems(_v.restrictedAlphabet); 1.464 + } 1.465 + 1.466 + if ((b & EncodingConstants.INITIAL_VOCABULARY_ENCODING_ALGORITHMS_FLAG) > 0) { 1.467 + decodeTableItems(_v.encodingAlgorithm); 1.468 + } 1.469 + 1.470 + if ((b & EncodingConstants.INITIAL_VOCABULARY_PREFIXES_FLAG) > 0) { 1.471 + decodeTableItems(_v.prefix); 1.472 + } 1.473 + 1.474 + if ((b & EncodingConstants.INITIAL_VOCABULARY_NAMESPACE_NAMES_FLAG) > 0) { 1.475 + decodeTableItems(_v.namespaceName); 1.476 + } 1.477 + 1.478 + if ((b2 & EncodingConstants.INITIAL_VOCABULARY_LOCAL_NAMES_FLAG) > 0) { 1.479 + decodeTableItems(_v.localName); 1.480 + } 1.481 + 1.482 + if ((b2 & EncodingConstants.INITIAL_VOCABULARY_OTHER_NCNAMES_FLAG) > 0) { 1.483 + decodeTableItems(_v.otherNCName); 1.484 + } 1.485 + 1.486 + if ((b2 & EncodingConstants.INITIAL_VOCABULARY_OTHER_URIS_FLAG) > 0) { 1.487 + decodeTableItems(_v.otherURI); 1.488 + } 1.489 + 1.490 + if ((b2 & EncodingConstants.INITIAL_VOCABULARY_ATTRIBUTE_VALUES_FLAG) > 0) { 1.491 + decodeTableItems(_v.attributeValue); 1.492 + } 1.493 + 1.494 + if ((b2 & EncodingConstants.INITIAL_VOCABULARY_CONTENT_CHARACTER_CHUNKS_FLAG) > 0) { 1.495 + decodeTableItems(_v.characterContentChunk); 1.496 + } 1.497 + 1.498 + if ((b2 & EncodingConstants.INITIAL_VOCABULARY_OTHER_STRINGS_FLAG) > 0) { 1.499 + decodeTableItems(_v.otherString); 1.500 + } 1.501 + 1.502 + if ((b2 & EncodingConstants.INITIAL_VOCABULARY_ELEMENT_NAME_SURROGATES_FLAG) > 0) { 1.503 + decodeTableItems(_v.elementName, false); 1.504 + } 1.505 + 1.506 + if ((b2 & EncodingConstants.INITIAL_VOCABULARY_ATTRIBUTE_NAME_SURROGATES_FLAG) > 0) { 1.507 + decodeTableItems(_v.attributeName, true); 1.508 + } 1.509 + } 1.510 + 1.511 + private void decodeExternalVocabularyURI() throws FastInfosetException, IOException { 1.512 + if (_externalVocabularies == null) { 1.513 + throw new IOException(CommonResourceBundle. 1.514 + getInstance().getString("message.noExternalVocabularies")); 1.515 + } 1.516 + 1.517 + String externalVocabularyURI = 1.518 + decodeNonEmptyOctetStringOnSecondBitAsUtf8String(); 1.519 + 1.520 + Object o = _externalVocabularies.get(externalVocabularyURI); 1.521 + if (o instanceof ParserVocabulary) { 1.522 + _v.setReferencedVocabulary(externalVocabularyURI, 1.523 + (ParserVocabulary)o, false); 1.524 + } else if (o instanceof com.sun.xml.internal.org.jvnet.fastinfoset.ExternalVocabulary) { 1.525 + com.sun.xml.internal.org.jvnet.fastinfoset.ExternalVocabulary v = 1.526 + (com.sun.xml.internal.org.jvnet.fastinfoset.ExternalVocabulary)o; 1.527 + ParserVocabulary pv = new ParserVocabulary(v.vocabulary); 1.528 + 1.529 + _externalVocabularies.put(externalVocabularyURI, pv); 1.530 + _v.setReferencedVocabulary(externalVocabularyURI, 1.531 + pv, false); 1.532 + } else { 1.533 + throw new FastInfosetException(CommonResourceBundle.getInstance(). 1.534 + getString("message.externalVocabularyNotRegistered", 1.535 + new Object[]{externalVocabularyURI})); 1.536 + } 1.537 + } 1.538 + 1.539 + private void decodeTableItems(StringArray array) throws FastInfosetException, IOException { 1.540 + final int noOfItems = decodeNumberOfItemsOfSequence(); 1.541 + 1.542 + for (int i = 0; i < noOfItems; i++) { 1.543 + array.add(decodeNonEmptyOctetStringOnSecondBitAsUtf8String()); 1.544 + } 1.545 + } 1.546 + 1.547 + private void decodeTableItems(PrefixArray array) throws FastInfosetException, IOException { 1.548 + final int noOfItems = decodeNumberOfItemsOfSequence(); 1.549 + 1.550 + for (int i = 0; i < noOfItems; i++) { 1.551 + array.add(decodeNonEmptyOctetStringOnSecondBitAsUtf8String()); 1.552 + } 1.553 + } 1.554 + 1.555 + private void decodeTableItems(ContiguousCharArrayArray array) throws FastInfosetException, IOException { 1.556 + final int noOfItems = decodeNumberOfItemsOfSequence(); 1.557 + 1.558 + for (int i = 0; i < noOfItems; i++) { 1.559 + switch(decodeNonIdentifyingStringOnFirstBit()) { 1.560 + case NISTRING_STRING: 1.561 + array.add(_charBuffer, _charBufferLength); 1.562 + break; 1.563 + default: 1.564 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.illegalState")); 1.565 + } 1.566 + } 1.567 + } 1.568 + 1.569 + private void decodeTableItems(CharArrayArray array) throws FastInfosetException, IOException { 1.570 + final int noOfItems = decodeNumberOfItemsOfSequence(); 1.571 + 1.572 + for (int i = 0; i < noOfItems; i++) { 1.573 + switch(decodeNonIdentifyingStringOnFirstBit()) { 1.574 + case NISTRING_STRING: 1.575 + array.add(new CharArray(_charBuffer, 0, _charBufferLength, true)); 1.576 + break; 1.577 + default: 1.578 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.illegalState")); 1.579 + } 1.580 + } 1.581 + } 1.582 + 1.583 + private void decodeTableItems(QualifiedNameArray array, boolean isAttribute) throws FastInfosetException, IOException { 1.584 + final int noOfItems = decodeNumberOfItemsOfSequence(); 1.585 + 1.586 + for (int i = 0; i < noOfItems; i++) { 1.587 + final int b = read(); 1.588 + 1.589 + String prefix = ""; 1.590 + int prefixIndex = -1; 1.591 + if ((b & EncodingConstants.NAME_SURROGATE_PREFIX_FLAG) > 0) { 1.592 + prefixIndex = decodeIntegerIndexOnSecondBit(); 1.593 + prefix = _v.prefix.get(prefixIndex); 1.594 + } 1.595 + 1.596 + String namespaceName = ""; 1.597 + int namespaceNameIndex = -1; 1.598 + if ((b & EncodingConstants.NAME_SURROGATE_NAME_FLAG) > 0) { 1.599 + namespaceNameIndex = decodeIntegerIndexOnSecondBit(); 1.600 + namespaceName = _v.namespaceName.get(namespaceNameIndex); 1.601 + } 1.602 + 1.603 + if (namespaceName == "" && prefix != "") { 1.604 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.missingNamespace")); 1.605 + } 1.606 + 1.607 + final int localNameIndex = decodeIntegerIndexOnSecondBit(); 1.608 + final String localName = _v.localName.get(localNameIndex); 1.609 + 1.610 + QualifiedName qualifiedName = new QualifiedName(prefix, namespaceName, localName, 1.611 + prefixIndex, namespaceNameIndex, localNameIndex, 1.612 + _charBuffer); 1.613 + if (isAttribute) { 1.614 + qualifiedName.createAttributeValues(DuplicateAttributeVerifier.MAP_SIZE); 1.615 + } 1.616 + array.add(qualifiedName); 1.617 + } 1.618 + } 1.619 + 1.620 + private int decodeNumberOfItemsOfSequence() throws IOException { 1.621 + final int b = read(); 1.622 + if (b < 128) { 1.623 + return b + 1; 1.624 + } else { 1.625 + return (((b & 0x0F) << 16) | (read() << 8) | read()) + 129; 1.626 + } 1.627 + } 1.628 + 1.629 + protected final void decodeNotations() throws FastInfosetException, IOException { 1.630 + if (_notations == null) { 1.631 + _notations = new ArrayList(); 1.632 + } else { 1.633 + _notations.clear(); 1.634 + } 1.635 + 1.636 + int b = read(); 1.637 + while ((b & EncodingConstants.NOTATIONS_MASK) == EncodingConstants.NOTATIONS) { 1.638 + String name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName); 1.639 + 1.640 + String system_identifier = ((_b & EncodingConstants.NOTATIONS_SYSTEM_IDENTIFIER_FLAG) > 0) 1.641 + ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : ""; 1.642 + String public_identifier = ((_b & EncodingConstants.NOTATIONS_PUBLIC_IDENTIFIER_FLAG) > 0) 1.643 + ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : ""; 1.644 + 1.645 + Notation notation = new Notation(name, system_identifier, public_identifier); 1.646 + _notations.add(notation); 1.647 + 1.648 + b = read(); 1.649 + } 1.650 + if (b != EncodingConstants.TERMINATOR) { 1.651 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IIsNotTerminatedCorrectly")); 1.652 + } 1.653 + } 1.654 + 1.655 + protected final void decodeUnparsedEntities() throws FastInfosetException, IOException { 1.656 + if (_unparsedEntities == null) { 1.657 + _unparsedEntities = new ArrayList(); 1.658 + } else { 1.659 + _unparsedEntities.clear(); 1.660 + } 1.661 + 1.662 + int b = read(); 1.663 + while ((b & EncodingConstants.UNPARSED_ENTITIES_MASK) == EncodingConstants.UNPARSED_ENTITIES) { 1.664 + String name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName); 1.665 + String system_identifier = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI); 1.666 + 1.667 + String public_identifier = ((_b & EncodingConstants.UNPARSED_ENTITIES_PUBLIC_IDENTIFIER_FLAG) > 0) 1.668 + ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : ""; 1.669 + 1.670 + String notation_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName); 1.671 + 1.672 + UnparsedEntity unparsedEntity = new UnparsedEntity(name, system_identifier, public_identifier, notation_name); 1.673 + _unparsedEntities.add(unparsedEntity); 1.674 + 1.675 + b = read(); 1.676 + } 1.677 + if (b != EncodingConstants.TERMINATOR) { 1.678 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.unparsedEntities")); 1.679 + } 1.680 + } 1.681 + 1.682 + protected final String decodeCharacterEncodingScheme() throws FastInfosetException, IOException { 1.683 + return decodeNonEmptyOctetStringOnSecondBitAsUtf8String(); 1.684 + } 1.685 + 1.686 + protected final String decodeVersion() throws FastInfosetException, IOException { 1.687 + switch(decodeNonIdentifyingStringOnFirstBit()) { 1.688 + case NISTRING_STRING: 1.689 + final String data = new String(_charBuffer, 0, _charBufferLength); 1.690 + if (_addToTable) { 1.691 + _v.otherString.add(new CharArrayString(data)); 1.692 + } 1.693 + return data; 1.694 + case NISTRING_ENCODING_ALGORITHM: 1.695 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingNotSupported")); 1.696 + case NISTRING_INDEX: 1.697 + return _v.otherString.get(_integer).toString(); 1.698 + case NISTRING_EMPTY_STRING: 1.699 + default: 1.700 + return ""; 1.701 + } 1.702 + } 1.703 + 1.704 + protected final QualifiedName decodeEIIIndexMedium() throws FastInfosetException, IOException { 1.705 + final int i = (((_b & EncodingConstants.INTEGER_3RD_BIT_MEDIUM_MASK) << 8) | read()) 1.706 + + EncodingConstants.INTEGER_3RD_BIT_SMALL_LIMIT; 1.707 + return _v.elementName._array[i]; 1.708 + } 1.709 + 1.710 + protected final QualifiedName decodeEIIIndexLarge() throws FastInfosetException, IOException { 1.711 + int i; 1.712 + if ((_b & EncodingConstants.INTEGER_3RD_BIT_LARGE_LARGE_FLAG) == 0x20) { 1.713 + // EII large index 1.714 + i = (((_b & EncodingConstants.INTEGER_3RD_BIT_LARGE_MASK) << 16) | (read() << 8) | read()) 1.715 + + EncodingConstants.INTEGER_3RD_BIT_MEDIUM_LIMIT; 1.716 + } else { 1.717 + // EII large large index 1.718 + i = (((read() & EncodingConstants.INTEGER_3RD_BIT_LARGE_LARGE_MASK) << 16) | (read() << 8) | read()) 1.719 + + EncodingConstants.INTEGER_3RD_BIT_LARGE_LIMIT; 1.720 + } 1.721 + return _v.elementName._array[i]; 1.722 + } 1.723 + 1.724 + protected final QualifiedName decodeLiteralQualifiedName(int state, QualifiedName q) 1.725 + throws FastInfosetException, IOException { 1.726 + if (q == null) q = new QualifiedName(); 1.727 + switch (state) { 1.728 + // no prefix, no namespace 1.729 + case 0: 1.730 + return q.set( 1.731 + "", 1.732 + "", 1.733 + decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName), 1.734 + -1, 1.735 + -1, 1.736 + _identifier, 1.737 + null); 1.738 + // no prefix, namespace 1.739 + case 1: 1.740 + return q.set( 1.741 + "", 1.742 + decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(false), 1.743 + decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName), 1.744 + -1, 1.745 + _namespaceNameIndex, 1.746 + _identifier, 1.747 + null); 1.748 + // prefix, no namespace 1.749 + case 2: 1.750 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameMissingNamespaceName")); 1.751 + // prefix, namespace 1.752 + case 3: 1.753 + return q.set( 1.754 + decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(true), 1.755 + decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(true), 1.756 + decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName), 1.757 + _prefixIndex, 1.758 + _namespaceNameIndex, 1.759 + _identifier, 1.760 + _charBuffer); 1.761 + default: 1.762 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingEII")); 1.763 + } 1.764 + } 1.765 + 1.766 + protected static final int NISTRING_STRING = 0; 1.767 + protected static final int NISTRING_INDEX = 1; 1.768 + protected static final int NISTRING_ENCODING_ALGORITHM = 2; 1.769 + protected static final int NISTRING_EMPTY_STRING = 3; 1.770 + 1.771 + /* 1.772 + * C.14 1.773 + * decodeNonIdentifyingStringOnFirstBit 1.774 + */ 1.775 + protected final int decodeNonIdentifyingStringOnFirstBit() throws FastInfosetException, IOException { 1.776 + final int b = read(); 1.777 + switch(DecoderStateTables.NISTRING(b)) { 1.778 + case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH: 1.779 + _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0; 1.780 + _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1; 1.781 + decodeUtf8StringAsCharBuffer(); 1.782 + return NISTRING_STRING; 1.783 + case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH: 1.784 + _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0; 1.785 + _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT; 1.786 + decodeUtf8StringAsCharBuffer(); 1.787 + return NISTRING_STRING; 1.788 + case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH: 1.789 + { 1.790 + _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0; 1.791 + final int length = (read() << 24) | 1.792 + (read() << 16) | 1.793 + (read() << 8) | 1.794 + read(); 1.795 + _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT; 1.796 + decodeUtf8StringAsCharBuffer(); 1.797 + return NISTRING_STRING; 1.798 + } 1.799 + case DecoderStateTables.NISTRING_UTF16_SMALL_LENGTH: 1.800 + _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0; 1.801 + _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1; 1.802 + decodeUtf16StringAsCharBuffer(); 1.803 + return NISTRING_STRING; 1.804 + case DecoderStateTables.NISTRING_UTF16_MEDIUM_LENGTH: 1.805 + _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0; 1.806 + _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT; 1.807 + decodeUtf16StringAsCharBuffer(); 1.808 + return NISTRING_STRING; 1.809 + case DecoderStateTables.NISTRING_UTF16_LARGE_LENGTH: 1.810 + { 1.811 + _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0; 1.812 + final int length = (read() << 24) | 1.813 + (read() << 16) | 1.814 + (read() << 8) | 1.815 + read(); 1.816 + _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT; 1.817 + decodeUtf16StringAsCharBuffer(); 1.818 + return NISTRING_STRING; 1.819 + } 1.820 + case DecoderStateTables.NISTRING_RA: 1.821 + { 1.822 + _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0; 1.823 + // Decode resitricted alphabet integer 1.824 + _identifier = (b & 0x0F) << 4; 1.825 + final int b2 = read(); 1.826 + _identifier |= (b2 & 0xF0) >> 4; 1.827 + 1.828 + decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b2); 1.829 + 1.830 + decodeRestrictedAlphabetAsCharBuffer(); 1.831 + return NISTRING_STRING; 1.832 + } 1.833 + case DecoderStateTables.NISTRING_EA: 1.834 + { 1.835 + _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0; 1.836 + // Decode encoding algorithm integer 1.837 + _identifier = (b & 0x0F) << 4; 1.838 + final int b2 = read(); 1.839 + _identifier |= (b2 & 0xF0) >> 4; 1.840 + 1.841 + decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b2); 1.842 + return NISTRING_ENCODING_ALGORITHM; 1.843 + } 1.844 + case DecoderStateTables.NISTRING_INDEX_SMALL: 1.845 + _integer = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK; 1.846 + return NISTRING_INDEX; 1.847 + case DecoderStateTables.NISTRING_INDEX_MEDIUM: 1.848 + _integer = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read()) 1.849 + + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT; 1.850 + return NISTRING_INDEX; 1.851 + case DecoderStateTables.NISTRING_INDEX_LARGE: 1.852 + _integer = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read()) 1.853 + + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT; 1.854 + return NISTRING_INDEX; 1.855 + case DecoderStateTables.NISTRING_EMPTY: 1.856 + return NISTRING_EMPTY_STRING; 1.857 + default: 1.858 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingNonIdentifyingString")); 1.859 + } 1.860 + } 1.861 + 1.862 + protected final void decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(int b) throws FastInfosetException, IOException { 1.863 + // Remove top 4 bits of restricted alphabet or encoding algorithm integer 1.864 + b &= 0x0F; 1.865 + // Reuse UTF8 length states 1.866 + switch(DecoderStateTables.NISTRING(b)) { 1.867 + case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH: 1.868 + _octetBufferLength = b + 1; 1.869 + break; 1.870 + case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH: 1.871 + _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT; 1.872 + break; 1.873 + case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH: 1.874 + final int length = (read() << 24) | 1.875 + (read() << 16) | 1.876 + (read() << 8) | 1.877 + read(); 1.878 + _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT; 1.879 + break; 1.880 + default: 1.881 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingOctets")); 1.882 + } 1.883 + ensureOctetBufferSize(); 1.884 + _octetBufferStart = _octetBufferOffset; 1.885 + _octetBufferOffset += _octetBufferLength; 1.886 + } 1.887 + 1.888 + protected final void decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(int b) throws FastInfosetException, IOException { 1.889 + // Remove top 6 bits of restricted alphabet or encoding algorithm integer 1.890 + switch (b & 0x03) { 1.891 + // Small length 1.892 + case 0: 1.893 + _octetBufferLength = 1; 1.894 + break; 1.895 + // Small length 1.896 + case 1: 1.897 + _octetBufferLength = 2; 1.898 + break; 1.899 + // Medium length 1.900 + case 2: 1.901 + _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT; 1.902 + break; 1.903 + // Large length 1.904 + case 3: 1.905 + _octetBufferLength = (read() << 24) | 1.906 + (read() << 16) | 1.907 + (read() << 8) | 1.908 + read(); 1.909 + _octetBufferLength += EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT; 1.910 + break; 1.911 + } 1.912 + 1.913 + ensureOctetBufferSize(); 1.914 + _octetBufferStart = _octetBufferOffset; 1.915 + _octetBufferOffset += _octetBufferLength; 1.916 + } 1.917 + 1.918 + /* 1.919 + * C.13 1.920 + */ 1.921 + protected final String decodeIdentifyingNonEmptyStringOnFirstBit(StringArray table) throws FastInfosetException, IOException { 1.922 + final int b = read(); 1.923 + switch(DecoderStateTables.ISTRING(b)) { 1.924 + case DecoderStateTables.ISTRING_SMALL_LENGTH: 1.925 + { 1.926 + _octetBufferLength = b + 1; 1.927 + final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString(); 1.928 + _identifier = table.add(s) - 1; 1.929 + return s; 1.930 + } 1.931 + case DecoderStateTables.ISTRING_MEDIUM_LENGTH: 1.932 + { 1.933 + _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT; 1.934 + final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString(); 1.935 + _identifier = table.add(s) - 1; 1.936 + return s; 1.937 + } 1.938 + case DecoderStateTables.ISTRING_LARGE_LENGTH: 1.939 + { 1.940 + final int length = (read() << 24) | 1.941 + (read() << 16) | 1.942 + (read() << 8) | 1.943 + read(); 1.944 + _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT; 1.945 + final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString(); 1.946 + _identifier = table.add(s) - 1; 1.947 + return s; 1.948 + } 1.949 + case DecoderStateTables.ISTRING_INDEX_SMALL: 1.950 + _identifier = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK; 1.951 + return table._array[_identifier]; 1.952 + case DecoderStateTables.ISTRING_INDEX_MEDIUM: 1.953 + _identifier = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read()) 1.954 + + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT; 1.955 + return table._array[_identifier]; 1.956 + case DecoderStateTables.ISTRING_INDEX_LARGE: 1.957 + _identifier = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read()) 1.958 + + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT; 1.959 + return table._array[_identifier]; 1.960 + default: 1.961 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIdentifyingString")); 1.962 + } 1.963 + } 1.964 + 1.965 + protected int _prefixIndex; 1.966 + 1.967 + /* 1.968 + * C.13 1.969 + */ 1.970 + protected final String decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(boolean namespaceNamePresent) throws FastInfosetException, IOException { 1.971 + final int b = read(); 1.972 + switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE(b)) { 1.973 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_3: 1.974 + { 1.975 + _octetBufferLength = EncodingConstants.XML_NAMESPACE_PREFIX_LENGTH; 1.976 + decodeUtf8StringAsCharBuffer(); 1.977 + 1.978 + if (_charBuffer[0] == 'x' && 1.979 + _charBuffer[1] == 'm' && 1.980 + _charBuffer[2] == 'l') { 1.981 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.prefixIllegal")); 1.982 + } 1.983 + 1.984 + final String s = (_stringInterning) ? new String(_charBuffer, 0, _charBufferLength).intern() : 1.985 + new String(_charBuffer, 0, _charBufferLength); 1.986 + _prefixIndex = _v.prefix.add(s); 1.987 + return s; 1.988 + } 1.989 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_5: 1.990 + { 1.991 + _octetBufferLength = EncodingConstants.XMLNS_NAMESPACE_PREFIX_LENGTH; 1.992 + decodeUtf8StringAsCharBuffer(); 1.993 + 1.994 + if (_charBuffer[0] == 'x' && 1.995 + _charBuffer[1] == 'm' && 1.996 + _charBuffer[2] == 'l' && 1.997 + _charBuffer[3] == 'n' && 1.998 + _charBuffer[4] == 's') { 1.999 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.xmlns")); 1.1000 + } 1.1001 + 1.1002 + final String s = (_stringInterning) ? new String(_charBuffer, 0, _charBufferLength).intern() : 1.1003 + new String(_charBuffer, 0, _charBufferLength); 1.1004 + _prefixIndex = _v.prefix.add(s); 1.1005 + return s; 1.1006 + } 1.1007 + case DecoderStateTables.ISTRING_SMALL_LENGTH: 1.1008 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_29: 1.1009 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_36: 1.1010 + { 1.1011 + _octetBufferLength = b + 1; 1.1012 + final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString(); 1.1013 + _prefixIndex = _v.prefix.add(s); 1.1014 + return s; 1.1015 + } 1.1016 + case DecoderStateTables.ISTRING_MEDIUM_LENGTH: 1.1017 + { 1.1018 + _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT; 1.1019 + final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString(); 1.1020 + _prefixIndex = _v.prefix.add(s); 1.1021 + return s; 1.1022 + } 1.1023 + case DecoderStateTables.ISTRING_LARGE_LENGTH: 1.1024 + { 1.1025 + final int length = (read() << 24) | 1.1026 + (read() << 16) | 1.1027 + (read() << 8) | 1.1028 + read(); 1.1029 + _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT; 1.1030 + final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString(); 1.1031 + _prefixIndex = _v.prefix.add(s); 1.1032 + return s; 1.1033 + } 1.1034 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO: 1.1035 + if (namespaceNamePresent) { 1.1036 + _prefixIndex = 0; 1.1037 + // Peak at next byte and check the index of the XML namespace name 1.1038 + if (DecoderStateTables.ISTRING_PREFIX_NAMESPACE(peek()) 1.1039 + != DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO) { 1.1040 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.wrongNamespaceName")); 1.1041 + } 1.1042 + return EncodingConstants.XML_NAMESPACE_PREFIX; 1.1043 + } else { 1.1044 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.missingNamespaceName")); 1.1045 + } 1.1046 + case DecoderStateTables.ISTRING_INDEX_SMALL: 1.1047 + _prefixIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK; 1.1048 + return _v.prefix._array[_prefixIndex - 1]; 1.1049 + case DecoderStateTables.ISTRING_INDEX_MEDIUM: 1.1050 + _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read()) 1.1051 + + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT; 1.1052 + return _v.prefix._array[_prefixIndex - 1]; 1.1053 + case DecoderStateTables.ISTRING_INDEX_LARGE: 1.1054 + _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read()) 1.1055 + + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT; 1.1056 + return _v.prefix._array[_prefixIndex - 1]; 1.1057 + default: 1.1058 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIdentifyingStringForPrefix")); 1.1059 + } 1.1060 + } 1.1061 + 1.1062 + /* 1.1063 + * C.13 1.1064 + */ 1.1065 + protected final String decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(boolean namespaceNamePresent) throws FastInfosetException, IOException { 1.1066 + final int b = read(); 1.1067 + switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE(b)) { 1.1068 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO: 1.1069 + if (namespaceNamePresent) { 1.1070 + _prefixIndex = 0; 1.1071 + // Peak at next byte and check the index of the XML namespace name 1.1072 + if (DecoderStateTables.ISTRING_PREFIX_NAMESPACE(peek()) 1.1073 + != DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO) { 1.1074 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.wrongNamespaceName")); 1.1075 + } 1.1076 + return EncodingConstants.XML_NAMESPACE_PREFIX; 1.1077 + } else { 1.1078 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.missingNamespaceName")); 1.1079 + } 1.1080 + case DecoderStateTables.ISTRING_INDEX_SMALL: 1.1081 + _prefixIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK; 1.1082 + return _v.prefix._array[_prefixIndex - 1]; 1.1083 + case DecoderStateTables.ISTRING_INDEX_MEDIUM: 1.1084 + _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read()) 1.1085 + + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT; 1.1086 + return _v.prefix._array[_prefixIndex - 1]; 1.1087 + case DecoderStateTables.ISTRING_INDEX_LARGE: 1.1088 + _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read()) 1.1089 + + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT; 1.1090 + return _v.prefix._array[_prefixIndex - 1]; 1.1091 + default: 1.1092 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIdentifyingStringForPrefix")); 1.1093 + } 1.1094 + } 1.1095 + 1.1096 + protected int _namespaceNameIndex; 1.1097 + 1.1098 + /* 1.1099 + * C.13 1.1100 + */ 1.1101 + protected final String decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(boolean prefixPresent) throws FastInfosetException, IOException { 1.1102 + final int b = read(); 1.1103 + switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE(b)) { 1.1104 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_3: 1.1105 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_5: 1.1106 + case DecoderStateTables.ISTRING_SMALL_LENGTH: 1.1107 + { 1.1108 + _octetBufferLength = b + 1; 1.1109 + final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString(); 1.1110 + _namespaceNameIndex = _v.namespaceName.add(s); 1.1111 + return s; 1.1112 + } 1.1113 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_29: 1.1114 + { 1.1115 + _octetBufferLength = EncodingConstants.XMLNS_NAMESPACE_NAME_LENGTH; 1.1116 + decodeUtf8StringAsCharBuffer(); 1.1117 + 1.1118 + if (compareCharsWithCharBufferFromEndToStart(XMLNS_NAMESPACE_NAME_CHARS)) { 1.1119 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.xmlnsConnotBeBoundToPrefix")); 1.1120 + } 1.1121 + 1.1122 + final String s = (_stringInterning) ? new String(_charBuffer, 0, _charBufferLength).intern() : 1.1123 + new String(_charBuffer, 0, _charBufferLength); 1.1124 + _namespaceNameIndex = _v.namespaceName.add(s); 1.1125 + return s; 1.1126 + } 1.1127 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_36: 1.1128 + { 1.1129 + _octetBufferLength = EncodingConstants.XML_NAMESPACE_NAME_LENGTH; 1.1130 + decodeUtf8StringAsCharBuffer(); 1.1131 + 1.1132 + if (compareCharsWithCharBufferFromEndToStart(XML_NAMESPACE_NAME_CHARS)) { 1.1133 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.illegalNamespaceName")); 1.1134 + } 1.1135 + 1.1136 + final String s = (_stringInterning) ? new String(_charBuffer, 0, _charBufferLength).intern() : 1.1137 + new String(_charBuffer, 0, _charBufferLength); 1.1138 + _namespaceNameIndex = _v.namespaceName.add(s); 1.1139 + return s; 1.1140 + } 1.1141 + case DecoderStateTables.ISTRING_MEDIUM_LENGTH: 1.1142 + { 1.1143 + _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT; 1.1144 + final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString(); 1.1145 + _namespaceNameIndex = _v.namespaceName.add(s); 1.1146 + return s; 1.1147 + } 1.1148 + case DecoderStateTables.ISTRING_LARGE_LENGTH: 1.1149 + { 1.1150 + final int length = (read() << 24) | 1.1151 + (read() << 16) | 1.1152 + (read() << 8) | 1.1153 + read(); 1.1154 + _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT; 1.1155 + final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString(); 1.1156 + _namespaceNameIndex = _v.namespaceName.add(s); 1.1157 + return s; 1.1158 + } 1.1159 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO: 1.1160 + if (prefixPresent) { 1.1161 + _namespaceNameIndex = 0; 1.1162 + return EncodingConstants.XML_NAMESPACE_NAME; 1.1163 + } else { 1.1164 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.namespaceWithoutPrefix")); 1.1165 + } 1.1166 + case DecoderStateTables.ISTRING_INDEX_SMALL: 1.1167 + _namespaceNameIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK; 1.1168 + return _v.namespaceName._array[_namespaceNameIndex - 1]; 1.1169 + case DecoderStateTables.ISTRING_INDEX_MEDIUM: 1.1170 + _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read()) 1.1171 + + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT; 1.1172 + return _v.namespaceName._array[_namespaceNameIndex - 1]; 1.1173 + case DecoderStateTables.ISTRING_INDEX_LARGE: 1.1174 + _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read()) 1.1175 + + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT; 1.1176 + return _v.namespaceName._array[_namespaceNameIndex - 1]; 1.1177 + default: 1.1178 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingForNamespaceName")); 1.1179 + } 1.1180 + } 1.1181 + 1.1182 + /* 1.1183 + * C.13 1.1184 + */ 1.1185 + protected final String decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(boolean prefixPresent) throws FastInfosetException, IOException { 1.1186 + final int b = read(); 1.1187 + switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE(b)) { 1.1188 + case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO: 1.1189 + if (prefixPresent) { 1.1190 + _namespaceNameIndex = 0; 1.1191 + return EncodingConstants.XML_NAMESPACE_NAME; 1.1192 + } else { 1.1193 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.namespaceWithoutPrefix")); 1.1194 + } 1.1195 + case DecoderStateTables.ISTRING_INDEX_SMALL: 1.1196 + _namespaceNameIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK; 1.1197 + return _v.namespaceName._array[_namespaceNameIndex - 1]; 1.1198 + case DecoderStateTables.ISTRING_INDEX_MEDIUM: 1.1199 + _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read()) 1.1200 + + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT; 1.1201 + return _v.namespaceName._array[_namespaceNameIndex - 1]; 1.1202 + case DecoderStateTables.ISTRING_INDEX_LARGE: 1.1203 + _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read()) 1.1204 + + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT; 1.1205 + return _v.namespaceName._array[_namespaceNameIndex - 1]; 1.1206 + default: 1.1207 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingForNamespaceName")); 1.1208 + } 1.1209 + } 1.1210 + 1.1211 + private boolean compareCharsWithCharBufferFromEndToStart(char[] c) { 1.1212 + int i = _charBufferLength ; 1.1213 + while (--i >= 0) { 1.1214 + if (c[i] != _charBuffer[i]) { 1.1215 + return false; 1.1216 + } 1.1217 + } 1.1218 + return true; 1.1219 + } 1.1220 + 1.1221 + /* 1.1222 + * C.22 1.1223 + */ 1.1224 + protected final String decodeNonEmptyOctetStringOnSecondBitAsUtf8String() throws FastInfosetException, IOException { 1.1225 + decodeNonEmptyOctetStringOnSecondBitAsUtf8CharArray(); 1.1226 + return new String(_charBuffer, 0, _charBufferLength); 1.1227 + } 1.1228 + 1.1229 + /* 1.1230 + * C.22 1.1231 + */ 1.1232 + protected final void decodeNonEmptyOctetStringOnSecondBitAsUtf8CharArray() throws FastInfosetException, IOException { 1.1233 + decodeNonEmptyOctetStringLengthOnSecondBit(); 1.1234 + decodeUtf8StringAsCharBuffer(); 1.1235 + } 1.1236 + 1.1237 + /* 1.1238 + * C.22 1.1239 + */ 1.1240 + protected final void decodeNonEmptyOctetStringLengthOnSecondBit() throws FastInfosetException, IOException { 1.1241 + final int b = read(); 1.1242 + switch(DecoderStateTables.ISTRING(b)) { 1.1243 + case DecoderStateTables.ISTRING_SMALL_LENGTH: 1.1244 + _octetBufferLength = b + 1; 1.1245 + break; 1.1246 + case DecoderStateTables.ISTRING_MEDIUM_LENGTH: 1.1247 + _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT; 1.1248 + break; 1.1249 + case DecoderStateTables.ISTRING_LARGE_LENGTH: 1.1250 + { 1.1251 + final int length = (read() << 24) | 1.1252 + (read() << 16) | 1.1253 + (read() << 8) | 1.1254 + read(); 1.1255 + _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT; 1.1256 + break; 1.1257 + } 1.1258 + case DecoderStateTables.ISTRING_INDEX_SMALL: 1.1259 + case DecoderStateTables.ISTRING_INDEX_MEDIUM: 1.1260 + case DecoderStateTables.ISTRING_INDEX_LARGE: 1.1261 + default: 1.1262 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingNonEmptyOctet")); 1.1263 + } 1.1264 + } 1.1265 + 1.1266 + /* 1.1267 + * C.25 1.1268 + */ 1.1269 + protected final int decodeIntegerIndexOnSecondBit() throws FastInfosetException, IOException { 1.1270 + final int b = read() | 0x80; 1.1271 + switch(DecoderStateTables.ISTRING(b)) { 1.1272 + case DecoderStateTables.ISTRING_INDEX_SMALL: 1.1273 + return b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK; 1.1274 + case DecoderStateTables.ISTRING_INDEX_MEDIUM: 1.1275 + return (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read()) 1.1276 + + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT; 1.1277 + case DecoderStateTables.ISTRING_INDEX_LARGE: 1.1278 + return (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read()) 1.1279 + + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT; 1.1280 + case DecoderStateTables.ISTRING_SMALL_LENGTH: 1.1281 + case DecoderStateTables.ISTRING_MEDIUM_LENGTH: 1.1282 + case DecoderStateTables.ISTRING_LARGE_LENGTH: 1.1283 + default: 1.1284 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIndexOnSecondBit")); 1.1285 + } 1.1286 + } 1.1287 + 1.1288 + protected final void decodeHeader() throws FastInfosetException, IOException { 1.1289 + if (!_isFastInfosetDocument()) { 1.1290 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.notFIDocument")); 1.1291 + } 1.1292 + } 1.1293 + 1.1294 + protected final void decodeRestrictedAlphabetAsCharBuffer() throws FastInfosetException, IOException { 1.1295 + if (_identifier <= EncodingConstants.RESTRICTED_ALPHABET_BUILTIN_END) { 1.1296 + decodeFourBitAlphabetOctetsAsCharBuffer(BuiltInRestrictedAlphabets.table[_identifier]); 1.1297 + // decodeAlphabetOctetsAsCharBuffer(BuiltInRestrictedAlphabets.table[_identifier]); 1.1298 + } else if (_identifier >= EncodingConstants.RESTRICTED_ALPHABET_APPLICATION_START) { 1.1299 + CharArray ca = _v.restrictedAlphabet.get(_identifier - EncodingConstants.RESTRICTED_ALPHABET_APPLICATION_START); 1.1300 + if (ca == null) { 1.1301 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.alphabetNotPresent", new Object[]{Integer.valueOf(_identifier)})); 1.1302 + } 1.1303 + decodeAlphabetOctetsAsCharBuffer(ca.ch); 1.1304 + } else { 1.1305 + // Reserved built-in algorithms for future use 1.1306 + // TODO should use sax property to decide if event will be 1.1307 + // reported, allows for support through handler if required. 1.1308 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.alphabetIdentifiersReserved")); 1.1309 + } 1.1310 + } 1.1311 + 1.1312 + protected final String decodeRestrictedAlphabetAsString() throws FastInfosetException, IOException { 1.1313 + decodeRestrictedAlphabetAsCharBuffer(); 1.1314 + return new String(_charBuffer, 0, _charBufferLength); 1.1315 + } 1.1316 + 1.1317 + protected final String decodeRAOctetsAsString(char[] restrictedAlphabet) throws FastInfosetException, IOException { 1.1318 + decodeAlphabetOctetsAsCharBuffer(restrictedAlphabet); 1.1319 + return new String(_charBuffer, 0, _charBufferLength); 1.1320 + } 1.1321 + 1.1322 + protected final void decodeFourBitAlphabetOctetsAsCharBuffer(char[] restrictedAlphabet) throws FastInfosetException, IOException { 1.1323 + _charBufferLength = 0; 1.1324 + final int characters = _octetBufferLength * 2; 1.1325 + if (_charBuffer.length < characters) { 1.1326 + _charBuffer = new char[characters]; 1.1327 + } 1.1328 + 1.1329 + int v = 0; 1.1330 + for (int i = 0; i < _octetBufferLength - 1; i++) { 1.1331 + v = _octetBuffer[_octetBufferStart++] & 0xFF; 1.1332 + _charBuffer[_charBufferLength++] = restrictedAlphabet[v >> 4]; 1.1333 + _charBuffer[_charBufferLength++] = restrictedAlphabet[v & 0x0F]; 1.1334 + } 1.1335 + v = _octetBuffer[_octetBufferStart++] & 0xFF; 1.1336 + _charBuffer[_charBufferLength++] = restrictedAlphabet[v >> 4]; 1.1337 + v &= 0x0F; 1.1338 + if (v != 0x0F) { 1.1339 + _charBuffer[_charBufferLength++] = restrictedAlphabet[v & 0x0F]; 1.1340 + } 1.1341 + } 1.1342 + 1.1343 + protected final void decodeAlphabetOctetsAsCharBuffer(char[] restrictedAlphabet) throws FastInfosetException, IOException { 1.1344 + if (restrictedAlphabet.length < 2) { 1.1345 + throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.alphabetMustContain2orMoreChars")); 1.1346 + } 1.1347 + 1.1348 + int bitsPerCharacter = 1; 1.1349 + while ((1 << bitsPerCharacter) <= restrictedAlphabet.length) { 1.1350 + bitsPerCharacter++; 1.1351 + } 1.1352 + final int terminatingValue = (1 << bitsPerCharacter) - 1; 1.1353 + 1.1354 + int characters = (_octetBufferLength << 3) / bitsPerCharacter; 1.1355 + if (characters == 0) { 1.1356 + throw new IOException(""); 1.1357 + } 1.1358 + 1.1359 + _charBufferLength = 0; 1.1360 + if (_charBuffer.length < characters) { 1.1361 + _charBuffer = new char[characters]; 1.1362 + } 1.1363 + 1.1364 + resetBits(); 1.1365 + for (int i = 0; i < characters; i++) { 1.1366 + int value = readBits(bitsPerCharacter); 1.1367 + if (bitsPerCharacter < 8 && value == terminatingValue) { 1.1368 + int octetPosition = (i * bitsPerCharacter) >>> 3; 1.1369 + if (octetPosition != _octetBufferLength - 1) { 1.1370 + throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.alphabetIncorrectlyTerminated")); 1.1371 + } 1.1372 + break; 1.1373 + } 1.1374 + _charBuffer[_charBufferLength++] = restrictedAlphabet[value]; 1.1375 + } 1.1376 + } 1.1377 + 1.1378 + private int _bitsLeftInOctet; 1.1379 + 1.1380 + private void resetBits() { 1.1381 + _bitsLeftInOctet = 0; 1.1382 + } 1.1383 + 1.1384 + private int readBits(int bits) throws IOException { 1.1385 + int value = 0; 1.1386 + while (bits > 0) { 1.1387 + if (_bitsLeftInOctet == 0) { 1.1388 + _b = _octetBuffer[_octetBufferStart++] & 0xFF; 1.1389 + _bitsLeftInOctet = 8; 1.1390 + } 1.1391 + int bit = ((_b & (1 << --_bitsLeftInOctet)) > 0) ? 1 : 0; 1.1392 + value |= (bit << --bits); 1.1393 + } 1.1394 + 1.1395 + return value; 1.1396 + } 1.1397 + 1.1398 + protected final void decodeUtf8StringAsCharBuffer() throws IOException { 1.1399 + ensureOctetBufferSize(); 1.1400 + decodeUtf8StringIntoCharBuffer(); 1.1401 + } 1.1402 + 1.1403 + protected final void decodeUtf8StringAsCharBuffer(char[] ch, int offset) throws IOException { 1.1404 + ensureOctetBufferSize(); 1.1405 + decodeUtf8StringIntoCharBuffer(ch, offset); 1.1406 + } 1.1407 + 1.1408 + protected final String decodeUtf8StringAsString() throws IOException { 1.1409 + decodeUtf8StringAsCharBuffer(); 1.1410 + return new String(_charBuffer, 0, _charBufferLength); 1.1411 + } 1.1412 + 1.1413 + protected final void decodeUtf16StringAsCharBuffer() throws IOException { 1.1414 + ensureOctetBufferSize(); 1.1415 + decodeUtf16StringIntoCharBuffer(); 1.1416 + } 1.1417 + 1.1418 + protected final String decodeUtf16StringAsString() throws IOException { 1.1419 + decodeUtf16StringAsCharBuffer(); 1.1420 + return new String(_charBuffer, 0, _charBufferLength); 1.1421 + } 1.1422 + 1.1423 + private void ensureOctetBufferSize() throws IOException { 1.1424 + if (_octetBufferEnd < (_octetBufferOffset + _octetBufferLength)) { 1.1425 + final int octetsInBuffer = _octetBufferEnd - _octetBufferOffset; 1.1426 + 1.1427 + if (_octetBuffer.length < _octetBufferLength) { 1.1428 + // Length to read is too large, resize the buffer 1.1429 + byte[] newOctetBuffer = new byte[_octetBufferLength]; 1.1430 + // Move partially read octets to the start of the buffer 1.1431 + System.arraycopy(_octetBuffer, _octetBufferOffset, newOctetBuffer, 0, octetsInBuffer); 1.1432 + _octetBuffer = newOctetBuffer; 1.1433 + } else { 1.1434 + // Move partially read octets to the start of the buffer 1.1435 + System.arraycopy(_octetBuffer, _octetBufferOffset, _octetBuffer, 0, octetsInBuffer); 1.1436 + } 1.1437 + _octetBufferOffset = 0; 1.1438 + 1.1439 + // Read as many octets as possible to fill the buffer 1.1440 + final int octetsRead = _s.read(_octetBuffer, octetsInBuffer, _octetBuffer.length - octetsInBuffer); 1.1441 + if (octetsRead < 0) { 1.1442 + throw new EOFException("Unexpeceted EOF"); 1.1443 + } 1.1444 + _octetBufferEnd = octetsInBuffer + octetsRead; 1.1445 + 1.1446 + // Check if the number of octets that have been read is not enough 1.1447 + // This can happen when underlying non-blocking is used to read 1.1448 + if (_octetBufferEnd < _octetBufferLength) { 1.1449 + repeatedRead(); 1.1450 + } 1.1451 + } 1.1452 + } 1.1453 + 1.1454 + private void repeatedRead() throws IOException { 1.1455 + // Check if the number of octets that have been read is not enough 1.1456 + while (_octetBufferEnd < _octetBufferLength) { 1.1457 + // Read as many octets as possible to fill the buffer 1.1458 + final int octetsRead = _s.read(_octetBuffer, _octetBufferEnd, _octetBuffer.length - _octetBufferEnd); 1.1459 + if (octetsRead < 0) { 1.1460 + throw new EOFException("Unexpeceted EOF"); 1.1461 + } 1.1462 + _octetBufferEnd += octetsRead; 1.1463 + } 1.1464 + } 1.1465 + 1.1466 + protected final void decodeUtf8StringIntoCharBuffer() throws IOException { 1.1467 + if (_charBuffer.length < _octetBufferLength) { 1.1468 + _charBuffer = new char[_octetBufferLength]; 1.1469 + } 1.1470 + 1.1471 + _charBufferLength = 0; 1.1472 + final int end = _octetBufferLength + _octetBufferOffset; 1.1473 + int b1; 1.1474 + while (end != _octetBufferOffset) { 1.1475 + b1 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1476 + if (DecoderStateTables.UTF8(b1) == DecoderStateTables.UTF8_ONE_BYTE) { 1.1477 + _charBuffer[_charBufferLength++] = (char) b1; 1.1478 + } else { 1.1479 + decodeTwoToFourByteUtf8Character(b1, end); 1.1480 + } 1.1481 + } 1.1482 + } 1.1483 + 1.1484 + protected final void decodeUtf8StringIntoCharBuffer(char[] ch, int offset) throws IOException { 1.1485 + _charBufferLength = offset; 1.1486 + final int end = _octetBufferLength + _octetBufferOffset; 1.1487 + int b1; 1.1488 + while (end != _octetBufferOffset) { 1.1489 + b1 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1490 + if (DecoderStateTables.UTF8(b1) == DecoderStateTables.UTF8_ONE_BYTE) { 1.1491 + ch[_charBufferLength++] = (char) b1; 1.1492 + } else { 1.1493 + decodeTwoToFourByteUtf8Character(ch, b1, end); 1.1494 + } 1.1495 + } 1.1496 + _charBufferLength -= offset; 1.1497 + } 1.1498 + 1.1499 + private void decodeTwoToFourByteUtf8Character(int b1, int end) throws IOException { 1.1500 + switch(DecoderStateTables.UTF8(b1)) { 1.1501 + case DecoderStateTables.UTF8_TWO_BYTES: 1.1502 + { 1.1503 + // Decode byte 2 1.1504 + if (end == _octetBufferOffset) { 1.1505 + decodeUtf8StringLengthTooSmall(); 1.1506 + } 1.1507 + final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1508 + if ((b2 & 0xC0) != 0x80) { 1.1509 + decodeUtf8StringIllegalState(); 1.1510 + } 1.1511 + 1.1512 + // Character guaranteed to be in [0x20, 0xD7FF] range 1.1513 + // since a character encoded in two bytes will be in the 1.1514 + // range [0x80, 0x1FFF] 1.1515 + _charBuffer[_charBufferLength++] = (char) ( 1.1516 + ((b1 & 0x1F) << 6) 1.1517 + | (b2 & 0x3F)); 1.1518 + break; 1.1519 + } 1.1520 + case DecoderStateTables.UTF8_THREE_BYTES: 1.1521 + final char c = decodeUtf8ThreeByteChar(end, b1); 1.1522 + if (XMLChar.isContent(c)) { 1.1523 + _charBuffer[_charBufferLength++] = c; 1.1524 + } else { 1.1525 + decodeUtf8StringIllegalState(); 1.1526 + } 1.1527 + break; 1.1528 + case DecoderStateTables.UTF8_FOUR_BYTES: 1.1529 + { 1.1530 + final int supplemental = decodeUtf8FourByteChar(end, b1); 1.1531 + if (XMLChar.isContent(supplemental)) { 1.1532 + _charBuffer[_charBufferLength++] = _utf8_highSurrogate; 1.1533 + _charBuffer[_charBufferLength++] = _utf8_lowSurrogate; 1.1534 + } else { 1.1535 + decodeUtf8StringIllegalState(); 1.1536 + } 1.1537 + break; 1.1538 + } 1.1539 + default: 1.1540 + decodeUtf8StringIllegalState(); 1.1541 + } 1.1542 + } 1.1543 + 1.1544 + private void decodeTwoToFourByteUtf8Character(char ch[], int b1, int end) throws IOException { 1.1545 + switch(DecoderStateTables.UTF8(b1)) { 1.1546 + case DecoderStateTables.UTF8_TWO_BYTES: 1.1547 + { 1.1548 + // Decode byte 2 1.1549 + if (end == _octetBufferOffset) { 1.1550 + decodeUtf8StringLengthTooSmall(); 1.1551 + } 1.1552 + final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1553 + if ((b2 & 0xC0) != 0x80) { 1.1554 + decodeUtf8StringIllegalState(); 1.1555 + } 1.1556 + 1.1557 + // Character guaranteed to be in [0x20, 0xD7FF] range 1.1558 + // since a character encoded in two bytes will be in the 1.1559 + // range [0x80, 0x1FFF] 1.1560 + ch[_charBufferLength++] = (char) ( 1.1561 + ((b1 & 0x1F) << 6) 1.1562 + | (b2 & 0x3F)); 1.1563 + break; 1.1564 + } 1.1565 + case DecoderStateTables.UTF8_THREE_BYTES: 1.1566 + final char c = decodeUtf8ThreeByteChar(end, b1); 1.1567 + if (XMLChar.isContent(c)) { 1.1568 + ch[_charBufferLength++] = c; 1.1569 + } else { 1.1570 + decodeUtf8StringIllegalState(); 1.1571 + } 1.1572 + break; 1.1573 + case DecoderStateTables.UTF8_FOUR_BYTES: 1.1574 + { 1.1575 + final int supplemental = decodeUtf8FourByteChar(end, b1); 1.1576 + if (XMLChar.isContent(supplemental)) { 1.1577 + ch[_charBufferLength++] = _utf8_highSurrogate; 1.1578 + ch[_charBufferLength++] = _utf8_lowSurrogate; 1.1579 + } else { 1.1580 + decodeUtf8StringIllegalState(); 1.1581 + } 1.1582 + break; 1.1583 + } 1.1584 + default: 1.1585 + decodeUtf8StringIllegalState(); 1.1586 + } 1.1587 + } 1.1588 + 1.1589 + protected final void decodeUtf8NCNameIntoCharBuffer() throws IOException { 1.1590 + _charBufferLength = 0; 1.1591 + if (_charBuffer.length < _octetBufferLength) { 1.1592 + _charBuffer = new char[_octetBufferLength]; 1.1593 + } 1.1594 + 1.1595 + final int end = _octetBufferLength + _octetBufferOffset; 1.1596 + 1.1597 + int b1 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1598 + if (DecoderStateTables.UTF8_NCNAME(b1) == DecoderStateTables.UTF8_NCNAME_NCNAME) { 1.1599 + _charBuffer[_charBufferLength++] = (char) b1; 1.1600 + } else { 1.1601 + decodeUtf8NCNameStartTwoToFourByteCharacters(b1, end); 1.1602 + } 1.1603 + 1.1604 + while (end != _octetBufferOffset) { 1.1605 + b1 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1606 + if (DecoderStateTables.UTF8_NCNAME(b1) < DecoderStateTables.UTF8_TWO_BYTES) { 1.1607 + _charBuffer[_charBufferLength++] = (char) b1; 1.1608 + } else { 1.1609 + decodeUtf8NCNameTwoToFourByteCharacters(b1, end); 1.1610 + } 1.1611 + } 1.1612 + } 1.1613 + 1.1614 + private void decodeUtf8NCNameStartTwoToFourByteCharacters(int b1, int end) throws IOException { 1.1615 + switch(DecoderStateTables.UTF8_NCNAME(b1)) { 1.1616 + case DecoderStateTables.UTF8_TWO_BYTES: 1.1617 + { 1.1618 + // Decode byte 2 1.1619 + if (end == _octetBufferOffset) { 1.1620 + decodeUtf8StringLengthTooSmall(); 1.1621 + } 1.1622 + final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1623 + if ((b2 & 0xC0) != 0x80) { 1.1624 + decodeUtf8StringIllegalState(); 1.1625 + } 1.1626 + 1.1627 + final char c = (char) ( 1.1628 + ((b1 & 0x1F) << 6) 1.1629 + | (b2 & 0x3F)); 1.1630 + if (XMLChar.isNCNameStart(c)) { 1.1631 + _charBuffer[_charBufferLength++] = c; 1.1632 + } else { 1.1633 + decodeUtf8NCNameIllegalState(); 1.1634 + } 1.1635 + break; 1.1636 + } 1.1637 + case DecoderStateTables.UTF8_THREE_BYTES: 1.1638 + final char c = decodeUtf8ThreeByteChar(end, b1); 1.1639 + if (XMLChar.isNCNameStart(c)) { 1.1640 + _charBuffer[_charBufferLength++] = c; 1.1641 + } else { 1.1642 + decodeUtf8NCNameIllegalState(); 1.1643 + } 1.1644 + break; 1.1645 + case DecoderStateTables.UTF8_FOUR_BYTES: 1.1646 + { 1.1647 + final int supplemental = decodeUtf8FourByteChar(end, b1); 1.1648 + if (XMLChar.isNCNameStart(supplemental)) { 1.1649 + _charBuffer[_charBufferLength++] = _utf8_highSurrogate; 1.1650 + _charBuffer[_charBufferLength++] = _utf8_lowSurrogate; 1.1651 + } else { 1.1652 + decodeUtf8NCNameIllegalState(); 1.1653 + } 1.1654 + break; 1.1655 + } 1.1656 + case DecoderStateTables.UTF8_NCNAME_NCNAME_CHAR: 1.1657 + default: 1.1658 + decodeUtf8NCNameIllegalState(); 1.1659 + } 1.1660 + 1.1661 + } 1.1662 + 1.1663 + private void decodeUtf8NCNameTwoToFourByteCharacters(int b1, int end) throws IOException { 1.1664 + switch(DecoderStateTables.UTF8_NCNAME(b1)) { 1.1665 + case DecoderStateTables.UTF8_TWO_BYTES: 1.1666 + { 1.1667 + // Decode byte 2 1.1668 + if (end == _octetBufferOffset) { 1.1669 + decodeUtf8StringLengthTooSmall(); 1.1670 + } 1.1671 + final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1672 + if ((b2 & 0xC0) != 0x80) { 1.1673 + decodeUtf8StringIllegalState(); 1.1674 + } 1.1675 + 1.1676 + final char c = (char) ( 1.1677 + ((b1 & 0x1F) << 6) 1.1678 + | (b2 & 0x3F)); 1.1679 + if (XMLChar.isNCName(c)) { 1.1680 + _charBuffer[_charBufferLength++] = c; 1.1681 + } else { 1.1682 + decodeUtf8NCNameIllegalState(); 1.1683 + } 1.1684 + break; 1.1685 + } 1.1686 + case DecoderStateTables.UTF8_THREE_BYTES: 1.1687 + final char c = decodeUtf8ThreeByteChar(end, b1); 1.1688 + if (XMLChar.isNCName(c)) { 1.1689 + _charBuffer[_charBufferLength++] = c; 1.1690 + } else { 1.1691 + decodeUtf8NCNameIllegalState(); 1.1692 + } 1.1693 + break; 1.1694 + case DecoderStateTables.UTF8_FOUR_BYTES: 1.1695 + { 1.1696 + final int supplemental = decodeUtf8FourByteChar(end, b1); 1.1697 + if (XMLChar.isNCName(supplemental)) { 1.1698 + _charBuffer[_charBufferLength++] = _utf8_highSurrogate; 1.1699 + _charBuffer[_charBufferLength++] = _utf8_lowSurrogate; 1.1700 + } else { 1.1701 + decodeUtf8NCNameIllegalState(); 1.1702 + } 1.1703 + break; 1.1704 + } 1.1705 + default: 1.1706 + decodeUtf8NCNameIllegalState(); 1.1707 + } 1.1708 + } 1.1709 + 1.1710 + private char decodeUtf8ThreeByteChar(int end, int b1) throws IOException { 1.1711 + // Decode byte 2 1.1712 + if (end == _octetBufferOffset) { 1.1713 + decodeUtf8StringLengthTooSmall(); 1.1714 + } 1.1715 + final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1716 + if ((b2 & 0xC0) != 0x80 1.1717 + || (b1 == 0xED && b2 >= 0xA0) 1.1718 + || ((b1 & 0x0F) == 0 && (b2 & 0x20) == 0)) { 1.1719 + decodeUtf8StringIllegalState(); 1.1720 + } 1.1721 + 1.1722 + // Decode byte 3 1.1723 + if (end == _octetBufferOffset) { 1.1724 + decodeUtf8StringLengthTooSmall(); 1.1725 + } 1.1726 + final int b3 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1727 + if ((b3 & 0xC0) != 0x80) { 1.1728 + decodeUtf8StringIllegalState(); 1.1729 + } 1.1730 + 1.1731 + return (char) ( 1.1732 + (b1 & 0x0F) << 12 1.1733 + | (b2 & 0x3F) << 6 1.1734 + | (b3 & 0x3F)); 1.1735 + } 1.1736 + 1.1737 + private char _utf8_highSurrogate; 1.1738 + private char _utf8_lowSurrogate; 1.1739 + 1.1740 + private int decodeUtf8FourByteChar(int end, int b1) throws IOException { 1.1741 + // Decode byte 2 1.1742 + if (end == _octetBufferOffset) { 1.1743 + decodeUtf8StringLengthTooSmall(); 1.1744 + } 1.1745 + final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1746 + if ((b2 & 0xC0) != 0x80 1.1747 + || ((b2 & 0x30) == 0 && (b1 & 0x07) == 0)) { 1.1748 + decodeUtf8StringIllegalState(); 1.1749 + } 1.1750 + 1.1751 + // Decode byte 3 1.1752 + if (end == _octetBufferOffset) { 1.1753 + decodeUtf8StringLengthTooSmall(); 1.1754 + } 1.1755 + final int b3 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1756 + if ((b3 & 0xC0) != 0x80) { 1.1757 + decodeUtf8StringIllegalState(); 1.1758 + } 1.1759 + 1.1760 + // Decode byte 4 1.1761 + if (end == _octetBufferOffset) { 1.1762 + decodeUtf8StringLengthTooSmall(); 1.1763 + } 1.1764 + final int b4 = _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1765 + if ((b4 & 0xC0) != 0x80) { 1.1766 + decodeUtf8StringIllegalState(); 1.1767 + } 1.1768 + 1.1769 + final int uuuuu = ((b1 << 2) & 0x001C) | ((b2 >> 4) & 0x0003); 1.1770 + if (uuuuu > 0x10) { 1.1771 + decodeUtf8StringIllegalState(); 1.1772 + } 1.1773 + final int wwww = uuuuu - 1; 1.1774 + 1.1775 + _utf8_highSurrogate = (char) (0xD800 | 1.1776 + ((wwww << 6) & 0x03C0) | ((b2 << 2) & 0x003C) | 1.1777 + ((b3 >> 4) & 0x0003)); 1.1778 + _utf8_lowSurrogate = (char) (0xDC00 | ((b3 << 6) & 0x03C0) | (b4 & 0x003F)); 1.1779 + 1.1780 + return XMLChar.supplemental(_utf8_highSurrogate, _utf8_lowSurrogate); 1.1781 + } 1.1782 + 1.1783 + private void decodeUtf8StringLengthTooSmall() throws IOException { 1.1784 + throw new IOException(CommonResourceBundle.getInstance().getString("message.deliminatorTooSmall")); 1.1785 + } 1.1786 + 1.1787 + private void decodeUtf8StringIllegalState() throws IOException { 1.1788 + throw new IOException(CommonResourceBundle.getInstance().getString("message.UTF8Encoded")); 1.1789 + } 1.1790 + 1.1791 + private void decodeUtf8NCNameIllegalState() throws IOException { 1.1792 + throw new IOException(CommonResourceBundle.getInstance().getString("message.UTF8EncodedNCName")); 1.1793 + } 1.1794 + 1.1795 + private void decodeUtf16StringIntoCharBuffer() throws IOException { 1.1796 + _charBufferLength = _octetBufferLength / 2; 1.1797 + if (_charBuffer.length < _charBufferLength) { 1.1798 + _charBuffer = new char[_charBufferLength]; 1.1799 + } 1.1800 + 1.1801 + for (int i = 0; i < _charBufferLength; i++) { 1.1802 + final char c = (char)((read() << 8) | read()); 1.1803 + // TODO check c is a valid Char character 1.1804 + _charBuffer[i] = c; 1.1805 + } 1.1806 + 1.1807 + } 1.1808 + 1.1809 + protected String createQualifiedNameString(String second) { 1.1810 + return createQualifiedNameString(XMLNS_NAMESPACE_PREFIX_CHARS, second); 1.1811 + } 1.1812 + 1.1813 + protected String createQualifiedNameString(char[] first, String second) { 1.1814 + final int l1 = first.length; 1.1815 + final int l2 = second.length(); 1.1816 + final int total = l1 + l2 + 1; 1.1817 + if (total < _charBuffer.length) { 1.1818 + System.arraycopy(first, 0, _charBuffer, 0, l1); 1.1819 + _charBuffer[l1] = ':'; 1.1820 + second.getChars(0, l2, _charBuffer, l1 + 1); 1.1821 + return new String(_charBuffer, 0, total); 1.1822 + } else { 1.1823 + StringBuffer b = new StringBuffer(new String(first)); 1.1824 + b.append(':'); 1.1825 + b.append(second); 1.1826 + return b.toString(); 1.1827 + } 1.1828 + } 1.1829 + 1.1830 + protected final int read() throws IOException { 1.1831 + if (_octetBufferOffset < _octetBufferEnd) { 1.1832 + return _octetBuffer[_octetBufferOffset++] & 0xFF; 1.1833 + } else { 1.1834 + _octetBufferEnd = _s.read(_octetBuffer); 1.1835 + if (_octetBufferEnd < 0) { 1.1836 + throw new EOFException(CommonResourceBundle.getInstance().getString("message.EOF")); 1.1837 + } 1.1838 + 1.1839 + _octetBufferOffset = 1; 1.1840 + return _octetBuffer[0] & 0xFF; 1.1841 + } 1.1842 + } 1.1843 + 1.1844 + protected final void closeIfRequired() throws IOException { 1.1845 + if (_s != null && _needForceStreamClose) { 1.1846 + _s.close(); 1.1847 + } 1.1848 + } 1.1849 + 1.1850 + protected final int peek() throws IOException { 1.1851 + return peek(null); 1.1852 + } 1.1853 + 1.1854 + protected final int peek(OctetBufferListener octetBufferListener) throws IOException { 1.1855 + if (_octetBufferOffset < _octetBufferEnd) { 1.1856 + return _octetBuffer[_octetBufferOffset] & 0xFF; 1.1857 + } else { 1.1858 + if (octetBufferListener != null) { 1.1859 + octetBufferListener.onBeforeOctetBufferOverwrite(); 1.1860 + } 1.1861 + 1.1862 + _octetBufferEnd = _s.read(_octetBuffer); 1.1863 + if (_octetBufferEnd < 0) { 1.1864 + throw new EOFException(CommonResourceBundle.getInstance().getString("message.EOF")); 1.1865 + } 1.1866 + 1.1867 + _octetBufferOffset = 0; 1.1868 + return _octetBuffer[0] & 0xFF; 1.1869 + } 1.1870 + } 1.1871 + 1.1872 + protected final int peek2(OctetBufferListener octetBufferListener) throws IOException { 1.1873 + if (_octetBufferOffset + 1 < _octetBufferEnd) { 1.1874 + return _octetBuffer[_octetBufferOffset + 1] & 0xFF; 1.1875 + } else { 1.1876 + if (octetBufferListener != null) { 1.1877 + octetBufferListener.onBeforeOctetBufferOverwrite(); 1.1878 + } 1.1879 + 1.1880 + int offset = 0; 1.1881 + if (_octetBufferOffset < _octetBufferEnd) { 1.1882 + _octetBuffer[0] = _octetBuffer[_octetBufferOffset]; 1.1883 + offset = 1; 1.1884 + } 1.1885 + _octetBufferEnd = _s.read(_octetBuffer, offset, _octetBuffer.length - offset); 1.1886 + 1.1887 + if (_octetBufferEnd < 0) { 1.1888 + throw new EOFException(CommonResourceBundle.getInstance().getString("message.EOF")); 1.1889 + } 1.1890 + 1.1891 + _octetBufferOffset = 0; 1.1892 + return _octetBuffer[1] & 0xFF; 1.1893 + } 1.1894 + } 1.1895 + 1.1896 + protected class EncodingAlgorithmInputStream extends InputStream { 1.1897 + 1.1898 + public int read() throws IOException { 1.1899 + if (_octetBufferStart < _octetBufferOffset) { 1.1900 + return (_octetBuffer[_octetBufferStart++] & 0xFF); 1.1901 + } else { 1.1902 + return -1; 1.1903 + } 1.1904 + } 1.1905 + 1.1906 + @Override 1.1907 + public int read(byte b[]) throws IOException { 1.1908 + return read(b, 0, b.length); 1.1909 + } 1.1910 + 1.1911 + @Override 1.1912 + public int read(byte b[], int off, int len) throws IOException { 1.1913 + if (b == null) { 1.1914 + throw new NullPointerException(); 1.1915 + } else if ((off < 0) || (off > b.length) || (len < 0) || 1.1916 + ((off + len) > b.length) || ((off + len) < 0)) { 1.1917 + throw new IndexOutOfBoundsException(); 1.1918 + } else if (len == 0) { 1.1919 + return 0; 1.1920 + } 1.1921 + 1.1922 + final int newOctetBufferStart = _octetBufferStart + len; 1.1923 + if (newOctetBufferStart < _octetBufferOffset) { 1.1924 + System.arraycopy(_octetBuffer, _octetBufferStart, b, off, len); 1.1925 + _octetBufferStart = newOctetBufferStart; 1.1926 + return len; 1.1927 + } else if (_octetBufferStart < _octetBufferOffset) { 1.1928 + final int bytesToRead = _octetBufferOffset - _octetBufferStart; 1.1929 + System.arraycopy(_octetBuffer, _octetBufferStart, b, off, bytesToRead); 1.1930 + _octetBufferStart += bytesToRead; 1.1931 + return bytesToRead; 1.1932 + } else { 1.1933 + return -1; 1.1934 + } 1.1935 + } 1.1936 + } 1.1937 + 1.1938 + protected final boolean _isFastInfosetDocument() throws IOException { 1.1939 + // Fill up the octet buffer 1.1940 + peek(); 1.1941 + 1.1942 + _octetBufferLength = EncodingConstants.BINARY_HEADER.length; 1.1943 + ensureOctetBufferSize(); 1.1944 + _octetBufferOffset += _octetBufferLength; 1.1945 + 1.1946 + // Check for binary header 1.1947 + if (_octetBuffer[0] != EncodingConstants.BINARY_HEADER[0] || 1.1948 + _octetBuffer[1] != EncodingConstants.BINARY_HEADER[1] || 1.1949 + _octetBuffer[2] != EncodingConstants.BINARY_HEADER[2] || 1.1950 + _octetBuffer[3] != EncodingConstants.BINARY_HEADER[3]) { 1.1951 + 1.1952 + // Check for each form of XML declaration 1.1953 + for (int i = 0; i < EncodingConstants.XML_DECLARATION_VALUES.length; i++) { 1.1954 + _octetBufferLength = EncodingConstants.XML_DECLARATION_VALUES[i].length - _octetBufferOffset; 1.1955 + ensureOctetBufferSize(); 1.1956 + _octetBufferOffset += _octetBufferLength; 1.1957 + 1.1958 + // Check XML declaration 1.1959 + if (arrayEquals(_octetBuffer, 0, 1.1960 + EncodingConstants.XML_DECLARATION_VALUES[i], 1.1961 + EncodingConstants.XML_DECLARATION_VALUES[i].length)) { 1.1962 + _octetBufferLength = EncodingConstants.BINARY_HEADER.length; 1.1963 + ensureOctetBufferSize(); 1.1964 + 1.1965 + // Check for binary header 1.1966 + if (_octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[0] || 1.1967 + _octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[1] || 1.1968 + _octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[2] || 1.1969 + _octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[3]) { 1.1970 + return false; 1.1971 + } else { 1.1972 + // Fast Infoset document with XML declaration and binary header 1.1973 + return true; 1.1974 + } 1.1975 + } 1.1976 + } 1.1977 + 1.1978 + return false; 1.1979 + } 1.1980 + 1.1981 + // Fast Infoset document with binary header 1.1982 + return true; 1.1983 + } 1.1984 + 1.1985 + private boolean arrayEquals(byte[] b1, int offset, byte[] b2, int length) { 1.1986 + for (int i = 0; i < length; i++) { 1.1987 + if (b1[offset + i] != b2[i]) { 1.1988 + return false; 1.1989 + } 1.1990 + } 1.1991 + 1.1992 + return true; 1.1993 + } 1.1994 + 1.1995 + static public boolean isFastInfosetDocument(InputStream s) throws IOException { 1.1996 + // TODO 1.1997 + // Check for <?xml declaration with 'finf' encoding 1.1998 + 1.1999 + final byte[] header = new byte[4]; 1.2000 + s.read(header); 1.2001 + if (header[0] != EncodingConstants.BINARY_HEADER[0] || 1.2002 + header[1] != EncodingConstants.BINARY_HEADER[1] || 1.2003 + header[2] != EncodingConstants.BINARY_HEADER[2] || 1.2004 + header[3] != EncodingConstants.BINARY_HEADER[3]) { 1.2005 + return false; 1.2006 + } 1.2007 + 1.2008 + // TODO 1.2009 + return true; 1.2010 + } 1.2011 +}