KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > xml > fastinfoset > sax > SAXDocumentParser


1 /*
2  * Fast Infoset ver. 0.1 software ("Software")
3  *
4  * Copyright, 2004-2005 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * Software is licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License. You may
8  * obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15  * License for the specific language governing permissions and limitations.
16  *
17  * Sun supports and benefits from the global community of open source
18  * developers, and thanks the community for its important contributions and
19  * open standards-based technology, which Sun has adopted into many of its
20  * products.
21  *
22  * Please note that portions of Software may be provided with notices and
23  * open source licenses from such communities and third parties that govern the
24  * use of those portions, and any licenses granted hereunder do not alter any
25  * rights and obligations you may have under such open source licenses,
26  * however, the disclaimer of warranty and limitation of liability provisions
27  * in this License will apply to all Software in this distribution.
28  *
29  * You acknowledge that the Software is not designed, licensed or intended
30  * for use in the design, construction, operation or maintenance of any nuclear
31  * facility.
32  *
33  * Apache License
34  * Version 2.0, January 2004
35  * http://www.apache.org/licenses/
36  *
37  */

38
39
40 package com.sun.xml.fastinfoset.sax;
41
42 import com.sun.xml.fastinfoset.Decoder;
43 import com.sun.xml.fastinfoset.DecoderStateTables;
44 import com.sun.xml.fastinfoset.EncodingConstants;
45 import com.sun.xml.fastinfoset.QualifiedName;
46 import com.sun.xml.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
47 import com.sun.xml.fastinfoset.algorithm.BuiltInEncodingAlgorithmState;
48 import org.jvnet.fastinfoset.sax.EncodingAlgorithmContentHandler;
49 import org.jvnet.fastinfoset.sax.FastInfosetReader;
50 import org.jvnet.fastinfoset.sax.PrimitiveTypeContentHandler;
51 import com.sun.xml.fastinfoset.util.CharArray;
52 import com.sun.xml.fastinfoset.util.CharArrayString;
53 import com.sun.xml.fastinfoset.util.PrefixArray;
54 import java.io.IOException JavaDoc;
55 import java.io.InputStream JavaDoc;
56 import java.net.URL JavaDoc;
57 import java.util.Map JavaDoc;
58 import org.jvnet.fastinfoset.EncodingAlgorithm;
59 import org.jvnet.fastinfoset.EncodingAlgorithmException;
60 import org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
61 import org.jvnet.fastinfoset.FastInfosetException;
62 import org.xml.sax.ContentHandler JavaDoc;
63 import org.xml.sax.DTDHandler JavaDoc;
64 import org.xml.sax.EntityResolver JavaDoc;
65 import org.xml.sax.ErrorHandler JavaDoc;
66 import org.xml.sax.InputSource JavaDoc;
67 import org.xml.sax.SAXException JavaDoc;
68 import org.xml.sax.SAXNotRecognizedException JavaDoc;
69 import org.xml.sax.SAXNotSupportedException JavaDoc;
70 import org.xml.sax.SAXParseException JavaDoc;
71 import org.xml.sax.ext.LexicalHandler JavaDoc;
72 import org.xml.sax.helpers.DefaultHandler JavaDoc;
73 import com.sun.xml.fastinfoset.CommonResourceBundle;
74
75 public class SAXDocumentParser extends Decoder implements FastInfosetReader {
76     
77     /**
78      * SAX Namespace attributes features
79      */

80     protected boolean _namespacePrefixesFeature = false;
81     
82     /**
83      * Reference to entity resolver.
84      */

85     protected EntityResolver JavaDoc _entityResolver;
86     
87     /**
88      * Reference to dtd handler.
89      */

90     protected DTDHandler JavaDoc _dtdHandler;
91     
92     /**
93      * Reference to content handler.
94      */

95     protected ContentHandler _contentHandler;
96     
97     /**
98      * Reference to error handler.
99      */

100     protected ErrorHandler JavaDoc _errorHandler;
101     
102     /**
103      * Reference to lexical handler.
104      */

105     protected LexicalHandler JavaDoc _lexicalHandler;
106     
107     protected EncodingAlgorithmContentHandler _algorithmHandler;
108     
109     protected PrimitiveTypeContentHandler _primitiveHandler;
110         
111     protected BuiltInEncodingAlgorithmState builtInAlgorithmState =
112             new BuiltInEncodingAlgorithmState();
113     
114     protected AttributesHolder _attributes;
115     
116     protected int[] _namespacePrefixes = new int[16];
117     
118     protected int _namespacePrefixesIndex;
119     
120     protected boolean _clearAttributes = false;
121     
122     /** Creates a new instance of DocumetParser2 */
123     public SAXDocumentParser() {
124         DefaultHandler JavaDoc handler = new DefaultHandler JavaDoc();
125         _attributes = new AttributesHolder(_registeredEncodingAlgorithms);
126         
127         _entityResolver = handler;
128         _dtdHandler = handler;
129         _contentHandler = handler;
130         _errorHandler = handler;
131         _lexicalHandler = null;
132         
133     }
134     
135     protected void resetOnError() {
136         _clearAttributes = false;
137         _attributes.clear();
138         _namespacePrefixesIndex = 0;
139
140         if (_v != null) {
141             _v.prefix.clearCompletely();
142         }
143         _duplicateAttributeVerifier.clear();
144     }
145     
146     // XMLReader interface
147

148     public boolean getFeature(String JavaDoc name)
149     throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
150         if (name.equals(Features.NAMESPACES_FEATURE)) {
151             return true;
152         } else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) {
153             return _namespacePrefixesFeature;
154         } else if (name.equals(Features.STRING_INTERNING_FEATURE) ||
155                 name.equals(FastInfosetReader.STRING_INTERNING_PROPERTY)) {
156             return getStringInterning();
157         } else {
158             throw new SAXNotRecognizedException JavaDoc(
159                     CommonResourceBundle.getInstance().getString("message.featureNotSupported") + name);
160         }
161     }
162     
163     public void setFeature(String JavaDoc name, boolean value)
164     throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
165         if (name.equals(Features.NAMESPACES_FEATURE)
166         && value == false) {
167             throw new SAXNotSupportedException JavaDoc(name + ":" + value);
168         } else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) {
169             _namespacePrefixesFeature = value;
170         } else if (name.equals(Features.STRING_INTERNING_FEATURE) ||
171                 name.equals(FastInfosetReader.STRING_INTERNING_PROPERTY)) {
172             setStringInterning(value);
173         } else {
174             throw new SAXNotRecognizedException JavaDoc(
175                     CommonResourceBundle.getInstance().getString("message.featureNotSupported") + name);
176         }
177     }
178     
179     public Object JavaDoc getProperty(String JavaDoc name)
180     throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
181         if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) {
182             return getLexicalHandler();
183         } else if (name.equals(FastInfosetReader.EXTERNAL_VOCABULARIES_PROPERTY)) {
184             return _externalVocabularies;
185         } else if (name.equals(FastInfosetReader.REGISTERED_ENCODING_ALGORITHMS_PROPERTY)) {
186             return getRegisteredEncodingAlgorithms();
187         } else if (name.equals(FastInfosetReader.ENCODING_ALGORITHM_CONTENT_HANDLER_PROPERTY)) {
188             return getEncodingAlgorithmContentHandler();
189         } else if (name.equals(FastInfosetReader.PRIMITIVE_TYPE_CONTENT_HANDLER_PROPERTY)) {
190             return getPrimitiveTypeContentHandler();
191         } else {
192             throw new SAXNotRecognizedException JavaDoc(CommonResourceBundle.getInstance().
193                     getString("message.propertyNotRecognized", new Object JavaDoc[]{name}));
194         }
195     }
196     
197     public void setProperty(String JavaDoc name, Object JavaDoc value)
198     throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
199         if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) {
200             if (value instanceof LexicalHandler JavaDoc) {
201                 setLexicalHandler((LexicalHandler JavaDoc)value);
202             } else {
203                 throw new SAXNotSupportedException JavaDoc(Properties.LEXICAL_HANDLER_PROPERTY);
204             }
205         } else if (name.equals(FastInfosetReader.EXTERNAL_VOCABULARIES_PROPERTY)) {
206             if (value instanceof Map JavaDoc) {
207                 _externalVocabularies = (Map JavaDoc)value;
208             } else {
209                 throw new SAXNotSupportedException JavaDoc(FastInfosetReader.EXTERNAL_VOCABULARIES_PROPERTY);
210             }
211         } else if (name.equals(FastInfosetReader.REGISTERED_ENCODING_ALGORITHMS_PROPERTY)) {
212             if (value instanceof Map JavaDoc) {
213                 setRegisteredEncodingAlgorithms((Map JavaDoc)value);
214             } else {
215                 throw new SAXNotSupportedException JavaDoc(FastInfosetReader.REGISTERED_ENCODING_ALGORITHMS_PROPERTY);
216             }
217         } else if (name.equals(FastInfosetReader.ENCODING_ALGORITHM_CONTENT_HANDLER_PROPERTY)) {
218             if (value instanceof EncodingAlgorithmContentHandler) {
219                 setEncodingAlgorithmContentHandler((EncodingAlgorithmContentHandler)value);
220             } else {
221                 throw new SAXNotSupportedException JavaDoc(FastInfosetReader.ENCODING_ALGORITHM_CONTENT_HANDLER_PROPERTY);
222             }
223         } else if (name.equals(FastInfosetReader.PRIMITIVE_TYPE_CONTENT_HANDLER_PROPERTY)) {
224             if (value instanceof PrimitiveTypeContentHandler) {
225                 setPrimitiveTypeContentHandler((PrimitiveTypeContentHandler)value);
226             } else {
227                 throw new SAXNotSupportedException JavaDoc(FastInfosetReader.PRIMITIVE_TYPE_CONTENT_HANDLER_PROPERTY);
228             }
229         } else if (name.equals(FastInfosetReader.BUFFER_SIZE_PROPERTY)) {
230             if (value instanceof Integer JavaDoc) {
231                 setBufferSize(((Integer JavaDoc)value).intValue());
232             } else {
233                 throw new SAXNotSupportedException JavaDoc(FastInfosetReader.BUFFER_SIZE_PROPERTY);
234             }
235         } else {
236             throw new SAXNotRecognizedException JavaDoc(CommonResourceBundle.getInstance().
237                     getString("message.propertyNotRecognized", new Object JavaDoc[]{name}));
238         }
239     }
240     
241     public void setEntityResolver(EntityResolver JavaDoc resolver) {
242         _entityResolver = resolver;
243     }
244     
245     public EntityResolver JavaDoc getEntityResolver() {
246         return _entityResolver;
247     }
248     
249     public void setDTDHandler(DTDHandler JavaDoc handler) {
250         _dtdHandler = handler;
251     }
252     
253     public DTDHandler JavaDoc getDTDHandler() {
254         return _dtdHandler;
255     }
256     public void setContentHandler(ContentHandler handler) {
257         _contentHandler = handler;
258     }
259     
260     public ContentHandler getContentHandler() {
261         return _contentHandler;
262     }
263     
264     public void setErrorHandler(ErrorHandler JavaDoc handler) {
265         _errorHandler = handler;
266     }
267     
268     public ErrorHandler JavaDoc getErrorHandler() {
269         return _errorHandler;
270     }
271     
272     public void parse(InputSource JavaDoc input) throws IOException JavaDoc, SAXException JavaDoc {
273         try {
274             InputStream JavaDoc s = input.getByteStream();
275             if (s == null) {
276                 String JavaDoc systemId = input.getSystemId();
277                 if (systemId == null) {
278                     throw new SAXException JavaDoc(CommonResourceBundle.getInstance().getString("message.inputSource"));
279                 }
280                 parse(systemId);
281             } else {
282                 parse(s);
283             }
284         } catch (FastInfosetException e) {
285             e.printStackTrace();
286             throw new SAXException JavaDoc(e);
287         }
288     }
289     
290     public void parse(String JavaDoc systemId) throws IOException JavaDoc, SAXException JavaDoc {
291         try {
292             systemId = SystemIdResolver.getAbsoluteURI(systemId);
293             parse(new URL JavaDoc(systemId).openStream());
294         } catch (FastInfosetException e) {
295             e.printStackTrace();
296             throw new SAXException JavaDoc(e);
297         }
298     }
299     
300     
301     
302     
303     // FastInfosetReader
304

