KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > xml > fastinfoset > Decoder


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;
41
42 import com.sun.xml.fastinfoset.alphabet.BuiltInRestrictedAlphabets;
43 import com.sun.xml.fastinfoset.org.apache.xerces.util.XMLChar;
44 import com.sun.xml.fastinfoset.util.CharArray;
45 import com.sun.xml.fastinfoset.util.CharArrayArray;
46 import com.sun.xml.fastinfoset.util.CharArrayString;
47 import com.sun.xml.fastinfoset.util.ContiguousCharArrayArray;
48 import com.sun.xml.fastinfoset.util.DuplicateAttributeVerifier;
49 import com.sun.xml.fastinfoset.util.PrefixArray;
50 import com.sun.xml.fastinfoset.util.QualifiedNameArray;
51 import com.sun.xml.fastinfoset.util.StringArray;
52 import com.sun.xml.fastinfoset.vocab.ParserVocabulary;
53 import java.io.EOFException JavaDoc;
54 import java.io.IOException JavaDoc;
55 import java.io.InputStream JavaDoc;
56 import java.net.URI JavaDoc;
57 import java.net.URISyntaxException JavaDoc;
58 import java.util.ArrayList JavaDoc;
59 import java.util.HashMap JavaDoc;
60 import java.util.List JavaDoc;
61 import java.util.Map JavaDoc;
62 import org.jvnet.fastinfoset.FastInfosetException;
63 import org.jvnet.fastinfoset.FastInfosetParser;
64 import org.jvnet.fastinfoset.ReferencedVocabulary;
65 import org.jvnet.fastinfoset.Vocabulary;
66
67 public abstract class Decoder implements FastInfosetParser {
68
69     // String interning system property
70
public static final String JavaDoc STRING_INTERNING_SYSTEM_PROPERTY =
71         "com.sun.xml.fastinfoset.parser.string-interning";
72
73     // Buffer size system property
74
public static final String JavaDoc BUFFER_SIZE_SYSTEM_PROPERTY =
75         "com.sun.xml.fastinfoset.parser.buffer-size";
76
77     protected static boolean _stringInterningSystemDefault = false;
78     
79     protected static int _bufferSizeSystemDefault = 1024;
80
81     protected static QualifiedName DEFAULT_NAMESPACE_DECLARATION = new QualifiedName(
82             "",
83             EncodingConstants.XMLNS_NAMESPACE_NAME,
84             EncodingConstants.XMLNS_NAMESPACE_PREFIX,
85             EncodingConstants.XMLNS_NAMESPACE_PREFIX);
86     
87     static {
88         String JavaDoc p = System.getProperty(STRING_INTERNING_SYSTEM_PROPERTY,
89             Boolean.toString(_stringInterningSystemDefault));
90         _stringInterningSystemDefault = Boolean.valueOf(p).booleanValue();
91
92         p = System.getProperty(BUFFER_SIZE_SYSTEM_PROPERTY,
93             Integer.toString(_bufferSizeSystemDefault));
94         try {
95             int i = Integer.valueOf(p).intValue();
96             if (i > 0) {
97                 _bufferSizeSystemDefault = i;
98             }
99         } catch (NumberFormatException JavaDoc e) {
100         }
101     }
102
103     
104     protected boolean _stringInterning = _stringInterningSystemDefault;
105
106     protected int _bufferSize = _bufferSizeSystemDefault;
107     
108     protected InputStream JavaDoc _s;
109
110     protected Map JavaDoc _externalVocabularies;
111
112     protected Map JavaDoc _registeredEncodingAlgorithms = new HashMap JavaDoc();
113     
114     protected ParserVocabulary _v;
115
116     protected PrefixArray _prefixTable;
117     
118     protected QualifiedNameArray _elementNameTable;
119     
120     protected QualifiedNameArray _attributeNameTable;
121
122     protected ContiguousCharArrayArray _characterContentChunkTable;
123
124     protected StringArray _attributeValueTable;
125     
126     protected boolean _vIsInternal;
127
128     protected List JavaDoc _notations;
129
130     protected List JavaDoc _unparsedEntities;
131
132     protected int _b;
133
134     protected boolean _terminate;
135
136     protected boolean _doubleTerminate;
137
138     protected boolean _addToTable;
139
140     protected int _integer;
141
142     protected int _identifier;
143
144     protected byte[] _octetBuffer = new byte[_bufferSizeSystemDefault];
145
146     protected int _octetBufferStart;
147
148     protected int _octetBufferOffset;
149
150     protected int _octetBufferEnd;
151
152     protected int _octetBufferLength;
153
154     protected EncodingAlgorithmInputStream _encodingAlgorithmInputStream = new EncodingAlgorithmInputStream();
155
156     protected char[] _charBuffer = new char[512];
157
158     protected int _charBufferLength;
159
160     protected DuplicateAttributeVerifier _duplicateAttributeVerifier = new DuplicateAttributeVerifier();
161     
162     public Decoder() {
163         _v = new ParserVocabulary();
164         _prefixTable = _v.prefix;
165         _elementNameTable = _v.elementName;
166         _attributeNameTable = _v.attributeName;
167         _characterContentChunkTable = _v.characterContentChunk;
168         _attributeValueTable = _v.attributeValue;
169         _vIsInternal = true;
170     }
171
172     
173     // FastInfosetParser
174

175     public void setStringInterning(boolean stringInterning) {
176         _stringInterning = stringInterning;
177     }
178     
179     public boolean getStringInterning() {
180         return _stringInterning;
181     }
182     
183     public void setBufferSize(int bufferSize) {
184         if (_bufferSize > _octetBuffer.length) {
185             _bufferSize = bufferSize;
186         }
187     }
188     
189     public int getBufferSize() {
190         return _bufferSize;
191     }
192     
193     public void setRegisteredEncodingAlgorithms(Map JavaDoc algorithms) {
194         _registeredEncodingAlgorithms = algorithms;
195         if (_registeredEncodingAlgorithms == null) {
196             _registeredEncodingAlgorithms = new HashMap JavaDoc();
197         }
198     }
199     
200     public Map JavaDoc getRegisteredEncodingAlgorithms() {
201         return _registeredEncodingAlgorithms;
202     }
203     
204     public void setExternalVocabularies(Map JavaDoc referencedVocabualries) {
205         throw new UnsupportedOperationException JavaDoc();
206     }
207
208     public void setDynamicVocabulary(Vocabulary v) {
209         throw new UnsupportedOperationException JavaDoc();
210     }
211
212     public ReferencedVocabulary getExternalVocabulary() {
213         throw new UnsupportedOperationException JavaDoc();
214     }
215
216     public Vocabulary getIntitialVocabulary() {
217         throw new UnsupportedOperationException JavaDoc();
218     }
219
220     public Vocabulary getDynamicVocabulary() {
221         throw new UnsupportedOperationException JavaDoc();
222     }
223
224     public Vocabulary getFinalVocabulary() {
225         throw new UnsupportedOperationException JavaDoc();
226     }
227     
228     
229     
230     public void reset() {
231         _terminate = _doubleTerminate = false;
232     }
233
234     public void setVocabulary(ParserVocabulary v) {
235         _v = v;
236         _prefixTable = _v.prefix;
237         _elementNameTable = _v.elementName;
238         _attributeNameTable = _v.attributeName;
239         _characterContentChunkTable = _v.characterContentChunk;
240         _attributeValueTable = _v.attributeValue;
241         _vIsInternal = false;
242     }
243
244     public void setInputStream(InputStream JavaDoc s) {
245         _s = s;
246         _octetBufferOffset = 0;
247         _octetBufferEnd = 0;
248         if (_vIsInternal == true) {
249             _v.clear();
250         }
251     }
252
253     public final void decodeDII() throws FastInfosetException, IOException JavaDoc {
254         final int b = read();
255         if (b == EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG) {
256             decodeInitialVocabulary();
257         } else if (b != 0) {
258             throw new IOException JavaDoc(CommonResourceBundle.getInstance().
259                 getString("message.optinalValues"));
260         }
261     }
262
263     public final void decodeAdditionalData() throws FastInfosetException, IOException JavaDoc {
264         for (int i = 0; i < decodeNumberOfItemsOfSequence(); i++) {
265             String JavaDoc URI = decodeNonEmptyOctetStringOnSecondBitAsUtf8String();
266             
267             decodeNonEmptyOctetStringLengthOnSecondBit();
268             ensureOctetBufferSize();
269             _octetBufferStart = _octetBufferOffset;
270             _octetBufferOffset += _octetBufferLength;
271         }
272     }
273
274     public final void decodeInitialVocabulary() throws FastInfosetException, IOException JavaDoc {
275         // First 5 optionals of 13 bit optional field
276
int b = read();
277         // Next 8 optionals of 13 bit optional field
278
int b2 = read();
279
280         // Optimize for the most common case
281
if (b == EncodingConstants.INITIAL_VOCABULARY_EXTERNAL_VOCABULARY_FLAG && b2 == 0) {
282             decodeExternalVocabularyURI();
283             return;
284         }
285
286         if ((b & EncodingConstants.INITIAL_VOCABULARY_EXTERNAL_VOCABULARY_FLAG) > 0) {
287             decodeExternalVocabularyURI();
288         }
289
290         if ((b & EncodingConstants.INITIAL_VOCABULARY_RESTRICTED_ALPHABETS_FLAG) > 0) {
291             decodeTableItems(_v.restrictedAlphabet);
292         }
293
294         if ((b & EncodingConstants.INITIAL_VOCABULARY_ENCODING_ALGORITHMS_FLAG) > 0) {
295             decodeTableItems(_v.encodingAlgorithm);
296         }
297
298         if ((b & EncodingConstants.INITIAL_VOCABULARY_PREFIXES_FLAG) > 0) {
299             decodeTableItems(_v.prefix);
300         }
301
302         if ((b & EncodingConstants.INITIAL_VOCABULARY_NAMESPACE_NAMES_FLAG) > 0) {
303             decodeTableItems(_v.namespaceName);
304         }
305
306         if ((b2 & EncodingConstants.INITIAL_VOCABULARY_LOCAL_NAMES_FLAG) > 0) {
307             decodeTableItems(_v.localName);
308         }
309
310         if ((b2 & EncodingConstants.INITIAL_VOCABULARY_OTHER_NCNAMES_FLAG) > 0) {
311             decodeTableItems(_v.otherNCName);
312         }
313
314         if ((b2 & EncodingConstants.INITIAL_VOCABULARY_OTHER_URIS_FLAG) > 0) {
315             decodeTableItems(_v.otherURI);
316         }
317
318         if ((b2 & EncodingConstants.INITIAL_VOCABULARY_ATTRIBUTE_VALUES_FLAG) > 0) {
319             decodeTableItems(_v.attributeValue);
320         }
321
322         if ((b2 & EncodingConstants.INITIAL_VOCABULARY_CONTENT_CHARACTER_CHUNKS_FLAG) > 0) {
323             decodeTableItems(_v.characterContentChunk);
324         }
325
326         if ((b2 & EncodingConstants.INITIAL_VOCABULARY_OTHER_STRINGS_FLAG) > 0) {
327             decodeTableItems(_v.otherString);
328         }
329
330         if ((b2 & EncodingConstants.INITIAL_VOCABULARY_ELEMENT_NAME_SURROGATES_FLAG) > 0) {
331             decodeTableItems(_v.elementName, false);
332         }
333
334         if ((b2 & EncodingConstants.INITIAL_VOCABULARY_ATTRIBUTE_NAME_SURROGATES_FLAG) > 0) {
335             decodeTableItems(_v.attributeName, true);
336         }
337     }
338
339     public void decodeExternalVocabularyURI() throws FastInfosetException, IOException JavaDoc {
340         if (_externalVocabularies == null) {
341             throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.noExternalVocabularies"));
342         }
343
344         String JavaDoc externalVocabularyURI = decodeNonEmptyOctetStringOnSecondBitAsUtf8String();
345         ParserVocabulary externalVocabulary =
346             (ParserVocabulary) _externalVocabularies.get(externalVocabularyURI);
347         if (externalVocabulary == null) {
348             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.externalVocabularyNotRegistered", new Object JavaDoc[]{externalVocabularyURI}));
349         }
350
351         try {
352             _v.setReferencedVocabulary(new URI JavaDoc(externalVocabularyURI), externalVocabulary, false);
353         } catch (URISyntaxException JavaDoc e) {
354             throw new FastInfosetException("URISyntaxException", e);
355         }
356     }
357
358     public final void decodeTableItems(StringArray array) throws FastInfosetException, IOException JavaDoc {
359         for (int i = 0; i < decodeNumberOfItemsOfSequence(); i++) {
360             array.add(decodeNonEmptyOctetStringOnSecondBitAsUtf8String());
361         }
362     }
363
364     public final void decodeTableItems(PrefixArray array) throws FastInfosetException, IOException JavaDoc {
365         for (int i = 0; i < decodeNumberOfItemsOfSequence(); i++) {
366             array.add(decodeNonEmptyOctetStringOnSecondBitAsUtf8String());
367         }
368     }
369     
370     public final void decodeTableItems(ContiguousCharArrayArray array) throws FastInfosetException, IOException JavaDoc {
371         for (int i = 0; i < decodeNumberOfItemsOfSequence(); i++) {
372             switch(decodeNonIdentifyingStringOnFirstBit()) {
373                 case NISTRING_STRING:
374                     array.add(_charBuffer, _charBufferLength);
375                     break;
376                 default:
377                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.illegalState"));
378             }
379         }
380     }
381     
382     public final void decodeTableItems(CharArrayArray array) throws FastInfosetException, IOException JavaDoc {
383         for (int i = 0; i < decodeNumberOfItemsOfSequence(); i++) {
384             switch(decodeNonIdentifyingStringOnFirstBit()) {
385                 case NISTRING_STRING:
386                     array.add(new CharArray(_charBuffer, 0, _charBufferLength, true));
387                     break;
388                 default:
389                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.illegalState"));
390             }
391         }
392     }
393
394     public final void decodeTableItems(QualifiedNameArray array, boolean isAttribute) throws FastInfosetException, IOException JavaDoc {
395         for (int i = 0; i < decodeNumberOfItemsOfSequence(); i++) {
396             final int b = read();
397
398             String JavaDoc prefix = "";
399             int prefixIndex = -1;
400             if ((b & EncodingConstants.NAME_SURROGATE_PREFIX_FLAG) > 0) {
401                 prefixIndex = decodeIntegerIndexOnSecondBit();
402                 prefix = _v.prefix.get(prefixIndex);
403             }
404             
405             String JavaDoc namespaceName = "";
406             int namespaceNameIndex = -1;
407             if ((b & EncodingConstants.NAME_SURROGATE_NAME_FLAG) > 0) {
408                 namespaceNameIndex = decodeIntegerIndexOnSecondBit();
409                 namespaceName = _v.prefix.get(prefixIndex);
410             }
411             
412             if (namespaceName == "" && prefix != "") {
413                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.missingNamespace"));
414             }
415
416             final int localNameIndex = decodeIntegerIndexOnSecondBit();
417             final String JavaDoc localName = _v.localName.get(localNameIndex);
418
419             QualifiedName qualifiedName = new QualifiedName(prefix, namespaceName, localName,
420                     prefixIndex, namespaceNameIndex, localNameIndex,
421                     _charBuffer);
422             if (isAttribute) {
423                 qualifiedName.createAttributeValues(_duplicateAttributeVerifier.MAP_SIZE);
424             }
425             array.add(qualifiedName);
426         }
427     }
428
429     public final int decodeNumberOfItemsOfSequence() throws IOException JavaDoc {
430         final int b = read();
431         if (b < 128) {
432             return b;
433         } else {
434             return ((b & 0x0F) << 16) | (read() << 8) | read();
435         }
436     }
437
438     public final void decodeNotations() throws FastInfosetException, IOException JavaDoc {
439         if (_notations == null) {
440             _notations = new ArrayList JavaDoc();
441         } else {
442             _notations.clear();
443         }
444
445         int b = read();
446         while ((b & EncodingConstants.NOTATIONS_MASK) == EncodingConstants.NOTATIONS) {
447             String JavaDoc name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
448
449             String JavaDoc system_identifier = ((_b & EncodingConstants.NOTATIONS_SYSTEM_IDENTIFIER_FLAG) > 0)
450                 ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
451             String JavaDoc public_identifier = ((_b & EncodingConstants.NOTATIONS_PUBLIC_IDENTIFIER_FLAG) > 0)
452                 ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
453
454             Notation notation = new Notation(name, system_identifier, public_identifier);
455             _notations.add(notation);
456
457             b = read();
458         }
459         if (b != EncodingConstants.TERMINATOR) {
460             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.IIsNotTerminatedCorrectly"));
461         }
462     }
463
464     public final void decodeUnparsedEntities() throws FastInfosetException, IOException JavaDoc {
465         if (_unparsedEntities == null) {
466             _unparsedEntities = new ArrayList JavaDoc();
467         } else {
468             _unparsedEntities.clear();
469         }
470
471         int b = read();
472         while ((b & EncodingConstants.UNPARSED_ENTITIES_MASK) == EncodingConstants.UNPARSED_ENTITIES) {
473             String JavaDoc name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
474             String JavaDoc system_identifier = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI);
475
476             String JavaDoc public_identifier = ((_b & EncodingConstants.UNPARSED_ENTITIES_PUBLIC_IDENTIFIER_FLAG) > 0)
477                 ? decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherURI) : "";
478
479             String JavaDoc notation_name = decodeIdentifyingNonEmptyStringOnFirstBit(_v.otherNCName);
480
481             UnparsedEntity unparsedEntity = new UnparsedEntity(name, system_identifier, public_identifier, notation_name);
482             _unparsedEntities.add(unparsedEntity);
483
484             b = read();
485         }
486         if (b != EncodingConstants.TERMINATOR) {
487             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.unparsedEntities"));
488         }
489     }
490
491     public final String JavaDoc decodeCharacterEncodingScheme() throws FastInfosetException, IOException JavaDoc {
492         return decodeNonEmptyOctetStringOnSecondBitAsUtf8String();
493     }
494     
495     public final String JavaDoc decodeVersion() throws FastInfosetException, IOException JavaDoc {
496         switch(decodeNonIdentifyingStringOnFirstBit()) {
497             case NISTRING_STRING:
498                 final String JavaDoc data = new String JavaDoc(_charBuffer, 0, _charBufferLength);
499                 if (_addToTable) {
500                     _v.otherString.add(new CharArrayString(data));
501                 }
502                 return data;
503             case NISTRING_ENCODING_ALGORITHM:
504                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingNotSupported"));
505             case NISTRING_INDEX:
506                 return _v.otherString.get(_integer).toString();
507             case NISTRING_EMPTY_STRING:
508             default:
509                 return "";
510         }
511     }
512
513     protected final QualifiedName decodeEIIIndexMedium() throws FastInfosetException, IOException JavaDoc {
514         final int i = (((_b & EncodingConstants.INTEGER_3RD_BIT_MEDIUM_MASK) << 8) | read())
515             + EncodingConstants.INTEGER_3RD_BIT_SMALL_LIMIT;
516         return _v.elementName._array[i];
517     }
518
519     protected final QualifiedName decodeEIIIndexLarge() throws FastInfosetException, IOException JavaDoc {
520         int i;
521         if ((_b & EncodingConstants.INTEGER_3RD_BIT_LARGE_LARGE_FLAG) == 0x20) {
522             // EII large index
523
i = (((_b & EncodingConstants.INTEGER_3RD_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
524                 + EncodingConstants.INTEGER_3RD_BIT_MEDIUM_LIMIT;
525         } else {
526             // EII large large index
527
i = (((read() & EncodingConstants.INTEGER_3RD_BIT_LARGE_LARGE_MASK) << 16) | (read() << 8) | read())
528                 + EncodingConstants.INTEGER_3RD_BIT_LARGE_LIMIT;
529         }
530         return _v.elementName._array[i];
531     }
532
533     protected final QualifiedName decodeLiteralQualifiedName(int state) throws FastInfosetException, IOException JavaDoc {
534         switch (state) {
535             // no prefix, no namespace
536
case 0:
537                 return new QualifiedName(
538                         "",
539                         "",
540                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
541                         -1,
542                         -1,
543                         _identifier,
544                         null);
545             // no prefix, namespace
546
case 1:
547                 return new QualifiedName(
548                         "",
549                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(false),
550                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
551                         -1,
552                         _namespaceNameIndex,
553                         _identifier,
554                         null);
555             // prefix, no namespace
556
case 2:
557                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.qNameMissingNamespaceName"));
558             // prefix, namespace
559
case 3:
560                 return new QualifiedName(
561                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(true),
562                         decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(true),
563                         decodeIdentifyingNonEmptyStringOnFirstBit(_v.localName),
564                         _prefixIndex,
565                         _namespaceNameIndex,
566                         _identifier,
567                         _charBuffer);
568             default:
569                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingEII"));
570         }
571     }
572
573     public static final int NISTRING_STRING = 0;
574     public static final int NISTRING_INDEX = 1;
575     public static final int NISTRING_ENCODING_ALGORITHM = 2;
576     public static final int NISTRING_EMPTY_STRING = 3;
577
578     /*
579      * C.14
580      * decodeNonIdentifyingStringOnFirstBit
581      */

582     public final int decodeNonIdentifyingStringOnFirstBit() throws FastInfosetException, IOException JavaDoc {
583         final int b = read();
584         switch(DecoderStateTables.NISTRING[b]) {
585             case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH:
586                 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
587                 _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
588                 decodeUtf8StringAsCharBuffer();
589                 return NISTRING_STRING;
590             case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH:
591                 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
592                 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
593                 decodeUtf8StringAsCharBuffer();
594                 return NISTRING_STRING;
595             case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH:
596             {
597                 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
598                 final int length = (read() << 24) |
599                     (read() << 16) |
600                     (read() << 8) |
601                     read();
602                 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
603                 decodeUtf8StringAsCharBuffer();
604                 return NISTRING_STRING;
605             }
606             case DecoderStateTables.NISTRING_UTF16_SMALL_LENGTH:
607                 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
608                 _octetBufferLength = (b & EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_MASK) + 1;
609                 decodeUtf16StringAsCharBuffer();
610                 return NISTRING_STRING;
611             case DecoderStateTables.NISTRING_UTF16_MEDIUM_LENGTH:
612                 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
613                 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
614                 decodeUtf16StringAsCharBuffer();
615                 return NISTRING_STRING;
616             case DecoderStateTables.NISTRING_UTF16_LARGE_LENGTH:
617             {
618                 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
619                 final int length = (read() << 24) |
620                     (read() << 16) |
621                     (read() << 8) |
622                     read();
623                 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
624                 decodeUtf16StringAsCharBuffer();
625                 return NISTRING_STRING;
626             }
627             case DecoderStateTables.NISTRING_RA:
628             {
629                 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
630                 // Decode resitricted alphabet integer
631
_identifier = (b & 0x0F) << 4;
632                 final int b2 = read();
633                 _identifier |= (b2 & 0xF0) >> 4;
634
635                 decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b2);
636                 
637                 decodeRestrictedAlphabetAsCharBuffer();
638                 return NISTRING_STRING;
639             }
640             case DecoderStateTables.NISTRING_EA:
641             {
642                 _addToTable = (b & EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG) > 0;
643                 // Decode encoding algorithm integer
644
_identifier = (b & 0x0F) << 4;
645                 final int b2 = read();
646                 _identifier |= (b2 & 0xF0) >> 4;
647
648                 decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(b2);
649                 return NISTRING_ENCODING_ALGORITHM;
650             }
651             case DecoderStateTables.NISTRING_INDEX_SMALL:
652                 _integer = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
653                 return NISTRING_INDEX;
654             case DecoderStateTables.NISTRING_INDEX_MEDIUM:
655                 _integer = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
656                     + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
657                 return NISTRING_INDEX;
658             case DecoderStateTables.NISTRING_INDEX_LARGE:
659                 _integer = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
660                     + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
661                 return NISTRING_INDEX;
662             case DecoderStateTables.NISTRING_EMPTY:
663                 return NISTRING_EMPTY_STRING;
664             default:
665                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingNonIdentifyingString"));
666         }
667     }
668
669     public final void decodeOctetsOnFifthBitOfNonIdentifyingStringOnFirstBit(int b) throws FastInfosetException, IOException JavaDoc {
670         // Remove top 4 bits of restricted alphabet or encoding algorithm integer
671
b &= 0x0F;
672         // Reuse UTF8 length states
673
switch(DecoderStateTables.NISTRING[b]) {
674             case DecoderStateTables.NISTRING_UTF8_SMALL_LENGTH:
675                 _octetBufferLength = b + 1;
676                 break;
677             case DecoderStateTables.NISTRING_UTF8_MEDIUM_LENGTH:
678                 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT;
679                 break;
680             case DecoderStateTables.NISTRING_UTF8_LARGE_LENGTH:
681                 final int length = (read() << 24) |
682                     (read() << 16) |
683                     (read() << 8) |
684                     read();
685                 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
686                 break;
687             default:
688                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingOctets"));
689         }
690         ensureOctetBufferSize();
691         _octetBufferStart = _octetBufferOffset;
692         _octetBufferOffset += _octetBufferLength;
693     }
694
695     public final void decodeOctetsOnSeventhBitOfNonIdentifyingStringOnThirdBit(int b) throws FastInfosetException, IOException JavaDoc {
696         // Remove top 6 bits of restricted alphabet or encoding algorithm integer
697
switch (b & 0x03) {
698             // Small length
699
case 0:
700                 _octetBufferLength = 1;
701                 break;
702             // Small length
703
case 1:
704                 _octetBufferLength = 2;
705                 break;
706             // Medium length
707
case 2:
708                 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT;
709                 break;
710             // Large length
711
case 3:
712                 _octetBufferLength = (read() << 24) |
713                     (read() << 16) |
714                     (read() << 8) |
715                     read();
716                 _octetBufferLength += EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
717                 break;
718         }
719
720         ensureOctetBufferSize();
721         _octetBufferStart = _octetBufferOffset;
722         _octetBufferOffset += _octetBufferLength;
723     }
724
725     /*
726      * C.13
727      */

728     public final String JavaDoc decodeIdentifyingNonEmptyStringOnFirstBit(StringArray table) throws FastInfosetException, IOException JavaDoc {
729         final int b = read();
730         switch(DecoderStateTables.ISTRING[b]) {
731             case DecoderStateTables.ISTRING_SMALL_LENGTH:
732             {
733                 _octetBufferLength = b + 1;
734                 final String JavaDoc s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
735                 _identifier = table.add(s) - 1;
736                 return s;
737             }
738             case DecoderStateTables.ISTRING_MEDIUM_LENGTH:
739             {
740                 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT;
741                 final String JavaDoc s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
742                 _identifier = table.add(s) - 1;
743                 return s;
744             }
745             case DecoderStateTables.ISTRING_LARGE_LENGTH:
746             {
747                 final int length = (read() << 24) |
748                     (read() << 16) |
749                     (read() << 8) |
750                     read();
751                 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT;
752                 final String JavaDoc s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
753                 _identifier = table.add(s) - 1;
754                 return s;
755             }
756             case DecoderStateTables.ISTRING_INDEX_SMALL:
757                 _identifier = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
758                 return table._array[_identifier];
759             case DecoderStateTables.ISTRING_INDEX_MEDIUM:
760                 _identifier = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
761                     + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
762                 return table._array[_identifier];
763             case DecoderStateTables.ISTRING_INDEX_LARGE:
764                 _identifier = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
765                     + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
766                 return table._array[_identifier];
767             default:
768                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIdentifyingString"));
769         }
770     }
771
772     protected int _prefixIndex;
773     
774     /*
775      * C.13
776      */

777     public final String JavaDoc decodeIdentifyingNonEmptyStringOnFirstBitAsPrefix(boolean namespaceNamePresent) throws FastInfosetException, IOException JavaDoc {
778         final int b = read();
779         switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE[b]) {
780             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_3:
781             {
782                 _octetBufferLength = EncodingConstants.XML_NAMESPACE_PREFIX_LENGTH;
783                 decodeUtf8StringAsCharBuffer();
784                 
785                 if (_charBuffer[0] == 'x' &&
786                         _charBuffer[1] == 'm' &&
787                         _charBuffer[2] == 'l') {
788                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.prefixIllegal"));
789                 }
790                 
791                 final String JavaDoc s = (_stringInterning) ? new String JavaDoc(_charBuffer, 0, _charBufferLength).intern() :
792                     new String JavaDoc(_charBuffer, 0, _charBufferLength);
793                 _prefixIndex = _v.prefix.add(s);
794                 return s;
795             }
796             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_5:
797             {
798                 _octetBufferLength = EncodingConstants.XMLNS_NAMESPACE_PREFIX_LENGTH;
799                 decodeUtf8StringAsCharBuffer();
800                 
801                 if (_charBuffer[0] == 'x' &&
802                         _charBuffer[1] == 'm' &&
803                         _charBuffer[2] == 'l' &&
804                         _charBuffer[3] == 'n' &&
805                         _charBuffer[4] == 's') {
806                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.xmlns"));
807                 }
808                 
809                 final String JavaDoc s = (_stringInterning) ? new String JavaDoc(_charBuffer, 0, _charBufferLength).intern() :
810                     new String JavaDoc(_charBuffer, 0, _charBufferLength);
811                 _prefixIndex = _v.prefix.add(s);
812                 return s;
813             }
814             case DecoderStateTables.ISTRING_SMALL_LENGTH:
815             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_29:
816             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_36:
817             {
818                 _octetBufferLength = b + 1;
819                 final String JavaDoc s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
820                 _prefixIndex = _v.prefix.add(s);
821                 return s;
822             }
823             case DecoderStateTables.ISTRING_MEDIUM_LENGTH:
824             {
825                 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT;
826                 final String JavaDoc s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
827                 _prefixIndex = _v.prefix.add(s);
828                 return s;
829             }
830             case DecoderStateTables.ISTRING_LARGE_LENGTH:
831             {
832                 final int length = (read() << 24) |
833                     (read() << 16) |
834                     (read() << 8) |
835                     read();
836                 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT;
837                 final String JavaDoc s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
838                 _prefixIndex = _v.prefix.add(s);
839                 return s;
840             }
841             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO:
842                 if (namespaceNamePresent) {
843                     _prefixIndex = 0;
844                     // Peak at next byte and check the index of the XML namespace name
845
if (DecoderStateTables.ISTRING_PREFIX_NAMESPACE[peak()]
846                             != DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO) {
847                         throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.wrongNamespaceName"));
848                     }
849                     return EncodingConstants.XML_NAMESPACE_PREFIX;
850                 } else {
851                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.missingNamespaceName"));
852                 }
853             case DecoderStateTables.ISTRING_INDEX_SMALL:
854                 _prefixIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
855                 return _v.prefix._array[_prefixIndex - 1];
856             case DecoderStateTables.ISTRING_INDEX_MEDIUM:
857                 _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
858                     + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
859                 return _v.prefix._array[_prefixIndex - 1];
860             case DecoderStateTables.ISTRING_INDEX_LARGE:
861                 _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
862                     + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
863                 return _v.prefix._array[_prefixIndex - 1];
864             default:
865                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIdentifyingStringForPrefix"));
866         }
867     }
868     
869     /*
870      * C.13
871      */

872     public final String JavaDoc decodeIdentifyingNonEmptyStringIndexOnFirstBitAsPrefix(boolean namespaceNamePresent) throws FastInfosetException, IOException JavaDoc {
873         final int b = read();
874         switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE[b]) {
875             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO:
876                 if (namespaceNamePresent) {
877                     _prefixIndex = 0;
878                     // Peak at next byte and check the index of the XML namespace name
879
if (DecoderStateTables.ISTRING_PREFIX_NAMESPACE[peak()]
880                             != DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO) {
881                         throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.wrongNamespaceName"));
882                     }
883                     return EncodingConstants.XML_NAMESPACE_PREFIX;
884                 } else {
885                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.missingNamespaceName"));
886                 }
887             case DecoderStateTables.ISTRING_INDEX_SMALL:
888                 _prefixIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
889                 return _v.prefix._array[_prefixIndex - 1];
890             case DecoderStateTables.ISTRING_INDEX_MEDIUM:
891                 _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
892                     + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
893                 return _v.prefix._array[_prefixIndex - 1];
894             case DecoderStateTables.ISTRING_INDEX_LARGE:
895                 _prefixIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
896                     + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
897                 return _v.prefix._array[_prefixIndex - 1];
898             default:
899                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIdentifyingStringForPrefix"));
900         }
901     }
902     
903     protected int _namespaceNameIndex;
904     
905     /*
906      * C.13
907      */

