src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/Decoder.java

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

author
aoqi
date
Thu, 12 Oct 2017 19:44:07 +0800
changeset 760
e530533619ec
parent 637
9c07ef4934dd
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 *
aoqi@0 25 * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
aoqi@0 26 */
aoqi@0 27
aoqi@0 28 package com.sun.xml.internal.fastinfoset;
aoqi@0 29
aoqi@0 30 import com.sun.xml.internal.fastinfoset.alphabet.BuiltInRestrictedAlphabets;
aoqi@0 31 import com.sun.xml.internal.fastinfoset.org.apache.xerces.util.XMLChar;
aoqi@0 32 import com.sun.xml.internal.fastinfoset.util.CharArray;
aoqi@0 33 import com.sun.xml.internal.fastinfoset.util.CharArrayArray;
aoqi@0 34 import com.sun.xml.internal.fastinfoset.util.CharArrayString;
aoqi@0 35 import com.sun.xml.internal.fastinfoset.util.ContiguousCharArrayArray;
aoqi@0 36 import com.sun.xml.internal.fastinfoset.util.DuplicateAttributeVerifier;
aoqi@0 37 import com.sun.xml.internal.fastinfoset.util.PrefixArray;
aoqi@0 38 import com.sun.xml.internal.fastinfoset.util.QualifiedNameArray;
aoqi@0 39 import com.sun.xml.internal.fastinfoset.util.StringArray;
aoqi@0 40 import com.sun.xml.internal.fastinfoset.vocab.ParserVocabulary;
aoqi@0 41 import java.io.EOFException;
aoqi@0 42 import java.io.IOException;
aoqi@0 43 import java.io.InputStream;
aoqi@0 44 import java.util.ArrayList;
aoqi@0 45 import java.util.HashMap;
aoqi@0 46 import java.util.List;
aoqi@0 47 import java.util.Map;
aoqi@0 48 import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
aoqi@0 49 import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetParser;
aoqi@0 50
aoqi@0 51 /**
aoqi@0 52 * Abstract decoder for developing concrete encoders.
aoqi@0 53 *
aoqi@0 54 * Concrete implementations extending Decoder will utilize methods on Decoder
aoqi@0 55 * to decode XML infoset according to the Fast Infoset standard. It is the
aoqi@0 56 * responsibility of the concrete implementation to ensure that methods are
aoqi@0 57 * invoked in the correct order to correctly decode a valid fast infoset
aoqi@0 58 * document.
aoqi@0 59 *
aoqi@0 60 * <p>
aoqi@0 61 * This class extends org.sax.xml.DefaultHandler so that concrete SAX
aoqi@0 62 * implementations can be used with javax.xml.parsers.SAXParser and the parse
aoqi@0 63 * methods that take org.sax.xml.DefaultHandler as a parameter.
aoqi@0 64 *
aoqi@0 65 * <p>
aoqi@0 66 * Buffering of octets that are read from an {@link java.io.InputStream} is
aoqi@0 67 * supported in a similar manner to a {@link java.io.BufferedInputStream}.
aoqi@0 68 * Combining buffering with decoding enables better performance.
aoqi@0 69 *
aoqi@0 70 * <p>
aoqi@0 71 * More than one fast infoset document may be decoded from the
aoqi@0 72 * {@link java.io.InputStream}.
aoqi@0 73 */
aoqi@0 74 public abstract class Decoder implements FastInfosetParser {
aoqi@0 75
aoqi@0 76 private static final char[] XML_NAMESPACE_NAME_CHARS =
aoqi@0 77 EncodingConstants.XML_NAMESPACE_NAME.toCharArray();
aoqi@0 78
aoqi@0 79 private static final char[] XMLNS_NAMESPACE_PREFIX_CHARS =
aoqi@0 80 EncodingConstants.XMLNS_NAMESPACE_PREFIX.toCharArray();
aoqi@0 81
aoqi@0 82 private static final char[] XMLNS_NAMESPACE_NAME_CHARS =
aoqi@0 83 EncodingConstants.XMLNS_NAMESPACE_NAME.toCharArray();
aoqi@0 84
aoqi@0 85 /**
aoqi@0 86 * String interning system property.
aoqi@0 87 */
aoqi@0 88 public static final String STRING_INTERNING_SYSTEM_PROPERTY =
aoqi@0 89 "com.sun.xml.internal.fastinfoset.parser.string-interning";
aoqi@0 90
aoqi@0 91 /**
aoqi@0 92 * Internal buffer size interning system property.
aoqi@0 93 */
aoqi@0 94 public static final String BUFFER_SIZE_SYSTEM_PROPERTY =
aoqi@0 95 "com.sun.xml.internal.fastinfoset.parser.buffer-size";
aoqi@0 96
aoqi@0 97 private static boolean _stringInterningSystemDefault = false;
aoqi@0 98
aoqi@0 99 private static int _bufferSizeSystemDefault = 1024;
aoqi@0 100
aoqi@0 101 static {
aoqi@0 102 String p = System.getProperty(STRING_INTERNING_SYSTEM_PROPERTY,
aoqi@0 103 Boolean.toString(_stringInterningSystemDefault));
aoqi@0 104 _stringInterningSystemDefault = Boolean.valueOf(p).booleanValue();
aoqi@0 105
aoqi@0 106 p = System.getProperty(BUFFER_SIZE_SYSTEM_PROPERTY,
aoqi@0 107 Integer.toString(_bufferSizeSystemDefault));
aoqi@0 108 try {
aoqi@0 109 int i = Integer.valueOf(p).intValue();
aoqi@0 110 if (i > 0) {
aoqi@0 111 _bufferSizeSystemDefault = i;
aoqi@0 112 }
aoqi@0 113 } catch (NumberFormatException e) {
aoqi@0 114 }
aoqi@0 115 }
aoqi@0 116
aoqi@0 117 /**
aoqi@0 118 * True if string interning is performed by the decoder.
aoqi@0 119 */
aoqi@0 120 private boolean _stringInterning = _stringInterningSystemDefault;
aoqi@0 121
aoqi@0 122 /**
aoqi@0 123 * The input stream from which the fast infoset document is being read.
aoqi@0 124 */
aoqi@0 125 private InputStream _s;
aoqi@0 126
aoqi@0 127 /**
aoqi@0 128 * The map of URIs to referenced vocabularies.
aoqi@0 129 */
aoqi@0 130 private Map _externalVocabularies;
aoqi@0 131
aoqi@0 132 /**
aoqi@0 133 * True if can parse fragments.
aoqi@0 134 */
aoqi@0 135 protected boolean _parseFragments;
aoqi@0 136
aoqi@0 137 /**
aoqi@0 138 * True if needs to close underlying input stream.
aoqi@0 139 */
aoqi@0 140 protected boolean _needForceStreamClose;
aoqi@0 141
aoqi@0 142 /**
aoqi@0 143 * True if the vocabulary is internally created by decoder.
aoqi@0 144 */
aoqi@0 145 private boolean _vIsInternal;
aoqi@0 146
aoqi@0 147 /**
aoqi@0 148 * The list of Notation Information Items that are part of the
aoqi@0 149 * Document Information Item.
aoqi@0 150 */
aoqi@0 151 protected List _notations;
aoqi@0 152
aoqi@0 153 /**
aoqi@0 154 * The list of Unparsed Entity Information Items that are part of the
aoqi@0 155 * Document Information Item.
aoqi@0 156 */
aoqi@0 157 protected List _unparsedEntities;
aoqi@0 158
aoqi@0 159 /**
aoqi@0 160 * The map of URIs to registered encoding algorithms.
aoqi@0 161 */
aoqi@0 162 protected Map _registeredEncodingAlgorithms = new HashMap();
aoqi@0 163
aoqi@0 164 /**
aoqi@0 165 * The vocabulary used for decoding.
aoqi@0 166 */
aoqi@0 167 protected ParserVocabulary _v;
aoqi@0 168
aoqi@0 169 /**
aoqi@0 170 * The prefix table of the vocabulary.
aoqi@0 171 */
aoqi@0 172 protected PrefixArray _prefixTable;
aoqi@0 173
aoqi@0 174 /**
aoqi@0 175 * The element name table of the vocabulary.
aoqi@0 176 */
aoqi@0 177 protected QualifiedNameArray _elementNameTable;
aoqi@0 178
aoqi@0 179 /**
aoqi@0 180 * The attribute name table of the vocabulary.
aoqi@0 181 */
aoqi@0 182 protected QualifiedNameArray _attributeNameTable;
aoqi@0 183
aoqi@0 184 /**
aoqi@0 185 * The character content chunk table of the vocabulary.
aoqi@0 186 */
aoqi@0 187 protected ContiguousCharArrayArray _characterContentChunkTable;
aoqi@0 188
aoqi@0 189 /**
aoqi@0 190 * The attribute value table of the vocabulary.
aoqi@0 191 */
aoqi@0 192 protected StringArray _attributeValueTable;
aoqi@0 193
aoqi@0 194 /**
aoqi@0 195 * The current octet that is being read
aoqi@0 196 */
aoqi@0 197 protected int _b;
aoqi@0 198
aoqi@0 199 /**
aoqi@0 200 * True if an information item is terminated.
aoqi@0 201 */
aoqi@0 202 protected boolean _terminate;
aoqi@0 203
aoqi@0 204 /**
aoqi@0 205 * True if two information item are terminated in direct sequence.
aoqi@0 206 */
aoqi@0 207 protected boolean _doubleTerminate;
aoqi@0 208
aoqi@0 209 /**
aoqi@0 210 * True if an entry is required to be added to a table
aoqi@0 211 */
aoqi@0 212 protected boolean _addToTable;
aoqi@0 213
aoqi@0 214 /**
aoqi@0 215 * The vocabulary table index to an indexed non identifying string.
aoqi@0 216 */
aoqi@0 217 protected int _integer;
aoqi@0 218
aoqi@0 219 /**
aoqi@0 220 * The vocabulary table index of identifying string or the identifier of
aoqi@0 221 * an encoding algorithm or restricted alphabet.
aoqi@0 222 */
aoqi@0 223 protected int _identifier;
aoqi@0 224
aoqi@0 225 /**
aoqi@0 226 * The size of the internal buffer.
aoqi@0 227 */
aoqi@0 228 protected int _bufferSize = _bufferSizeSystemDefault;
aoqi@0 229
aoqi@0 230 /**
aoqi@0 231 * The internal buffer used for decoding.
aoqi@0 232 */
aoqi@0 233 protected byte[] _octetBuffer = new byte[_bufferSizeSystemDefault];
aoqi@0 234
aoqi@0 235 /**
aoqi@0 236 * A mark into the internal buffer used for decoding encoded algorithm
aoqi@0 237 * or restricted alphabet data.
aoqi@0 238 */
aoqi@0 239 protected int _octetBufferStart;
aoqi@0 240
aoqi@0 241 /**
aoqi@0 242 * The offset into the buffer to read the next byte.
aoqi@0 243 */
aoqi@0 244 protected int _octetBufferOffset;
aoqi@0 245
aoqi@0 246 /**
aoqi@0 247 * The end of the buffer.
aoqi@0 248 */
aoqi@0 249 protected int _octetBufferEnd;
aoqi@0 250
aoqi@0 251 /**
aoqi@0 252 * The length of some octets in the buffer that are to be read.
aoqi@0 253 */
aoqi@0 254 protected int _octetBufferLength;
aoqi@0 255
aoqi@0 256 /**
aoqi@0 257 * The internal buffer of characters.
aoqi@0 258 */
aoqi@0 259 protected char[] _charBuffer = new char[512];
aoqi@0 260
aoqi@0 261 /**
aoqi@0 262 * The length of characters in the buffer of characters.
aoqi@0 263 */
aoqi@0 264 protected int _charBufferLength;
aoqi@0 265
aoqi@0 266 /**
aoqi@0 267 * Helper class that checks for duplicate attribute information items.
aoqi@0 268 */
aoqi@0 269 protected DuplicateAttributeVerifier _duplicateAttributeVerifier = new DuplicateAttributeVerifier();
aoqi@0 270
aoqi@0 271 /**
aoqi@0 272 * Default constructor for the Decoder.
aoqi@0 273 */
aoqi@0 274 protected Decoder() {
aoqi@0 275 _v = new ParserVocabulary();
aoqi@0 276 _prefixTable = _v.prefix;
aoqi@0 277 _elementNameTable = _v.elementName;
aoqi@0 278 _attributeNameTable = _v.attributeName;
aoqi@0 279 _characterContentChunkTable = _v.characterContentChunk;
aoqi@0 280 _attributeValueTable = _v.attributeValue;
aoqi@0 281 _vIsInternal = true;
aoqi@0 282 }
aoqi@0 283
aoqi@0 284
aoqi@0 285 // FastInfosetParser interface
aoqi@0 286
aoqi@0 287 /**
aoqi@0 288 * {@inheritDoc}
aoqi@0 289 */
aoqi@0 290 public void setStringInterning(boolean stringInterning) {
aoqi@0 291 _stringInterning = stringInterning;
aoqi@0 292 }
aoqi@0 293
aoqi@0 294 /**
aoqi@0 295 * {@inheritDoc}
aoqi@0 296 */
aoqi@0 297 public boolean getStringInterning() {
aoqi@0 298 return _stringInterning;
aoqi@0 299 }
aoqi@0 300
aoqi@0 301 /**
aoqi@0 302 * {@inheritDoc}
aoqi@0 303 */
aoqi@0 304 public void setBufferSize(int bufferSize) {
aoqi@0 305 if (_bufferSize > _octetBuffer.length) {
aoqi@0 306 _bufferSize = bufferSize;
aoqi@0 307 }
aoqi@0 308 }
aoqi@0 309
aoqi@0 310 /**
aoqi@0 311 * {@inheritDoc}
aoqi@0 312 */
aoqi@0 313 public int getBufferSize() {
aoqi@0 314 return _bufferSize;
aoqi@0 315 }
aoqi@0 316
aoqi@0 317 /**
aoqi@0 318 * {@inheritDoc}
aoqi@0 319 */
aoqi@0 320 public void setRegisteredEncodingAlgorithms(Map algorithms) {
aoqi@0 321 _registeredEncodingAlgorithms = algorithms;
aoqi@0 322 if (_registeredEncodingAlgorithms == null) {
aoqi@0 323 _registeredEncodingAlgorithms = new HashMap();
aoqi@0 324 }
aoqi@0 325 }
aoqi@0 326
aoqi@0 327 /**
aoqi@0 328 * {@inheritDoc}
aoqi@0 329 */
aoqi@0 330 public Map getRegisteredEncodingAlgorithms() {
aoqi@0 331 return _registeredEncodingAlgorithms;
aoqi@0 332 }
aoqi@0 333
aoqi@0 334 /**
aoqi@0 335 * {@inheritDoc}
aoqi@0 336 */
aoqi@0 337 public void setExternalVocabularies(Map referencedVocabualries) {
aoqi@0 338 if (referencedVocabualries != null) {
aoqi@0 339 // Clone the input map
aoqi@0 340 _externalVocabularies = new HashMap();
aoqi@0 341 _externalVocabularies.putAll(referencedVocabualries);
aoqi@0 342 } else {
aoqi@0 343 _externalVocabularies = null;
aoqi@0 344 }
aoqi@0 345 }
aoqi@0 346
aoqi@0 347 /**
aoqi@0 348 * {@inheritDoc}
aoqi@0 349 */
aoqi@0 350 public Map getExternalVocabularies() {
aoqi@0 351 return _externalVocabularies;
aoqi@0 352 }
aoqi@0 353
aoqi@0 354 /**
aoqi@0 355 * {@inheritDoc}
aoqi@0 356 */
aoqi@0 357 public void setParseFragments(boolean parseFragments) {
aoqi@0 358 _parseFragments = parseFragments;
aoqi@0 359 }
aoqi@0 360
aoqi@0 361 /**
aoqi@0 362 * {@inheritDoc}
aoqi@0 363 */
aoqi@0 364 public boolean getParseFragments() {
aoqi@0 365 return _parseFragments;
aoqi@0 366 }
aoqi@0 367
aoqi@0 368 /**
aoqi@0 369 * {@inheritDoc}
aoqi@0 370 */
aoqi@0 371 public void setForceStreamClose(boolean needForceStreamClose) {
aoqi@0 372 _needForceStreamClose = needForceStreamClose;
aoqi@0 373 }
aoqi@0 374
aoqi@0 375 /**
aoqi@0 376 * {@inheritDoc}
aoqi@0 377 */
aoqi@0 378 public boolean getForceStreamClose() {
aoqi@0 379 return _needForceStreamClose;
aoqi@0 380 }
aoqi@0 381
aoqi@0 382 // End FastInfosetParser interface
aoqi@0 383
aoqi@0 384 /**
aoqi@0 385 * Reset the decoder for reuse decoding another XML infoset.
aoqi@0 386 */
aoqi@0 387 public void reset() {
aoqi@0 388 _terminate = _doubleTerminate = false;
aoqi@0 389 }
aoqi@0 390
aoqi@0 391 /**
aoqi@0 392 * Set the ParserVocabulary to be used for decoding.
aoqi@0 393 *
aoqi@0 394 * @param v the vocabulary to be used for decoding.
aoqi@0 395 */
aoqi@0 396 public void setVocabulary(ParserVocabulary v) {
aoqi@0 397 _v = v;
aoqi@0 398 _prefixTable = _v.prefix;
aoqi@0 399 _elementNameTable = _v.elementName;
aoqi@0 400 _attributeNameTable = _v.attributeName;
aoqi@0 401 _characterContentChunkTable = _v.characterContentChunk;
aoqi@0 402 _attributeValueTable = _v.attributeValue;
aoqi@0 403 _vIsInternal = false;
aoqi@0 404 }
aoqi@0 405
aoqi@0 406 /**
aoqi@0 407 * Set the InputStream to decode the fast infoset document.
aoqi@0 408 *
aoqi@0 409 * @param s the InputStream where the fast infoset document is decoded from.
aoqi@0 410 */
aoqi@0 411 public void setInputStream(InputStream s) {
aoqi@0 412 _s = s;
aoqi@0 413 _octetBufferOffset = 0;
aoqi@0 414 _octetBufferEnd = 0;
aoqi@0 415 if (_vIsInternal == true) {
aoqi@0 416 _v.clear();
aoqi@0 417 }
aoqi@0 418 }
aoqi@0 419
aoqi@0 420 protected final void decodeDII() throws FastInfosetException, IOException {
aoqi@0 421 final int b = read();
aoqi@0 422 if (b == EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) {
aoqi@0 423 decodeInitialVocabulary();
aoqi@0 424 } else if (b != 0) {
aoqi@0 425 throw new IOException(CommonResourceBundle.getInstance().
aoqi@0 426 getString("message.optinalValues"));
aoqi@0 427 }
aoqi@0 428 }
aoqi@0 429
aoqi@0 430 protected final void decodeAdditionalData() throws FastInfosetException, IOException {
aoqi@0 431 final int noOfItems = decodeNumberOfItemsOfSequence();
aoqi@0 432
aoqi@0 433 for (int i = 0; i < noOfItems; i++) {
aoqi@0 434 /*String URI = */decodeNonEmptyOctetStringOnSecondBitAsUtf8String();
aoqi@0 435
aoqi@0 436 decodeNonEmptyOctetStringLengthOnSecondBit();
aoqi@0 437 ensureOctetBufferSize();
aoqi@0 438 _octetBufferStart = _octetBufferOffset;
aoqi@0 439 _octetBufferOffset += _octetBufferLength;
aoqi@0 440 }
aoqi@0 441 }
aoqi@0 442
aoqi@0 443 protected final void decodeInitialVocabulary() throws FastInfosetException, IOException {
aoqi@0 444 // First 5 optionals of 13 bit optional field
aoqi@0 445 int b = read();
aoqi@0 446 // Next 8 optionals of 13 bit optional field
aoqi@0 447 int b2 = read();
aoqi@0 448
aoqi@0 449 // Optimize for the most common case
aoqi@0 450 if (b == EncodingConstants.INITIAL_VOCABULARY_EXTERNAL_VOCABULARY_FLAG && b2 == 0) {
aoqi@0 451 decodeExternalVocabularyURI();
aoqi@0 452 return;
aoqi@0 453 }
aoqi@0 454
aoqi@0 455 if ((b & EncodingConstants.INITIAL_VOCABULARY_EXTERNAL_VOCABULARY_FLAG) > 0) {
aoqi@0 456 decodeExternalVocabularyURI();
aoqi@0 457 }
aoqi@0 458
aoqi@0 459 if ((b & EncodingConstants.INITIAL_VOCABULARY_RESTRICTED_ALPHABETS_FLAG) > 0) {
aoqi@0 460 decodeTableItems(_v.restrictedAlphabet);
aoqi@0 461 }
aoqi@0 462
aoqi@0 463 if ((b & EncodingConstants.INITIAL_VOCABULARY_ENCODING_ALGORITHMS_FLAG) > 0) {
aoqi@0 464 decodeTableItems(_v.encodingAlgorithm);
aoqi@0 465 }
aoqi@0 466
aoqi@0 467 if ((b & EncodingConstants.INITIAL_VOCABULARY_PREFIXES_FLAG) > 0) {
aoqi@0 468 decodeTableItems(_v.prefix);
aoqi@0 469 }
aoqi@0 470
aoqi@0 471 if ((b & EncodingConstants.INITIAL_VOCABULARY_NAMESPACE_NAMES_FLAG) > 0) {
aoqi@0 472 decodeTableItems(_v.namespaceName);
aoqi@0 473 }
aoqi@0 474
aoqi@0 475 if ((b2 & EncodingConstants.INITIAL_VOCABULARY_LOCAL_NAMES_FLAG) > 0) {
aoqi@0 476 decodeTableItems(_v.localName);
aoqi@0 477 }
aoqi@0 478
aoqi@0 479 if ((b2 & EncodingConstants.INITIAL_VOCABULARY_OTHER_NCNAMES_FLAG) > 0) {
aoqi@0 480 decodeTableItems(_v.otherNCName);
aoqi@0 481 }
aoqi@0 482
aoqi@0 483 if ((b2 & EncodingConstants.INITIAL_VOCABULARY_OTHER_URIS_FLAG) > 0) {
aoqi@0 484 decodeTableItems(_v.otherURI);
aoqi@0 485 }
aoqi@0 486
aoqi@0 487 if ((b2 & EncodingConstants.INITIAL_VOCABULARY_ATTRIBUTE_VALUES_FLAG) > 0) {
aoqi@0 488 decodeTableItems(_v.attributeValue);
aoqi@0 489 }
aoqi@0 490
aoqi@0 491 if ((b2 & EncodingConstants.INITIAL_VOCABULARY_CONTENT_CHARACTER_CHUNKS_FLAG) > 0) {
aoqi@0 492 decodeTableItems(_v.characterContentChunk);
aoqi@0 493 }
aoqi@0 494
aoqi@0 495 if ((b2 & EncodingConstants.INITIAL_VOCABULARY_OTHER_STRINGS_FLAG) > 0) {
aoqi@0 496 decodeTableItems(_v.otherString);
aoqi@0 497 }
aoqi@0 498
aoqi@0 499 if ((b2 & EncodingConstants.INITIAL_VOCABULARY_ELEMENT_NAME_SURROGATES_FLAG) > 0) {
aoqi@0 500 decodeTableItems(_v.elementName, false);
aoqi@0 501 }
aoqi@0 502
aoqi@0 503 if ((b2 & EncodingConstants.INITIAL_VOCABULARY_ATTRIBUTE_NAME_SURROGATES_FLAG) > 0) {
aoqi@0 504 decodeTableItems(_v.attributeName, true);
aoqi@0 505 }
aoqi@0 506 }
aoqi@0 507
aoqi@0 508 private void decodeExternalVocabularyURI() throws FastInfosetException, IOException {
aoqi@0 509 if (_externalVocabularies == null) {
aoqi@0 510 throw new IOException(CommonResourceBundle.
aoqi@0 511 getInstance().getString("message.noExternalVocabularies"));
aoqi@0 512 }
aoqi@0 513
aoqi@0 514 String externalVocabularyURI =
aoqi@0 515 decodeNonEmptyOctetStringOnSecondBitAsUtf8String();
aoqi@0 516
aoqi@0 517 Object o = _externalVocabularies.get(externalVocabularyURI);
aoqi@0 518 if (o instanceof ParserVocabulary) {
aoqi@0 519 _v.setReferencedVocabulary(externalVocabularyURI,
aoqi@0 520 (ParserVocabulary)o, false);
aoqi@0 521 } else if (o instanceof com.sun.xml.internal.org.jvnet.fastinfoset.ExternalVocabulary) {
aoqi@0 522 com.sun.xml.internal.org.jvnet.fastinfoset.ExternalVocabulary v =
aoqi@0 523 (com.sun.xml.internal.org.jvnet.fastinfoset.ExternalVocabulary)o;
aoqi@0 524 ParserVocabulary pv = new ParserVocabulary(v.vocabulary);
aoqi@0 525
aoqi@0 526 _externalVocabularies.put(externalVocabularyURI, pv);
aoqi@0 527 _v.setReferencedVocabulary(externalVocabularyURI,
aoqi@0 528 pv, false);
aoqi@0 529 } else {
aoqi@0 530 throw new FastInfosetException(CommonResourceBundle.getInstance().
aoqi@0 531 getString("message.externalVocabularyNotRegistered",
aoqi@0 532 new Object[]{externalVocabularyURI}));
aoqi@0 533 }
aoqi@0 534 }
aoqi@0 535
aoqi@0 536 private void decodeTableItems(StringArray array) throws FastInfosetException, IOException {
aoqi@0 537 final int noOfItems = decodeNumberOfItemsOfSequence();
aoqi@0 538
aoqi@0 539 for (int i = 0; i < noOfItems; i++) {
aoqi@0 540 array.add(decodeNonEmptyOctetStringOnSecondBitAsUtf8String());
aoqi@0 541 }
aoqi@0 542 }
aoqi@0 543
aoqi@0 544 private void decodeTableItems(PrefixArray array) throws FastInfosetException, IOException {
aoqi@0 545 final int noOfItems = decodeNumberOfItemsOfSequence();
aoqi@0 546
aoqi@0 547 for (int i = 0; i < noOfItems; i++) {
aoqi@0 548 array.add(decodeNonEmptyOctetStringOnSecondBitAsUtf8String());
aoqi@0 549 }
aoqi@0 550 }
aoqi@0 551
aoqi@0 552 private void decodeTableItems(ContiguousCharArrayArray array) throws FastInfosetException, IOException {
aoqi@0 553 final int noOfItems = decodeNumberOfItemsOfSequence();
aoqi@0 554
aoqi@0 555 for (int i = 0; i < noOfItems; i++) {
aoqi@0 556 switch(decodeNonIdentifyingStringOnFirstBit()) {
aoqi@0 557 case NISTRING_STRING:
aoqi@0 558 array.add(_charBuffer, _charBufferLength);
aoqi@0 559 break;
aoqi@0 560 default:
aoqi@0 561 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.illegalState"));
aoqi@0 562 }
aoqi@0 563 }
aoqi@0 564 }
aoqi@0 565
aoqi@0 566 private void decodeTableItems(CharArrayArray array) throws FastInfosetException, IOException {
aoqi@0 567 final int noOfItems = decodeNumberOfItemsOfSequence();
aoqi@0 568
aoqi@0 569 for (int i = 0; i < noOfItems; i++) {
aoqi@0 570 switch(decodeNonIdentifyingStringOnFirstBit()) {
aoqi@0 571 case NISTRING_STRING:
aoqi@0 572 array.add(new CharArray(_charBuffer, 0, _charBufferLength, true));
aoqi@0 573 break;
aoqi@0 574 default:
aoqi@0 575 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.illegalState"));
aoqi@0 576 }
aoqi@0 577 }
aoqi@0 578 }
aoqi@0 579
aoqi@0 580 private void decodeTableItems(QualifiedNameArray array, boolean isAttribute) throws FastInfosetException, IOException {
aoqi@0 581 final int noOfItems = decodeNumberOfItemsOfSequence();
aoqi@0 582
aoqi@0 583 for (int i = 0; i < noOfItems; i++) {
aoqi@0 584 final int b = read();
aoqi@0 585
aoqi@0 586 String prefix = "";
aoqi@0 587 int prefixIndex = -1;
aoqi@0 588 if ((b & EncodingConstants.NAME_SURROGATE_PREFIX_FLAG) > 0) {
aoqi@0 589 prefixIndex = decodeIntegerIndexOnSecondBit();
aoqi@0 590 prefix = _v.prefix.get(prefixIndex);
aoqi@0 591 }
aoqi@0 592
aoqi@0 593 String namespaceName = "";
aoqi@0 594 int namespaceNameIndex = -1;
aoqi@0 595 if ((b & EncodingConstants.NAME_SURROGATE_NAME_FLAG) > 0) {
aoqi@0 596 namespaceNameIndex = decodeIntegerIndexOnSecondBit();
aoqi@0 597 namespaceName = _v.namespaceName.get(namespaceNameIndex);
aoqi@0 598 }
aoqi@0 599
aoqi@0 600 if (namespaceName == "" && prefix != "") {
aoqi@0 601 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.missingNamespace"));
aoqi@0 602 }
aoqi@0 603
aoqi@0 604 final int localNameIndex = decodeIntegerIndexOnSecondBit();
aoqi@0 605 final String localName = _v.localName.get(localNameIndex);
aoqi@0 606
aoqi@0 607 QualifiedName qualifiedName = new QualifiedName(prefix, namespaceName, localName,
aoqi@0 608 prefixIndex, namespaceNameIndex, localNameIndex,
aoqi@0 609 _charBuffer);
aoqi@0 610 if (isAttribute) {
aoqi@0 611 qualifiedName.createAttributeValues(DuplicateAttributeVerifier.MAP_SIZE);
aoqi@0 612 }
aoqi@0 613 array.add(qualifiedName);
aoqi@0 614 }
aoqi@0 615 }
aoqi@0 616
aoqi@0 617 private int decodeNumberOfItemsOfSequence() throws IOException {
aoqi@0 618 final int b = read();
aoqi@0 619 if (b < 128) {
aoqi@0 620 return b + 1;
aoqi@0 621 } else {
aoqi@0 622 return (((b & 0x0F) << 16) | (read() << 8) | read()) + 129;
aoqi@0 623 }
aoqi@0 624 }
aoqi@0 625
aoqi@0 626 protected final void decodeNotations() throws FastInfosetException, IOException {
aoqi@0 627 if (_notations == null) {
aoqi@0 628 _notations = new ArrayList();
aoqi@0 629 } else {
aoqi@0 630 _notations.clear();
aoqi@0 631 }
aoqi@0 632
aoqi@0 633 int b = read();
aoqi@0 634 while ((b & EncodingConstants.NOTATIONS_MASK) == EncodingConstants.NOTATIONS) {
aoqi@0 635 String name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
aoqi@0 636
aoqi@0 637 String system_identifier = ((_b & EncodingConstants.NOTATIONS_SYSTEM_IDENTIFIER_FLAG) > 0)
aoqi@0 638 ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
aoqi@0 639 String public_identifier = ((_b & EncodingConstants.NOTATIONS_PUBLIC_IDENTIFIER_FLAG) > 0)
aoqi@0 640 ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
aoqi@0 641
aoqi@0 642 Notation notation = new Notation(name, system_identifier, public_identifier);
aoqi@0 643 _notations.add(notation);
aoqi@0 644
aoqi@0 645 b = read();
aoqi@0 646 }
aoqi@0 647 if (b != EncodingConstants.TERMINATOR) {
aoqi@0 648 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IIsNotTerminatedCorrectly"));
aoqi@0 649 }
aoqi@0 650 }
aoqi@0 651
aoqi@0 652 protected final void decodeUnparsedEntities() throws FastInfosetException, IOException {
aoqi@0 653 if (_unparsedEntities == null) {
aoqi@0 654 _unparsedEntities = new ArrayList();
aoqi@0 655 } else {
aoqi@0 656 _unparsedEntities.clear();
aoqi@0 657 }
aoqi@0 658
aoqi@0 659 int b = read();
aoqi@0 660 while ((b & EncodingConstants.UNPARSED_ENTITIES_MASK) == EncodingConstants.UNPARSED_ENTITIES) {
aoqi@0 661 String name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
aoqi@0 662 String system_identifier = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI);
aoqi@0 663
aoqi@0 664 String public_identifier = ((_b & EncodingConstants.UNPARSED_ENTITIES_PUBLIC_IDENTIFIER_FLAG) > 0)
aoqi@0 665 ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
aoqi@0 666
aoqi@0 667 String notation_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
aoqi@0 668
aoqi@0 669 UnparsedEntity unparsedEntity = new UnparsedEntity(name, system_identifier, public_identifier, notation_name);
aoqi@0 670 _unparsedEntities.add(unparsedEntity);
aoqi@0 671
aoqi@0 672 b = read();
aoqi@0 673 }
aoqi@0 674 if (b != EncodingConstants.TERMINATOR) {
aoqi@0 675 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.unparsedEntities"));
aoqi@0 676 }
aoqi@0 677 }
aoqi@0 678
aoqi@0 679 protected final String decodeCharacterEncodingScheme() throws FastInfosetException, IOException {
aoqi@0 680 return decodeNonEmptyOctetStringOnSecondBitAsUtf8String();
aoqi@0 681 }
aoqi@0 682
aoqi@0 683 protected final String decodeVersion() throws FastInfosetException, IOException {
aoqi@0 684 switch(decodeNonIdentifyingStringOnFirstBit()) {
aoqi@0 685 case NISTRING_STRING:
aoqi@0 686 final String data = new String(_charBuffer, 0, _charBufferLength);
aoqi@0 687 if (_addToTable) {
aoqi@0 688 _v.otherString.add(new CharArrayString(data));
aoqi@0 689 }
aoqi@0 690 return data;
aoqi@0 691 case NISTRING_ENCODING_ALGORITHM:
aoqi@0 692 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingNotSupported"));
aoqi@0 693 case NISTRING_INDEX:
aoqi@0 694 return _v.otherString.get(_integer).toString();
aoqi@0 695 case NISTRING_EMPTY_STRING:
aoqi@0 696 default:
aoqi@0 697 return "";
aoqi@0 698 }
aoqi@0 699 }
aoqi@0 700
aoqi@0 701 protected final QualifiedName decodeEIIIndexMedium() throws FastInfosetException, IOException {
aoqi@0 702 final int i = (((_b & EncodingConstants.INTEGER_3RD_BIT_MEDIUM_MASK) << 8) | read())
aoqi@0 703 + EncodingConstants.INTEGER_3RD_BIT_SMALL_LIMIT;
aoqi@0 704 return _v.elementName._array[i];
aoqi@0 705 }
aoqi@0 706
aoqi@0 707 protected final QualifiedName decodeEIIIndexLarge() throws FastInfosetException, IOException {
aoqi@0 708 int i;
aoqi@0 709 if ((_b & EncodingConstants.INTEGER_3RD_BIT_LARGE_LARGE_FLAG) == 0x20) {
aoqi@0 710 // EII large index
aoqi@0 711 i = (((_b & EncodingConstants.INTEGER_3RD_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
aoqi@0 712 + EncodingConstants.INTEGER_3RD_BIT_MEDIUM_LIMIT;
aoqi@0 713 } else {
aoqi@0 714 // EII large large index
aoqi@0 715 i = (((read() & EncodingConstants.INTEGER_3RD_BIT_LARGE_LARGE_MASK) << 16) | (read() << 8) | read())
aoqi@0 716 + EncodingConstants.INTEGER_3RD_BIT_LARGE_LIMIT;
aoqi@0 717 }
aoqi@0 718 return _v.elementName._array[i];
aoqi@0 719 }
aoqi@0 720
aoqi@0 721 protected final QualifiedName decodeLiteralQualifiedName(int state, QualifiedName q)
aoqi@0 722 throws FastInfosetException, IOException {
aoqi@0 723 if (q == null) q = new QualifiedName();
aoqi@0 724 switch (state) {
aoqi@0 725 // no prefix, no namespace
aoqi@0 726 case 0:
aoqi@0 727 return q.set(
aoqi@0 728 "",
aoqi@0 729 "",
aoqi@0 730 decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
aoqi@0 731 -1,
aoqi@0 732 -1,
aoqi@0 733 _identifier,
aoqi@0 734 null);
aoqi@0 735 // no prefix, namespace
aoqi@0 736 case 1:
aoqi@0 737 return q.set(
aoqi@0 738 "",
aoqi@0 739 decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(false),
aoqi@0 740 decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
aoqi@0 741 -1,
aoqi@0 742 _namespaceNameIndex,
aoqi@0 743 _identifier,
aoqi@0 744 null);
aoqi@0 745 // prefix, no namespace
aoqi@0 746 case 2:
aoqi@0 747 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameMissingNamespaceName"));
aoqi@0 748 // prefix, namespace
aoqi@0 749 case 3:
aoqi@0 750 return q.set(
aoqi@0 751 decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(true),
aoqi@0 752 decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(true),
aoqi@0 753 decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
aoqi@0 754 _prefixIndex,
aoqi@0 755 _namespaceNameIndex,
aoqi@0 756 _identifier,
aoqi@0 757 _charBuffer);
aoqi@0 758 default:
aoqi@0 759 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingEII"));
aoqi@0 760 }
aoqi@0 761 }
aoqi@0 762
aoqi@0 763 protected static final int NISTRING_STRING = 0;
aoqi@0 764 protected static final int NISTRING_INDEX = 1;
aoqi@0 765 protected static final int NISTRING_ENCODING_ALGORITHM = 2;
aoqi@0 766 protected static final int NISTRING_EMPTY_STRING = 3;
aoqi@0 767
aoqi@0 768 /*
aoqi@0 769 * C.14
aoqi@0 770 * decodeNonIdentifyingStringOnFirstBit
aoqi@0 771 */
aoqi@0 772 protected final int decodeNonIdentifyingStringOnFirstBit() throws FastInfosetException, IOException {
aoqi@0 773 final int b = read();
aoqi@0 774 switch(DecoderStateTables.NISTRING(b)) {
aoqi@0 775 case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH:
aoqi@0 776 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
aoqi@0 777 _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
aoqi@0 778 decodeUtf8StringAsCharBuffer();
aoqi@0 779 return NISTRING_STRING;
aoqi@0 780 case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH:
aoqi@0 781 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
aoqi@0 782 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
aoqi@0 783 decodeUtf8StringAsCharBuffer();
aoqi@0 784 return NISTRING_STRING;
aoqi@0 785 case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH:
aoqi@0 786 {
aoqi@0 787 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
aoqi@0 788 final int length = (read() << 24) |
aoqi@0 789 (read() << 16) |
aoqi@0 790 (read() << 8) |
aoqi@0 791 read();
aoqi@0 792 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
aoqi@0 793 decodeUtf8StringAsCharBuffer();
aoqi@0 794 return NISTRING_STRING;
aoqi@0 795 }
aoqi@0 796 case DecoderStateTables.NISTRING_UTF16_SMALL_LENGTH:
aoqi@0 797 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
aoqi@0 798 _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
aoqi@0 799 decodeUtf16StringAsCharBuffer();
aoqi@0 800 return NISTRING_STRING;
aoqi@0 801 case DecoderStateTables.NISTRING_UTF16_MEDIUM_LENGTH:
aoqi@0 802 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
aoqi@0 803 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
aoqi@0 804 decodeUtf16StringAsCharBuffer();
aoqi@0 805 return NISTRING_STRING;
aoqi@0 806 case DecoderStateTables.NISTRING_UTF16_LARGE_LENGTH:
aoqi@0 807 {
aoqi@0 808 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
aoqi@0 809 final int length = (read() << 24) |
aoqi@0 810 (read() << 16) |
aoqi@0 811 (read() << 8) |
aoqi@0 812 read();
aoqi@0 813 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
aoqi@0 814 decodeUtf16StringAsCharBuffer();
aoqi@0 815 return NISTRING_STRING;
aoqi@0 816 }
aoqi@0 817 case DecoderStateTables.NISTRING_RA:
aoqi@0 818 {
aoqi@0 819 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
aoqi@0 820 // Decode resitricted alphabet integer
aoqi@0 821 _identifier = (b & 0x0F) << 4;
aoqi@0 822 final int b2 = read();
aoqi@0 823 _identifier |= (b2 & 0xF0) >> 4;
aoqi@0 824
aoqi@0 825 decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b2);
aoqi@0 826
aoqi@0 827 decodeRestrictedAlphabetAsCharBuffer();
aoqi@0 828 return NISTRING_STRING;
aoqi@0 829 }
aoqi@0 830 case DecoderStateTables.NISTRING_EA:
aoqi@0 831 {
aoqi@0 832 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
aoqi@0 833 // Decode encoding algorithm integer
aoqi@0 834 _identifier = (b & 0x0F) << 4;
aoqi@0 835 final int b2 = read();
aoqi@0 836 _identifier |= (b2 & 0xF0) >> 4;
aoqi@0 837
aoqi@0 838 decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b2);
aoqi@0 839 return NISTRING_ENCODING_ALGORITHM;
aoqi@0 840 }
aoqi@0 841 case DecoderStateTables.NISTRING_INDEX_SMALL:
aoqi@0 842 _integer = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
aoqi@0 843 return NISTRING_INDEX;
aoqi@0 844 case DecoderStateTables.NISTRING_INDEX_MEDIUM:
aoqi@0 845 _integer = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
aoqi@0 846 + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
aoqi@0 847 return NISTRING_INDEX;
aoqi@0 848 case DecoderStateTables.NISTRING_INDEX_LARGE:
aoqi@0 849 _integer = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
aoqi@0 850 + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 851 return NISTRING_INDEX;
aoqi@0 852 case DecoderStateTables.NISTRING_EMPTY:
aoqi@0 853 return NISTRING_EMPTY_STRING;
aoqi@0 854 default:
aoqi@0 855 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingNonIdentifyingString"));
aoqi@0 856 }
aoqi@0 857 }
aoqi@0 858
aoqi@0 859 protected final void decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(int b) throws FastInfosetException, IOException {
aoqi@0 860 // Remove top 4 bits of restricted alphabet or encoding algorithm integer
aoqi@0 861 b &= 0x0F;
aoqi@0 862 // Reuse UTF8 length states
aoqi@0 863 switch(DecoderStateTables.NISTRING(b)) {
aoqi@0 864 case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH:
aoqi@0 865 _octetBufferLength = b + 1;
aoqi@0 866 break;
aoqi@0 867 case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH:
aoqi@0 868 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
aoqi@0 869 break;
aoqi@0 870 case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH:
aoqi@0 871 final int length = (read() << 24) |
aoqi@0 872 (read() << 16) |
aoqi@0 873 (read() << 8) |
aoqi@0 874 read();
aoqi@0 875 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
aoqi@0 876 break;
aoqi@0 877 default:
aoqi@0 878 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingOctets"));
aoqi@0 879 }
aoqi@0 880 ensureOctetBufferSize();
aoqi@0 881 _octetBufferStart = _octetBufferOffset;
aoqi@0 882 _octetBufferOffset += _octetBufferLength;
aoqi@0 883 }
aoqi@0 884
aoqi@0 885 protected final void decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(int b) throws FastInfosetException, IOException {
aoqi@0 886 // Remove top 6 bits of restricted alphabet or encoding algorithm integer
aoqi@0 887 switch (b & 0x03) {
aoqi@0 888 // Small length
aoqi@0 889 case 0:
aoqi@0 890 _octetBufferLength = 1;
aoqi@0 891 break;
aoqi@0 892 // Small length
aoqi@0 893 case 1:
aoqi@0 894 _octetBufferLength = 2;
aoqi@0 895 break;
aoqi@0 896 // Medium length
aoqi@0 897 case 2:
aoqi@0 898 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
aoqi@0 899 break;
aoqi@0 900 // Large length
aoqi@0 901 case 3:
aoqi@0 902 _octetBufferLength = (read() << 24) |
aoqi@0 903 (read() << 16) |
aoqi@0 904 (read() << 8) |
aoqi@0 905 read();
aoqi@0 906 _octetBufferLength += EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
aoqi@0 907 break;
aoqi@0 908 }
aoqi@0 909
aoqi@0 910 ensureOctetBufferSize();
aoqi@0 911 _octetBufferStart = _octetBufferOffset;
aoqi@0 912 _octetBufferOffset += _octetBufferLength;
aoqi@0 913 }
aoqi@0 914
aoqi@0 915 /*
aoqi@0 916 * C.13
aoqi@0 917 */
aoqi@0 918 protected final String decodeIdentifyingNonEmptyStringOnFirstBit(StringArray table) throws FastInfosetException, IOException {
aoqi@0 919 final int b = read();
aoqi@0 920 switch(DecoderStateTables.ISTRING(b)) {
aoqi@0 921 case DecoderStateTables.ISTRING_SMALL_LENGTH:
aoqi@0 922 {
aoqi@0 923 _octetBufferLength = b + 1;
aoqi@0 924 final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
aoqi@0 925 _identifier = table.add(s) - 1;
aoqi@0 926 return s;
aoqi@0 927 }
aoqi@0 928 case DecoderStateTables.ISTRING_MEDIUM_LENGTH:
aoqi@0 929 {
aoqi@0 930 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT;
aoqi@0 931 final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
aoqi@0 932 _identifier = table.add(s) - 1;
aoqi@0 933 return s;
aoqi@0 934 }
aoqi@0 935 case DecoderStateTables.ISTRING_LARGE_LENGTH:
aoqi@0 936 {
aoqi@0 937 final int length = (read() << 24) |
aoqi@0 938 (read() << 16) |
aoqi@0 939 (read() << 8) |
aoqi@0 940 read();
aoqi@0 941 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 942 final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
aoqi@0 943 _identifier = table.add(s) - 1;
aoqi@0 944 return s;
aoqi@0 945 }
aoqi@0 946 case DecoderStateTables.ISTRING_INDEX_SMALL:
aoqi@0 947 _identifier = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
aoqi@0 948 return table._array[_identifier];
aoqi@0 949 case DecoderStateTables.ISTRING_INDEX_MEDIUM:
aoqi@0 950 _identifier = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
aoqi@0 951 + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
aoqi@0 952 return table._array[_identifier];
aoqi@0 953 case DecoderStateTables.ISTRING_INDEX_LARGE:
aoqi@0 954 _identifier = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
aoqi@0 955 + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 956 return table._array[_identifier];
aoqi@0 957 default:
aoqi@0 958 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIdentifyingString"));
aoqi@0 959 }
aoqi@0 960 }
aoqi@0 961
aoqi@0 962 protected int _prefixIndex;
aoqi@0 963
aoqi@0 964 /*
aoqi@0 965 * C.13
aoqi@0 966 */
aoqi@0 967 protected final String decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(boolean namespaceNamePresent) throws FastInfosetException, IOException {
aoqi@0 968 final int b = read();
aoqi@0 969 switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE(b)) {
aoqi@0 970 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_3:
aoqi@0 971 {
aoqi@0 972 _octetBufferLength = EncodingConstants.XML_NAMESPACE_PREFIX_LENGTH;
aoqi@0 973 decodeUtf8StringAsCharBuffer();
aoqi@0 974
aoqi@0 975 if (_charBuffer[0] == 'x' &&
aoqi@0 976 _charBuffer[1] == 'm' &&
aoqi@0 977 _charBuffer[2] == 'l') {
aoqi@0 978 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.prefixIllegal"));
aoqi@0 979 }
aoqi@0 980
aoqi@0 981 final String s = (_stringInterning) ? new String(_charBuffer, 0, _charBufferLength).intern() :
aoqi@0 982 new String(_charBuffer, 0, _charBufferLength);
aoqi@0 983 _prefixIndex = _v.prefix.add(s);
aoqi@0 984 return s;
aoqi@0 985 }
aoqi@0 986 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_5:
aoqi@0 987 {
aoqi@0 988 _octetBufferLength = EncodingConstants.XMLNS_NAMESPACE_PREFIX_LENGTH;
aoqi@0 989 decodeUtf8StringAsCharBuffer();
aoqi@0 990
aoqi@0 991 if (_charBuffer[0] == 'x' &&
aoqi@0 992 _charBuffer[1] == 'm' &&
aoqi@0 993 _charBuffer[2] == 'l' &&
aoqi@0 994 _charBuffer[3] == 'n' &&
aoqi@0 995 _charBuffer[4] == 's') {
aoqi@0 996 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.xmlns"));
aoqi@0 997 }
aoqi@0 998
aoqi@0 999 final String s = (_stringInterning) ? new String(_charBuffer, 0, _charBufferLength).intern() :
aoqi@0 1000 new String(_charBuffer, 0, _charBufferLength);
aoqi@0 1001 _prefixIndex = _v.prefix.add(s);
aoqi@0 1002 return s;
aoqi@0 1003 }
aoqi@0 1004 case DecoderStateTables.ISTRING_SMALL_LENGTH:
aoqi@0 1005 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_29:
aoqi@0 1006 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_36:
aoqi@0 1007 {
aoqi@0 1008 _octetBufferLength = b + 1;
aoqi@0 1009 final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
aoqi@0 1010 _prefixIndex = _v.prefix.add(s);
aoqi@0 1011 return s;
aoqi@0 1012 }
aoqi@0 1013 case DecoderStateTables.ISTRING_MEDIUM_LENGTH:
aoqi@0 1014 {
aoqi@0 1015 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT;
aoqi@0 1016 final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
aoqi@0 1017 _prefixIndex = _v.prefix.add(s);
aoqi@0 1018 return s;
aoqi@0 1019 }
aoqi@0 1020 case DecoderStateTables.ISTRING_LARGE_LENGTH:
aoqi@0 1021 {
aoqi@0 1022 final int length = (read() << 24) |
aoqi@0 1023 (read() << 16) |
aoqi@0 1024 (read() << 8) |
aoqi@0 1025 read();
aoqi@0 1026 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 1027 final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
aoqi@0 1028 _prefixIndex = _v.prefix.add(s);
aoqi@0 1029 return s;
aoqi@0 1030 }
aoqi@0 1031 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO:
aoqi@0 1032 if (namespaceNamePresent) {
aoqi@0 1033 _prefixIndex = 0;
aoqi@0 1034 // Peak at next byte and check the index of the XML namespace name
aoqi@0 1035 if (DecoderStateTables.ISTRING_PREFIX_NAMESPACE(peek())
aoqi@0 1036 != DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO) {
aoqi@0 1037 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.wrongNamespaceName"));
aoqi@0 1038 }
aoqi@0 1039 return EncodingConstants.XML_NAMESPACE_PREFIX;
aoqi@0 1040 } else {
aoqi@0 1041 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.missingNamespaceName"));
aoqi@0 1042 }
aoqi@0 1043 case DecoderStateTables.ISTRING_INDEX_SMALL:
aoqi@0 1044 _prefixIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
aoqi@0 1045 return _v.prefix._array[_prefixIndex - 1];
aoqi@0 1046 case DecoderStateTables.ISTRING_INDEX_MEDIUM:
aoqi@0 1047 _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
aoqi@0 1048 + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
aoqi@0 1049 return _v.prefix._array[_prefixIndex - 1];
aoqi@0 1050 case DecoderStateTables.ISTRING_INDEX_LARGE:
aoqi@0 1051 _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
aoqi@0 1052 + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 1053 return _v.prefix._array[_prefixIndex - 1];
aoqi@0 1054 default:
aoqi@0 1055 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIdentifyingStringForPrefix"));
aoqi@0 1056 }
aoqi@0 1057 }
aoqi@0 1058
aoqi@0 1059 /*
aoqi@0 1060 * C.13
aoqi@0 1061 */
aoqi@0 1062 protected final String decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(boolean namespaceNamePresent) throws FastInfosetException, IOException {
aoqi@0 1063 final int b = read();
aoqi@0 1064 switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE(b)) {
aoqi@0 1065 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO:
aoqi@0 1066 if (namespaceNamePresent) {
aoqi@0 1067 _prefixIndex = 0;
aoqi@0 1068 // Peak at next byte and check the index of the XML namespace name
aoqi@0 1069 if (DecoderStateTables.ISTRING_PREFIX_NAMESPACE(peek())
aoqi@0 1070 != DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO) {
aoqi@0 1071 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.wrongNamespaceName"));
aoqi@0 1072 }
aoqi@0 1073 return EncodingConstants.XML_NAMESPACE_PREFIX;
aoqi@0 1074 } else {
aoqi@0 1075 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.missingNamespaceName"));
aoqi@0 1076 }
aoqi@0 1077 case DecoderStateTables.ISTRING_INDEX_SMALL:
aoqi@0 1078 _prefixIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
aoqi@0 1079 return _v.prefix._array[_prefixIndex - 1];
aoqi@0 1080 case DecoderStateTables.ISTRING_INDEX_MEDIUM:
aoqi@0 1081 _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
aoqi@0 1082 + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
aoqi@0 1083 return _v.prefix._array[_prefixIndex - 1];
aoqi@0 1084 case DecoderStateTables.ISTRING_INDEX_LARGE:
aoqi@0 1085 _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
aoqi@0 1086 + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 1087 return _v.prefix._array[_prefixIndex - 1];
aoqi@0 1088 default:
aoqi@0 1089 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIdentifyingStringForPrefix"));
aoqi@0 1090 }
aoqi@0 1091 }
aoqi@0 1092
aoqi@0 1093 protected int _namespaceNameIndex;
aoqi@0 1094
aoqi@0 1095 /*
aoqi@0 1096 * C.13
aoqi@0 1097 */
aoqi@0 1098 protected final String decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(boolean prefixPresent) throws FastInfosetException, IOException {
aoqi@0 1099 final int b = read();
aoqi@0 1100 switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE(b)) {
aoqi@0 1101 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_3:
aoqi@0 1102 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_5:
aoqi@0 1103 case DecoderStateTables.ISTRING_SMALL_LENGTH:
aoqi@0 1104 {
aoqi@0 1105 _octetBufferLength = b + 1;
aoqi@0 1106 final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
aoqi@0 1107 _namespaceNameIndex = _v.namespaceName.add(s);
aoqi@0 1108 return s;
aoqi@0 1109 }
aoqi@0 1110 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_29:
aoqi@0 1111 {
aoqi@0 1112 _octetBufferLength = EncodingConstants.XMLNS_NAMESPACE_NAME_LENGTH;
aoqi@0 1113 decodeUtf8StringAsCharBuffer();
aoqi@0 1114
aoqi@0 1115 if (compareCharsWithCharBufferFromEndToStart(XMLNS_NAMESPACE_NAME_CHARS)) {
aoqi@0 1116 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.xmlnsConnotBeBoundToPrefix"));
aoqi@0 1117 }
aoqi@0 1118
aoqi@0 1119 final String s = (_stringInterning) ? new String(_charBuffer, 0, _charBufferLength).intern() :
aoqi@0 1120 new String(_charBuffer, 0, _charBufferLength);
aoqi@0 1121 _namespaceNameIndex = _v.namespaceName.add(s);
aoqi@0 1122 return s;
aoqi@0 1123 }
aoqi@0 1124 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_36:
aoqi@0 1125 {
aoqi@0 1126 _octetBufferLength = EncodingConstants.XML_NAMESPACE_NAME_LENGTH;
aoqi@0 1127 decodeUtf8StringAsCharBuffer();
aoqi@0 1128
aoqi@0 1129 if (compareCharsWithCharBufferFromEndToStart(XML_NAMESPACE_NAME_CHARS)) {
aoqi@0 1130 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.illegalNamespaceName"));
aoqi@0 1131 }
aoqi@0 1132
aoqi@0 1133 final String s = (_stringInterning) ? new String(_charBuffer, 0, _charBufferLength).intern() :
aoqi@0 1134 new String(_charBuffer, 0, _charBufferLength);
aoqi@0 1135 _namespaceNameIndex = _v.namespaceName.add(s);
aoqi@0 1136 return s;
aoqi@0 1137 }
aoqi@0 1138 case DecoderStateTables.ISTRING_MEDIUM_LENGTH:
aoqi@0 1139 {
aoqi@0 1140 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT;
aoqi@0 1141 final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
aoqi@0 1142 _namespaceNameIndex = _v.namespaceName.add(s);
aoqi@0 1143 return s;
aoqi@0 1144 }
aoqi@0 1145 case DecoderStateTables.ISTRING_LARGE_LENGTH:
aoqi@0 1146 {
aoqi@0 1147 final int length = (read() << 24) |
aoqi@0 1148 (read() << 16) |
aoqi@0 1149 (read() << 8) |
aoqi@0 1150 read();
aoqi@0 1151 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 1152 final String s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
aoqi@0 1153 _namespaceNameIndex = _v.namespaceName.add(s);
aoqi@0 1154 return s;
aoqi@0 1155 }
aoqi@0 1156 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO:
aoqi@0 1157 if (prefixPresent) {
aoqi@0 1158 _namespaceNameIndex = 0;
aoqi@0 1159 return EncodingConstants.XML_NAMESPACE_NAME;
aoqi@0 1160 } else {
aoqi@0 1161 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.namespaceWithoutPrefix"));
aoqi@0 1162 }
aoqi@0 1163 case DecoderStateTables.ISTRING_INDEX_SMALL:
aoqi@0 1164 _namespaceNameIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
aoqi@0 1165 return _v.namespaceName._array[_namespaceNameIndex - 1];
aoqi@0 1166 case DecoderStateTables.ISTRING_INDEX_MEDIUM:
aoqi@0 1167 _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
aoqi@0 1168 + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
aoqi@0 1169 return _v.namespaceName._array[_namespaceNameIndex - 1];
aoqi@0 1170 case DecoderStateTables.ISTRING_INDEX_LARGE:
aoqi@0 1171 _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
aoqi@0 1172 + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 1173 return _v.namespaceName._array[_namespaceNameIndex - 1];
aoqi@0 1174 default:
aoqi@0 1175 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingForNamespaceName"));
aoqi@0 1176 }
aoqi@0 1177 }
aoqi@0 1178
aoqi@0 1179 /*
aoqi@0 1180 * C.13
aoqi@0 1181 */
aoqi@0 1182 protected final String decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(boolean prefixPresent) throws FastInfosetException, IOException {
aoqi@0 1183 final int b = read();
aoqi@0 1184 switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE(b)) {
aoqi@0 1185 case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO:
aoqi@0 1186 if (prefixPresent) {
aoqi@0 1187 _namespaceNameIndex = 0;
aoqi@0 1188 return EncodingConstants.XML_NAMESPACE_NAME;
aoqi@0 1189 } else {
aoqi@0 1190 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.namespaceWithoutPrefix"));
aoqi@0 1191 }
aoqi@0 1192 case DecoderStateTables.ISTRING_INDEX_SMALL:
aoqi@0 1193 _namespaceNameIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
aoqi@0 1194 return _v.namespaceName._array[_namespaceNameIndex - 1];
aoqi@0 1195 case DecoderStateTables.ISTRING_INDEX_MEDIUM:
aoqi@0 1196 _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
aoqi@0 1197 + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
aoqi@0 1198 return _v.namespaceName._array[_namespaceNameIndex - 1];
aoqi@0 1199 case DecoderStateTables.ISTRING_INDEX_LARGE:
aoqi@0 1200 _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
aoqi@0 1201 + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 1202 return _v.namespaceName._array[_namespaceNameIndex - 1];
aoqi@0 1203 default:
aoqi@0 1204 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingForNamespaceName"));
aoqi@0 1205 }
aoqi@0 1206 }
aoqi@0 1207
aoqi@0 1208 private boolean compareCharsWithCharBufferFromEndToStart(char[] c) {
aoqi@0 1209 int i = _charBufferLength ;
aoqi@0 1210 while (--i >= 0) {
aoqi@0 1211 if (c[i] != _charBuffer[i]) {
aoqi@0 1212 return false;
aoqi@0 1213 }
aoqi@0 1214 }
aoqi@0 1215 return true;
aoqi@0 1216 }
aoqi@0 1217
aoqi@0 1218 /*
aoqi@0 1219 * C.22
aoqi@0 1220 */
aoqi@0 1221 protected final String decodeNonEmptyOctetStringOnSecondBitAsUtf8String() throws FastInfosetException, IOException {
aoqi@0 1222 decodeNonEmptyOctetStringOnSecondBitAsUtf8CharArray();
aoqi@0 1223 return new String(_charBuffer, 0, _charBufferLength);
aoqi@0 1224 }
aoqi@0 1225
aoqi@0 1226 /*
aoqi@0 1227 * C.22
aoqi@0 1228 */
aoqi@0 1229 protected final void decodeNonEmptyOctetStringOnSecondBitAsUtf8CharArray() throws FastInfosetException, IOException {
aoqi@0 1230 decodeNonEmptyOctetStringLengthOnSecondBit();
aoqi@0 1231 decodeUtf8StringAsCharBuffer();
aoqi@0 1232 }
aoqi@0 1233
aoqi@0 1234 /*
aoqi@0 1235 * C.22
aoqi@0 1236 */
aoqi@0 1237 protected final void decodeNonEmptyOctetStringLengthOnSecondBit() throws FastInfosetException, IOException {
aoqi@0 1238 final int b = read();
aoqi@0 1239 switch(DecoderStateTables.ISTRING(b)) {
aoqi@0 1240 case DecoderStateTables.ISTRING_SMALL_LENGTH:
aoqi@0 1241 _octetBufferLength = b + 1;
aoqi@0 1242 break;
aoqi@0 1243 case DecoderStateTables.ISTRING_MEDIUM_LENGTH:
aoqi@0 1244 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT;
aoqi@0 1245 break;
aoqi@0 1246 case DecoderStateTables.ISTRING_LARGE_LENGTH:
aoqi@0 1247 {
aoqi@0 1248 final int length = (read() << 24) |
aoqi@0 1249 (read() << 16) |
aoqi@0 1250 (read() << 8) |
aoqi@0 1251 read();
aoqi@0 1252 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 1253 break;
aoqi@0 1254 }
aoqi@0 1255 case DecoderStateTables.ISTRING_INDEX_SMALL:
aoqi@0 1256 case DecoderStateTables.ISTRING_INDEX_MEDIUM:
aoqi@0 1257 case DecoderStateTables.ISTRING_INDEX_LARGE:
aoqi@0 1258 default:
aoqi@0 1259 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingNonEmptyOctet"));
aoqi@0 1260 }
aoqi@0 1261 }
aoqi@0 1262
aoqi@0 1263 /*
aoqi@0 1264 * C.25
aoqi@0 1265 */
aoqi@0 1266 protected final int decodeIntegerIndexOnSecondBit() throws FastInfosetException, IOException {
aoqi@0 1267 final int b = read() | 0x80;
aoqi@0 1268 switch(DecoderStateTables.ISTRING(b)) {
aoqi@0 1269 case DecoderStateTables.ISTRING_INDEX_SMALL:
aoqi@0 1270 return b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
aoqi@0 1271 case DecoderStateTables.ISTRING_INDEX_MEDIUM:
aoqi@0 1272 return (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
aoqi@0 1273 + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
aoqi@0 1274 case DecoderStateTables.ISTRING_INDEX_LARGE:
aoqi@0 1275 return (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
aoqi@0 1276 + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
aoqi@0 1277 case DecoderStateTables.ISTRING_SMALL_LENGTH:
aoqi@0 1278 case DecoderStateTables.ISTRING_MEDIUM_LENGTH:
aoqi@0 1279 case DecoderStateTables.ISTRING_LARGE_LENGTH:
aoqi@0 1280 default:
aoqi@0 1281 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIndexOnSecondBit"));
aoqi@0 1282 }
aoqi@0 1283 }
aoqi@0 1284
aoqi@0 1285 protected final void decodeHeader() throws FastInfosetException, IOException {
aoqi@0 1286 if (!_isFastInfosetDocument()) {
aoqi@0 1287 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.notFIDocument"));
aoqi@0 1288 }
aoqi@0 1289 }
aoqi@0 1290
aoqi@0 1291 protected final void decodeRestrictedAlphabetAsCharBuffer() throws FastInfosetException, IOException {
aoqi@0 1292 if (_identifier <= EncodingConstants.RESTRICTED_ALPHABET_BUILTIN_END) {
aoqi@0 1293 decodeFourBitAlphabetOctetsAsCharBuffer(BuiltInRestrictedAlphabets.table[_identifier]);
aoqi@0 1294 // decodeAlphabetOctetsAsCharBuffer(BuiltInRestrictedAlphabets.table[_identifier]);
aoqi@0 1295 } else if (_identifier >= EncodingConstants.RESTRICTED_ALPHABET_APPLICATION_START) {
aoqi@0 1296 CharArray ca = _v.restrictedAlphabet.get(_identifier - EncodingConstants.RESTRICTED_ALPHABET_APPLICATION_START);
aoqi@0 1297 if (ca == null) {
aoqi@0 1298 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.alphabetNotPresent", new Object[]{Integer.valueOf(_identifier)}));
aoqi@0 1299 }
aoqi@0 1300 decodeAlphabetOctetsAsCharBuffer(ca.ch);
aoqi@0 1301 } else {
aoqi@0 1302 // Reserved built-in algorithms for future use
aoqi@0 1303 // TODO should use sax property to decide if event will be
aoqi@0 1304 // reported, allows for support through handler if required.
aoqi@0 1305 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.alphabetIdentifiersReserved"));
aoqi@0 1306 }
aoqi@0 1307 }
aoqi@0 1308
aoqi@0 1309 protected final String decodeRestrictedAlphabetAsString() throws FastInfosetException, IOException {
aoqi@0 1310 decodeRestrictedAlphabetAsCharBuffer();
aoqi@0 1311 return new String(_charBuffer, 0, _charBufferLength);
aoqi@0 1312 }
aoqi@0 1313
aoqi@0 1314 protected final String decodeRAOctetsAsString(char[] restrictedAlphabet) throws FastInfosetException, IOException {
aoqi@0 1315 decodeAlphabetOctetsAsCharBuffer(restrictedAlphabet);
aoqi@0 1316 return new String(_charBuffer, 0, _charBufferLength);
aoqi@0 1317 }
aoqi@0 1318
aoqi@0 1319 protected final void decodeFourBitAlphabetOctetsAsCharBuffer(char[] restrictedAlphabet) throws FastInfosetException, IOException {
aoqi@0 1320 _charBufferLength = 0;
aoqi@0 1321 final int characters = _octetBufferLength * 2;
aoqi@0 1322 if (_charBuffer.length < characters) {
aoqi@0 1323 _charBuffer = new char[characters];
aoqi@0 1324 }
aoqi@0 1325
aoqi@0 1326 int v = 0;
aoqi@0 1327 for (int i = 0; i < _octetBufferLength - 1; i++) {
aoqi@0 1328 v = _octetBuffer[_octetBufferStart++] & 0xFF;
aoqi@0 1329 _charBuffer[_charBufferLength++] = restrictedAlphabet[v >> 4];
aoqi@0 1330 _charBuffer[_charBufferLength++] = restrictedAlphabet[v & 0x0F];
aoqi@0 1331 }
aoqi@0 1332 v = _octetBuffer[_octetBufferStart++] & 0xFF;
aoqi@0 1333 _charBuffer[_charBufferLength++] = restrictedAlphabet[v >> 4];
aoqi@0 1334 v &= 0x0F;
aoqi@0 1335 if (v != 0x0F) {
aoqi@0 1336 _charBuffer[_charBufferLength++] = restrictedAlphabet[v & 0x0F];
aoqi@0 1337 }
aoqi@0 1338 }
aoqi@0 1339
aoqi@0 1340 protected final void decodeAlphabetOctetsAsCharBuffer(char[] restrictedAlphabet) throws FastInfosetException, IOException {
aoqi@0 1341 if (restrictedAlphabet.length < 2) {
aoqi@0 1342 throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.alphabetMustContain2orMoreChars"));
aoqi@0 1343 }
aoqi@0 1344
aoqi@0 1345 int bitsPerCharacter = 1;
aoqi@0 1346 while ((1 << bitsPerCharacter) <= restrictedAlphabet.length) {
aoqi@0 1347 bitsPerCharacter++;
aoqi@0 1348 }
aoqi@0 1349 final int terminatingValue = (1 << bitsPerCharacter) - 1;
aoqi@0 1350
aoqi@0 1351 int characters = (_octetBufferLength << 3) / bitsPerCharacter;
aoqi@0 1352 if (characters == 0) {
aoqi@0 1353 throw new IOException("");
aoqi@0 1354 }
aoqi@0 1355
aoqi@0 1356 _charBufferLength = 0;
aoqi@0 1357 if (_charBuffer.length < characters) {
aoqi@0 1358 _charBuffer = new char[characters];
aoqi@0 1359 }
aoqi@0 1360
aoqi@0 1361 resetBits();
aoqi@0 1362 for (int i = 0; i < characters; i++) {
aoqi@0 1363 int value = readBits(bitsPerCharacter);
aoqi@0 1364 if (bitsPerCharacter < 8 && value == terminatingValue) {
aoqi@0 1365 int octetPosition = (i * bitsPerCharacter) >>> 3;
aoqi@0 1366 if (octetPosition != _octetBufferLength - 1) {
aoqi@0 1367 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.alphabetIncorrectlyTerminated"));
aoqi@0 1368 }
aoqi@0 1369 break;
aoqi@0 1370 }
aoqi@0 1371 _charBuffer[_charBufferLength++] = restrictedAlphabet[value];
aoqi@0 1372 }
aoqi@0 1373 }
aoqi@0 1374
aoqi@0 1375 private int _bitsLeftInOctet;
aoqi@0 1376
aoqi@0 1377 private void resetBits() {
aoqi@0 1378 _bitsLeftInOctet = 0;
aoqi@0 1379 }
aoqi@0 1380
aoqi@0 1381 private int readBits(int bits) throws IOException {
aoqi@0 1382 int value = 0;
aoqi@0 1383 while (bits > 0) {
aoqi@0 1384 if (_bitsLeftInOctet == 0) {
aoqi@0 1385 _b = _octetBuffer[_octetBufferStart++] & 0xFF;
aoqi@0 1386 _bitsLeftInOctet = 8;
aoqi@0 1387 }
aoqi@0 1388 int bit = ((_b & (1 << --_bitsLeftInOctet)) > 0) ? 1 : 0;
aoqi@0 1389 value |= (bit << --bits);
aoqi@0 1390 }
aoqi@0 1391
aoqi@0 1392 return value;
aoqi@0 1393 }
aoqi@0 1394
aoqi@0 1395 protected final void decodeUtf8StringAsCharBuffer() throws IOException {
aoqi@0 1396 ensureOctetBufferSize();
aoqi@0 1397 decodeUtf8StringIntoCharBuffer();
aoqi@0 1398 }
aoqi@0 1399
aoqi@0 1400 protected final void decodeUtf8StringAsCharBuffer(char[] ch, int offset) throws IOException {
aoqi@0 1401 ensureOctetBufferSize();
aoqi@0 1402 decodeUtf8StringIntoCharBuffer(ch, offset);
aoqi@0 1403 }
aoqi@0 1404
aoqi@0 1405 protected final String decodeUtf8StringAsString() throws IOException {
aoqi@0 1406 decodeUtf8StringAsCharBuffer();
aoqi@0 1407 return new String(_charBuffer, 0, _charBufferLength);
aoqi@0 1408 }
aoqi@0 1409
aoqi@0 1410 protected final void decodeUtf16StringAsCharBuffer() throws IOException {
aoqi@0 1411 ensureOctetBufferSize();
aoqi@0 1412 decodeUtf16StringIntoCharBuffer();
aoqi@0 1413 }
aoqi@0 1414
aoqi@0 1415 protected final String decodeUtf16StringAsString() throws IOException {
aoqi@0 1416 decodeUtf16StringAsCharBuffer();
aoqi@0 1417 return new String(_charBuffer, 0, _charBufferLength);
aoqi@0 1418 }
aoqi@0 1419
aoqi@0 1420 private void ensureOctetBufferSize() throws IOException {
aoqi@0 1421 if (_octetBufferEnd < (_octetBufferOffset + _octetBufferLength)) {
aoqi@0 1422 final int octetsInBuffer = _octetBufferEnd - _octetBufferOffset;
aoqi@0 1423
aoqi@0 1424 if (_octetBuffer.length < _octetBufferLength) {
aoqi@0 1425 // Length to read is too large, resize the buffer
aoqi@0 1426 byte[] newOctetBuffer = new byte[_octetBufferLength];
aoqi@0 1427 // Move partially read octets to the start of the buffer
aoqi@0 1428 System.arraycopy(_octetBuffer, _octetBufferOffset, newOctetBuffer, 0, octetsInBuffer);
aoqi@0 1429 _octetBuffer = newOctetBuffer;
aoqi@0 1430 } else {
aoqi@0 1431 // Move partially read octets to the start of the buffer
aoqi@0 1432 System.arraycopy(_octetBuffer, _octetBufferOffset, _octetBuffer, 0, octetsInBuffer);
aoqi@0 1433 }
aoqi@0 1434 _octetBufferOffset = 0;
aoqi@0 1435
aoqi@0 1436 // Read as many octets as possible to fill the buffer
aoqi@0 1437 final int octetsRead = _s.read(_octetBuffer, octetsInBuffer, _octetBuffer.length - octetsInBuffer);
aoqi@0 1438 if (octetsRead < 0) {
aoqi@0 1439 throw new EOFException("Unexpeceted EOF");
aoqi@0 1440 }
aoqi@0 1441 _octetBufferEnd = octetsInBuffer + octetsRead;
aoqi@0 1442
aoqi@0 1443 // Check if the number of octets that have been read is not enough
aoqi@0 1444 // This can happen when underlying non-blocking is used to read
aoqi@0 1445 if (_octetBufferEnd < _octetBufferLength) {
aoqi@0 1446 repeatedRead();
aoqi@0 1447 }
aoqi@0 1448 }
aoqi@0 1449 }
aoqi@0 1450
aoqi@0 1451 private void repeatedRead() throws IOException {
aoqi@0 1452 // Check if the number of octets that have been read is not enough
aoqi@0 1453 while (_octetBufferEnd < _octetBufferLength) {
aoqi@0 1454 // Read as many octets as possible to fill the buffer
aoqi@0 1455 final int octetsRead = _s.read(_octetBuffer, _octetBufferEnd, _octetBuffer.length - _octetBufferEnd);
aoqi@0 1456 if (octetsRead < 0) {
aoqi@0 1457 throw new EOFException("Unexpeceted EOF");
aoqi@0 1458 }
aoqi@0 1459 _octetBufferEnd += octetsRead;
aoqi@0 1460 }
aoqi@0 1461 }
aoqi@0 1462
aoqi@0 1463 protected final void decodeUtf8StringIntoCharBuffer() throws IOException {
aoqi@0 1464 if (_charBuffer.length < _octetBufferLength) {
aoqi@0 1465 _charBuffer = new char[_octetBufferLength];
aoqi@0 1466 }
aoqi@0 1467
aoqi@0 1468 _charBufferLength = 0;
aoqi@0 1469 final int end = _octetBufferLength + _octetBufferOffset;
aoqi@0 1470 int b1;
aoqi@0 1471 while (end != _octetBufferOffset) {
aoqi@0 1472 b1 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1473 if (DecoderStateTables.UTF8(b1) == DecoderStateTables.UTF8_ONE_BYTE) {
aoqi@0 1474 _charBuffer[_charBufferLength++] = (char) b1;
aoqi@0 1475 } else {
aoqi@0 1476 decodeTwoToFourByteUtf8Character(b1, end);
aoqi@0 1477 }
aoqi@0 1478 }
aoqi@0 1479 }
aoqi@0 1480
aoqi@0 1481 protected final void decodeUtf8StringIntoCharBuffer(char[] ch, int offset) throws IOException {
aoqi@0 1482 _charBufferLength = offset;
aoqi@0 1483 final int end = _octetBufferLength + _octetBufferOffset;
aoqi@0 1484 int b1;
aoqi@0 1485 while (end != _octetBufferOffset) {
aoqi@0 1486 b1 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1487 if (DecoderStateTables.UTF8(b1) == DecoderStateTables.UTF8_ONE_BYTE) {
aoqi@0 1488 ch[_charBufferLength++] = (char) b1;
aoqi@0 1489 } else {
aoqi@0 1490 decodeTwoToFourByteUtf8Character(ch, b1, end);
aoqi@0 1491 }
aoqi@0 1492 }
aoqi@0 1493 _charBufferLength -= offset;
aoqi@0 1494 }
aoqi@0 1495
aoqi@0 1496 private void decodeTwoToFourByteUtf8Character(int b1, int end) throws IOException {
aoqi@0 1497 switch(DecoderStateTables.UTF8(b1)) {
aoqi@0 1498 case DecoderStateTables.UTF8_TWO_BYTES:
aoqi@0 1499 {
aoqi@0 1500 // Decode byte 2
aoqi@0 1501 if (end == _octetBufferOffset) {
aoqi@0 1502 decodeUtf8StringLengthTooSmall();
aoqi@0 1503 }
aoqi@0 1504 final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1505 if ((b2 & 0xC0) != 0x80) {
aoqi@0 1506 decodeUtf8StringIllegalState();
aoqi@0 1507 }
aoqi@0 1508
aoqi@0 1509 // Character guaranteed to be in [0x20, 0xD7FF] range
aoqi@0 1510 // since a character encoded in two bytes will be in the
aoqi@0 1511 // range [0x80, 0x1FFF]
aoqi@0 1512 _charBuffer[_charBufferLength++] = (char) (
aoqi@0 1513 ((b1 & 0x1F) << 6)
aoqi@0 1514 | (b2 & 0x3F));
aoqi@0 1515 break;
aoqi@0 1516 }
aoqi@0 1517 case DecoderStateTables.UTF8_THREE_BYTES:
aoqi@0 1518 final char c = decodeUtf8ThreeByteChar(end, b1);
aoqi@0 1519 if (XMLChar.isContent(c)) {
aoqi@0 1520 _charBuffer[_charBufferLength++] = c;
aoqi@0 1521 } else {
aoqi@0 1522 decodeUtf8StringIllegalState();
aoqi@0 1523 }
aoqi@0 1524 break;
aoqi@0 1525 case DecoderStateTables.UTF8_FOUR_BYTES:
aoqi@0 1526 {
aoqi@0 1527 final int supplemental = decodeUtf8FourByteChar(end, b1);
aoqi@0 1528 if (XMLChar.isContent(supplemental)) {
aoqi@0 1529 _charBuffer[_charBufferLength++] = _utf8_highSurrogate;
aoqi@0 1530 _charBuffer[_charBufferLength++] = _utf8_lowSurrogate;
aoqi@0 1531 } else {
aoqi@0 1532 decodeUtf8StringIllegalState();
aoqi@0 1533 }
aoqi@0 1534 break;
aoqi@0 1535 }
aoqi@0 1536 default:
aoqi@0 1537 decodeUtf8StringIllegalState();
aoqi@0 1538 }
aoqi@0 1539 }
aoqi@0 1540
aoqi@0 1541 private void decodeTwoToFourByteUtf8Character(char ch[], int b1, int end) throws IOException {
aoqi@0 1542 switch(DecoderStateTables.UTF8(b1)) {
aoqi@0 1543 case DecoderStateTables.UTF8_TWO_BYTES:
aoqi@0 1544 {
aoqi@0 1545 // Decode byte 2
aoqi@0 1546 if (end == _octetBufferOffset) {
aoqi@0 1547 decodeUtf8StringLengthTooSmall();
aoqi@0 1548 }
aoqi@0 1549 final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1550 if ((b2 & 0xC0) != 0x80) {
aoqi@0 1551 decodeUtf8StringIllegalState();
aoqi@0 1552 }
aoqi@0 1553
aoqi@0 1554 // Character guaranteed to be in [0x20, 0xD7FF] range
aoqi@0 1555 // since a character encoded in two bytes will be in the
aoqi@0 1556 // range [0x80, 0x1FFF]
aoqi@0 1557 ch[_charBufferLength++] = (char) (
aoqi@0 1558 ((b1 & 0x1F) << 6)
aoqi@0 1559 | (b2 & 0x3F));
aoqi@0 1560 break;
aoqi@0 1561 }
aoqi@0 1562 case DecoderStateTables.UTF8_THREE_BYTES:
aoqi@0 1563 final char c = decodeUtf8ThreeByteChar(end, b1);
aoqi@0 1564 if (XMLChar.isContent(c)) {
aoqi@0 1565 ch[_charBufferLength++] = c;
aoqi@0 1566 } else {
aoqi@0 1567 decodeUtf8StringIllegalState();
aoqi@0 1568 }
aoqi@0 1569 break;
aoqi@0 1570 case DecoderStateTables.UTF8_FOUR_BYTES:
aoqi@0 1571 {
aoqi@0 1572 final int supplemental = decodeUtf8FourByteChar(end, b1);
aoqi@0 1573 if (XMLChar.isContent(supplemental)) {
aoqi@0 1574 ch[_charBufferLength++] = _utf8_highSurrogate;
aoqi@0 1575 ch[_charBufferLength++] = _utf8_lowSurrogate;
aoqi@0 1576 } else {
aoqi@0 1577 decodeUtf8StringIllegalState();
aoqi@0 1578 }
aoqi@0 1579 break;
aoqi@0 1580 }
aoqi@0 1581 default:
aoqi@0 1582 decodeUtf8StringIllegalState();
aoqi@0 1583 }
aoqi@0 1584 }
aoqi@0 1585
aoqi@0 1586 protected final void decodeUtf8NCNameIntoCharBuffer() throws IOException {
aoqi@0 1587 _charBufferLength = 0;
aoqi@0 1588 if (_charBuffer.length < _octetBufferLength) {
aoqi@0 1589 _charBuffer = new char[_octetBufferLength];
aoqi@0 1590 }
aoqi@0 1591
aoqi@0 1592 final int end = _octetBufferLength + _octetBufferOffset;
aoqi@0 1593
aoqi@0 1594 int b1 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1595 if (DecoderStateTables.UTF8_NCNAME(b1) == DecoderStateTables.UTF8_NCNAME_NCNAME) {
aoqi@0 1596 _charBuffer[_charBufferLength++] = (char) b1;
aoqi@0 1597 } else {
aoqi@0 1598 decodeUtf8NCNameStartTwoToFourByteCharacters(b1, end);
aoqi@0 1599 }
aoqi@0 1600
aoqi@0 1601 while (end != _octetBufferOffset) {
aoqi@0 1602 b1 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1603 if (DecoderStateTables.UTF8_NCNAME(b1) < DecoderStateTables.UTF8_TWO_BYTES) {
aoqi@0 1604 _charBuffer[_charBufferLength++] = (char) b1;
aoqi@0 1605 } else {
aoqi@0 1606 decodeUtf8NCNameTwoToFourByteCharacters(b1, end);
aoqi@0 1607 }
aoqi@0 1608 }
aoqi@0 1609 }
aoqi@0 1610
aoqi@0 1611 private void decodeUtf8NCNameStartTwoToFourByteCharacters(int b1, int end) throws IOException {
aoqi@0 1612 switch(DecoderStateTables.UTF8_NCNAME(b1)) {
aoqi@0 1613 case DecoderStateTables.UTF8_TWO_BYTES:
aoqi@0 1614 {
aoqi@0 1615 // Decode byte 2
aoqi@0 1616 if (end == _octetBufferOffset) {
aoqi@0 1617 decodeUtf8StringLengthTooSmall();
aoqi@0 1618 }
aoqi@0 1619 final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1620 if ((b2 & 0xC0) != 0x80) {
aoqi@0 1621 decodeUtf8StringIllegalState();
aoqi@0 1622 }
aoqi@0 1623
aoqi@0 1624 final char c = (char) (
aoqi@0 1625 ((b1 & 0x1F) << 6)
aoqi@0 1626 | (b2 & 0x3F));
aoqi@0 1627 if (XMLChar.isNCNameStart(c)) {
aoqi@0 1628 _charBuffer[_charBufferLength++] = c;
aoqi@0 1629 } else {
aoqi@0 1630 decodeUtf8NCNameIllegalState();
aoqi@0 1631 }
aoqi@0 1632 break;
aoqi@0 1633 }
aoqi@0 1634 case DecoderStateTables.UTF8_THREE_BYTES:
aoqi@0 1635 final char c = decodeUtf8ThreeByteChar(end, b1);
aoqi@0 1636 if (XMLChar.isNCNameStart(c)) {
aoqi@0 1637 _charBuffer[_charBufferLength++] = c;
aoqi@0 1638 } else {
aoqi@0 1639 decodeUtf8NCNameIllegalState();
aoqi@0 1640 }
aoqi@0 1641 break;
aoqi@0 1642 case DecoderStateTables.UTF8_FOUR_BYTES:
aoqi@0 1643 {
aoqi@0 1644 final int supplemental = decodeUtf8FourByteChar(end, b1);
aoqi@0 1645 if (XMLChar.isNCNameStart(supplemental)) {
aoqi@0 1646 _charBuffer[_charBufferLength++] = _utf8_highSurrogate;
aoqi@0 1647 _charBuffer[_charBufferLength++] = _utf8_lowSurrogate;
aoqi@0 1648 } else {
aoqi@0 1649 decodeUtf8NCNameIllegalState();
aoqi@0 1650 }
aoqi@0 1651 break;
aoqi@0 1652 }
aoqi@0 1653 case DecoderStateTables.UTF8_NCNAME_NCNAME_CHAR:
aoqi@0 1654 default:
aoqi@0 1655 decodeUtf8NCNameIllegalState();
aoqi@0 1656 }
aoqi@0 1657
aoqi@0 1658 }
aoqi@0 1659
aoqi@0 1660 private void decodeUtf8NCNameTwoToFourByteCharacters(int b1, int end) throws IOException {
aoqi@0 1661 switch(DecoderStateTables.UTF8_NCNAME(b1)) {
aoqi@0 1662 case DecoderStateTables.UTF8_TWO_BYTES:
aoqi@0 1663 {
aoqi@0 1664 // Decode byte 2
aoqi@0 1665 if (end == _octetBufferOffset) {
aoqi@0 1666 decodeUtf8StringLengthTooSmall();
aoqi@0 1667 }
aoqi@0 1668 final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1669 if ((b2 & 0xC0) != 0x80) {
aoqi@0 1670 decodeUtf8StringIllegalState();
aoqi@0 1671 }
aoqi@0 1672
aoqi@0 1673 final char c = (char) (
aoqi@0 1674 ((b1 & 0x1F) << 6)
aoqi@0 1675 | (b2 & 0x3F));
aoqi@0 1676 if (XMLChar.isNCName(c)) {
aoqi@0 1677 _charBuffer[_charBufferLength++] = c;
aoqi@0 1678 } else {
aoqi@0 1679 decodeUtf8NCNameIllegalState();
aoqi@0 1680 }
aoqi@0 1681 break;
aoqi@0 1682 }
aoqi@0 1683 case DecoderStateTables.UTF8_THREE_BYTES:
aoqi@0 1684 final char c = decodeUtf8ThreeByteChar(end, b1);
aoqi@0 1685 if (XMLChar.isNCName(c)) {
aoqi@0 1686 _charBuffer[_charBufferLength++] = c;
aoqi@0 1687 } else {
aoqi@0 1688 decodeUtf8NCNameIllegalState();
aoqi@0 1689 }
aoqi@0 1690 break;
aoqi@0 1691 case DecoderStateTables.UTF8_FOUR_BYTES:
aoqi@0 1692 {
aoqi@0 1693 final int supplemental = decodeUtf8FourByteChar(end, b1);
aoqi@0 1694 if (XMLChar.isNCName(supplemental)) {
aoqi@0 1695 _charBuffer[_charBufferLength++] = _utf8_highSurrogate;
aoqi@0 1696 _charBuffer[_charBufferLength++] = _utf8_lowSurrogate;
aoqi@0 1697 } else {
aoqi@0 1698 decodeUtf8NCNameIllegalState();
aoqi@0 1699 }
aoqi@0 1700 break;
aoqi@0 1701 }
aoqi@0 1702 default:
aoqi@0 1703 decodeUtf8NCNameIllegalState();
aoqi@0 1704 }
aoqi@0 1705 }
aoqi@0 1706
aoqi@0 1707 private char decodeUtf8ThreeByteChar(int end, int b1) throws IOException {
aoqi@0 1708 // Decode byte 2
aoqi@0 1709 if (end == _octetBufferOffset) {
aoqi@0 1710 decodeUtf8StringLengthTooSmall();
aoqi@0 1711 }
aoqi@0 1712 final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1713 if ((b2 & 0xC0) != 0x80
aoqi@0 1714 || (b1 == 0xED && b2 >= 0xA0)
aoqi@0 1715 || ((b1 & 0x0F) == 0 && (b2 & 0x20) == 0)) {
aoqi@0 1716 decodeUtf8StringIllegalState();
aoqi@0 1717 }
aoqi@0 1718
aoqi@0 1719 // Decode byte 3
aoqi@0 1720 if (end == _octetBufferOffset) {
aoqi@0 1721 decodeUtf8StringLengthTooSmall();
aoqi@0 1722 }
aoqi@0 1723 final int b3 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1724 if ((b3 & 0xC0) != 0x80) {
aoqi@0 1725 decodeUtf8StringIllegalState();
aoqi@0 1726 }
aoqi@0 1727
aoqi@0 1728 return (char) (
aoqi@0 1729 (b1 & 0x0F) << 12
aoqi@0 1730 | (b2 & 0x3F) << 6
aoqi@0 1731 | (b3 & 0x3F));
aoqi@0 1732 }
aoqi@0 1733
aoqi@0 1734 private char _utf8_highSurrogate;
aoqi@0 1735 private char _utf8_lowSurrogate;
aoqi@0 1736
aoqi@0 1737 private int decodeUtf8FourByteChar(int end, int b1) throws IOException {
aoqi@0 1738 // Decode byte 2
aoqi@0 1739 if (end == _octetBufferOffset) {
aoqi@0 1740 decodeUtf8StringLengthTooSmall();
aoqi@0 1741 }
aoqi@0 1742 final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1743 if ((b2 & 0xC0) != 0x80
aoqi@0 1744 || ((b2 & 0x30) == 0 && (b1 & 0x07) == 0)) {
aoqi@0 1745 decodeUtf8StringIllegalState();
aoqi@0 1746 }
aoqi@0 1747
aoqi@0 1748 // Decode byte 3
aoqi@0 1749 if (end == _octetBufferOffset) {
aoqi@0 1750 decodeUtf8StringLengthTooSmall();
aoqi@0 1751 }
aoqi@0 1752 final int b3 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1753 if ((b3 & 0xC0) != 0x80) {
aoqi@0 1754 decodeUtf8StringIllegalState();
aoqi@0 1755 }
aoqi@0 1756
aoqi@0 1757 // Decode byte 4
aoqi@0 1758 if (end == _octetBufferOffset) {
aoqi@0 1759 decodeUtf8StringLengthTooSmall();
aoqi@0 1760 }
aoqi@0 1761 final int b4 = _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1762 if ((b4 & 0xC0) != 0x80) {
aoqi@0 1763 decodeUtf8StringIllegalState();
aoqi@0 1764 }
aoqi@0 1765
aoqi@0 1766 final int uuuuu = ((b1 << 2) & 0x001C) | ((b2 >> 4) & 0x0003);
aoqi@0 1767 if (uuuuu > 0x10) {
aoqi@0 1768 decodeUtf8StringIllegalState();
aoqi@0 1769 }
aoqi@0 1770 final int wwww = uuuuu - 1;
aoqi@0 1771
aoqi@0 1772 _utf8_highSurrogate = (char) (0xD800 |
aoqi@0 1773 ((wwww << 6) & 0x03C0) | ((b2 << 2) & 0x003C) |
aoqi@0 1774 ((b3 >> 4) & 0x0003));
aoqi@0 1775 _utf8_lowSurrogate = (char) (0xDC00 | ((b3 << 6) & 0x03C0) | (b4 & 0x003F));
aoqi@0 1776
aoqi@0 1777 return XMLChar.supplemental(_utf8_highSurrogate, _utf8_lowSurrogate);
aoqi@0 1778 }
aoqi@0 1779
aoqi@0 1780 private void decodeUtf8StringLengthTooSmall() throws IOException {
aoqi@0 1781 throw new IOException(CommonResourceBundle.getInstance().getString("message.deliminatorTooSmall"));
aoqi@0 1782 }
aoqi@0 1783
aoqi@0 1784 private void decodeUtf8StringIllegalState() throws IOException {
aoqi@0 1785 throw new IOException(CommonResourceBundle.getInstance().getString("message.UTF8Encoded"));
aoqi@0 1786 }
aoqi@0 1787
aoqi@0 1788 private void decodeUtf8NCNameIllegalState() throws IOException {
aoqi@0 1789 throw new IOException(CommonResourceBundle.getInstance().getString("message.UTF8EncodedNCName"));
aoqi@0 1790 }
aoqi@0 1791
aoqi@0 1792 private void decodeUtf16StringIntoCharBuffer() throws IOException {
aoqi@0 1793 _charBufferLength = _octetBufferLength / 2;
aoqi@0 1794 if (_charBuffer.length < _charBufferLength) {
aoqi@0 1795 _charBuffer = new char[_charBufferLength];
aoqi@0 1796 }
aoqi@0 1797
aoqi@0 1798 for (int i = 0; i < _charBufferLength; i++) {
aoqi@0 1799 final char c = (char)((read() << 8) | read());
aoqi@0 1800 // TODO check c is a valid Char character
aoqi@0 1801 _charBuffer[i] = c;
aoqi@0 1802 }
aoqi@0 1803
aoqi@0 1804 }
aoqi@0 1805
aoqi@0 1806 protected String createQualifiedNameString(String second) {
aoqi@0 1807 return createQualifiedNameString(XMLNS_NAMESPACE_PREFIX_CHARS, second);
aoqi@0 1808 }
aoqi@0 1809
aoqi@0 1810 protected String createQualifiedNameString(char[] first, String second) {
aoqi@0 1811 final int l1 = first.length;
aoqi@0 1812 final int l2 = second.length();
aoqi@0 1813 final int total = l1 + l2 + 1;
aoqi@0 1814 if (total < _charBuffer.length) {
aoqi@0 1815 System.arraycopy(first, 0, _charBuffer, 0, l1);
aoqi@0 1816 _charBuffer[l1] = ':';
aoqi@0 1817 second.getChars(0, l2, _charBuffer, l1 + 1);
aoqi@0 1818 return new String(_charBuffer, 0, total);
aoqi@0 1819 } else {
aoqi@0 1820 StringBuilder b = new StringBuilder(new String(first));
aoqi@0 1821 b.append(':');
aoqi@0 1822 b.append(second);
aoqi@0 1823 return b.toString();
aoqi@0 1824 }
aoqi@0 1825 }
aoqi@0 1826
aoqi@0 1827 protected final int read() throws IOException {
aoqi@0 1828 if (_octetBufferOffset < _octetBufferEnd) {
aoqi@0 1829 return _octetBuffer[_octetBufferOffset++] & 0xFF;
aoqi@0 1830 } else {
aoqi@0 1831 _octetBufferEnd = _s.read(_octetBuffer);
aoqi@0 1832 if (_octetBufferEnd < 0) {
aoqi@0 1833 throw new EOFException(CommonResourceBundle.getInstance().getString("message.EOF"));
aoqi@0 1834 }
aoqi@0 1835
aoqi@0 1836 _octetBufferOffset = 1;
aoqi@0 1837 return _octetBuffer[0] & 0xFF;
aoqi@0 1838 }
aoqi@0 1839 }
aoqi@0 1840
aoqi@0 1841 protected final void closeIfRequired() throws IOException {
aoqi@0 1842 if (_s != null && _needForceStreamClose) {
aoqi@0 1843 _s.close();
aoqi@0 1844 }
aoqi@0 1845 }
aoqi@0 1846
aoqi@0 1847 protected final int peek() throws IOException {
aoqi@0 1848 return peek(null);
aoqi@0 1849 }
aoqi@0 1850
aoqi@0 1851 protected final int peek(OctetBufferListener octetBufferListener) throws IOException {
aoqi@0 1852 if (_octetBufferOffset < _octetBufferEnd) {
aoqi@0 1853 return _octetBuffer[_octetBufferOffset] & 0xFF;
aoqi@0 1854 } else {
aoqi@0 1855 if (octetBufferListener != null) {
aoqi@0 1856 octetBufferListener.onBeforeOctetBufferOverwrite();
aoqi@0 1857 }
aoqi@0 1858
aoqi@0 1859 _octetBufferEnd = _s.read(_octetBuffer);
aoqi@0 1860 if (_octetBufferEnd < 0) {
aoqi@0 1861 throw new EOFException(CommonResourceBundle.getInstance().getString("message.EOF"));
aoqi@0 1862 }
aoqi@0 1863
aoqi@0 1864 _octetBufferOffset = 0;
aoqi@0 1865 return _octetBuffer[0] & 0xFF;
aoqi@0 1866 }
aoqi@0 1867 }
aoqi@0 1868
aoqi@0 1869 protected final int peek2(OctetBufferListener octetBufferListener) throws IOException {
aoqi@0 1870 if (_octetBufferOffset + 1 < _octetBufferEnd) {
aoqi@0 1871 return _octetBuffer[_octetBufferOffset + 1] & 0xFF;
aoqi@0 1872 } else {
aoqi@0 1873 if (octetBufferListener != null) {
aoqi@0 1874 octetBufferListener.onBeforeOctetBufferOverwrite();
aoqi@0 1875 }
aoqi@0 1876
aoqi@0 1877 int offset = 0;
aoqi@0 1878 if (_octetBufferOffset < _octetBufferEnd) {
aoqi@0 1879 _octetBuffer[0] = _octetBuffer[_octetBufferOffset];
aoqi@0 1880 offset = 1;
aoqi@0 1881 }
aoqi@0 1882 _octetBufferEnd = _s.read(_octetBuffer, offset, _octetBuffer.length - offset);
aoqi@0 1883
aoqi@0 1884 if (_octetBufferEnd < 0) {
aoqi@0 1885 throw new EOFException(CommonResourceBundle.getInstance().getString("message.EOF"));
aoqi@0 1886 }
aoqi@0 1887
aoqi@0 1888 _octetBufferOffset = 0;
aoqi@0 1889 return _octetBuffer[1] & 0xFF;
aoqi@0 1890 }
aoqi@0 1891 }
aoqi@0 1892
aoqi@0 1893 protected class EncodingAlgorithmInputStream extends InputStream {
aoqi@0 1894
aoqi@0 1895 public int read() throws IOException {
aoqi@0 1896 if (_octetBufferStart < _octetBufferOffset) {
aoqi@0 1897 return (_octetBuffer[_octetBufferStart++] & 0xFF);
aoqi@0 1898 } else {
aoqi@0 1899 return -1;
aoqi@0 1900 }
aoqi@0 1901 }
aoqi@0 1902
aoqi@0 1903 @Override
aoqi@0 1904 public int read(byte b[]) throws IOException {
aoqi@0 1905 return read(b, 0, b.length);
aoqi@0 1906 }
aoqi@0 1907
aoqi@0 1908 @Override
aoqi@0 1909 public int read(byte b[], int off, int len) throws IOException {
aoqi@0 1910 if (b == null) {
aoqi@0 1911 throw new NullPointerException();
aoqi@0 1912 } else if ((off < 0) || (off > b.length) || (len < 0) ||
aoqi@0 1913 ((off + len) > b.length) || ((off + len) < 0)) {
aoqi@0 1914 throw new IndexOutOfBoundsException();
aoqi@0 1915 } else if (len == 0) {
aoqi@0 1916 return 0;
aoqi@0 1917 }
aoqi@0 1918
aoqi@0 1919 final int newOctetBufferStart = _octetBufferStart + len;
aoqi@0 1920 if (newOctetBufferStart < _octetBufferOffset) {
aoqi@0 1921 System.arraycopy(_octetBuffer, _octetBufferStart, b, off, len);
aoqi@0 1922 _octetBufferStart = newOctetBufferStart;
aoqi@0 1923 return len;
aoqi@0 1924 } else if (_octetBufferStart < _octetBufferOffset) {
aoqi@0 1925 final int bytesToRead = _octetBufferOffset - _octetBufferStart;
aoqi@0 1926 System.arraycopy(_octetBuffer, _octetBufferStart, b, off, bytesToRead);
aoqi@0 1927 _octetBufferStart += bytesToRead;
aoqi@0 1928 return bytesToRead;
aoqi@0 1929 } else {
aoqi@0 1930 return -1;
aoqi@0 1931 }
aoqi@0 1932 }
aoqi@0 1933 }
aoqi@0 1934
aoqi@0 1935 protected final boolean _isFastInfosetDocument() throws IOException {
aoqi@0 1936 // Fill up the octet buffer
aoqi@0 1937 peek();
aoqi@0 1938
aoqi@0 1939 _octetBufferLength = EncodingConstants.BINARY_HEADER.length;
aoqi@0 1940 ensureOctetBufferSize();
aoqi@0 1941 _octetBufferOffset += _octetBufferLength;
aoqi@0 1942
aoqi@0 1943 // Check for binary header
aoqi@0 1944 if (_octetBuffer[0] != EncodingConstants.BINARY_HEADER[0] ||
aoqi@0 1945 _octetBuffer[1] != EncodingConstants.BINARY_HEADER[1] ||
aoqi@0 1946 _octetBuffer[2] != EncodingConstants.BINARY_HEADER[2] ||
aoqi@0 1947 _octetBuffer[3] != EncodingConstants.BINARY_HEADER[3]) {
aoqi@0 1948
aoqi@0 1949 // Check for each form of XML declaration
aoqi@0 1950 for (int i = 0; i < EncodingConstants.XML_DECLARATION_VALUES.length; i++) {
aoqi@0 1951 _octetBufferLength = EncodingConstants.XML_DECLARATION_VALUES[i].length - _octetBufferOffset;
aoqi@0 1952 ensureOctetBufferSize();
aoqi@0 1953 _octetBufferOffset += _octetBufferLength;
aoqi@0 1954
aoqi@0 1955 // Check XML declaration
aoqi@0 1956 if (arrayEquals(_octetBuffer, 0,
aoqi@0 1957 EncodingConstants.XML_DECLARATION_VALUES[i],
aoqi@0 1958 EncodingConstants.XML_DECLARATION_VALUES[i].length)) {
aoqi@0 1959 _octetBufferLength = EncodingConstants.BINARY_HEADER.length;
aoqi@0 1960 ensureOctetBufferSize();
aoqi@0 1961
aoqi@0 1962 // Check for binary header
aoqi@0 1963 if (_octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[0] ||
aoqi@0 1964 _octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[1] ||
aoqi@0 1965 _octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[2] ||
aoqi@0 1966 _octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[3]) {
aoqi@0 1967 return false;
aoqi@0 1968 } else {
aoqi@0 1969 // Fast Infoset document with XML declaration and binary header
aoqi@0 1970 return true;
aoqi@0 1971 }
aoqi@0 1972 }
aoqi@0 1973 }
aoqi@0 1974
aoqi@0 1975 return false;
aoqi@0 1976 }
aoqi@0 1977
aoqi@0 1978 // Fast Infoset document with binary header
aoqi@0 1979 return true;
aoqi@0 1980 }
aoqi@0 1981
aoqi@0 1982 private boolean arrayEquals(byte[] b1, int offset, byte[] b2, int length) {
aoqi@0 1983 for (int i = 0; i < length; i++) {
aoqi@0 1984 if (b1[offset + i] != b2[i]) {
aoqi@0 1985 return false;
aoqi@0 1986 }
aoqi@0 1987 }
aoqi@0 1988
aoqi@0 1989 return true;
aoqi@0 1990 }
aoqi@0 1991
aoqi@0 1992 static public boolean isFastInfosetDocument(InputStream s) throws IOException {
aoqi@0 1993 // TODO
aoqi@0 1994 // Check for <?xml declaration with 'finf' encoding
aoqi@0 1995 final int headerSize = 4;
aoqi@0 1996
aoqi@0 1997 final byte[] header = new byte[headerSize];
aoqi@0 1998 final int readBytesCount = s.read(header);
aoqi@0 1999 if (readBytesCount < headerSize ||
aoqi@0 2000 header[0] != EncodingConstants.BINARY_HEADER[0] ||
aoqi@0 2001 header[1] != EncodingConstants.BINARY_HEADER[1] ||
aoqi@0 2002 header[2] != EncodingConstants.BINARY_HEADER[2] ||
aoqi@0 2003 header[3] != EncodingConstants.BINARY_HEADER[3]) {
aoqi@0 2004 return false;
aoqi@0 2005 }
aoqi@0 2006
aoqi@0 2007 // TODO
aoqi@0 2008 return true;
aoqi@0 2009 }
aoqi@0 2010 }

mercurial