Thu, 31 Aug 2017 15:18:52 +0800
merge
1 /*
2 * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
25 * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
26 */
28 package com.sun.xml.internal.fastinfoset.dom;
30 import com.sun.xml.internal.fastinfoset.Decoder;
31 import com.sun.xml.internal.fastinfoset.DecoderStateTables;
32 import com.sun.xml.internal.fastinfoset.EncodingConstants;
33 import com.sun.xml.internal.fastinfoset.QualifiedName;
34 import com.sun.xml.internal.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
35 import com.sun.xml.internal.fastinfoset.util.CharArray;
36 import com.sun.xml.internal.fastinfoset.util.CharArrayString;
37 import java.io.IOException;
38 import java.io.InputStream;
39 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithm;
40 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException;
41 import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
42 import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
43 import org.w3c.dom.Attr;
44 import org.w3c.dom.Document;
45 import org.w3c.dom.Element;
46 import org.w3c.dom.Node;
47 import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
48 import com.sun.xml.internal.fastinfoset.util.DuplicateAttributeVerifier;
49 import org.w3c.dom.Text;
51 /**
52 * The Fast Infoset DOM parser.
53 * <p>
54 * Instantiate this parser to parse a fast infoset document in accordance
55 * with the DOM API.
56 *
57 */
58 public class DOMDocumentParser extends Decoder {
59 protected Document _document;
61 protected Node _currentNode;
63 protected Element _currentElement;
65 protected Attr[] _namespaceAttributes = new Attr[16];
67 protected int _namespaceAttributesIndex;
69 protected int[] _namespacePrefixes = new int[16];
71 protected int _namespacePrefixesIndex;
73 /**
74 * Parse a fast infoset document into a {@link Document} instance.
75 * <p>
76 * {@link Node}s will be created and appended to the {@link Document}
77 * instance.
78 *
79 * @param d the {@link Document} instance.
80 * @param s the input stream containing the fast infoset document.
81 */
82 public void parse(Document d, InputStream s) throws FastInfosetException, IOException {
83 _currentNode = _document = d;
84 _namespaceAttributesIndex = 0;
86 parse(s);
87 }
89 protected final void parse(InputStream s) throws FastInfosetException, IOException {
90 setInputStream(s);
91 parse();
92 }
94 protected void resetOnError() {
95 _namespacePrefixesIndex = 0;
97 if (_v == null) {
98 _prefixTable.clearCompletely();
99 }
100 _duplicateAttributeVerifier.clear();
101 }
103 protected final void parse() throws FastInfosetException, IOException {
104 try {
105 reset();
106 decodeHeader();
107 processDII();
108 } catch (RuntimeException e) {
109 resetOnError();
110 // Wrap runtime exception
111 throw new FastInfosetException(e);
112 } catch (FastInfosetException e) {
113 resetOnError();
114 throw e;
115 } catch (IOException e) {
116 resetOnError();
117 throw e;
118 }
119 }
121 protected final void processDII() throws FastInfosetException, IOException {
122 _b = read();
123 if (_b > 0) {
124 processDIIOptionalProperties();
125 }
127 // Decode one Document Type II, Comment IIs, PI IIs and one EII
128 boolean firstElementHasOccured = false;
129 boolean documentTypeDeclarationOccured = false;
130 while(!_terminate || !firstElementHasOccured) {
131 _b = read();
132 switch(DecoderStateTables.DII(_b)) {
133 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
134 processEII(_elementNameTable._array[_b], false);
135 firstElementHasOccured = true;
136 break;
137 case DecoderStateTables.EII_AIIS_INDEX_SMALL:
138 processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true);
139 firstElementHasOccured = true;
140 break;
141 case DecoderStateTables.EII_INDEX_MEDIUM:
142 processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
143 firstElementHasOccured = true;
144 break;
145 case DecoderStateTables.EII_INDEX_LARGE:
146 processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
147 firstElementHasOccured = true;
148 break;
149 case DecoderStateTables.EII_LITERAL:
150 {
151 final QualifiedName qn = processLiteralQualifiedName(
152 _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
153 _elementNameTable.getNext());
154 _elementNameTable.add(qn);
155 processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
156 firstElementHasOccured = true;
157 break;
158 }
159 case DecoderStateTables.EII_NAMESPACES:
160 processEIIWithNamespaces();
161 firstElementHasOccured = true;
162 break;
163 case DecoderStateTables.DOCUMENT_TYPE_DECLARATION_II:
164 {
165 if (documentTypeDeclarationOccured) {
166 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.secondOccurenceOfDTDII"));
167 }
168 documentTypeDeclarationOccured = true;
170 String system_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_SYSTEM_IDENTIFIER_FLAG) > 0)
171 ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
172 String public_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_PUBLIC_IDENTIFIER_FLAG) > 0)
173 ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
175 _b = read();
176 while (_b == EncodingConstants.PROCESSING_INSTRUCTION) {
177 switch(decodeNonIdentifyingStringOnFirstBit()) {
178 case NISTRING_STRING:
179 if (_addToTable) {
180 _v.otherString.add(new CharArray(_charBuffer, 0, _charBufferLength, true));
181 }
182 break;
183 case NISTRING_ENCODING_ALGORITHM:
184 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm"));
185 case NISTRING_INDEX:
186 break;
187 case NISTRING_EMPTY_STRING:
188 break;
189 }
190 _b = read();
191 }
192 if ((_b & EncodingConstants.TERMINATOR) != EncodingConstants.TERMINATOR) {
193 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingInstructionIIsNotTerminatedCorrectly"));
194 }
195 if (_b == EncodingConstants.DOUBLE_TERMINATOR) {
196 _terminate = true;
197 }
199 _notations.clear();
200 _unparsedEntities.clear();
201 /*
202 * TODO
203 * Report All events associated with DTD, PIs, notations etc
204 */
205 break;
206 }
207 case DecoderStateTables.COMMENT_II:
208 processCommentII();
209 break;
210 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
211 processProcessingII();
212 break;
213 case DecoderStateTables.TERMINATOR_DOUBLE:
214 _doubleTerminate = true;
215 case DecoderStateTables.TERMINATOR_SINGLE:
216 _terminate = true;
217 break;
218 default:
219 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingDII"));
220 }
221 }
223 // Decode any remaining Comment IIs, PI IIs
224 while(!_terminate) {
225 _b = read();
226 switch(DecoderStateTables.DII(_b)) {
227 case DecoderStateTables.COMMENT_II:
228 processCommentII();
229 break;
230 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
231 processProcessingII();
232 break;
233 case DecoderStateTables.TERMINATOR_DOUBLE:
234 _doubleTerminate = true;
235 case DecoderStateTables.TERMINATOR_SINGLE:
236 _terminate = true;
237 break;
238 default:
239 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingDII"));
240 }
241 }
243 }
245 protected final void processDIIOptionalProperties() throws FastInfosetException, IOException {
246 // Optimize for the most common case
247 if (_b == EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) {
248 decodeInitialVocabulary();
249 return;
250 }
252 if ((_b & EncodingConstants.DOCUMENT_ADDITIONAL_DATA_FLAG) > 0) {
253 decodeAdditionalData();
254 /*
255 * TODO
256 * how to report the additional data?
257 */
258 }
260 if ((_b & EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) > 0) {
261 decodeInitialVocabulary();
262 }
264 if ((_b & EncodingConstants.DOCUMENT_NOTATIONS_FLAG) > 0) {
265 decodeNotations();
266 // TODO Report notations
267 }
269 if ((_b & EncodingConstants.DOCUMENT_UNPARSED_ENTITIES_FLAG) > 0) {
270 decodeUnparsedEntities();
271 // TODO Report unparsed entities
272 }
274 if ((_b & EncodingConstants.DOCUMENT_CHARACTER_ENCODING_SCHEME) > 0) {
275 /*String version = */decodeCharacterEncodingScheme();
276 /*
277 * TODO
278 * how to report the character encoding scheme?
279 */
280 }
282 if ((_b & EncodingConstants.DOCUMENT_STANDALONE_FLAG) > 0) {
283 /*boolean standalone = (*/read()/* > 0) ? true : false*/ ;
284 /*
285 * TODO
286 * how to report the standalone flag?
287 */
288 }
290 if ((_b & EncodingConstants.DOCUMENT_VERSION_FLAG) > 0) {
291 decodeVersion();
292 /*
293 * TODO
294 * how to report the document version?
295 */
296 }
297 }
299 protected final void processEII(QualifiedName name, boolean hasAttributes) throws FastInfosetException, IOException {
300 if (_prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
301 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qnameOfEIINotInScope"));
302 }
304 final Node parentCurrentNode = _currentNode;
306 _currentNode = _currentElement = createElement(name.namespaceName, name.qName, name.localName);
308 if (_namespaceAttributesIndex > 0) {
309 for (int i = 0; i < _namespaceAttributesIndex; i++) {
310 _currentElement.setAttributeNode(_namespaceAttributes[i]);
311 _namespaceAttributes[i] = null;
312 }
313 _namespaceAttributesIndex = 0;
314 }
316 if (hasAttributes) {
317 processAIIs();
318 }
320 parentCurrentNode.appendChild(_currentElement);
322 while(!_terminate) {
323 _b = read();
324 switch(DecoderStateTables.EII(_b)) {
325 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
326 processEII(_elementNameTable._array[_b], false);
327 break;
328 case DecoderStateTables.EII_AIIS_INDEX_SMALL:
329 processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true);
330 break;
331 case DecoderStateTables.EII_INDEX_MEDIUM:
332 processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
333 break;
334 case DecoderStateTables.EII_INDEX_LARGE:
335 processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
336 break;
337 case DecoderStateTables.EII_LITERAL:
338 {
339 final QualifiedName qn = processLiteralQualifiedName(
340 _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
341 _elementNameTable.getNext());
342 _elementNameTable.add(qn);
343 processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
344 break;
345 }
346 case DecoderStateTables.EII_NAMESPACES:
347 processEIIWithNamespaces();
348 break;
349 case DecoderStateTables.CII_UTF8_SMALL_LENGTH:
350 {
351 _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK)
352 + 1;
353 appendOrCreateTextData(processUtf8CharacterString());
354 break;
355 }
356 case DecoderStateTables.CII_UTF8_MEDIUM_LENGTH:
357 {
358 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
359 appendOrCreateTextData(processUtf8CharacterString());
360 break;
361 }
362 case DecoderStateTables.CII_UTF8_LARGE_LENGTH:
363 {
364 _octetBufferLength = (read() << 24) |
365 (read() << 16) |
366 (read() << 8) |
367 read();
368 _octetBufferLength += EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
369 appendOrCreateTextData(processUtf8CharacterString());
370 break;
371 }
372 case DecoderStateTables.CII_UTF16_SMALL_LENGTH:
373 {
374 _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK)
375 + 1;
376 String v = decodeUtf16StringAsString();
377 if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
378 _characterContentChunkTable.add(_charBuffer, _charBufferLength);
379 }
381 appendOrCreateTextData(v);
382 break;
383 }
384 case DecoderStateTables.CII_UTF16_MEDIUM_LENGTH:
385 {
386 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
387 String v = decodeUtf16StringAsString();
388 if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
389 _characterContentChunkTable.add(_charBuffer, _charBufferLength);
390 }
392 appendOrCreateTextData(v);
393 break;
394 }
395 case DecoderStateTables.CII_UTF16_LARGE_LENGTH:
396 {
397 _octetBufferLength = (read() << 24) |
398 (read() << 16) |
399 (read() << 8) |
400 read();
401 _octetBufferLength += EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
402 String v = decodeUtf16StringAsString();
403 if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
404 _characterContentChunkTable.add(_charBuffer, _charBufferLength);
405 }
407 appendOrCreateTextData(v);
408 break;
409 }
410 case DecoderStateTables.CII_RA:
411 {
412 final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0;
414 // Decode resitricted alphabet integer
415 _identifier = (_b & 0x02) << 6;
416 _b = read();
417 _identifier |= (_b & 0xFC) >> 2;
419 decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b);
421 String v = decodeRestrictedAlphabetAsString();
422 if (addToTable) {
423 _characterContentChunkTable.add(_charBuffer, _charBufferLength);
424 }
426 appendOrCreateTextData(v);
427 break;
428 }
429 case DecoderStateTables.CII_EA:
430 {
431 final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0;
432 // Decode encoding algorithm integer
433 _identifier = (_b & 0x02) << 6;
434 _b = read();
435 _identifier |= (_b & 0xFC) >> 2;
437 decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b);
438 final String s = convertEncodingAlgorithmDataToCharacters(false);
439 if (addToTable) {
440 _characterContentChunkTable.add(s.toCharArray(), s.length());
441 }
442 appendOrCreateTextData(s);
443 break;
444 }
445 case DecoderStateTables.CII_INDEX_SMALL:
446 {
447 final String s = _characterContentChunkTable.getString(_b & EncodingConstants.INTEGER_4TH_BIT_SMALL_MASK);
449 appendOrCreateTextData(s);
450 break;
451 }
452 case DecoderStateTables.CII_INDEX_MEDIUM:
453 {
454 final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_MEDIUM_MASK) << 8) | read())
455 + EncodingConstants.INTEGER_4TH_BIT_SMALL_LIMIT;
456 final String s = _characterContentChunkTable.getString(index);
458 appendOrCreateTextData(s);
459 break;
460 }
461 case DecoderStateTables.CII_INDEX_LARGE:
462 {
463 int index = ((_b & EncodingConstants.INTEGER_4TH_BIT_LARGE_MASK) << 16) |
464 (read() << 8) |
465 read();
466 index += EncodingConstants.INTEGER_4TH_BIT_MEDIUM_LIMIT;
467 final String s = _characterContentChunkTable.getString(index);
469 appendOrCreateTextData(s);
470 break;
471 }
472 case DecoderStateTables.CII_INDEX_LARGE_LARGE:
473 {
474 int index = (read() << 16) |
475 (read() << 8) |
476 read();
477 index += EncodingConstants.INTEGER_4TH_BIT_LARGE_LIMIT;
478 final String s = _characterContentChunkTable.getString(index);
480 appendOrCreateTextData(s);
481 break;
482 }
483 case DecoderStateTables.COMMENT_II:
484 processCommentII();
485 break;
486 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
487 processProcessingII();
488 break;
489 case DecoderStateTables.UNEXPANDED_ENTITY_REFERENCE_II:
490 {
491 String entity_reference_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
493 String system_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_SYSTEM_IDENTIFIER_FLAG) > 0)
494 ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
495 String public_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_PUBLIC_IDENTIFIER_FLAG) > 0)
496 ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : null;
498 // TODO create Node
499 break;
500 }
501 case DecoderStateTables.TERMINATOR_DOUBLE:
502 _doubleTerminate = true;
503 case DecoderStateTables.TERMINATOR_SINGLE:
504 _terminate = true;
505 break;
506 default:
507 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEII"));
508 }
509 }
511 _terminate = _doubleTerminate;
512 _doubleTerminate = false;
514 _currentNode = parentCurrentNode;
515 }
517 private void appendOrCreateTextData(String textData) {
518 Node lastChild = _currentNode.getLastChild();
519 if (lastChild instanceof Text) {
520 ((Text) lastChild).appendData(textData);
521 } else {
522 _currentNode.appendChild(
523 _document.createTextNode(textData));
524 }
525 }
527 private final String processUtf8CharacterString() throws FastInfosetException, IOException {
528 if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
529 _characterContentChunkTable.ensureSize(_octetBufferLength);
530 final int charactersOffset = _characterContentChunkTable._arrayIndex;
531 decodeUtf8StringAsCharBuffer(_characterContentChunkTable._array, charactersOffset);
532 _characterContentChunkTable.add(_charBufferLength);
533 return _characterContentChunkTable.getString(_characterContentChunkTable._cachedIndex);
534 } else {
535 decodeUtf8StringAsCharBuffer();
536 return new String(_charBuffer, 0, _charBufferLength);
537 }
538 }
540 protected final void processEIIWithNamespaces() throws FastInfosetException, IOException {
541 final boolean hasAttributes = (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0;
543 if (++_prefixTable._declarationId == Integer.MAX_VALUE) {
544 _prefixTable.clearDeclarationIds();
545 }
547 String prefix;
548 Attr a = null;
549 final int start = _namespacePrefixesIndex;
550 int b = read();
551 while ((b & EncodingConstants.NAMESPACE_ATTRIBUTE_MASK) == EncodingConstants.NAMESPACE_ATTRIBUTE) {
552 if (_namespaceAttributesIndex == _namespaceAttributes.length) {
553 final Attr[] newNamespaceAttributes = new Attr[_namespaceAttributesIndex * 3 / 2 + 1];
554 System.arraycopy(_namespaceAttributes, 0, newNamespaceAttributes, 0, _namespaceAttributesIndex);
555 _namespaceAttributes = newNamespaceAttributes;
556 }
558 if (_namespacePrefixesIndex == _namespacePrefixes.length) {
559 final int[] namespaceAIIs = new int[_namespacePrefixesIndex * 3 / 2 + 1];
560 System.arraycopy(_namespacePrefixes, 0, namespaceAIIs, 0, _namespacePrefixesIndex);
561 _namespacePrefixes = namespaceAIIs;
562 }
565 switch (b & EncodingConstants.NAMESPACE_ATTRIBUTE_PREFIX_NAME_MASK) {
566 // no prefix, no namespace
567 // Undeclaration of default namespace
568 case 0:
569 a = createAttribute(
570 EncodingConstants.XMLNS_NAMESPACE_NAME,
571 EncodingConstants.XMLNS_NAMESPACE_PREFIX,
572 EncodingConstants.XMLNS_NAMESPACE_PREFIX);
573 a.setValue("");
575 _prefixIndex = _namespaceNameIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1;
576 break;
577 // no prefix, namespace
578 // Declaration of default namespace
579 case 1:
580 a = createAttribute(
581 EncodingConstants.XMLNS_NAMESPACE_NAME,
582 EncodingConstants.XMLNS_NAMESPACE_PREFIX,
583 EncodingConstants.XMLNS_NAMESPACE_PREFIX);
584 a.setValue(decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(false));
586 _prefixIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1;
587 break;
588 // prefix, no namespace
589 // Undeclaration of namespace
590 case 2:
591 prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(false);
592 a = createAttribute(
593 EncodingConstants.XMLNS_NAMESPACE_NAME,
594 createQualifiedNameString(prefix),
595 prefix);
596 a.setValue("");
598 _namespaceNameIndex = -1;
599 _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex;
600 break;
601 // prefix, namespace
602 // Declaration of prefixed namespace
603 case 3:
604 prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(true);
605 a = createAttribute(
606 EncodingConstants.XMLNS_NAMESPACE_NAME,
607 createQualifiedNameString(prefix),
608 prefix);
609 a.setValue(decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(true));
611 _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex;
612 break;
613 }
615 _prefixTable.pushScope(_prefixIndex, _namespaceNameIndex);
617 _namespaceAttributes[_namespaceAttributesIndex++] = a;
619 b = read();
620 }
621 if (b != EncodingConstants.TERMINATOR) {
622 throw new IOException(CommonResourceBundle.getInstance().getString("message.EIInamespaceNameNotTerminatedCorrectly"));
623 }
624 final int end = _namespacePrefixesIndex;
626 _b = read();
627 switch(DecoderStateTables.EII(_b)) {
628 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
629 processEII(_elementNameTable._array[_b], hasAttributes);
630 break;
631 case DecoderStateTables.EII_INDEX_MEDIUM:
632 processEII(decodeEIIIndexMedium(), hasAttributes);
633 break;
634 case DecoderStateTables.EII_INDEX_LARGE:
635 processEII(decodeEIIIndexLarge(), hasAttributes);
636 break;
637 case DecoderStateTables.EII_LITERAL:
638 {
639 final QualifiedName qn = processLiteralQualifiedName(
640 _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
641 _elementNameTable.getNext());
642 _elementNameTable.add(qn);
643 processEII(qn, hasAttributes);
644 break;
645 }
646 default:
647 throw new IOException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEIIAfterAIIs"));
648 }
650 for (int i = start; i < end; i++) {
651 _prefixTable.popScope(_namespacePrefixes[i]);
652 }
653 _namespacePrefixesIndex = start;
655 }
657 protected final QualifiedName processLiteralQualifiedName(int state, QualifiedName q)
658 throws FastInfosetException, IOException {
659 if (q == null) q = new QualifiedName();
661 switch (state) {
662 // no prefix, no namespace
663 case 0:
664 return q.set(
665 null,
666 null,
667 decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
668 -1,
669 -1,
670 _identifier,
671 null);
672 // no prefix, namespace
673 case 1:
674 return q.set(
675 null,
676 decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(false),
677 decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
678 -1,
679 _namespaceNameIndex,
680 _identifier,
681 null);
682 // prefix, no namespace
683 case 2:
684 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameMissingNamespaceName"));
685 // prefix, namespace
686 case 3:
687 return q.set(
688 decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(true),
689 decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(true),
690 decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
691 _prefixIndex,
692 _namespaceNameIndex,
693 _identifier,
694 _charBuffer);
695 default:
696 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingEII"));
697 }
698 }
700 protected final QualifiedName processLiteralQualifiedName(int state)
701 throws FastInfosetException, IOException {
702 switch (state) {
703 // no prefix, no namespace
704 case 0:
705 return new QualifiedName(
706 null,
707 null,
708 decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
709 -1,
710 -1,
711 _identifier,
712 null);
713 // no prefix, namespace
714 case 1:
715 return new QualifiedName(
716 null,
717 decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(false),
718 decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
719 -1,
720 _namespaceNameIndex,
721 _identifier,
722 null);
723 // prefix, no namespace
724 case 2:
725 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameMissingNamespaceName"));
726 // prefix, namespace
727 case 3:
728 return new QualifiedName(
729 decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(true),
730 decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(true),
731 decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
732 _prefixIndex,
733 _namespaceNameIndex,
734 _identifier,
735 _charBuffer);
736 default:
737 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingEII"));
738 }
739 }
741 protected final void processAIIs() throws FastInfosetException, IOException {
742 QualifiedName name;
743 int b;
744 String value;
746 if (++_duplicateAttributeVerifier._currentIteration == Integer.MAX_VALUE) {
747 _duplicateAttributeVerifier.clear();
748 }
750 do {
751 // AII qualified name
752 b = read();
753 switch (DecoderStateTables.AII(b)) {
754 case DecoderStateTables.AII_INDEX_SMALL:
755 name = _attributeNameTable._array[b];
756 break;
757 case DecoderStateTables.AII_INDEX_MEDIUM:
758 {
759 final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
760 + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
761 name = _attributeNameTable._array[i];
762 break;
763 }
764 case DecoderStateTables.AII_INDEX_LARGE:
765 {
766 final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
767 + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
768 name = _attributeNameTable._array[i];
769 break;
770 }
771 case DecoderStateTables.AII_LITERAL:
772 name = processLiteralQualifiedName(
773 b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK,
774 _attributeNameTable.getNext());
775 name.createAttributeValues(DuplicateAttributeVerifier.MAP_SIZE);
776 _attributeNameTable.add(name);
777 break;
778 case DecoderStateTables.AII_TERMINATOR_DOUBLE:
779 _doubleTerminate = true;
780 case DecoderStateTables.AII_TERMINATOR_SINGLE:
781 _terminate = true;
782 // AIIs have finished break out of loop
783 continue;
784 default:
785 throw new IOException(CommonResourceBundle.getInstance().getString("message.decodingAIIs"));
786 }
788 if (name.prefixIndex > 0 && _prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
789 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.AIIqNameNotInScope"));
790 }
792 _duplicateAttributeVerifier.checkForDuplicateAttribute(name.attributeHash, name.attributeId);
794 Attr a = createAttribute(
795 name.namespaceName,
796 name.qName,
797 name.localName);
799 // [normalized value] of AII
801 b = read();
802 switch(DecoderStateTables.NISTRING(b)) {
803 case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH:
804 {
805 final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
806 _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
807 value = decodeUtf8StringAsString();
808 if (addToTable) {
809 _attributeValueTable.add(value);
810 }
812 a.setValue(value);
813 _currentElement.setAttributeNode(a);
814 break;
815 }
816 case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH:
817 {
818 final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
819 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
820 value = decodeUtf8StringAsString();
821 if (addToTable) {
822 _attributeValueTable.add(value);
823 }
825 a.setValue(value);
826 _currentElement.setAttributeNode(a);
827 break;
828 }
829 case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH:
830 {
831 final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
832 final int length = (read() << 24) |
833 (read() << 16) |
834 (read() << 8) |
835 read();
836 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
837 value = decodeUtf8StringAsString();
838 if (addToTable) {
839 _attributeValueTable.add(value);
840 }
842 a.setValue(value);
843 _currentElement.setAttributeNode(a);
844 break;
845 }
846 case DecoderStateTables.NISTRING_UTF16_SMALL_LENGTH:
847 {
848 final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
849 _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
850 value = decodeUtf16StringAsString();
851 if (addToTable) {
852 _attributeValueTable.add(value);
853 }
855 a.setValue(value);
856 _currentElement.setAttributeNode(a);
857 break;
858 }
859 case DecoderStateTables.NISTRING_UTF16_MEDIUM_LENGTH:
860 {
861 final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
862 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
863 value = decodeUtf16StringAsString();
864 if (addToTable) {
865 _attributeValueTable.add(value);
866 }
868 a.setValue(value);
869 _currentElement.setAttributeNode(a);
870 break;
871 }
872 case DecoderStateTables.NISTRING_UTF16_LARGE_LENGTH:
873 {
874 final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
875 final int length = (read() << 24) |
876 (read() << 16) |
877 (read() << 8) |
878 read();
879 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
880 value = decodeUtf16StringAsString();
881 if (addToTable) {
882 _attributeValueTable.add(value);
883 }
885 a.setValue(value);
886 _currentElement.setAttributeNode(a);
887 break;
888 }
889 case DecoderStateTables.NISTRING_RA:
890 {
891 final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
892 // Decode resitricted alphabet integer
893 _identifier = (b & 0x0F) << 4;
894 b = read();
895 _identifier |= (b & 0xF0) >> 4;
897 decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
899 value = decodeRestrictedAlphabetAsString();
900 if (addToTable) {
901 _attributeValueTable.add(value);
902 }
904 a.setValue(value);
905 _currentElement.setAttributeNode(a);
906 break;
907 }
908 case DecoderStateTables.NISTRING_EA:
909 {
910 final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
911 _identifier = (b & 0x0F) << 4;
912 b = read();
913 _identifier |= (b & 0xF0) >> 4;
915 decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
916 value = convertEncodingAlgorithmDataToCharacters(true);
917 if (addToTable) {
918 _attributeValueTable.add(value);
919 }
920 a.setValue(value);
921 _currentElement.setAttributeNode(a);
922 break;
923 }
924 case DecoderStateTables.NISTRING_INDEX_SMALL:
925 value = _attributeValueTable._array[b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK];
927 a.setValue(value);
928 _currentElement.setAttributeNode(a);
929 break;
930 case DecoderStateTables.NISTRING_INDEX_MEDIUM:
931 {
932 final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
933 + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
934 value = _attributeValueTable._array[index];
936 a.setValue(value);
937 _currentElement.setAttributeNode(a);
938 break;
939 }
940 case DecoderStateTables.NISTRING_INDEX_LARGE:
941 {
942 final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
943 + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
944 value = _attributeValueTable._array[index];
946 a.setValue(value);
947 _currentElement.setAttributeNode(a);
948 break;
949 }
950 case DecoderStateTables.NISTRING_EMPTY:
951 a.setValue("");
952 _currentElement.setAttributeNode(a);
953 break;
954 default:
955 throw new IOException(CommonResourceBundle.getInstance().getString("message.decodingAIIValue"));
956 }
958 } while (!_terminate);
960 // Reset duplication attribute verfifier
961 _duplicateAttributeVerifier._poolCurrent = _duplicateAttributeVerifier._poolHead;
963 _terminate = _doubleTerminate;
964 _doubleTerminate = false;
965 }
967 protected final void processCommentII() throws FastInfosetException, IOException {
968 switch(decodeNonIdentifyingStringOnFirstBit()) {
969 case NISTRING_STRING:
970 {
971 final String s = new String(_charBuffer, 0, _charBufferLength);
972 if (_addToTable) {
973 _v.otherString.add(new CharArrayString(s, false));
974 }
976 _currentNode.appendChild(_document.createComment(s));
977 break;
978 }
979 case NISTRING_ENCODING_ALGORITHM:
980 throw new IOException(CommonResourceBundle.getInstance().getString("message.commentIIAlgorithmNotSupported"));
981 case NISTRING_INDEX:
982 {
983 final String s = _v.otherString.get(_integer).toString();
985 _currentNode.appendChild(_document.createComment(s));
986 break;
987 }
988 case NISTRING_EMPTY_STRING:
989 _currentNode.appendChild(_document.createComment(""));
990 break;
991 }
992 }
994 protected final void processProcessingII() throws FastInfosetException, IOException {
995 final String target = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
997 switch(decodeNonIdentifyingStringOnFirstBit()) {
998 case NISTRING_STRING:
999 {
1000 final String data = new String(_charBuffer, 0, _charBufferLength);
1001 if (_addToTable) {
1002 _v.otherString.add(new CharArrayString(data, false));
1003 }
1005 _currentNode.appendChild(_document.createProcessingInstruction(target, data));
1006 break;
1007 }
1008 case NISTRING_ENCODING_ALGORITHM:
1009 throw new IOException(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm"));
1010 case NISTRING_INDEX:
1011 {
1012 final String data = _v.otherString.get(_integer).toString();
1014 _currentNode.appendChild(_document.createProcessingInstruction(target, data));
1015 break;
1016 }
1017 case NISTRING_EMPTY_STRING:
1018 _currentNode.appendChild(_document.createProcessingInstruction(target, ""));
1019 break;
1020 }
1021 }
1023 protected Element createElement(String namespaceName, String qName, String localName) {
1024 return _document.createElementNS(namespaceName, qName);
1025 }
1027 protected Attr createAttribute(String namespaceName, String qName, String localName) {
1028 return _document.createAttributeNS(namespaceName, qName);
1029 }
1031 protected String convertEncodingAlgorithmDataToCharacters(boolean isAttributeValue) throws FastInfosetException, IOException {
1032 StringBuffer buffer = new StringBuffer();
1033 if (_identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
1034 Object array = BuiltInEncodingAlgorithmFactory.getAlgorithm(_identifier).
1035 decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
1036 BuiltInEncodingAlgorithmFactory.getAlgorithm(_identifier).convertToCharacters(array, buffer);
1037 } else if (_identifier == EncodingAlgorithmIndexes.CDATA) {
1038 if (!isAttributeValue) {
1039 // Set back buffer position to start of encoded string
1040 _octetBufferOffset -= _octetBufferLength;
1041 return decodeUtf8StringAsString();
1042 }
1043 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.CDATAAlgorithmNotSupported"));
1044 } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
1045 final String URI = _v.encodingAlgorithm.get(_identifier - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START);
1046 final EncodingAlgorithm ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI);
1047 if (ea != null) {
1048 final Object data = ea.decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
1049 ea.convertToCharacters(data, buffer);
1050 } else {
1051 throw new EncodingAlgorithmException(
1052 CommonResourceBundle.getInstance().getString("message.algorithmDataCannotBeReported"));
1053 }
1054 }
1055 return buffer.toString();
1056 }
1057 }