908     public final String JavaDoc decodeIdentifyingNonEmptyStringOnFirstBitAsNamespaceName(boolean prefixPresent) throws FastInfosetException, IOException JavaDoc {
909         final int b = read();
910         switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE[b]) {
911             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_3:
912             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_5:
913             case DecoderStateTables.ISTRING_SMALL_LENGTH:
914             {
915                 _octetBufferLength = b + 1;
916                 final String JavaDoc s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
917                 _namespaceNameIndex = _v.namespaceName.add(s);
918                 return s;
919             }
920             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_29:
921             {
922                 _octetBufferLength = EncodingConstants.XMLNS_NAMESPACE_NAME_LENGTH;
923                 decodeUtf8StringAsCharBuffer();
924                 
925                 if (compareCharsWithCharBufferFromEndToStart(EncodingConstants.XMLNS_NAMESPACE_NAME_CHARS)) {
926                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.xmlnsConnotBeBoundToPrefix"));
927                 }
928                 
929                 final String JavaDoc s = (_stringInterning) ? new String JavaDoc(_charBuffer, 0, _charBufferLength).intern() :
930                     new String JavaDoc(_charBuffer, 0, _charBufferLength);
931                 _namespaceNameIndex = _v.namespaceName.add(s);
932                 return s;
933             }
934             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_LENGTH_36:
935             {
936                 _octetBufferLength = EncodingConstants.XML_NAMESPACE_NAME_LENGTH;
937                 decodeUtf8StringAsCharBuffer();
938                 
939                 if (compareCharsWithCharBufferFromEndToStart(EncodingConstants.XML_NAMESPACE_NAME_CHARS)) {
940                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.illegalNamespaceName"));
941                 }
942                 
943                 final String JavaDoc s = (_stringInterning) ? new String JavaDoc(_charBuffer, 0, _charBufferLength).intern() :
944                     new String JavaDoc(_charBuffer, 0, _charBufferLength);
945                 _namespaceNameIndex = _v.namespaceName.add(s);
946                 return s;
947             }
948             case DecoderStateTables.ISTRING_MEDIUM_LENGTH:
949             {
950                 _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT;
951                 final String JavaDoc s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
952                 _namespaceNameIndex = _v.namespaceName.add(s);
953                 return s;
954             }
955             case DecoderStateTables.ISTRING_LARGE_LENGTH:
956             {
957                 final int length = (read() << 24) |
958                     (read() << 16) |
959                     (read() << 8) |
960                     read();
961                 _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT;
962                 final String JavaDoc s = (_stringInterning) ? decodeUtf8StringAsString().intern() : decodeUtf8StringAsString();
963                 _namespaceNameIndex = _v.namespaceName.add(s);
964                 return s;
965             }
966             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO:
967                 if (prefixPresent) {
968                     _namespaceNameIndex = 0;
969                     return EncodingConstants.XML_NAMESPACE_NAME;
970                 } else {
971                     throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.namespaceWithoutPrefix"));
972                 }
973             case DecoderStateTables.ISTRING_INDEX_SMALL:
974                 _namespaceNameIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
975                 return _v.namespaceName._array[_namespaceNameIndex - 1];
976             case DecoderStateTables.ISTRING_INDEX_MEDIUM:
977                 _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
978                     + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
979                 return _v.namespaceName._array[_namespaceNameIndex - 1];
980             case DecoderStateTables.ISTRING_INDEX_LARGE:
981                 _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
982                     + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
983                 return _v.namespaceName._array[_namespaceNameIndex - 1];
984             default:
985                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingForNamespaceName"));
986         }
987     }
988     
989     /*
990      * C.13
991      */