305     public final void parse(InputStream JavaDoc s) throws IOException JavaDoc, FastInfosetException, SAXException JavaDoc {
306         setInputStream(s);
307         parse();
308     }
309         
310     public void setLexicalHandler(LexicalHandler JavaDoc handler) {
311         _lexicalHandler = handler;
312     }
313     
314     public LexicalHandler JavaDoc getLexicalHandler() {
315         return _lexicalHandler;
316     }
317     
318     public void setEncodingAlgorithmContentHandler(EncodingAlgorithmContentHandler handler) {
319         _algorithmHandler = handler;
320     }
321     
322     public EncodingAlgorithmContentHandler getEncodingAlgorithmContentHandler() {
323         return _algorithmHandler;
324     }
325     
326     public void setPrimitiveTypeContentHandler(PrimitiveTypeContentHandler handler) {
327         _primitiveHandler = handler;
328     }
329     
330     public PrimitiveTypeContentHandler getPrimitiveTypeContentHandler() {
331         return _primitiveHandler;
332     }
333     
334     
335     
336     
337     public final void parse() throws FastInfosetException, IOException JavaDoc {
338         if (_octetBuffer.length < _bufferSize) {
339             _octetBuffer = new byte[_bufferSize];
340         }
341         
342         try {
343             reset();
344             decodeHeader();
345             processDII();
346         } catch (RuntimeException JavaDoc e) {
347             try {
348                 _errorHandler.fatalError(new SAXParseException JavaDoc(e.getClass().getName(), null, e));
349             } catch (Exception JavaDoc ee) {
350             }
351             resetOnError();
352             // Wrap runtime exception
353
throw new FastInfosetException(e);
354         } catch (FastInfosetException e) {
355             try {
356                 _errorHandler.fatalError(new SAXParseException JavaDoc(e.getClass().getName(), null, e));
357             } catch (Exception JavaDoc ee) {
358             }
359             resetOnError();
360             throw e;
361         } catch (IOException JavaDoc e) {
362             try {
363                 _errorHandler.fatalError(new SAXParseException JavaDoc(e.getClass().getName(), null, e));
364             } catch (Exception JavaDoc ee) {
365             }
366             resetOnError();
367             throw e;
368         }
369     }
370     
371     protected final void processDII() throws FastInfosetException, IOException JavaDoc {
372         try {
373             _contentHandler.startDocument();
374         } catch (SAXException JavaDoc e) {
375             throw new FastInfosetException("processDII", e);
376         }
377                 
378         _b = read();
379         if (_b > 0) {
380             processDIIOptionalProperties();
381         }
382         
383         // Decode one Document Type II, Comment IIs, PI IIs and one EII
384
boolean firstElementHasOccured = false;
385         boolean documentTypeDeclarationOccured = false;
386         while(!_terminate || !firstElementHasOccured) {
387             _b = read();
388             switch(DecoderStateTables.DII[_b]) {
389                 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
390                     processEII(_elementNameTable._array[_b], false);
391                     firstElementHasOccured = true;
392                     break;
393                 case DecoderStateTables.EII_AIIS_INDEX_SMALL:
394                     processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true);
395                     firstElementHasOccured = true;
396                     break;
397                 case DecoderStateTables.EII_INDEX_MEDIUM:
398                     processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
399                     firstElementHasOccured = true;
400                     break;
401                 case DecoderStateTables.EII_INDEX_LARGE:
402                     processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
403                     firstElementHasOccured = true;
404                     break;
405                 case DecoderStateTables.EII_LITERAL:
406                 {
407                     final QualifiedName qn = decodeLiteralQualifiedName(
408                                 _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
409                     _elementNameTable.add(qn);
410                     processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
411                     firstElementHasOccured = true;
412                     break;
413                 }
414                 case DecoderStateTables.EII_NAMESPACES:
415                     processEIIWithNamespaces();
416                     firstElementHasOccured = true;
417                     break;
418                 case DecoderStateTables.DOCUMENT_TYPE_DECLARATION_II:
419                 {
420                     if (documentTypeDeclarationOccured) {
421                         throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.secondOccurenceOfDTDII"));
422                     }
423                     documentTypeDeclarationOccured = true;
424                     
425                     String JavaDoc system_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_SYSTEM_IDENTIFIER_FLAG) > 0)
426                     ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
427                     String JavaDoc public_identifier = ((_b & EncodingConstants.DOCUMENT_TYPE_PUBLIC_IDENTIFIER_FLAG) > 0)
428                     ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
429                     
430                     _b = read();
431                     while (_b == EncodingConstants.PROCESSING_INSTRUCTION) {
432                         switch(decodeNonIdentifyingStringOnFirstBit()) {
433                             case NISTRING_STRING:
434                                 final String JavaDoc data = new String JavaDoc(_charBuffer, 0, _charBufferLength);
435                                 if (_addToTable) {
436                                     _v.otherString.add(new CharArray(_charBuffer, 0, _charBufferLength, true));
437                                 }
438                                 break;
439                             case NISTRING_ENCODING_ALGORITHM:
440                                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm"));
441                             case NISTRING_INDEX:
442                                 break;
443                             case NISTRING_EMPTY_STRING:
444                                 break;
445                         }
446                         _b = read();
447                     }
448                     if ((_b & EncodingConstants.TERMINATOR) != EncodingConstants.TERMINATOR) {
449                         throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.processingInstructionIIsNotTerminatedCorrectly"));
450                     }
451                     if (_b == EncodingConstants.DOUBLE_TERMINATOR) {
452                         _terminate = true;
453                     }
454                     
455                     _notations.clear();
456                     _unparsedEntities.clear();
457                     /*
458                      * TODO
459                      * Report All events associated with DTD, PIs, notations etc
460                      */

461                     break;
462                 }
463                 case DecoderStateTables.COMMENT_II:
464                     processCommentII();
465                     break;
466                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
467                     processProcessingII();
468                     break;
469                 case DecoderStateTables.TERMINATOR_DOUBLE:
470                     _doubleTerminate = true;
471                 case DecoderStateTables.TERMINATOR_SINGLE:
472                     _terminate = true;
473                     break;
474                 default:
475                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingDII"));
476             }
477         }
478         
479         // Decode any remaining Comment IIs, PI IIs
480
while(!_terminate) {
481             _b = read();
482             switch(DecoderStateTables.DII[_b]) {
483                 case DecoderStateTables.COMMENT_II:
484                     processCommentII();
485                     break;
486                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
487                     processProcessingII();
488                     break;
489                 case DecoderStateTables.TERMINATOR_DOUBLE:
490                     _doubleTerminate = true;
491                 case DecoderStateTables.TERMINATOR_SINGLE:
492                     _terminate = true;
493                     break;
494                 default:
495                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingDII"));
496             }
497         }
498         
499         try {
500             _contentHandler.endDocument();
501         } catch (SAXException JavaDoc e) {
502             throw new FastInfosetException("processDII", e);
503         }
504     }
505     
506     protected final void processDIIOptionalProperties() throws FastInfosetException, IOException JavaDoc {
507         // Optimize for the most common case
508
if (_b == EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) {
509             decodeInitialVocabulary();
510             return;
511         }
512         
513         if ((_b & EncodingConstants.DOCUMENT_ADDITIONAL_DATA_FLAG) > 0) {
514             decodeAdditionalData();
515             /*
516              * TODO
517              * how to report the additional data?
518              */

519         }
520         
521         if ((_b & EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) > 0) {
522             decodeInitialVocabulary();
523         }
524         
525         if ((_b & EncodingConstants.DOCUMENT_NOTATIONS_FLAG) > 0) {
526             decodeNotations();
527             /*
528                 try {
529                     _dtdHandler.notationDecl(name, public_identifier, system_identifier);
530                 } catch (SAXException e) {
531                     throw new IOException("NotationsDeclarationII");
532                 }
533              */

534         }
535         
536         if ((_b & EncodingConstants.DOCUMENT_UNPARSED_ENTITIES_FLAG) > 0) {
537             decodeUnparsedEntities();
538             /*
539                 try {
540                     _dtdHandler.unparsedEntityDecl(name, public_identifier, system_identifier, notation_name);
541                 } catch (SAXException e) {
542                     throw new IOException("UnparsedEntitiesII");
543                 }
544              */

545         }
546         
547         if ((_b & EncodingConstants.DOCUMENT_CHARACTER_ENCODING_SCHEME) > 0) {
548             String JavaDoc characterEncodingScheme = decodeCharacterEncodingScheme();
549             /*
550              * TODO
551              * how to report the character encoding scheme?
552              */

553         }
554         
555         if ((_b & EncodingConstants.DOCUMENT_STANDALONE_FLAG) > 0) {
556             boolean standalone = (read() > 0) ? true : false ;
557             /*
558              * TODO
559              * how to report the standalone flag?
560              */

561         }
562         
563         if ((_b & EncodingConstants.DOCUMENT_VERSION_FLAG) > 0) {
564             String JavaDoc version = decodeVersion();
565             /*
566              * TODO
567              * how to report the standalone flag?
568              */

569         }
570     }
571     
572     protected final void processEII(QualifiedName name, boolean hasAttributes) throws FastInfosetException, IOException JavaDoc {
573         if (_prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
574             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameOfEIINotInScope"));
575         }
576         
577         if (hasAttributes) {
578             processAIIs();
579         }
580     
581         try {
582             _contentHandler.startElement(name.namespaceName, name.localName, name.qName, _attributes);
583         } catch (SAXException JavaDoc e) {
584             e.printStackTrace();
585             throw new FastInfosetException("processEII", e);
586         }
587         
588         if (_clearAttributes) {
589             _attributes.clear();
590             _clearAttributes = false;
591         }
592         
593         while(!_terminate) {
594             _b = read();
595             switch(DecoderStateTables.EII[_b]) {
596                 case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
597                     processEII(_elementNameTable._array[_b], false);
598                     break;
599                 case DecoderStateTables.EII_AIIS_INDEX_SMALL:
600                     processEII(_elementNameTable._array[_b & EncodingConstants.INTEGER_3RD_BIT_SMALL_MASK], true);
601                     break;
602                 case DecoderStateTables.EII_INDEX_MEDIUM:
603                     processEII(decodeEIIIndexMedium(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
604                     break;
605                 case DecoderStateTables.EII_INDEX_LARGE:
606                     processEII(decodeEIIIndexLarge(), (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
607                     break;
608                 case DecoderStateTables.EII_LITERAL:
609                 {
610                     final QualifiedName qn = decodeLiteralQualifiedName(
611                                 _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
612                     _elementNameTable.add(qn);
613                     processEII(qn, (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0);
614                     break;
615                 }
616                 case DecoderStateTables.EII_NAMESPACES:
617                     processEIIWithNamespaces();
618                     break;
619                 case DecoderStateTables.CII_UTF8_SMALL_LENGTH:
620                     _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK)
621                     + 1;
622                     decodeUtf8StringAsCharBuffer();
623                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
624                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
625                     }
626                     
627                     try {
628                         _contentHandler.characters(_charBuffer, 0, _charBufferLength);
629                     } catch (SAXException JavaDoc e) {
630                         throw new FastInfosetException("processCII", e);
631                     }
632                     break;
633                 case DecoderStateTables.CII_UTF8_MEDIUM_LENGTH:
634                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
635                     decodeUtf8StringAsCharBuffer();
636                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
637                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
638                     }
639                     
640                     try {
641                         _contentHandler.characters(_charBuffer, 0, _charBufferLength);
642                     } catch (SAXException JavaDoc e) {
643                         throw new FastInfosetException("processCII", e);
644                     }
645                     break;
646                 case DecoderStateTables.CII_UTF8_LARGE_LENGTH:
647                     _octetBufferLength = ((read() << 24) |
648                             (read() << 16) |
649                             (read() << 8) |
650                             read())
651                             + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
652                     decodeUtf8StringAsCharBuffer();
653                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
654                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
655                     }
656                     
657                     try {
658                         _contentHandler.characters(_charBuffer, 0, _charBufferLength);
659                     } catch (SAXException JavaDoc e) {
660                         throw new FastInfosetException("processCII", e);
661                     }
662                     break;
663                 case DecoderStateTables.CII_UTF16_SMALL_LENGTH:
664                     _octetBufferLength = (_b & EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_MASK)
665                     + 1;
666                     decodeUtf16StringAsCharBuffer();
667                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
668                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
669                     }
670                     
671                     try {
672                         _contentHandler.characters(_charBuffer, 0, _charBufferLength);
673                     } catch (SAXException JavaDoc e) {
674                         throw new FastInfosetException("processCII", e);
675                     }
676                     break;
677                 case DecoderStateTables.CII_UTF16_MEDIUM_LENGTH:
678                     _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
679                     decodeUtf16StringAsCharBuffer();
680                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
681                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
682                     }
683                     
684                     try {
685                         _contentHandler.characters(_charBuffer, 0, _charBufferLength);
686                     } catch (SAXException JavaDoc e) {
687                         throw new FastInfosetException("processCII", e);
688                     }
689                     break;
690                 case DecoderStateTables.CII_UTF16_LARGE_LENGTH:
691                     _octetBufferLength = ((read() << 24) |
692                             (read() << 16) |
693                             (read() << 8) |
694                             read())
695                             + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
696                     decodeUtf16StringAsCharBuffer();
697                     if ((_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0) {
698                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
699                     }
700                     
701                     try {
702                         _contentHandler.characters(_charBuffer, 0, _charBufferLength);
703                     } catch (SAXException JavaDoc e) {
704                         throw new FastInfosetException("processCII", e);
705                     }
706                     break;
707                 case DecoderStateTables.CII_RA:
708                 {
709                     final boolean addToTable = (_b & EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG) > 0;
710                     
711                     // Decode resitricted alphabet integer
712
_identifier = (_b & 0x02) << 6;
713                     _b = read();
714                     _identifier |= (_b & 0xFC) >> 2;
715                     
716                     decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b);
717                     
718                     decodeRestrictedAlphabetAsCharBuffer();
719                     
720                     if (addToTable) {
721                         _characterContentChunkTable.add(_charBuffer, _charBufferLength);
722                     }
723
724                     try {
725                         _contentHandler.characters(_charBuffer, 0, _charBufferLength);
726                     } catch (SAXException JavaDoc e) {
727                         throw new FastInfosetException("processCII", e);
728                     }
729                     break;
730                 }
731                 case DecoderStateTables.CII_EA:
732                 {
733                     if ((_b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
734                         throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.addToTableNotSupported"));
735                     }
736                     
737                     // Decode encoding algorithm integer
738
_identifier = (_b & 0x02) << 6;
739                     _b = read();
740                     _identifier |= (_b & 0xFC) >> 2;
741                     
742                     decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(_b);
743                     
744                     processCIIEncodingAlgorithm();
745                     break;
746                 }
747                 case DecoderStateTables.CII_INDEX_SMALL:
748                 {
749                     final int index = _b & EncodingConstants.INTEGER_4TH_BIT_SMALL_MASK;
750                     try {
751                         _contentHandler.characters(_characterContentChunkTable._array,
752                                 _characterContentChunkTable._offset[index],
753                                 _characterContentChunkTable._length[index]);
754                     } catch (SAXException JavaDoc e) {
755                         throw new FastInfosetException("processCII", e);
756                     }
757                     break;
758                 }
759                 case DecoderStateTables.CII_INDEX_MEDIUM:
760                 {
761                     final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_MEDIUM_MASK) << 8) | read())
762                             + EncodingConstants.INTEGER_4TH_BIT_SMALL_LIMIT;
763                     try {
764                         _contentHandler.characters(_characterContentChunkTable._array,
765                                 _characterContentChunkTable._offset[index],
766                                 _characterContentChunkTable._length[index]);
767                     } catch (SAXException JavaDoc e) {
768                         throw new FastInfosetException("processCII", e);
769                     }
770                     break;
771                 }
772                 case DecoderStateTables.CII_INDEX_LARGE:
773                 {
774                     final int index = (((_b & EncodingConstants.INTEGER_4TH_BIT_LARGE_MASK) << 16) |
775                             (read() << 8) |
776                             read())
777                             + EncodingConstants.INTEGER_4TH_BIT_MEDIUM_LIMIT;
778                     
779                     try {
780                         _contentHandler.characters(_characterContentChunkTable._array,
781                                 _characterContentChunkTable._offset[index],
782                                 _characterContentChunkTable._length[index]);
783                     } catch (SAXException JavaDoc e) {
784                         throw new FastInfosetException("processCII", e);
785                     }
786                     break;
787                 }
788                 case DecoderStateTables.CII_INDEX_LARGE_LARGE:
789                 {
790                     final int index = ((read() << 16) |
791                             (read() << 8) |
792                             read())
793                             + EncodingConstants.INTEGER_4TH_BIT_LARGE_LIMIT;
794                     
795                     try {
796                         _contentHandler.characters(_characterContentChunkTable._array,
797                                 _characterContentChunkTable._offset[index],
798                                 _characterContentChunkTable._length[index]);
799                     } catch (SAXException JavaDoc e) {
800                         throw new FastInfosetException("processCII", e);
801                     }
802                     break;
803                 }
804                 case DecoderStateTables.COMMENT_II:
805                     processCommentII();
806                     break;
807                 case DecoderStateTables.PROCESSING_INSTRUCTION_II:
808                     processProcessingII();
809                     break;
810                 case DecoderStateTables.UNEXPANDED_ENTITY_REFERENCE_II:
811                 {
812                     String JavaDoc entity_reference_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
813                     
814                     String JavaDoc system_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_SYSTEM_IDENTIFIER_FLAG) > 0)
815                     ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
816                     String JavaDoc public_identifier = ((_b & EncodingConstants.UNEXPANDED_ENTITY_PUBLIC_IDENTIFIER_FLAG) > 0)
817                     ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
818                     
819                     try {
820                         /*
821                          * TODO
822                          * Need to verify if the skippedEntity method:
823                          * http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/ContentHandler.html#skippedEntity(java.lang.String)
824                          * is the correct method to call. It appears so but a more extensive
825                          * check is necessary.
826                          */

827                         _contentHandler.skippedEntity(entity_reference_name);
828                     } catch (SAXException JavaDoc e) {
829                         throw new FastInfosetException("processUnexpandedEntityReferenceII", e);
830                     }
831                     break;
832                 }
833                 case DecoderStateTables.TERMINATOR_DOUBLE:
834                     _doubleTerminate = true;
835                 case DecoderStateTables.TERMINATOR_SINGLE:
836                     _terminate = true;
837                     break;
838                 default:
839                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEII"));
840             }
841         }
842         
843         _terminate = _doubleTerminate;
844         _doubleTerminate = false;
845         
846         try {
847             _contentHandler.endElement(name.namespaceName, name.localName, name.qName);
848         } catch (SAXException JavaDoc e) {
849             throw new FastInfosetException("processEII", e);
850         }
851     }
852     
853     protected final void processEIIWithNamespaces() throws FastInfosetException, IOException JavaDoc {
854         final boolean hasAttributes = (_b & EncodingConstants.ELEMENT_ATTRIBUTE_FLAG) > 0;
855         
856         _clearAttributes = (_namespacePrefixesFeature) ? true : false;
857         
858         if (++_prefixTable._declarationId == Integer.MAX_VALUE) {
859             _prefixTable.clearDeclarationIds();
860         }
861         
862         String JavaDoc prefix = "", namespaceName = "";
863         final int start = _namespacePrefixesIndex;
864         int b = read();
865         while ((b & EncodingConstants.NAMESPACE_ATTRIBUTE_MASK) == EncodingConstants.NAMESPACE_ATTRIBUTE) {
866             if (_namespacePrefixesIndex == _namespacePrefixes.length) {
867                 final int[] namespaceAIIs = new int[_namespacePrefixesIndex * 3 / 2 + 1];
868                 System.arraycopy(_namespacePrefixes, 0, namespaceAIIs, 0, _namespacePrefixesIndex);
869                 _namespacePrefixes = namespaceAIIs;
870             }
871             
872             switch (b & EncodingConstants.NAMESPACE_ATTRIBUTE_PREFIX_NAME_MASK) {
873                 // no prefix, no namespace
874
// Undeclaration of default namespace
875
case 0:
876                     prefix = namespaceName = "";
877                     _namespaceNameIndex = _prefixIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1;
878                     break;
879                 // no prefix, namespace
880
// Declaration of default namespace
881
case 1:
882                     prefix = "";
883                     namespaceName = decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(false);
884                            
885                     _prefixIndex = _namespacePrefixes[_namespacePrefixesIndex++] = -1;
886                     break;
887                 // prefix, no namespace
888
// Undeclaration of namespace
889
case 2:
890                     prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(false);
891                     namespaceName = "";
892                     
893                     _namespaceNameIndex = -1;
894                     _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex;
895                     break;
896                 // prefix, namespace
897
// Declaration of prefixed namespace
898
case 3:
899                     prefix = decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(true);
900                     namespaceName = decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(true);
901                     
902                     _namespacePrefixes[_namespacePrefixesIndex++] = _prefixIndex;
903                     break;
904             }
905     
906             _prefixTable.pushScope(_prefixIndex, _namespaceNameIndex);
907             
908             if (_namespacePrefixesFeature) {
909                 // Add the namespace delcaration as an attribute
910
if (prefix != "") {
911                     _attributes.addAttribute(new QualifiedName(
912                             EncodingConstants.XMLNS_NAMESPACE_PREFIX,
913                             EncodingConstants.XMLNS_NAMESPACE_NAME,
914                             prefix),
915                             namespaceName);
916                 } else {
917                     _attributes.addAttribute(DEFAULT_NAMESPACE_DECLARATION,
918                             namespaceName);
919                 }
920             }
921
922             try {
923                 _contentHandler.startPrefixMapping(prefix, namespaceName);
924             } catch (SAXException JavaDoc e) {
925                 throw new IOException JavaDoc("processStartNamespaceAII");
926             }
927
928             b = read();
929         }
930         if (b != EncodingConstants.TERMINATOR) {
931             throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.EIInamespaceNameNotTerminatedCorrectly"));
932         }
933         final int end = _namespacePrefixesIndex;
934                 
935         _b = read();
936         switch(DecoderStateTables.EII[_b]) {
937             case DecoderStateTables.EII_NO_AIIS_INDEX_SMALL:
938                 processEII(_elementNameTable._array[_b], hasAttributes);
939                 break;
940             case DecoderStateTables.EII_INDEX_MEDIUM:
941                 processEII(decodeEIIIndexMedium(), hasAttributes);
942                 break;
943             case DecoderStateTables.EII_INDEX_LARGE:
944                 processEII(decodeEIIIndexLarge(), hasAttributes);
945                 break;
946             case DecoderStateTables.EII_LITERAL:
947             {
948                 final QualifiedName qn = decodeLiteralQualifiedName(
949                             _b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
950                 _elementNameTable.add(qn);
951                 processEII(qn, hasAttributes);
952                 break;
953             }
954             default:
955                 throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.IllegalStateDecodingEIIAfterAIIs"));
956         }
957         
958         try {
959             for (int i = start; i < end; i++) {
960                 final int prefixIndex = _namespacePrefixes[i];
961                 _prefixTable.popScope(prefixIndex);
962                 _contentHandler.endPrefixMapping((prefixIndex == -1) ? "" : _prefixTable.get(prefixIndex));
963             }
964             _namespacePrefixesIndex = start;
965         } catch (SAXException JavaDoc e) {
966             throw new IOException JavaDoc("processStartNamespaceAII");
967         }
968     }
969     
970     protected final void processAIIs() throws FastInfosetException, IOException JavaDoc {
971         QualifiedName name;
972         int b;
973         String JavaDoc value;
974         
975         _clearAttributes = true;
976         
977         if (++_duplicateAttributeVerifier._currentIteration == Integer.MAX_VALUE) {
978             _duplicateAttributeVerifier.clear();
979         }
980         
981         do {
982             // AII qualified name
983
b = read();
984             switch (DecoderStateTables.AII[b]) {
985                 case DecoderStateTables.AII_INDEX_SMALL:
986                     name = _attributeNameTable._array[b];
987                     break;
988                 case DecoderStateTables.AII_INDEX_MEDIUM:
989                 {
990                     final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
991                             + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
992                     name = _attributeNameTable._array[i];
993                     break;
994                 }
995                 case DecoderStateTables.AII_INDEX_LARGE:
996                 {
997                     final int i = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
998                             + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
999                     name = _attributeNameTable._array[i];
1000                    break;
1001                }
1002                case DecoderStateTables.AII_LITERAL:
1003                    name = decodeLiteralQualifiedName(
1004                            b & EncodingConstants.LITERAL_QNAME_PREFIX_NAMESPACE_NAME_MASK);
1005                    name.createAttributeValues(_duplicateAttributeVerifier.MAP_SIZE);
1006                    _attributeNameTable.add(name);
1007                    break;
1008                case DecoderStateTables.AII_TERMINATOR_DOUBLE:
1009                    _doubleTerminate = true;
1010                case DecoderStateTables.AII_TERMINATOR_SINGLE:
1011                    _terminate = true;
1012                    // AIIs have finished break out of loop
1013
continue;
1014                default:
1015                    throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.decodingAIIs"));
1016            }
1017
1018            if (name.prefixIndex > 0 && _prefixTable._currentInScope[name.prefixIndex] != name.namespaceNameIndex) {
1019                throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.AIIqNameNotInScope"));
1020            }
1021
1022            _duplicateAttributeVerifier.checkForDuplicateAttribute(name.attributeHash, name.attributeId);
1023            
1024            // [normalized value] of AII
1025

1026            b = read();
1027            switch(DecoderStateTables.NISTRING[b]) {
1028                case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH:
1029                    _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
1030                    value = decodeUtf8StringAsString();
1031                    if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1032                        _attributeValueTable.add(value);
1033                    }
1034                    
1035                    _attributes.addAttribute(name, value);
1036                    break;
1037                case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH:
1038                    _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
1039                    value = decodeUtf8StringAsString();
1040                    if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1041                        _attributeValueTable.add(value);
1042                    }
1043                    
1044                    _attributes.addAttribute(name, value);
1045                    break;
1046                case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH:
1047                    _octetBufferLength = ((read() << 24) |
1048                            (read() << 16) |
1049                            (read() << 8) |
1050                            read())
1051                            + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
1052                    value = decodeUtf8StringAsString();
1053                    if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1054                        _attributeValueTable.add(value);
1055                    }
1056                    
1057                    _attributes.addAttribute(name, value);
1058                    break;
1059                case DecoderStateTables.NISTRING_UTF16_SMALL_LENGTH:
1060                    _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
1061                    value = decodeUtf16StringAsString();
1062                    if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1063                        _attributeValueTable.add(value);
1064                    }
1065                    
1066                    _attributes.addAttribute(name, value);
1067                    break;
1068                case DecoderStateTables.NISTRING_UTF16_MEDIUM_LENGTH:
1069                    _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
1070                    value = decodeUtf16StringAsString();
1071                    if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1072                        _attributeValueTable.add(value);
1073                    }
1074                    
1075                    _attributes.addAttribute(name, value);
1076                    break;
1077                case DecoderStateTables.NISTRING_UTF16_LARGE_LENGTH:
1078                    _octetBufferLength = ((read() << 24) |
1079                            (read() << 16) |
1080                            (read() << 8) |
1081                            read())
1082                            + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
1083                    value = decodeUtf16StringAsString();
1084                    if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1085                        _attributeValueTable.add(value);
1086                    }
1087                    
1088                    _attributes.addAttribute(name, value);
1089                    break;
1090                case DecoderStateTables.NISTRING_RA:
1091                {
1092                    final boolean addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
1093                    // Decode resitricted alphabet integer
1094
_identifier = (b & 0x0F) << 4;
1095                    b = read();
1096                    _identifier |= (b & 0xF0) >> 4;
1097                    
1098                    decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
1099                    
1100                    value = decodeRestrictedAlphabetAsString();
1101                    if (addToTable) {
1102                        _attributeValueTable.add(value);
1103                    }
1104                    
1105                    _attributes.addAttribute(name, value);
1106                    break;
1107                }
1108                case DecoderStateTables.NISTRING_EA:
1109                {
1110                    if ((b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0) {
1111                        throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.addToTableNotSupported"));
1112                    }
1113                    
1114                    _identifier = (b & 0x0F) << 4;
1115                    b = read();
1116                    _identifier |= (b & 0xF0) >> 4;
1117                    
1118                    decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b);
1119                    
1120                    processAIIEncodingAlgorithm(name);
1121                    break;
1122                }
1123                case DecoderStateTables.NISTRING_INDEX_SMALL:
1124                    _attributes.addAttribute(name,
1125                            _attributeValueTable._array[b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK]);
1126                    break;
1127                case DecoderStateTables.NISTRING_INDEX_MEDIUM:
1128                {
1129                    final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
1130                    + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
1131                    
1132                    _attributes.addAttribute(name,
1133                            _attributeValueTable._array[index]);
1134                    break;
1135                }
1136                case DecoderStateTables.NISTRING_INDEX_LARGE:
1137                {
1138                    final int index = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
1139                    + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
1140                    
1141                    _attributes.addAttribute(name,
1142                            _attributeValueTable._array[index]);
1143                    break;
1144                }
1145                case DecoderStateTables.NISTRING_EMPTY:
1146                    _attributes.addAttribute(name, "");
1147                    break;
1148                default:
1149                    throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.decodingAIIValue"));
1150            }
1151            
1152        } while (!_terminate);
1153
1154        // Reset duplication attribute verfifier
1155
_duplicateAttributeVerifier._poolCurrent = _duplicateAttributeVerifier._poolHead;
1156        
1157        _terminate = _doubleTerminate;
1158        _doubleTerminate = false;
1159    }
1160    
1161    protected final void processCommentII() throws FastInfosetException, IOException JavaDoc {
1162        switch(decodeNonIdentifyingStringOnFirstBit()) {
1163            case NISTRING_STRING:
1164                if (_addToTable) {
1165                    _v.otherString.add(new CharArray(_charBuffer, 0, _charBufferLength, true));
1166                }
1167                
1168                try {
1169                    _lexicalHandler.comment(_charBuffer, 0, _charBufferLength);
1170                } catch (SAXException JavaDoc e) {
1171                    throw new FastInfosetException("processCommentII", e);
1172                }
1173                break;
1174            case NISTRING_ENCODING_ALGORITHM:
1175                throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.commentIIAlgorithmNotSupported"));
1176            case NISTRING_INDEX:
1177                final CharArray ca = _v.otherString.get(_integer);
1178                
1179                try {
1180                    _lexicalHandler.comment(ca.ch, ca.start, ca.length);
1181                } catch (SAXException JavaDoc e) {
1182                    throw new FastInfosetException("processCommentII", e);
1183                }
1184                break;
1185            case NISTRING_EMPTY_STRING:
1186                try {
1187                    _lexicalHandler.comment(_charBuffer, 0, 0);
1188                } catch (SAXException JavaDoc e) {
1189                    throw new FastInfosetException("processCommentII", e);
1190                }
1191                break;
1192        }
1193    }
1194    
1195    protected final void processProcessingII() throws FastInfosetException, IOException JavaDoc {
1196        final String JavaDoc target = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
1197        
1198        switch(decodeNonIdentifyingStringOnFirstBit()) {
1199            case NISTRING_STRING:
1200                final String JavaDoc data = new String JavaDoc(_charBuffer, 0, _charBufferLength);
1201                if (_addToTable) {
1202                    _v.otherString.add(new CharArrayString(data));
1203                }
1204                try {
1205                    _contentHandler.processingInstruction(target, data);
1206                } catch (SAXException JavaDoc e) {
1207                    throw new FastInfosetException("processProcessingII", e);
1208                }
1209                break;
1210            case NISTRING_ENCODING_ALGORITHM:
1211                throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.processingIIWithEncodingAlgorithm"));
1212            case NISTRING_INDEX:
1213                try {
1214                    _contentHandler.processingInstruction(target, _v.otherString.get(_integer).toString());
1215                } catch (SAXException JavaDoc e) {
1216                    throw new FastInfosetException("processProcessingII", e);
1217                }
1218                break;
1219            case NISTRING_EMPTY_STRING:
1220                try {
1221                    _contentHandler.processingInstruction(target, "");
1222                } catch (SAXException JavaDoc e) {
1223                    throw new FastInfosetException("processProcessingII", e);
1224                }
1225                break;
1226        }
1227    }
1228        
1229    protected final void processCIIEncodingAlgorithm() throws FastInfosetException, IOException JavaDoc {
1230        if (_identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
1231            if (_primitiveHandler != null) {
1232                processCIIBuiltInEncodingAlgorithmAsPrimitive();
1233            } else if (_algorithmHandler != null) {
1234                Object JavaDoc array = processBuiltInEncodingAlgorithmAsObject();
1235                
1236                try {
1237                    _algorithmHandler.object(null, _identifier, array);
1238                } catch (SAXException JavaDoc e) {
1239                    throw new FastInfosetException(e);
1240                }
1241            } else {
1242                StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
1243                processBuiltInEncodingAlgorithmAsCharacters(buffer);
1244                
1245                try {
1246                    _contentHandler.characters(buffer.toString().toCharArray(), 0, buffer.length());
1247                } catch (SAXException JavaDoc e) {
1248                    throw new FastInfosetException(e);
1249                }
1250            }
1251        } else if (_identifier == EncodingAlgorithmIndexes.CDATA) {
1252                // Set back buffer position to start of encoded string
1253
_octetBufferOffset -= _octetBufferLength;
1254                decodeUtf8StringIntoCharBuffer();
1255                
1256                try {
1257                    _lexicalHandler.startCDATA();
1258                    _contentHandler.characters(_charBuffer, 0, _charBufferLength);
1259                    _lexicalHandler.endCDATA();
1260                } catch (SAXException JavaDoc e) {
1261                    throw new FastInfosetException(e);
1262                }
1263        } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START && _algorithmHandler != null) {
1264            final String JavaDoc URI = _v.encodingAlgorithm.get(_identifier - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START);
1265            if (URI == null) {
1266                throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().
1267                        getString("message.URINotPresent", new Object JavaDoc[]{new Integer JavaDoc(_identifier)}));
1268            }
1269            
1270            final EncodingAlgorithm ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI);
1271            if (ea != null) {
1272                final Object JavaDoc data = ea.decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
1273                try {
1274                    _algorithmHandler.object(URI, _identifier, data);
1275                } catch (SAXException JavaDoc e) {
1276                    throw new FastInfosetException(e);
1277                }
1278            } else {
1279                try {
1280                    _algorithmHandler.octets(URI, _identifier, _octetBuffer, _octetBufferStart, _octetBufferLength);
1281                } catch (SAXException JavaDoc e) {
1282                    throw new FastInfosetException(e);
1283                }
1284            }
1285        } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
1286            // TODO should have property to ignore
1287
throw new EncodingAlgorithmException(
1288                    CommonResourceBundle.getInstance().getString("message.algorithmDataCannotBeReported"));
1289        } else {
1290            // Reserved built-in algorithms for future use
1291
// TODO should use sax property to decide if event will be
1292
// reported, allows for support through handler if required.
1293
throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved"));
1294        }
1295    }
1296    
1297    protected final void processCIIBuiltInEncodingAlgorithmAsPrimitive() throws FastInfosetException, IOException JavaDoc {
1298        try {
1299            int length;
1300            switch(_identifier) {
1301                case EncodingAlgorithmIndexes.HEXADECIMAL:
1302                    _primitiveHandler.bytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
1303                    break;
1304                case EncodingAlgorithmIndexes.BASE64:
1305                    _primitiveHandler.bytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
1306                    break;
1307                case EncodingAlgorithmIndexes.SHORT:
1308                    length = BuiltInEncodingAlgorithmFactory.shortEncodingAlgorithm.
1309                            getPrimtiveLengthFromOctetLength(_octetBufferLength);
1310                    if (length > builtInAlgorithmState.shortArray.length) {
1311                        final short[] array = new short[length * 3 / 2 + 1];
1312                        System.arraycopy(builtInAlgorithmState.shortArray, 0,
1313                                array, 0, builtInAlgorithmState.shortArray.length);
1314                        builtInAlgorithmState.shortArray = array;
1315                    }
1316                    
1317                    BuiltInEncodingAlgorithmFactory.shortEncodingAlgorithm.
1318                            decodeFromBytesToShortArray(builtInAlgorithmState.shortArray, 0,
1319                            _octetBuffer, _octetBufferStart, _octetBufferLength);
1320                    _primitiveHandler.shorts(builtInAlgorithmState.shortArray, 0, length);
1321                    break;
1322                case EncodingAlgorithmIndexes.INT:
1323                    length = BuiltInEncodingAlgorithmFactory.intEncodingAlgorithm.
1324                            getPrimtiveLengthFromOctetLength(_octetBufferLength);
1325                    if (length > builtInAlgorithmState.intArray.length) {
1326                        final int[] array = new int[length * 3 / 2 + 1];
1327                        System.arraycopy(builtInAlgorithmState.intArray, 0,
1328                                array, 0, builtInAlgorithmState.intArray.length);
1329                        builtInAlgorithmState.intArray = array;
1330                    }
1331                    
1332                    BuiltInEncodingAlgorithmFactory.intEncodingAlgorithm.
1333                            decodeFromBytesToIntArray(builtInAlgorithmState.intArray, 0,
1334                            _octetBuffer, _octetBufferStart, _octetBufferLength);
1335                    _primitiveHandler.ints(builtInAlgorithmState.intArray, 0, length);
1336                    break;
1337                case EncodingAlgorithmIndexes.LONG:
1338                    length = BuiltInEncodingAlgorithmFactory.longEncodingAlgorithm.
1339                            getPrimtiveLengthFromOctetLength(_octetBufferLength);
1340                    if (length > builtInAlgorithmState.longArray.length) {
1341                        final long[] array = new long[length * 3 / 2 + 1];
1342                        System.arraycopy(builtInAlgorithmState.longArray, 0,
1343                                array, 0, builtInAlgorithmState.longArray.length);
1344                        builtInAlgorithmState.longArray = array;
1345                    }
1346                    
1347                    BuiltInEncodingAlgorithmFactory.longEncodingAlgorithm.
1348                            decodeFromBytesToLongArray(builtInAlgorithmState.longArray, 0,
1349                            _octetBuffer, _octetBufferStart, _octetBufferLength);
1350                    _primitiveHandler.ints(builtInAlgorithmState.intArray, 0, length);
1351                    break;
1352                case EncodingAlgorithmIndexes.BOOLEAN:
1353                    length = BuiltInEncodingAlgorithmFactory.booleanEncodingAlgorithm.
1354                            getPrimtiveLengthFromOctetLength(_octetBufferLength, _octetBuffer[_octetBufferStart] & 0xFF);
1355                    if (length > builtInAlgorithmState.booleanArray.length) {
1356                        final boolean[] array = new boolean[length * 3 / 2 + 1];
1357                        System.arraycopy(builtInAlgorithmState.booleanArray, 0,
1358                                array, 0, builtInAlgorithmState.booleanArray.length);
1359                        builtInAlgorithmState.booleanArray = array;
1360                    }
1361                    
1362                    BuiltInEncodingAlgorithmFactory.booleanEncodingAlgorithm.
1363                            decodeFromBytesToBooleanArray(
1364                            builtInAlgorithmState.booleanArray, 0, length,
1365                            _octetBuffer, _octetBufferStart, _octetBufferLength);
1366                    _primitiveHandler.booleans(builtInAlgorithmState.booleanArray, 0, length);
1367                    break;
1368                case EncodingAlgorithmIndexes.FLOAT:
1369                    length = BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm.
1370                            getPrimtiveLengthFromOctetLength(_octetBufferLength);
1371                    if (length > builtInAlgorithmState.floatArray.length) {
1372                        final float[] array = new float[length * 3 / 2 + 1];
1373                        System.arraycopy(builtInAlgorithmState.floatArray, 0,
1374                                array, 0, builtInAlgorithmState.floatArray.length);
1375                        builtInAlgorithmState.floatArray = array;
1376                    }
1377                    
1378                    BuiltInEncodingAlgorithmFactory.floatEncodingAlgorithm.
1379                            decodeFromBytesToFloatArray(builtInAlgorithmState.floatArray, 0,
1380                            _octetBuffer, _octetBufferStart, _octetBufferLength);
1381                    _primitiveHandler.floats(builtInAlgorithmState.floatArray, 0, length);
1382                    break;
1383                case EncodingAlgorithmIndexes.DOUBLE:
1384                    length = BuiltInEncodingAlgorithmFactory.doubleEncodingAlgorithm.
1385                            getPrimtiveLengthFromOctetLength(_octetBufferLength);
1386                    if (length > builtInAlgorithmState.doubleArray.length) {
1387                        final double[] array = new double[length * 3 / 2 + 1];
1388                        System.arraycopy(builtInAlgorithmState.doubleArray, 0,
1389                                array, 0, builtInAlgorithmState.doubleArray.length);
1390                        builtInAlgorithmState.doubleArray = array;
1391                    }
1392                    
1393                    BuiltInEncodingAlgorithmFactory.doubleEncodingAlgorithm.
1394                            decodeFromBytesToDoubleArray(builtInAlgorithmState.doubleArray, 0,
1395                            _octetBuffer, _octetBufferStart, _octetBufferLength);
1396                    _primitiveHandler.doubles(builtInAlgorithmState.doubleArray, 0, length);
1397                    break;
1398                case EncodingAlgorithmIndexes.UUID:
1399                    length = BuiltInEncodingAlgorithmFactory.uuidEncodingAlgorithm.
1400                            getPrimtiveLengthFromOctetLength(_octetBufferLength);
1401                    if (length > builtInAlgorithmState.longArray.length) {
1402                        final long[] array = new long[length * 3 / 2 + 1];
1403                        System.arraycopy(builtInAlgorithmState.longArray, 0,
1404                                array, 0, builtInAlgorithmState.longArray.length);
1405                        builtInAlgorithmState.longArray = array;
1406                    }
1407                    
1408                    BuiltInEncodingAlgorithmFactory.uuidEncodingAlgorithm.
1409                            decodeFromBytesToLongArray(builtInAlgorithmState.longArray, 0,
1410                            _octetBuffer, _octetBufferStart, _octetBufferLength);
1411                    _primitiveHandler.uuids(builtInAlgorithmState.longArray, 0, length);
1412                    break;
1413                case EncodingAlgorithmIndexes.CDATA:
1414                    throw new UnsupportedOperationException JavaDoc("CDATA");
1415                default:
1416                    throw new FastInfosetException(CommonResourceBundle.getInstance().
1417                            getString("message.unsupportedAlgorithm", new Object JavaDoc[]{new Integer JavaDoc(_identifier)}));
1418            }
1419        } catch (SAXException JavaDoc e) {
1420            throw new FastInfosetException(e);
1421        }
1422    }
1423    
1424    
1425    protected final void processAIIEncodingAlgorithm(QualifiedName name) throws FastInfosetException, IOException JavaDoc {
1426        if (_identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
1427            if (_primitiveHandler != null || _algorithmHandler != null) {
1428                Object JavaDoc data = processBuiltInEncodingAlgorithmAsObject();
1429                _attributes.addAttributeWithAlgorithmData(name, null, _identifier, data);
1430            } else {
1431                StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
1432                processBuiltInEncodingAlgorithmAsCharacters(buffer);
1433                _attributes.addAttribute(name, buffer.toString());
1434            }
1435        } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START && _algorithmHandler != null) {
1436            final String JavaDoc URI = _v.encodingAlgorithm.get(_identifier - EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START);
1437            if (URI == null) {
1438                throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().
1439                        getString("message.URINotPresent", new Object JavaDoc[]{new Integer JavaDoc(_identifier)}));
1440            }
1441            
1442            final EncodingAlgorithm ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI);
1443            if (ea != null) {
1444                final Object JavaDoc data = ea.decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
1445                _attributes.addAttributeWithAlgorithmData(name, URI, _identifier, data);
1446            } else {
1447                final byte[] data = new byte[_octetBufferLength];
1448                System.arraycopy(_octetBuffer, _octetBufferStart, data, 0, _octetBufferLength);
1449                _attributes.addAttributeWithAlgorithmData(name, URI, _identifier, data);
1450            }
1451        } else if (_identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
1452            // TODO should have property to ignore
1453
throw new EncodingAlgorithmException(
1454                    CommonResourceBundle.getInstance().getString("message.algorithmDataCannotBeReported"));
1455        } else if (_identifier == EncodingAlgorithmIndexes.CDATA) {
1456            throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.CDATAAlgorithmNotSupported"));
1457        } else {
1458            // Reserved built-in algorithms for future use
1459
// TODO should use sax property to decide if event will be
1460
// reported, allows for support through handler if required.
1461
throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved"));
1462        }
1463    }
1464    
1465    protected final void processBuiltInEncodingAlgorithmAsCharacters(StringBuffer JavaDoc buffer) throws FastInfosetException, IOException JavaDoc {
1466        // TODO not very efficient, need to reuse buffers
1467
Object JavaDoc array = BuiltInEncodingAlgorithmFactory.table[_identifier].
1468                decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
1469        
1470        BuiltInEncodingAlgorithmFactory.table[_identifier].convertToCharacters(array, buffer);
1471    }
1472    
1473    protected final Object JavaDoc processBuiltInEncodingAlgorithmAsObject() throws FastInfosetException, IOException JavaDoc {
1474        return BuiltInEncodingAlgorithmFactory.table[_identifier].
1475                decodeFromBytes(_octetBuffer, _octetBufferStart, _octetBufferLength);
1476    }
1477}
Popular Tags