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

Tue, 06 Mar 2012 16:09:35 -0800

author
ohair
date
Tue, 06 Mar 2012 16:09:35 -0800
changeset 286
f50545b5e2f1
child 384
8f2986ff0235
permissions
-rw-r--r--

7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom

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

mercurial