992     public final String JavaDoc decodeIdentifyingNonEmptyStringIndexOnFirstBitAsNamespaceName(boolean prefixPresent) throws FastInfosetException, IOException JavaDoc {
993         final int b = read();
994         switch(DecoderStateTables.ISTRING_PREFIX_NAMESPACE[b]) {
995             case DecoderStateTables.ISTRING_PREFIX_NAMESPACE_INDEX_ZERO:
996                 if (prefixPresent) {
997                     _namespaceNameIndex = 0;
998                     return EncodingConstants.XML_NAMESPACE_NAME;
999                 } else {
1000                    throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.namespaceWithoutPrefix"));
1001                }
1002            case DecoderStateTables.ISTRING_INDEX_SMALL:
1003                _namespaceNameIndex = b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
1004                return _v.namespaceName._array[_namespaceNameIndex - 1];
1005            case DecoderStateTables.ISTRING_INDEX_MEDIUM:
1006                _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
1007                    + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
1008                return _v.namespaceName._array[_namespaceNameIndex - 1];
1009            case DecoderStateTables.ISTRING_INDEX_LARGE:
1010                _namespaceNameIndex = (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
1011                    + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
1012                return _v.namespaceName._array[_namespaceNameIndex - 1];
1013            default:
1014                throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingForNamespaceName"));
1015        }
1016    }
1017    
1018    public final boolean compareCharsWithCharBufferFromEndToStart(char[] c) {
1019        int i = _charBufferLength ;
1020        while (--i >= 0) {
1021            if (c[i] != _charBuffer[i]) {
1022                return false;
1023            }
1024        }
1025        return true;
1026    }
1027    
1028    /*
1029     * C.22
1030     */

1031    public final String JavaDoc decodeNonEmptyOctetStringOnSecondBitAsUtf8String() throws FastInfosetException, IOException JavaDoc {
1032        decodeNonEmptyOctetStringOnSecondBitAsUtf8CharArray();
1033        return new String JavaDoc(_charBuffer, 0, _charBufferLength);
1034    }
1035
1036    /*
1037     * C.22
1038     */

1039    public final void decodeNonEmptyOctetStringOnSecondBitAsUtf8CharArray() throws FastInfosetException, IOException JavaDoc {
1040        decodeNonEmptyOctetStringLengthOnSecondBit();
1041        decodeUtf8StringAsCharBuffer();
1042    }
1043
1044    /*
1045     * C.22
1046     */

1047    public final void decodeNonEmptyOctetStringLengthOnSecondBit() throws FastInfosetException, IOException JavaDoc {
1048        final int b = read();
1049        switch(DecoderStateTables.ISTRING[b]) {
1050            case DecoderStateTables.ISTRING_SMALL_LENGTH:
1051                _octetBufferLength = b + 1;
1052                break;
1053            case DecoderStateTables.ISTRING_MEDIUM_LENGTH:
1054                _octetBufferLength = read() + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT;
1055                break;
1056            case DecoderStateTables.ISTRING_LARGE_LENGTH:
1057            {
1058                final int length = (read() << 24) |
1059                    (read() << 16) |
1060                    (read() << 8) |
1061                    read();
1062                _octetBufferLength = length + EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT;
1063                break;
1064            }
1065            case DecoderStateTables.ISTRING_INDEX_SMALL:
1066            case DecoderStateTables.ISTRING_INDEX_MEDIUM:
1067            case DecoderStateTables.ISTRING_INDEX_LARGE:
1068            default:
1069                throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingNonEmptyOctet"));
1070        }
1071    }
1072    
1073    /*
1074     * C.25
1075     */

1076    public final int decodeIntegerIndexOnSecondBit() throws FastInfosetException, IOException JavaDoc {
1077        final int b = read();
1078        switch(DecoderStateTables.ISTRING[b]) {
1079            case DecoderStateTables.ISTRING_INDEX_SMALL:
1080                return b & EncodingConstants.INTEGER_2ND_BIT_SMALL_MASK;
1081            case DecoderStateTables.ISTRING_INDEX_MEDIUM:
1082                return (((b & EncodingConstants.INTEGER_2ND_BIT_MEDIUM_MASK) << 8) | read())
1083                    + EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
1084            case DecoderStateTables.ISTRING_INDEX_LARGE:
1085                return (((b & EncodingConstants.INTEGER_2ND_BIT_LARGE_MASK) << 16) | (read() << 8) | read())
1086                    + EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
1087            case DecoderStateTables.ISTRING_SMALL_LENGTH:
1088            case DecoderStateTables.ISTRING_MEDIUM_LENGTH:
1089            case DecoderStateTables.ISTRING_LARGE_LENGTH:
1090            default:
1091                throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.decodingIndexOnSecondBit"));
1092        }
1093    }
1094
1095    public final void decodeHeader() throws FastInfosetException, IOException JavaDoc {
1096        if (!_isFastInfosetDocument()) {
1097            throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.notFIDocument"));
1098        }
1099    }
1100
1101    protected final void decodeRestrictedAlphabetAsCharBuffer() throws FastInfosetException, IOException JavaDoc {
1102        if (_identifier <= EncodingConstants.RESTRICTED_ALPHABET_BUILTIN_END) {
1103            decodeFourBitAlphabetOctetsAsCharBuffer(BuiltInRestrictedAlphabets.table[_identifier]);
1104            // decodeAlphabetOctetsAsCharBuffer(BuiltInRestrictedAlphabets.table[_identifier]);
1105
} else if (_identifier >= EncodingConstants.RESTRICTED_ALPHABET_APPLICATION_START) {
1106            CharArray ca = _v.restrictedAlphabet.get(_identifier - EncodingConstants.RESTRICTED_ALPHABET_APPLICATION_START);
1107            if (ca == null) {
1108                throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.alphabetNotPresent", new Object JavaDoc[]{new Integer JavaDoc(_identifier)}));
1109            }
1110            decodeAlphabetOctetsAsCharBuffer(ca.ch);
1111        } else {
1112            // Reserved built-in algorithms for future use
1113
// TODO should use sax property to decide if event will be
1114
// reported, allows for support through handler if required.
1115
throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.alphabetIdentifiersReserved"));
1116        }
1117    }
1118    
1119    protected final String JavaDoc decodeRestrictedAlphabetAsString() throws FastInfosetException, IOException JavaDoc {
1120        decodeRestrictedAlphabetAsCharBuffer();
1121        return new String JavaDoc(_charBuffer, 0, _charBufferLength);
1122    }
1123    
1124    public final String JavaDoc decodeRAOctetsAsString(char[] restrictedAlphabet) throws FastInfosetException, IOException JavaDoc {
1125        decodeAlphabetOctetsAsCharBuffer(null);
1126        return new String JavaDoc(_charBuffer, 0, _charBufferLength);
1127    }
1128
1129    public final void decodeFourBitAlphabetOctetsAsCharBuffer(char[] restrictedAlphabet) throws FastInfosetException, IOException JavaDoc {
1130        _charBufferLength = 0;
1131        final int characters = _octetBufferLength / 2;
1132        if (_charBuffer.length < characters) {
1133            _charBuffer = new char[characters];
1134        }
1135        
1136        int v = 0;
1137        for (int i = 0; i < _octetBufferLength - 1; i++) {
1138            v = _octetBuffer[_octetBufferStart++] & 0xFF;
1139            _charBuffer[_charBufferLength++] = restrictedAlphabet[v >> 4];
1140            _charBuffer[_charBufferLength++] = restrictedAlphabet[v & 0x0F];
1141        }
1142        v = _octetBuffer[_octetBufferStart++] & 0xFF;
1143        _charBuffer[_charBufferLength++] = restrictedAlphabet[v >> 4];
1144        v &= 0x0F;
1145        if (v != 0x0F) {
1146            _charBuffer[_charBufferLength++] = restrictedAlphabet[v & 0x0F];
1147        }
1148    }
1149    
1150    public final void decodeAlphabetOctetsAsCharBuffer(char[] restrictedAlphabet) throws FastInfosetException, IOException JavaDoc {
1151        if (restrictedAlphabet.length < 2) {
1152            throw new IllegalArgumentException JavaDoc(CommonResourceBundle.getInstance().getString("message.alphabetMustContain2orMoreChars"));
1153        }
1154
1155        int bitsPerCharacter = 1;
1156        while ((1 << bitsPerCharacter) <= restrictedAlphabet.length) {
1157            bitsPerCharacter++;
1158        }
1159        final int terminatingValue = (1 << bitsPerCharacter) - 1;
1160        
1161        int characters = (_octetBufferLength << 3) / bitsPerCharacter;
1162        if (characters == 0) {
1163            throw new IOException JavaDoc("");
1164        }
1165
1166        _charBufferLength = 0;
1167        if (_charBuffer.length < characters) {
1168            _charBuffer = new char[characters];
1169        }
1170        
1171        resetBits();
1172        for (int i = 0; i < characters; i++) {
1173            int value = readBits(bitsPerCharacter);
1174            if (bitsPerCharacter < 8 && value == terminatingValue) {
1175                int octetPosition = (i * bitsPerCharacter) >>> 3;
1176                if (octetPosition != _octetBufferLength - 1) {
1177                    throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.alphabetIncorrectlyTerminated"));
1178                }
1179                break;
1180            }
1181            _charBuffer[_charBufferLength++] = restrictedAlphabet[value];
1182        }
1183    }
1184
1185    protected int _bitsLeftInOctet;
1186    
1187    public final void resetBits() {
1188        _bitsLeftInOctet = 0;
1189    }
1190    
1191    public final int readBits(int bits) throws IOException JavaDoc {
1192        int value = 0;
1193        while (bits > 0) {
1194            if (_bitsLeftInOctet == 0) {
1195                _b = _octetBuffer[_octetBufferStart++] & 0xFF;
1196                _bitsLeftInOctet = 8;
1197            }
1198            int bit = ((_b & (1 << --_bitsLeftInOctet)) > 0) ? 1 : 0;
1199            value |= (bit << --bits);
1200        }
1201        
1202        return value;
1203    }
1204    
1205    public final void decodeUtf8StringAsCharBuffer() throws IOException JavaDoc {
1206        ensureOctetBufferSize();
1207        decodeUtf8StringIntoCharBuffer();
1208    }
1209
1210    public final String JavaDoc decodeUtf8StringAsString() throws IOException JavaDoc {
1211        decodeUtf8StringAsCharBuffer();
1212        return new String JavaDoc(_charBuffer, 0, _charBufferLength);
1213    }
1214
1215    public final void decodeUtf16StringAsCharBuffer() throws IOException JavaDoc {
1216        ensureOctetBufferSize();
1217        decodeUtf16StringIntoCharBuffer();
1218    }
1219
1220    public final String JavaDoc decodeUtf16StringAsString() throws IOException JavaDoc {
1221        decodeUtf16StringAsCharBuffer();
1222        return new String JavaDoc(_charBuffer, 0, _charBufferLength);
1223    }
1224
1225    public final void ensureOctetBufferSize() throws IOException JavaDoc {
1226        if (_octetBufferEnd < (_octetBufferOffset + _octetBufferLength)) {
1227            final int bytesRemaining = _octetBufferEnd - _octetBufferOffset;
1228
1229            if (_octetBuffer.length < _octetBufferLength) {
1230                byte[] newOctetBuffer = new byte[_octetBufferLength];
1231                System.arraycopy(_octetBuffer, _octetBufferOffset, newOctetBuffer, 0, bytesRemaining);
1232                _octetBuffer = newOctetBuffer;
1233            } else {
1234                System.arraycopy(_octetBuffer, _octetBufferOffset, _octetBuffer, 0, bytesRemaining);
1235            }
1236            _octetBufferOffset = 0;
1237
1238            final int bytesRead = _s.read(_octetBuffer, bytesRemaining, _octetBuffer.length - bytesRemaining);
1239            if (bytesRead < 0) {
1240                throw new EOFException JavaDoc("Unexpeceted EOF");
1241            }
1242
1243            if (bytesRead < _octetBufferLength - bytesRemaining) {
1244                // TODO keep reading until require bytes have been obtained
1245
throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.fullBytesNotRead"));
1246            }
1247
1248            _octetBufferEnd = bytesRemaining + bytesRead;
1249        }
1250    }
1251    
1252    public final void decodeUtf8StringIntoCharBuffer() throws IOException JavaDoc {
1253        if (_charBuffer.length < _octetBufferLength) {
1254            _charBuffer = new char[_octetBufferLength];
1255        }
1256        
1257        _charBufferLength = 0;
1258        final int end = _octetBufferLength + _octetBufferOffset;
1259        int b1;
1260        while (end != _octetBufferOffset) {
1261            b1 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1262            if (DecoderStateTables.UTF8[b1] == DecoderStateTables.UTF8_ONE_BYTE) {
1263                _charBuffer[_charBufferLength++] = (char) b1;
1264            } else {
1265                decodeTwoToFourByteUtf8Character(b1, end);
1266            }
1267        }
1268    }
1269
1270    public final void decodeTwoToFourByteUtf8Character(int b1, int end) throws IOException JavaDoc {
1271        switch(DecoderStateTables.UTF8[b1]) {
1272            case DecoderStateTables.UTF8_TWO_BYTES:
1273            {
1274                // Decode byte 2
1275
if (end == _octetBufferOffset) {
1276                    decodeUtf8StringLengthTooSmall();
1277                }
1278                final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1279                if ((b2 & 0xC0) != 0x80) {
1280                    decodeUtf8StringIllegalState();
1281                }
1282
1283                // Character guaranteed to be in [0x20, 0xD7FF] range
1284
// since a character encoded in two bytes will be in the
1285
// range [0x80, 0x1FFF]
1286
_charBuffer[_charBufferLength++] = (char) (
1287                    ((b1 & 0x1F) << 6)
1288                    | (b2 & 0x3F));
1289                break;
1290            }
1291            case DecoderStateTables.UTF8_THREE_BYTES:
1292                final char c = decodeUtf8ThreeByteChar(end, b1);
1293                if (XMLChar.isContent(c)) {
1294                    _charBuffer[_charBufferLength++] = c;
1295                    break;
1296                } else {
1297                    decodeUtf8StringIllegalState();
1298                }
1299            case DecoderStateTables.UTF8_FOUR_BYTES:
1300            {
1301                final int supplemental = decodeUtf8FourByteChar(end, b1);
1302                if (XMLChar.isContent(supplemental)) {
1303                    _charBuffer[_charBufferLength++] = _utf8_highSurrogate;
1304                    _charBuffer[_charBufferLength++] = _utf8_lowSurrogate;
1305                } else {
1306                    decodeUtf8StringIllegalState();
1307                }
1308                break;
1309            }
1310            default:
1311                decodeUtf8StringIllegalState();
1312        }
1313    }
1314    
1315    public final void decodeUtf8NCNameIntoCharBuffer() throws IOException JavaDoc {
1316        _charBufferLength = 0;
1317        if (_charBuffer.length < _octetBufferLength) {
1318            _charBuffer = new char[_octetBufferLength];
1319        }
1320
1321        final int end = _octetBufferLength + _octetBufferOffset;
1322
1323        int b1 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1324        if (DecoderStateTables.UTF8_NCNAME[b1] == DecoderStateTables.UTF8_NCNAME_NCNAME) {
1325            _charBuffer[_charBufferLength++] = (char) b1;
1326        } else {
1327            decodeUtf8NCNameStartTwoToFourByteCharacters(b1, end);
1328        }
1329
1330        while (end != _octetBufferOffset) {
1331            b1 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1332            if (DecoderStateTables.UTF8_NCNAME[b1] < DecoderStateTables.UTF8_TWO_BYTES) {
1333                _charBuffer[_charBufferLength++] = (char) b1;
1334            } else {
1335                decodeUtf8NCNameTwoToFourByteCharacters(b1, end);
1336            }
1337        }
1338    }
1339
1340    public final void decodeUtf8NCNameStartTwoToFourByteCharacters(int b1, int end) throws IOException JavaDoc {
1341        switch(DecoderStateTables.UTF8_NCNAME[b1]) {
1342            case DecoderStateTables.UTF8_TWO_BYTES:
1343            {
1344                // Decode byte 2
1345
if (end == _octetBufferOffset) {
1346                    decodeUtf8StringLengthTooSmall();
1347                }
1348                final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1349                if ((b2 & 0xC0) != 0x80) {
1350                    decodeUtf8StringIllegalState();
1351                }
1352
1353                final char c = (char) (
1354                    ((b1 & 0x1F) << 6)
1355                    | (b2 & 0x3F));
1356                if (XMLChar.isNCNameStart(c)) {
1357                    _charBuffer[_charBufferLength++] = c;
1358                    break;
1359                } else {
1360                    decodeUtf8NCNameIllegalState();
1361                }
1362            }
1363            case DecoderStateTables.UTF8_THREE_BYTES:
1364                final char c = decodeUtf8ThreeByteChar(end, b1);
1365                if (XMLChar.isNCNameStart(c)) {
1366                    _charBuffer[_charBufferLength++] = c;
1367                    break;
1368                } else {
1369                    decodeUtf8NCNameIllegalState();
1370                }
1371                break;
1372            case DecoderStateTables.UTF8_FOUR_BYTES:
1373            {
1374                final int supplemental = decodeUtf8FourByteChar(end, b1);
1375                if (XMLChar.isNCNameStart(supplemental)) {
1376                    _charBuffer[_charBufferLength++] = _utf8_highSurrogate;
1377                    _charBuffer[_charBufferLength++] = _utf8_lowSurrogate;
1378                } else {
1379                    decodeUtf8NCNameIllegalState();
1380                }
1381                break;
1382            }
1383            case DecoderStateTables.UTF8_NCNAME_NCNAME_CHAR:
1384            default:
1385                decodeUtf8NCNameIllegalState();
1386        }
1387        
1388    }
1389
1390    public final void decodeUtf8NCNameTwoToFourByteCharacters(int b1, int end) throws IOException JavaDoc {
1391        switch(DecoderStateTables.UTF8_NCNAME[b1]) {
1392            case DecoderStateTables.UTF8_TWO_BYTES:
1393            {
1394                // Decode byte 2
1395
if (end == _octetBufferOffset) {
1396                    decodeUtf8StringLengthTooSmall();
1397                }
1398                final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1399                if ((b2 & 0xC0) != 0x80) {
1400                    decodeUtf8StringIllegalState();
1401                }
1402
1403                final char c = (char) (
1404                    ((b1 & 0x1F) << 6)
1405                    | (b2 & 0x3F));
1406                if (XMLChar.isNCName(c)) {
1407                    _charBuffer[_charBufferLength++] = c;
1408                    break;
1409                } else {
1410                    decodeUtf8NCNameIllegalState();
1411                }
1412            }
1413            case DecoderStateTables.UTF8_THREE_BYTES:
1414                final char c = decodeUtf8ThreeByteChar(end, b1);
1415                if (XMLChar.isNCName(c)) {
1416                    _charBuffer[_charBufferLength++] = c;
1417                    break;
1418                } else {
1419                    decodeUtf8NCNameIllegalState();
1420                }
1421                break;
1422            case DecoderStateTables.UTF8_FOUR_BYTES:
1423            {
1424                final int supplemental = decodeUtf8FourByteChar(end, b1);
1425                if (XMLChar.isNCName(supplemental)) {
1426                    _charBuffer[_charBufferLength++] = _utf8_highSurrogate;
1427                    _charBuffer[_charBufferLength++] = _utf8_lowSurrogate;
1428                } else {
1429                    decodeUtf8NCNameIllegalState();
1430                }
1431                break;
1432            }
1433            default:
1434                decodeUtf8NCNameIllegalState();
1435        }
1436    }
1437    
1438    public final char decodeUtf8ThreeByteChar(int end, int b1) throws IOException JavaDoc {
1439        // Decode byte 2
1440
if (end == _octetBufferOffset) {
1441            decodeUtf8StringLengthTooSmall();
1442        }
1443        final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1444        if ((b2 & 0xC0) != 0x80
1445            || (b1 == 0xED && b2 >= 0xA0)
1446            || ((b1 & 0x0F) == 0 && (b2 & 0x20) == 0)) {
1447            decodeUtf8StringIllegalState();
1448        }
1449
1450        // Decode byte 3
1451
if (end == _octetBufferOffset) {
1452            decodeUtf8StringLengthTooSmall();
1453        }
1454        final int b3 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1455        if ((b3 & 0xC0) != 0x80) {
1456            decodeUtf8StringIllegalState();
1457        }
1458
1459        return (char) (
1460            (b1 & 0x0F) << 12
1461            | (b2 & 0x3F) << 6
1462            | (b3 & 0x3F));
1463    }
1464
1465    private char _utf8_highSurrogate;
1466    private char _utf8_lowSurrogate;
1467    
1468    public final int decodeUtf8FourByteChar(int end, int b1) throws IOException JavaDoc {
1469        // Decode byte 2
1470
if (end == _octetBufferOffset) {
1471            decodeUtf8StringLengthTooSmall();
1472        }
1473        final int b2 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1474        if ((b2 & 0xC0) != 0x80
1475            || ((b2 & 0x30) == 0 && (b1 & 0x07) == 0)) {
1476            decodeUtf8StringIllegalState();
1477        }
1478
1479        // Decode byte 3
1480
if (end == _octetBufferOffset) {
1481            decodeUtf8StringLengthTooSmall();
1482        }
1483        final int b3 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1484        if ((b3 & 0xC0) != 0x80) {
1485            decodeUtf8StringIllegalState();
1486        }
1487
1488        // Decode byte 4
1489
if (end == _octetBufferOffset) {
1490            decodeUtf8StringLengthTooSmall();
1491        }
1492        final int b4 = _octetBuffer[_octetBufferOffset++] & 0xFF;
1493        if ((b4 & 0xC0) != 0x80) {
1494            decodeUtf8StringIllegalState();
1495        }
1496
1497        final int uuuuu = ((b1 << 2) & 0x001C) | ((b2 >> 4) & 0x0003);
1498        if (uuuuu > 0x10) {
1499            decodeUtf8StringIllegalState();
1500        }
1501        final int wwww = uuuuu - 1;
1502
1503        _utf8_highSurrogate = (char) (0xD800 |
1504             ((wwww << 6) & 0x03C0) | ((b2 << 2) & 0x003C) |
1505             ((b3 >> 4) & 0x0003));
1506        _utf8_lowSurrogate = (char) (0xDC00 | ((b3 << 6) & 0x03C0) | (b4 & 0x003F));
1507        
1508        return XMLChar.supplemental(_utf8_highSurrogate, _utf8_lowSurrogate);
1509    }
1510
1511    public final void decodeUtf8StringLengthTooSmall() throws IOException JavaDoc {
1512        throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.deliminatorTooSmall"));
1513    }
1514
1515    public final void decodeUtf8StringIllegalState() throws IOException JavaDoc {
1516        throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.UTF8Encoded"));
1517    }
1518
1519    public final void decodeUtf8NCNameIllegalState() throws IOException JavaDoc {
1520        throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.UTF8EncodedNCName"));
1521    }
1522
1523    public final void decodeUtf16StringIntoCharBuffer() throws IOException JavaDoc {
1524        _charBufferLength = _octetBufferLength / 2;
1525        if (_charBuffer.length < _charBufferLength) {
1526            _charBuffer = new char[_charBufferLength];
1527        }
1528
1529        for (int i = 0; i < _charBufferLength; i++) {
1530            final char c = (char)((read() << 8) | read());
1531            // TODO check c is a valid Char character
1532
_charBuffer[i] = c;
1533        }
1534        
1535    }
1536
1537    public String JavaDoc createQualifiedNameString(char[] first, String JavaDoc second) {
1538        final int l1 = first.length;
1539        final int l2 = second.length();
1540        final int total = l1 + l2 + 1;
1541        if (total < _charBuffer.length) {
1542            System.arraycopy(first, 0, _charBuffer, 0, l1);
1543            _charBuffer[l1] = ':';
1544            second.getChars(0, l2, _charBuffer, l1 + 1);
1545            return new String JavaDoc(_charBuffer, 0, total);
1546        } else {
1547            StringBuffer JavaDoc b = new StringBuffer JavaDoc(new String JavaDoc(first));
1548            b.append(':');
1549            b.append(second);
1550            return b.toString();
1551        }
1552    }
1553    
1554    protected final int read() throws IOException JavaDoc {
1555        if (_octetBufferOffset < _octetBufferEnd) {
1556            return _octetBuffer[_octetBufferOffset++] & 0xFF;
1557        } else {
1558            _octetBufferEnd = _s.read(_octetBuffer);
1559            if (_octetBufferEnd < 0) {
1560                throw new EOFException JavaDoc(CommonResourceBundle.getInstance().getString("message.EOF"));
1561            }
1562
1563            _octetBufferOffset = 1;
1564            return _octetBuffer[0] & 0xFF;
1565        }
1566    }
1567
1568    protected final int peak() throws IOException JavaDoc {
1569        if (_octetBufferOffset < _octetBufferEnd) {
1570            return _octetBuffer[_octetBufferOffset] & 0xFF;
1571        } else {
1572            _octetBufferEnd = _s.read(_octetBuffer);
1573            if (_octetBufferEnd < 0) {
1574                throw new EOFException JavaDoc(CommonResourceBundle.getInstance().getString("message.EOF"));
1575            }
1576
1577            _octetBufferOffset = 0;
1578            return _octetBuffer[0] & 0xFF;
1579        }
1580    }
1581    
1582    protected class EncodingAlgorithmInputStream extends InputStream JavaDoc {
1583
1584        public int read() throws IOException JavaDoc {
1585            if (_octetBufferStart < _octetBufferOffset) {
1586                return (_octetBuffer[_octetBufferStart++] & 0xFF);
1587            } else {
1588                return -1;
1589            }
1590        }
1591
1592        public int read(byte b[]) throws IOException JavaDoc {
1593            return read(b, 0, b.length);
1594        }
1595
1596        public int read(byte b[], int off, int len) throws IOException JavaDoc {
1597            if (b == null) {
1598                throw new NullPointerException JavaDoc();
1599            } else if ((off < 0) || (off > b.length) || (len < 0) ||
1600                       ((off + len) > b.length) || ((off + len) < 0)) {
1601                throw new IndexOutOfBoundsException JavaDoc();
1602            } else if (len == 0) {
1603                return 0;
1604            }
1605
1606            final int newOctetBufferStart = _octetBufferStart + len;
1607            if (newOctetBufferStart < _octetBufferOffset) {
1608                System.arraycopy(_octetBuffer, _octetBufferStart, b, off, len);
1609                _octetBufferStart = newOctetBufferStart;
1610                return len;
1611            } else if (_octetBufferStart < _octetBufferOffset) {
1612                final int bytesToRead = _octetBufferOffset - _octetBufferStart;
1613                System.arraycopy(_octetBuffer, _octetBufferStart, b, off, bytesToRead);
1614                _octetBufferStart += bytesToRead;
1615                return bytesToRead;
1616            } else {
1617                return -1;
1618            }
1619        }
1620    }
1621
1622    protected final boolean _isFastInfosetDocument() throws IOException JavaDoc {
1623        // Fill up the octet buffer
1624
peak();
1625        
1626        _octetBufferLength = EncodingConstants.BINARY_HEADER.length;
1627        ensureOctetBufferSize();
1628        _octetBufferOffset += _octetBufferLength;
1629        
1630        // Check for binary header
1631
if (_octetBuffer[0] != EncodingConstants.BINARY_HEADER[0] ||
1632                _octetBuffer[1] != EncodingConstants.BINARY_HEADER[1] ||
1633                _octetBuffer[2] != EncodingConstants.BINARY_HEADER[2] ||
1634                _octetBuffer[3] != EncodingConstants.BINARY_HEADER[3]) {
1635                     
1636            // Check for each form of XML declaration
1637
for (int i = 0; i < EncodingConstants.XML_DECLARATION_VALUES.length; i++) {
1638                _octetBufferLength = EncodingConstants.XML_DECLARATION_VALUES[i].length - _octetBufferOffset;
1639                ensureOctetBufferSize();
1640                _octetBufferOffset += _octetBufferLength;
1641
1642                // Check XML declaration
1643
if (arrayEquals(_octetBuffer, 0,
1644                        EncodingConstants.XML_DECLARATION_VALUES[i],
1645                        EncodingConstants.XML_DECLARATION_VALUES[i].length)) {
1646                    _octetBufferLength = EncodingConstants.BINARY_HEADER.length;
1647                    ensureOctetBufferSize();
1648                    
1649                    // Check for binary header
1650
if (_octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[0] ||
1651                            _octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[1] ||
1652                            _octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[2] ||
1653                            _octetBuffer[_octetBufferOffset++] != EncodingConstants.BINARY_HEADER[3]) {
1654                        return false;
1655                    } else {
1656                        // Fast Infoset document with XML declaration and binary header
1657
return true;
1658                    }
1659                }
1660            }
1661            
1662            return false;
1663        }
1664
1665        // Fast Infoset document with binary header
1666
return true;
1667    }
1668
1669    protected final boolean arrayEquals(byte[] b1, int offset, byte[] b2, int length) {
1670        for (int i = 0; i < length; i++) {
1671            if (b1[offset + i] != b2[i]) {
1672                return false;
1673            }
1674        }
1675        
1676        return true;
1677    }
1678
1679    static public boolean isFastInfosetDocument(InputStream JavaDoc s) throws IOException JavaDoc {
1680        // TODO
1681
// Check for <?xml declaration with 'finf' encoding
1682

1683        final byte[] header = new byte[4];
1684        s.read(header);
1685        if (header[0] != EncodingConstants.BINARY_HEADER[0] ||
1686                header[1] != EncodingConstants.BINARY_HEADER[1] ||
1687                header[2] != EncodingConstants.BINARY_HEADER[2] ||
1688                header[3] != EncodingConstants.BINARY_HEADER[3]) {
1689            return false;
1690        }
1691
1692        // TODO
1693
return true;
1694    }
1695}
1696
Popular Tags