KickJava   Java API By Example, From Geeks To Geeks.

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


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.algorithm.BuiltInEncodingAlgorithm;
43 import com.sun.xml.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
44 import com.sun.xml.fastinfoset.org.apache.xerces.util.XMLChar;
45 import com.sun.xml.fastinfoset.util.CharArrayIntMap;
46 import com.sun.xml.fastinfoset.util.KeyIntMap;
47 import com.sun.xml.fastinfoset.util.LocalNameQualifiedNamesMap;
48 import com.sun.xml.fastinfoset.util.StringIntMap;
49 import com.sun.xml.fastinfoset.vocab.SerializerVocabulary;
50 import java.io.IOException JavaDoc;
51 import java.io.OutputStream JavaDoc;
52 import java.util.HashMap JavaDoc;
53 import java.util.Map JavaDoc;
54 import org.jvnet.fastinfoset.EncodingAlgorithm;
55 import org.jvnet.fastinfoset.EncodingAlgorithmException;
56 import org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
57 import org.jvnet.fastinfoset.FastInfosetException;
58 import org.jvnet.fastinfoset.FastInfosetSerializer;
59 import org.jvnet.fastinfoset.ReferencedVocabulary;
60 import org.jvnet.fastinfoset.Vocabulary;
61 import org.xml.sax.helpers.DefaultHandler JavaDoc;
62
63 public abstract class Encoder extends DefaultHandler JavaDoc implements FastInfosetSerializer {
64     
65     // Character encoding scheme system property
66
public static final String JavaDoc CHARACTER_ENCODING_SCHEME_SYSTEM_PROPERTY =
67         "com.sun.xml.fastinfoset.serializer.character-encoding-scheme";
68
69     protected static String JavaDoc _characterEncodingSchemeSystemDefault = UTF_8;
70         
71     static {
72         String JavaDoc p = System.getProperty(CHARACTER_ENCODING_SCHEME_SYSTEM_PROPERTY,
73             _characterEncodingSchemeSystemDefault);
74         if (p.equals(UTF_16BE)) {
75             _characterEncodingSchemeSystemDefault = UTF_16BE;
76         }
77     }
78
79     protected boolean _encodingStringsAsUtf8 = true;
80     
81     protected int _nonIdentifyingStringOnThirdBitCES;
82
83     protected int _nonIdentifyingStringOnFirstBitCES;
84     
85     protected Map _registeredEncodingAlgorithms = new HashMap JavaDoc();
86
87     protected SerializerVocabulary _v;
88
89     protected boolean _vIsInternal;
90
91     protected boolean _terminate = false;
92
93     protected int _b;
94
95     protected OutputStream JavaDoc _s;
96
97     protected char[] _charBuffer = new char[512];
98
99     protected byte[] _octetBuffer = new byte[1024];
100     
101     protected int _octetBufferIndex;
102    
103     protected int _markIndex = -1;
104
105     protected int attributeValueSizeConstraint = FastInfosetSerializer.ATTRIBUTE_VALUE_SIZE_CONSTRAINT;
106     
107     protected int characterContentChunkSizeContraint = FastInfosetSerializer.CHARACTER_CONTENT_CHUNK_SIZE_CONSTRAINT;
108
109     // FastInfosetSerializer
110

111     public Encoder() {
112         setCharacterEncodingScheme(_characterEncodingSchemeSystemDefault);
113     }
114     
115     public void reset() {
116         _terminate = false;
117     }
118     
119     public void setCharacterEncodingScheme(String JavaDoc characterEncodingScheme) {
120         if (characterEncodingScheme.equals(UTF_16BE)) {
121             _encodingStringsAsUtf8 = false;
122             _nonIdentifyingStringOnThirdBitCES = EncodingConstants.CHARACTER_CHUNK | EncodingConstants.CHARACTER_CHUNK_UTF_16_FLAG;
123             _nonIdentifyingStringOnFirstBitCES = EncodingConstants.NISTRING_UTF_16_FLAG;
124         } else {
125             _encodingStringsAsUtf8 = true;
126             _nonIdentifyingStringOnThirdBitCES = EncodingConstants.CHARACTER_CHUNK;
127             _nonIdentifyingStringOnFirstBitCES = 0;
128         }
129     }
130         
131     public String JavaDoc getCharacterEncodingScheme() {
132         return (_encodingStringsAsUtf8) ? UTF_8 : UTF_16BE;
133     }
134     
135     public void setRegisteredEncodingAlgorithms(Map algorithms) {
136         _registeredEncodingAlgorithms = algorithms;
137         if (_registeredEncodingAlgorithms == null) {
138             _registeredEncodingAlgorithms = new HashMap JavaDoc();
139         }
140     }
141
142     public Map getRegisteredEncodingAlgorithms() {
143         return _registeredEncodingAlgorithms;
144     }
145
146     public void setExternalVocabulary(ReferencedVocabulary referencedVocabulary) {
147         throw new UnsupportedOperationException JavaDoc();
148     }
149
150     public void setIntitialVocabulary(Vocabulary initialVocabulary) {
151         throw new UnsupportedOperationException JavaDoc();
152     }
153
154     public void setDynamicVocabulary(Vocabulary dynamicVocabulary) {
155         throw new UnsupportedOperationException JavaDoc();
156     }
157
158     public Vocabulary getDynamicVocabulary() {
159         throw new UnsupportedOperationException JavaDoc();
160     }
161
162     public Vocabulary getFinalVocabulary() {
163         throw new UnsupportedOperationException JavaDoc();
164     }
165
166     
167     
168     public void setOutputStream(OutputStream JavaDoc s) {
169         _octetBufferIndex = 0;
170         _markIndex = -1;
171         _s = s;
172     }
173
174     public void setVocabulary(SerializerVocabulary vocabulary) {
175         _v = vocabulary;
176         _vIsInternal = false;
177     }
178
179     public void setCharacterContentChunkSizeLimit(int size) {
180         if (size < 0 ) {
181             size = 0;
182         }
183                 
184         characterContentChunkSizeContraint = size;
185     }
186     
187     public int getCharacterContentChunkSizeLimit() {
188         return characterContentChunkSizeContraint;
189     }
190
191     public void setAttributeValueSizeLimit(int size) {
192         if (size < 0 ) {
193             size = 0;
194         }
195         
196         attributeValueSizeConstraint = size;
197     }
198     
199     public int getAttributeValueSizeLimit() {
200         return attributeValueSizeConstraint;
201     }
202     
203     protected final void encodeHeader(boolean encodeXmlDecl) throws IOException JavaDoc {
204         if (encodeXmlDecl) {
205             _s.write(EncodingConstants.XML_DECLARATION_VALUES[0]);
206         }
207         _s.write(EncodingConstants.BINARY_HEADER);
208     }
209
210     protected final void encodeInitialVocabulary() throws IOException JavaDoc {
211         if (_v == null) {
212             _v = new SerializerVocabulary();
213             _vIsInternal = true;
214         } else if (_vIsInternal) {
215             _v.clear();
216         }
217
218         if (_v.hasInitialVocabulary()) {
219             _b = EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG;
220             write(_b);
221
222             SerializerVocabulary initialVocabulary = _v.getReadOnlyVocabulary();
223
224             // TODO check for contents of vocabulary to assign bits
225
if (initialVocabulary.hasExternalVocabulary()) {
226                 _b = EncodingConstants.INITIAL_VOCABULARY_EXTERNAL_VOCABULARY_FLAG;
227                 write(_b);
228                 write(0);
229             }
230
231             if (initialVocabulary.hasExternalVocabulary()) {
232                 encodeNonEmptyOctetStringOnSecondBit(_v.getExternalVocabularyURI().toString());
233             }
234
235             // TODO check for contents of vocabulary to encode values
236
} else if (_v.hasExternalVocabulary()) {
237             _b = EncodingConstants.DOCUMENT_INITIAL_VOCABULARY_FLAG;
238             write(_b);
239
240             _b = EncodingConstants.INITIAL_VOCABULARY_EXTERNAL_VOCABULARY_FLAG;
241             write(_b);
242             write(0);
243
244             encodeNonEmptyOctetStringOnSecondBit(_v.getExternalVocabularyURI().toString());
245         } else {
246             write(0);
247         }
248     }
249
250     protected final void encodeDocumentTermination() throws IOException JavaDoc {
251         encodeElementTermination();
252         encodeTermination();
253         _flush();
254         _s.flush();
255     }
256
257     protected final void encodeElementTermination() throws IOException JavaDoc {
258         _terminate = true;
259         switch (_b) {
260             case EncodingConstants.TERMINATOR:
261                 _b = EncodingConstants.DOUBLE_TERMINATOR;
262                 break;
263             case EncodingConstants.DOUBLE_TERMINATOR:
264                 write(EncodingConstants.DOUBLE_TERMINATOR);
265             default:
266                 _b = EncodingConstants.TERMINATOR;
267         }
268     }
269
270     protected final void encodeTermination() throws IOException JavaDoc {
271         if (_terminate) {
272             write(_b);
273             _terminate = false;
274         }
275     }
276
277     protected final void encodeNamespaceAttribute(String JavaDoc prefix, String JavaDoc uri) throws IOException JavaDoc {
278         _b = EncodingConstants.NAMESPACE_ATTRIBUTE;
279         if (prefix != "") {
280             _b |= EncodingConstants.NAMESPACE_ATTRIBUTE_PREFIX_FLAG;
281         }
282         if (uri != "") {
283             _b |= EncodingConstants.NAMESPACE_ATTRIBUTE_NAME_FLAG;
284         }
285
286         // NOTE a prefix with out a namespace name is an undeclaration
287
// of the namespace bound to the prefix
288
// TODO needs to investigate how the startPrefixMapping works in
289
// relation to undeclaration
290

291         write(_b);
292
293         if (prefix != "") {
294             encodeIdentifyingNonEmptyStringOnFirstBit(prefix, _v.prefix);
295         }
296         if (uri != "") {
297             encodeIdentifyingNonEmptyStringOnFirstBit(uri, _v.namespaceName);
298         }
299     }
300
301     protected final void encodeCharacters(char[] ch, int start, int length) throws IOException JavaDoc {
302         final boolean addToTable = (length < characterContentChunkSizeContraint) ? true : false;
303         encodeNonIdentifyingStringOnThirdBit(ch, start, length, _v.characterContentChunk, addToTable, true);
304     }
305
306     protected final void encodeCharactersNoClone(char[] ch, int start, int length) throws IOException JavaDoc {
307         final boolean addToTable = (length < characterContentChunkSizeContraint) ? true : false;
308         encodeNonIdentifyingStringOnThirdBit(ch, start, length, _v.characterContentChunk, addToTable, false);
309     }
310     
311     protected final void encodeFourBitCharacters(int id, int[] table, char[] ch, int start, int length) throws FastInfosetException, IOException JavaDoc {
312         // This procedure assumes that id <= 64
313
_b = (length < characterContentChunkSizeContraint) ?
314             EncodingConstants.CHARACTER_CHUNK | EncodingConstants.CHARACTER_CHUNK_RESTRICTED_ALPHABET_FLAG | EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG :
315             EncodingConstants.CHARACTER_CHUNK | EncodingConstants.CHARACTER_CHUNK_RESTRICTED_ALPHABET_FLAG;
316         write (_b);
317
318         // Encode bottom 6 bits of enoding algorithm id
319
_b = id << 2;
320
321         encodeNonEmptyFourBitCharacterStringOnSeventhBit(table, ch, start, length);
322     }
323     
324     protected final void encodeAlphabetCharacters(String JavaDoc alphabet, char[] ch, int start, int length) throws FastInfosetException, IOException JavaDoc {
325         int id = _v.restrictedAlphabet.get(alphabet);
326         if (id == KeyIntMap.NOT_PRESENT) {
327             throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.restrictedAlphabetNotPresent"));
328         }
329         id += EncodingConstants.RESTRICTED_ALPHABET_APPLICATION_START;
330         
331         _b = (length < characterContentChunkSizeContraint) ?
332             EncodingConstants.CHARACTER_CHUNK | EncodingConstants.CHARACTER_CHUNK_RESTRICTED_ALPHABET_FLAG | EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG :
333             EncodingConstants.CHARACTER_CHUNK | EncodingConstants.CHARACTER_CHUNK_RESTRICTED_ALPHABET_FLAG;
334         _b |= (id & 0xC0) >> 6;
335         write (_b);
336
337         // Encode bottom 6 bits of enoding algorithm id
338
_b = (id & 0x3F) << 2;
339
340         encodeNonEmptyNBitCharacterStringOnSeventhBit(alphabet, ch, start, length);
341     }
342             
343     protected final void encodeProcessingInstruction(String JavaDoc target, String JavaDoc data) throws IOException JavaDoc {
344         write(EncodingConstants.PROCESSING_INSTRUCTION);
345
346         // Target
347
encodeIdentifyingNonEmptyStringOnFirstBit(target, _v.otherNCName);
348
349         // Data
350
boolean addToTable = (data.length() < characterContentChunkSizeContraint) ? true : false;
351         encodeNonIdentifyingStringOnFirstBit(data, _v.otherString, addToTable);
352     }
353
354     protected final void encodeComment(char[] ch, int start, int length) throws IOException JavaDoc {
355         write(EncodingConstants.COMMENT);
356
357         boolean addToTable = (length < characterContentChunkSizeContraint) ? true : false;
358         encodeNonIdentifyingStringOnFirstBit(ch, start, length, _v.otherString, addToTable, true);
359     }
360
361     protected final void encodeCommentNoClone(char[] ch, int start, int length) throws IOException JavaDoc {
362         write(EncodingConstants.COMMENT);
363
364         boolean addToTable = (length < characterContentChunkSizeContraint) ? true : false;
365         encodeNonIdentifyingStringOnFirstBit(ch, start, length, _v.otherString, addToTable, false);
366     }
367
368     /*
369      * C.18
370      */

371     protected final void encodeElementQualifiedNameOnThirdBit(String JavaDoc namespaceURI, String JavaDoc prefix, String JavaDoc localName) throws IOException JavaDoc {
372         LocalNameQualifiedNamesMap.Entry entry = _v.elementName.obtainEntry(localName);
373         if (entry._valueIndex > 0) {
374             QualifiedName[] names = entry._value;
375             for (int i = 0; i < entry._valueIndex; i++) {
376                 if ((prefix == names[i].prefix || prefix.equals(names[i].prefix))
377                         && (namespaceURI == names[i].namespaceName || namespaceURI.equals(names[i].namespaceName))) {
378                     encodeNonZeroIntegerOnThirdBit(names[i].index);
379                     return;
380                 }
381             }
382         }
383
384         encodeLiteralElementQualifiedNameOnThirdBit(namespaceURI, prefix,
385                 localName, entry);
386     }
387
388     /*
389      * C.18
390      */

391     protected final void encodeLiteralElementQualifiedNameOnThirdBit(String JavaDoc namespaceURI, String JavaDoc prefix, String JavaDoc localName,
392             LocalNameQualifiedNamesMap.Entry entry) throws IOException JavaDoc {
393         QualifiedName name = new QualifiedName(prefix, namespaceURI, localName, "", _v.elementName.getNextIndex());
394         entry.addQualifiedName(name);
395
396         int namespaceURIIndex = KeyIntMap.NOT_PRESENT;
397         int prefixIndex = KeyIntMap.NOT_PRESENT;
398         if (namespaceURI != "") {
399             namespaceURIIndex = _v.namespaceName.get(namespaceURI);
400             if (namespaceURIIndex == KeyIntMap.NOT_PRESENT) {
401                 throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.namespaceURINotIndexed", new Object JavaDoc[]{namespaceURI}));
402             }
403
404             if (prefix != "") {
405                 prefixIndex = _v.prefix.get(prefix);
406                 if (prefixIndex == KeyIntMap.NOT_PRESENT) {
407                     throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.prefixNotIndexed", new Object JavaDoc[]{prefix}));
408                 }
409             }
410         }
411
412         int localNameIndex = _v.localName.obtainIndex(localName);
413
414         _b |= EncodingConstants.ELEMENT_LITERAL_QNAME_FLAG;
415         if (namespaceURIIndex >= 0) {
416             _b |= EncodingConstants.LITERAL_QNAME_NAMESPACE_NAME_FLAG;
417             if (prefixIndex >= 0) {
418                 _b |= EncodingConstants.LITERAL_QNAME_PREFIX_FLAG;
419             }
420         }
421         write(_b);
422
423         if (namespaceURIIndex >= 0) {
424             if (prefixIndex >= 0) {
425                 encodeNonZeroIntegerOnSecondBitFirstBitOne(prefixIndex);
426             }
427             encodeNonZeroIntegerOnSecondBitFirstBitOne(namespaceURIIndex);
428         }
429
430         if (localNameIndex >= 0) {
431             encodeNonZeroIntegerOnSecondBitFirstBitOne(localNameIndex);
432         } else {
433             encodeNonEmptyOctetStringOnSecondBit(localName);
434         }
435     }
436
437     /*
438      * C.17
439      */

440     protected final void encodeAttributeQualifiedNameOnSecondBit(String JavaDoc namespaceURI, String JavaDoc prefix, String JavaDoc localName) throws IOException JavaDoc {
441         LocalNameQualifiedNamesMap.Entry entry = _v.attributeName.obtainEntry(localName);
442         if (entry._valueIndex > 0) {
443             QualifiedName[] names = entry._value;
444             for (int i = 0; i < entry._valueIndex; i++) {
445                 if ((prefix == names[i].prefix || prefix.equals(names[i].prefix))
446                         && (namespaceURI == names[i].namespaceName || namespaceURI.equals(names[i].namespaceName))) {
447                     encodeNonZeroIntegerOnSecondBitFirstBitZero(names[i].index);
448                     return;
449                 }
450             }
451         }
452
453         encodeLiteralAttributeQualifiedNameOnSecondBit(namespaceURI, prefix,
454                 localName, entry);
455     }
456
457     /*
458      * C.17
459      */

460     protected final boolean encodeLiteralAttributeQualifiedNameOnSecondBit(String JavaDoc namespaceURI, String JavaDoc prefix, String JavaDoc localName,
461                 LocalNameQualifiedNamesMap.Entry entry) throws IOException JavaDoc {
462         int namespaceURIIndex = KeyIntMap.NOT_PRESENT;
463         int prefixIndex = KeyIntMap.NOT_PRESENT;
464         if (namespaceURI != "") {
465             namespaceURIIndex = _v.namespaceName.get(namespaceURI);
466             if (namespaceURIIndex == KeyIntMap.NOT_PRESENT) {
467                 if (namespaceURI == EncodingConstants.XMLNS_NAMESPACE_NAME ||
468                         namespaceURI.equals(EncodingConstants.XMLNS_NAMESPACE_NAME)) {
469                     return false;
470                 } else {
471                     throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.namespaceURINotIndexed", new Object JavaDoc[]{namespaceURI}));
472                 }
473             }
474             
475             if (prefix != "") {
476                 prefixIndex = _v.prefix.get(prefix);
477                 if (prefixIndex == KeyIntMap.NOT_PRESENT) {
478                     throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.prefixNotIndexed", new Object JavaDoc[]{prefix}));
479                 }
480             }
481         }
482
483         int localNameIndex = _v.localName.obtainIndex(localName);
484
485         QualifiedName name = new QualifiedName(prefix, namespaceURI, localName, "", _v.attributeName.getNextIndex());
486         entry.addQualifiedName(name);
487
488         _b = EncodingConstants.ATTRIBUTE_LITERAL_QNAME_FLAG;
489         if (namespaceURI != "") {
490             _b |= EncodingConstants.LITERAL_QNAME_NAMESPACE_NAME_FLAG;
491             if (prefix != "") {
492                 _b |= EncodingConstants.LITERAL_QNAME_PREFIX_FLAG;
493             }
494         }
495
496         write(_b);
497
498         if (namespaceURIIndex >= 0) {
499             if (prefixIndex >= 0) {
500                 encodeNonZeroIntegerOnSecondBitFirstBitOne(prefixIndex);
501             }
502             encodeNonZeroIntegerOnSecondBitFirstBitOne(namespaceURIIndex);
503         } else if (namespaceURI != "") {
504             // XML prefix and namespace name
505
encodeNonEmptyOctetStringOnSecondBit("xml");
506             encodeNonEmptyOctetStringOnSecondBit("http://www.w3.org/XML/1998/namespace");
507         }
508
509         if (localNameIndex >= 0) {
510             encodeNonZeroIntegerOnSecondBitFirstBitOne(localNameIndex);
511         } else {
512             encodeNonEmptyOctetStringOnSecondBit(localName);
513         }
514         
515         return true;
516     }
517
518     /*
519      * C.14
520      */

521     protected final void encodeNonIdentifyingStringOnFirstBit(String JavaDoc s, StringIntMap map, boolean addToTable) throws IOException JavaDoc {
522         if (s == null || s.length() == 0) {
523             // C.26 an index (first bit '1') with seven '1' bits for an empty string
524
write(0xFF);
525         } else {
526             if (addToTable) {
527                 int index = map.obtainIndex(s);
528                 if (index == KeyIntMap.NOT_PRESENT) {
529                     _b = EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG | _nonIdentifyingStringOnFirstBitCES;
530                     encodeNonEmptyCharacterStringOnFifthBit(s);
531                 } else {
532                     encodeNonZeroIntegerOnSecondBitFirstBitOne(index);
533                 }
534             } else {
535                 _b = _nonIdentifyingStringOnFirstBitCES;
536                 encodeNonEmptyCharacterStringOnFifthBit(s);
537             }
538         }
539     }
540
541     /*
542      * C.14
543      */

544     protected final void encodeNonIdentifyingStringOnFirstBit(String JavaDoc s, CharArrayIntMap map, boolean addToTable) throws IOException JavaDoc {
545         if (s == null || s.length() == 0) {
546             // C.26 an index (first bit '1') with seven '1' bits for an empty string
547
write(0xFF);
548         } else {
549             if (addToTable) {
550                 final char[] ch = s.toCharArray();
551                 final int length = s.length();
552                 int index = map.obtainIndex(ch, 0, length, false);
553                 if (index == KeyIntMap.NOT_PRESENT) {
554                     _b = EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG | _nonIdentifyingStringOnFirstBitCES;
555                     encodeNonEmptyCharacterStringOnFifthBit(ch, 0, length);
556                 } else {
557                     encodeNonZeroIntegerOnSecondBitFirstBitOne(index);
558                 }
559             } else {
560                 _b = _nonIdentifyingStringOnFirstBitCES;
561                 encodeNonEmptyCharacterStringOnFifthBit(s);
562             }
563         }
564     }
565
566     /*
567      * C.14
568      */

569     protected final void encodeNonIdentifyingStringOnFirstBit(char[] array, int start, int length, CharArrayIntMap map,
570             boolean addToTable, boolean clone) throws IOException JavaDoc {
571         if (length == 0) {
572             // C.26 an index (first bit '1') with seven '1' bits for an empty string
573
write(0xFF);
574         } else {
575             if (addToTable) {
576                 int index = map.obtainIndex(array, start, length, clone);
577                 if (index == KeyIntMap.NOT_PRESENT) {
578                     _b = EncodingConstants.NISTRING_ADD_TO_TABLE_FLAG | _nonIdentifyingStringOnFirstBitCES;
579                     encodeNonEmptyCharacterStringOnFifthBit(array, start, length);
580                 } else {
581                     encodeNonZeroIntegerOnSecondBitFirstBitOne(index);
582                 }
583             } else {
584                 _b = _nonIdentifyingStringOnFirstBitCES;
585                 encodeNonEmptyCharacterStringOnFifthBit(array, start, length);
586             }
587         }
588     }
589
590     /*
591      * C.14
592      */

593     protected final void encodeNonIdentifyingStringOnFirstBit(String JavaDoc URI, int id, Object JavaDoc data) throws FastInfosetException, IOException JavaDoc {
594         if (URI != null) {
595             id = _v.encodingAlgorithm.get(URI);
596             if (id == KeyIntMap.NOT_PRESENT) {
597                 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.EncodingAlgorithmURI", new Object JavaDoc[]{URI}));
598             }
599             id += EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START;
600
601             EncodingAlgorithm ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI);
602             if (ea != null) {
603                 encodeAIIObjectAlgorithmData(URI, id, data, ea);
604             } else {
605                 if (data instanceof byte[]) {
606                     byte[] d = (byte[])data;
607                     encodeAIIOctetAlgorithmData(id, d, 0, d.length);
608                 } else {
609                     throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.nullEncodingAlgorithmURI"));
610                 }
611             }
612         } else if (id <= EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
613             BuiltInEncodingAlgorithm a = BuiltInEncodingAlgorithmFactory.table[id];
614             int length = 0;
615             switch(id) {
616                 case EncodingAlgorithmIndexes.HEXADECIMAL:
617                     length = ((byte[])data).length;
618                     break;
619                 case EncodingAlgorithmIndexes.BASE64:
620                     length = ((byte[])data).length;
621                     break;
622                 case EncodingAlgorithmIndexes.SHORT:
623                     length = ((short[])data).length;
624                     break;
625                 case EncodingAlgorithmIndexes.INT:
626                     length = ((int[])data).length;
627                     break;
628                 case EncodingAlgorithmIndexes.LONG:
629                     length = ((long[])data).length;
630                     break;
631                 case EncodingAlgorithmIndexes.BOOLEAN:
632                     length = ((boolean[])data).length;
633                     break;
634                 case EncodingAlgorithmIndexes.FLOAT:
635                     length = ((float[])data).length;
636                     break;
637                 case EncodingAlgorithmIndexes.DOUBLE:
638                     length = ((double[])data).length;
639                     break;
640                 case EncodingAlgorithmIndexes.UUID:
641                     length = ((long[])data).length;
642                     break;
643                 case EncodingAlgorithmIndexes.CDATA:
644                     throw new UnsupportedOperationException JavaDoc(CommonResourceBundle.getInstance().getString("message.CDATA"));
645                 default:
646                     throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.UnsupportedBuiltInAlgorithm", new Object JavaDoc[]{new Integer JavaDoc(id)}));
647             }
648             encodeAIIBuiltInAlgorithmData(id, data, 0, length);
649         } else if (id >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
650             if (data instanceof byte[]) {
651                 byte[] d = (byte[])data;
652                 encodeAIIOctetAlgorithmData(id, d, 0, d.length);
653             } else {
654                 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.nullEncodingAlgorithmURI"));
655             }
656         } else {
657             throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved"));
658         }
659     }
660
661     protected final void encodeAIIOctetAlgorithmData(int id, byte[] d, int start, int length) throws IOException JavaDoc {
662         // Encode identification and top four bits of encoding algorithm id
663
write (EncodingConstants.NISTRING_ENCODING_ALGORITHM_FLAG |
664                 ((id & 0xF0) >> 4));
665
666         // Encode bottom 4 bits of enoding algorithm id
667
_b = (id & 0x0F) << 4;
668
669         // Encode the length
670
encodeNonZeroOctetStringLengthOnFifthBit(length);
671
672         write(d, start, length);
673     }
674
675     protected final void encodeAIIObjectAlgorithmData(String JavaDoc URI, int id, Object JavaDoc data, EncodingAlgorithm ea) throws FastInfosetException, IOException JavaDoc {
676         // Encode identification and top four bits of encoding algorithm id
677
write (EncodingConstants.NISTRING_ENCODING_ALGORITHM_FLAG |
678                 ((id & 0xF0) >> 4));
679
680         // Encode bottom 4 bits of enoding algorithm id
681
_b = (id & 0x0F) << 4;
682
683         _encodingBufferOutputStream.reset();
684         ea.encodeToOutputStream(data, _encodingBufferOutputStream);
685         encodeNonZeroOctetStringLengthOnFifthBit(_encodingBufferIndex);
686         write(_encodingBuffer, _encodingBufferIndex);
687     }
688
689     protected final void encodeAIIBuiltInAlgorithmData(int id, Object JavaDoc o, int start, int length) throws IOException JavaDoc {
690         // Encode identification and top four bits of encoding algorithm id
691
write (EncodingConstants.NISTRING_ENCODING_ALGORITHM_FLAG |
692                 ((id & 0xF0) >> 4));
693
694         // Encode bottom 4 bits of enoding algorithm id
695
_b = (id & 0x0F) << 4;
696
697         final int octetLength = BuiltInEncodingAlgorithmFactory.table[id].
698                     getOctetLengthFromPrimitiveLength(length);
699
700         encodeNonZeroOctetStringLengthOnFifthBit(octetLength);
701
702         ensureSize(octetLength);
703         BuiltInEncodingAlgorithmFactory.table[id].
704                 encodeToBytes(o, start, length, _octetBuffer, _octetBufferIndex);
705         _octetBufferIndex += octetLength;
706     }
707
708     /*
709      * C.15
710      */

711     protected final void encodeNonIdentifyingStringOnThirdBit(char[] array, int start, int length,
712             CharArrayIntMap map, boolean addToTable, boolean clone) throws IOException JavaDoc {
713         // length cannot be zero since sequence of CIIs has to be > 0
714

715         if (addToTable) {
716             int index = map.obtainIndex(array, start, length, clone);
717             if (index == KeyIntMap.NOT_PRESENT) {
718                 _b = EncodingConstants.CHARACTER_CHUNK_ADD_TO_TABLE_FLAG |
719                         _nonIdentifyingStringOnThirdBitCES;
720                 encodeNonEmptyCharacterStringOnSeventhBit(array, start, length);
721             } else {
722                 _b = EncodingConstants.CHARACTER_CHUNK | 0x20;
723                 encodeNonZeroIntegerOnFourthBit(index);
724             }
725         } else {
726             _b = _nonIdentifyingStringOnThirdBitCES;
727             encodeNonEmptyCharacterStringOnSeventhBit(array, start, length);
728         }
729     }
730
731     protected final void encodeNonIdentifyingStringOnThirdBit(String JavaDoc URI, int id, Object JavaDoc data) throws FastInfosetException, IOException JavaDoc {
732         if (URI != null) {
733             id = _v.encodingAlgorithm.get(URI);
734             if (id == KeyIntMap.NOT_PRESENT) {
735                 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.EncodingAlgorithmURI", new Object JavaDoc[]{URI}));
736             }
737             id += EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START;
738
739             EncodingAlgorithm ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI);
740             if (ea != null) {
741                 encodeCIIObjectAlgorithmData(URI, id, data, ea);
742             } else {
743                 if (data instanceof byte[]) {
744                     byte[] d = (byte[])data;
745                     encodeCIIOctetAlgorithmData(id, d, 0, d.length);
746                 } else {
747                     throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.nullEncodingAlgorithmURI"));
748                 }
749             }
750         } else if (id <= EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
751             int length = 0;
752             switch(id) {
753                 case EncodingAlgorithmIndexes.HEXADECIMAL:
754                     length = ((byte[])data).length;
755                     break;
756                 case EncodingAlgorithmIndexes.BASE64:
757                     length = ((byte[])data).length;
758                     break;
759                 case EncodingAlgorithmIndexes.SHORT:
760                     length = ((short[])data).length;
761                     break;
762                 case EncodingAlgorithmIndexes.INT:
763                     length = ((int[])data).length;
764                     break;
765                 case EncodingAlgorithmIndexes.LONG:
766                     length = ((int[])data).length;
767                     break;
768                 case EncodingAlgorithmIndexes.BOOLEAN:
769                     length = ((boolean[])data).length;
770                     break;
771                 case EncodingAlgorithmIndexes.FLOAT:
772                     length = ((float[])data).length;
773                     break;
774                 case EncodingAlgorithmIndexes.DOUBLE:
775                     length = ((double[])data).length;
776                     break;
777                 case EncodingAlgorithmIndexes.UUID:
778                     length = ((int[])data).length;
779                     break;
780                 case EncodingAlgorithmIndexes.CDATA:
781                     throw new UnsupportedOperationException JavaDoc(CommonResourceBundle.getInstance().getString("message.CDATA"));
782                 default:
783                     throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.UnsupportedBuiltInAlgorithm", new Object JavaDoc[]{new Integer JavaDoc(id)}));
784             }
785             encodeCIIBuiltInAlgorithmData(id, data, 0, length);
786         } else if (id >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
787             if (data instanceof byte[]) {
788                 byte[] d = (byte[])data;
789                 encodeCIIOctetAlgorithmData(id, d, 0, d.length);
790             } else {
791                 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.nullEncodingAlgorithmURI"));
792             }
793         } else {
794             throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved"));
795         }
796     }
797
798     protected final void encodeNonIdentifyingStringOnThirdBit(String JavaDoc URI, int id, byte[] b, int start, int length) throws FastInfosetException, IOException JavaDoc {
799         if (URI != null) {
800             id = _v.encodingAlgorithm.get(URI);
801             if (id == KeyIntMap.NOT_PRESENT) {
802                 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.EncodingAlgorithmURI", new Object JavaDoc[]{URI}));
803             }
804             id += EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START;
805         }
806
807         encodeCIIOctetAlgorithmData(id, b, start, length);
808     }
809
810     protected final void encodeCIIOctetAlgorithmData(int id, byte[] d, int start, int length) throws IOException JavaDoc {
811         // Encode identification and top two bits of encoding algorithm id
812
write (EncodingConstants.CHARACTER_CHUNK | EncodingConstants.CHARACTER_CHUNK_ENCODING_ALGORITHM_FLAG |
813                 ((id & 0xC0) >> 6));
814
815         // Encode bottom 6 bits of enoding algorithm id
816
_b = (id & 0x3F) << 2;
817
818         // Encode the length
819
encodeNonZeroOctetStringLengthOnSenventhBit(length);
820
821         write(d, start, length);
822     }
823
824     protected final void encodeCIIObjectAlgorithmData(String JavaDoc URI, int id, Object JavaDoc data, EncodingAlgorithm ea) throws FastInfosetException, IOException JavaDoc {
825         // Encode identification and top two bits of encoding algorithm id
826
write (EncodingConstants.CHARACTER_CHUNK | EncodingConstants.CHARACTER_CHUNK_ENCODING_ALGORITHM_FLAG |
827                 ((id & 0xC0) >> 6));
828
829         // Encode bottom 6 bits of enoding algorithm id
830
_b = (id & 0x3F) << 2;
831
832         _encodingBufferOutputStream.reset();
833         ea.encodeToOutputStream(data, _encodingBufferOutputStream);
834         encodeNonZeroOctetStringLengthOnSenventhBit(_encodingBufferIndex);
835         write(_encodingBuffer, _encodingBufferIndex);
836     }
837
838     protected final void encodeCIIBuiltInAlgorithmData(int id, Object JavaDoc o, int start, int length) throws FastInfosetException, IOException JavaDoc {
839         // Encode identification and top two bits of encoding algorithm id
840
write (EncodingConstants.CHARACTER_CHUNK | EncodingConstants.CHARACTER_CHUNK_ENCODING_ALGORITHM_FLAG |
841                 ((id & 0xC0) >> 6));
842
843         // Encode bottom 6 bits of enoding algorithm id
844
_b = (id & 0x3F) << 2;
845
846         final int octetLength = BuiltInEncodingAlgorithmFactory.table[id].
847                     getOctetLengthFromPrimitiveLength(length);
848
849         encodeNonZeroOctetStringLengthOnSenventhBit(octetLength);
850
851         ensureSize(octetLength);
852         BuiltInEncodingAlgorithmFactory.table[id].
853                 encodeToBytes(o, start, length, _octetBuffer, _octetBufferIndex);
854         _octetBufferIndex += octetLength;
855     }
856
857     protected final void encodeCIIBuiltInAlgorithmDataAsCDATA(char[] c, int start, int length) throws FastInfosetException, IOException JavaDoc {
858         // Encode identification and top two bits of encoding algorithm id
859
write (EncodingConstants.CHARACTER_CHUNK | EncodingConstants.CHARACTER_CHUNK_ENCODING_ALGORITHM_FLAG);
860
861         // Encode bottom 6 bits of enoding algorithm id
862
_b = EncodingAlgorithmIndexes.CDATA << 2;
863
864         
865         length = encodeUTF8String(c, start, length);
866         encodeNonZeroOctetStringLengthOnSenventhBit(length);
867         write(_encodingBuffer, length);
868     }
869     
870     /*
871      * C.13
872      */

873     protected final void encodeIdentifyingNonEmptyStringOnFirstBit(String JavaDoc s, StringIntMap map) throws IOException JavaDoc {
874         int index = map.obtainIndex(s);
875         if (index == KeyIntMap.NOT_PRESENT) {
876             // _b = 0;
877
encodeNonEmptyOctetStringOnSecondBit(s);
878         } else {
879             // _b = 0x80;
880
encodeNonZeroIntegerOnSecondBitFirstBitOne(index);
881         }
882     }
883
884     /*
885      * C.22
886      */

887     protected final void encodeNonEmptyOctetStringOnSecondBit(String JavaDoc s) throws IOException JavaDoc {
888         final int length = encodeUTF8String(s);
889         encodeNonZeroOctetStringLengthOnSecondBit(length);
890         write(_encodingBuffer, length);
891     }
892
893     /*
894      * C.22
895      */

896     protected final void encodeNonZeroOctetStringLengthOnSecondBit(int length) throws IOException JavaDoc {
897         if (length < EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT) {
898             // [1, 64]
899
write(length - 1);
900         } else if (length < EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT) {
901             // [65, 320]
902
write(EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_FLAG); // 010 00000
903
write(length - EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_SMALL_LIMIT);
904         } else {
905             // [321, 4294967296]
906
write(EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_LARGE_FLAG); // 0110 0000
907
length -= EncodingConstants.OCTET_STRING_LENGTH_2ND_BIT_MEDIUM_LIMIT;
908             write(length >>> 24);
909             write((length >> 16) & 0xFF);
910             write((length >> 8) & 0xFF);
911             write(length & 0xFF);
912         }
913     }
914
915
916     /*
917      * C.23
918      */

919     protected final void encodeNonEmptyCharacterStringOnFifthBit(String JavaDoc s) throws IOException JavaDoc {
920         final int length = (_encodingStringsAsUtf8) ? encodeUTF8String(s) : encodeUtf16String(s);
921         encodeNonZeroOctetStringLengthOnFifthBit(length);
922         write(_encodingBuffer, length);
923     }
924
925     /*
926      * C.23
927      */

928     protected final void encodeNonEmptyCharacterStringOnFifthBit(char[] array, int start, int length) throws IOException JavaDoc {
929         length = (_encodingStringsAsUtf8) ? encodeUTF8String(array, start, length) : encodeUtf16String(array, start, length);
930         encodeNonZeroOctetStringLengthOnFifthBit(length);
931         write(_encodingBuffer, length);
932     }
933
934     /*
935      * C.23
936      */

937     protected final void encodeNonZeroOctetStringLengthOnFifthBit(int length) throws IOException JavaDoc {
938         if (length < EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT) {
939             // [1, 8]
940
write(_b | (length - 1));
941         } else if (length < EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT) {
942             // [9, 264]
943
write(_b | EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_FLAG); // 000010 00
944
write(length - EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_SMALL_LIMIT);
945         } else {
946             // [265, 4294967296]
947
write(_b | EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_LARGE_FLAG); // 000011 00
948
length -= EncodingConstants.OCTET_STRING_LENGTH_5TH_BIT_MEDIUM_LIMIT;
949             write(length >>> 24);
950             write((length >> 16) & 0xFF);
951             write((length >> 8) & 0xFF);
952             write(length & 0xFF);
953         }
954     }
955
956     /*
957      * C.24
958      */

959     protected final void encodeNonEmptyCharacterStringOnSeventhBit(char[] array, int start, int length) throws IOException JavaDoc {
960         length = (_encodingStringsAsUtf8) ? encodeUTF8String(array, start, length) : encodeUtf16String(array, start, length);
961         encodeNonZeroOctetStringLengthOnSenventhBit(length);
962         write(_encodingBuffer, length);
963     }
964
965     /*
966      * C.24
967      */

968     protected final void encodeNonEmptyFourBitCharacterStringOnSeventhBit(int[] table, char[] ch, int start, int length) throws FastInfosetException, IOException JavaDoc {
969         final int octetPairLength = length / 2;
970         final int octetSingleLength = length % 2;
971         
972         // Encode the length
973
encodeNonZeroOctetStringLengthOnSenventhBit(octetPairLength + octetSingleLength);
974
975         ensureSize(octetPairLength + octetSingleLength);
976         // Encode all pairs
977
int v = 0;
978         for (int i = 0; i < octetPairLength; i++) {
979             v = (table[ch[start++]] << 4) | table[ch[start++]];
980             if (v < 0) {
981                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.characterOutofAlphabetRange"));
982             }
983             _octetBuffer[_octetBufferIndex++] = (byte)v;
984         }
985         // Encode single character at end with termination bits
986
if (octetSingleLength == 1) {
987             v = (table[ch[start]] << 4) | 0x0F;
988             if (v < 0) {
989                 throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.characterOutofAlphabetRange"));
990             }
991             _octetBuffer[_octetBufferIndex++] = (byte)v;
992         }
993     }
994     
995     /*
996      * C.24
997      */

998     protected final void encodeNonEmptyNBitCharacterStringOnSeventhBit(String JavaDoc alphabet, char[] ch, int start, int length) throws FastInfosetException, IOException JavaDoc {
999         int bitsPerCharacter = 1;
1000        while ((1 << bitsPerCharacter) <= alphabet.length()) {
1001            bitsPerCharacter++;
1002        }
1003        final int terminatingValue = (1 << bitsPerCharacter) - 1;
1004        
1005        final int bits = length * bitsPerCharacter;
1006        final int octets = bits / 8;
1007        final int bitsOfLastOctet = bits % 8;
1008        final int totalOctets = octets + ((bitsOfLastOctet > 0) ? 1 : 0);
1009        
1010        // Encode the length
1011
encodeNonZeroOctetStringLengthOnSenventhBit(totalOctets);
1012
1013        resetBits();
1014        ensureSize(totalOctets);
1015        int v = 0;
1016        for (int i = 0; i < length; i++) {
1017            final char c = ch[start + i];
1018            // This is grotesquely slow, need to use hash table of character to int value
1019
for (v = 0; v < alphabet.length(); v++) {
1020                if (c == alphabet.charAt(v)) {
1021                    break;
1022                }
1023            }
1024            if (v == alphabet.length()) {
1025                throw new FastInfosetException(CommonResourceBundle.getInstance().getString("message.characterOutofAlphabetRange"));
1026            }
1027            writeBits(bitsPerCharacter, v);
1028        }
1029        
1030        if (bitsOfLastOctet > 0) {
1031            _b |= (1 << (8 - bitsOfLastOctet)) - 1;
1032            write(_b);
1033        }
1034    }
1035
1036    protected int _bitsLeftInOctet;
1037    
1038    public final void resetBits() {
1039        _bitsLeftInOctet = 8;
1040        _b = 0;
1041    }
1042    
1043    protected final void writeBits(int bits, int v) throws IOException JavaDoc {
1044        while (bits > 0) {
1045            final int bit = (v & (1 << --bits)) > 0 ? 1 : 0;
1046            _b |= bit << (--_bitsLeftInOctet);
1047            if (_bitsLeftInOctet == 0) {
1048                write(_b);
1049                _bitsLeftInOctet = 8;
1050                _b = 0;
1051            }
1052        }
1053    }
1054    
1055    /*
1056     * C.24
1057     */

1058    protected final void encodeNonZeroOctetStringLengthOnSenventhBit(int length) throws IOException JavaDoc {
1059        if (length < EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT) {
1060            // [1, 2]
1061
write(_b | (length - 1));
1062        } else if (length < EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT) {
1063            // [3, 258]
1064
write(_b | EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_FLAG); // 00000010
1065
write(length - EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_SMALL_LIMIT);
1066        } else {
1067            // [259, 4294967296]
1068
write(_b | EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_LARGE_FLAG); // 00000011
1069
length -= EncodingConstants.OCTET_STRING_LENGTH_7TH_BIT_MEDIUM_LIMIT;
1070            write(length >>> 24);
1071            write((length >> 16) & 0xFF);
1072            write((length >> 8) & 0xFF);
1073            write(length & 0xFF);
1074        }
1075    }
1076
1077    /*
1078     * C.25 (with first bit set to 1)
1079     *
1080     * i is a member of the interval [0, 1048575]
1081     *
1082     * In the specification the interval is [1, 1048576]
1083     *
1084     * The first bit of the first octet is set. As specified in C.13
1085     */

1086    protected final void encodeNonZeroIntegerOnSecondBitFirstBitOne(int i) throws IOException JavaDoc {
1087        if (i < EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT) {
1088            // [1, 64] ( [0, 63] ) 6 bits
1089
write(0x80 | i);
1090        } else if (i < EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT) {
1091            // [65, 8256] ( [64, 8255] ) 13 bits
1092
i -= EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
1093            _b = (0x80 | EncodingConstants.INTEGER_2ND_BIT_MEDIUM_FLAG) | (i >> 8); // 010 00000
1094
// _b = 0xC0 | (i >> 8); // 010 00000
1095
write(_b);
1096            write(i & 0xFF);
1097        } else {
1098            // [8257, 1048576] ( [8256, 1048575] ) 20 bits
1099
i -= EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
1100            _b = (0x80 | EncodingConstants.INTEGER_2ND_BIT_LARGE_FLAG) | (i >> 16); // 0110 0000
1101
// _b = 0xE0 | (i >> 16); // 0110 0000
1102
write(_b);
1103            write((i >> 8) & 0xFF);
1104            write(i & 0xFF);
1105        }
1106    }
1107
1108    /*
1109     * C.25 (with first bit set to 0)
1110     *
1111     * i is a member of the interval [0, 1048575]
1112     *
1113     * In the specification the interval is [1, 1048576]
1114     *
1115     * The first bit of the first octet is set. As specified in C.13
1116     */

1117    protected final void encodeNonZeroIntegerOnSecondBitFirstBitZero(int i) throws IOException JavaDoc {
1118        if (i < EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT) {
1119            // [1, 64] ( [0, 63] ) 6 bits
1120
write(i);
1121        } else if (i < EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT) {
1122            // [65, 8256] ( [64, 8255] ) 13 bits
1123
i -= EncodingConstants.INTEGER_2ND_BIT_SMALL_LIMIT;
1124            _b = EncodingConstants.INTEGER_2ND_BIT_MEDIUM_FLAG | (i >> 8); // 010 00000
1125
write(_b);
1126            write(i & 0xFF);
1127        } else {
1128            // [8257, 1048576] ( [8256, 1048575] ) 20 bits
1129
i -= EncodingConstants.INTEGER_2ND_BIT_MEDIUM_LIMIT;
1130            _b = EncodingConstants.INTEGER_2ND_BIT_LARGE_FLAG | (i >> 16); // 0110 0000
1131
write(_b);
1132            write((i >> 8) & 0xFF);
1133            write(i & 0xFF);
1134        }
1135    }
1136
1137    /*
1138     * C.27
1139     *
1140     * i is a member of the interval [0, 1048575]
1141     *
1142     * In the specification the interval is [1, 1048576]
1143     *
1144     */

1145    protected final void encodeNonZeroIntegerOnThirdBit(int i) throws IOException JavaDoc {
1146        if (i < EncodingConstants.INTEGER_3RD_BIT_SMALL_LIMIT) {
1147            // [1, 32] ( [0, 31] ) 5 bits
1148
write(_b | i);
1149        } else if (i < EncodingConstants.INTEGER_3RD_BIT_MEDIUM_LIMIT) {
1150            // [33, 2080] ( [32, 2079] ) 11 bits
1151
i -= EncodingConstants.INTEGER_3RD_BIT_SMALL_LIMIT;
1152            _b |= EncodingConstants.INTEGER_3RD_BIT_MEDIUM_FLAG | (i >> 8); // 00100 000
1153
write(_b);
1154            write(i & 0xFF);
1155        } else if (i < EncodingConstants.INTEGER_3RD_BIT_LARGE_LIMIT) {
1156            // [2081, 526368] ( [2080, 526367] ) 19 bits
1157
i -= EncodingConstants.INTEGER_3RD_BIT_MEDIUM_LIMIT;
1158            _b |= EncodingConstants.INTEGER_3RD_BIT_LARGE_FLAG | (i >> 16); // 00101 000
1159
write(_b);
1160            write((i >> 8) & 0xFF);
1161            write(i & 0xFF);
1162        } else {
1163            // [526369, 1048576] ( [526368, 1048575] ) 20 bits
1164
i -= EncodingConstants.INTEGER_3RD_BIT_LARGE_LIMIT;
1165            _b |= EncodingConstants.INTEGER_3RD_BIT_LARGE_LARGE_FLAG; // 00110 000
1166
write(_b);
1167            write(i >> 16);
1168            write((i >> 8) & 0xFF);
1169            write(i & 0xFF);
1170        }
1171    }
1172
1173    /*
1174     * C.28
1175     *
1176     * i is a member of the interval [0, 1048575]
1177     *
1178     * In the specification the interval is [1, 1048576]
1179     */

1180    protected final void encodeNonZeroIntegerOnFourthBit(int i) throws IOException JavaDoc {
1181        if (i < EncodingConstants.INTEGER_4TH_BIT_SMALL_LIMIT) {
1182            // [1, 16] ( [0, 15] ) 4 bits
1183
write(_b | i);
1184        } else if (i < EncodingConstants.INTEGER_4TH_BIT_MEDIUM_LIMIT) {
1185            // [17, 1040] ( [16, 1039] ) 10 bits
1186
i -= EncodingConstants.INTEGER_4TH_BIT_SMALL_LIMIT;
1187            _b |= EncodingConstants.INTEGER_4TH_BIT_MEDIUM_FLAG | (i >> 8); // 000 100 00
1188
write(_b);
1189            write(i & 0xFF);
1190        } else if (i < EncodingConstants.INTEGER_4TH_BIT_LARGE_LIMIT) {
1191            // [1041, 263184] ( [1040, 263183] ) 18 bits
1192
i -= EncodingConstants.INTEGER_4TH_BIT_MEDIUM_LIMIT;
1193            _b |= EncodingConstants.INTEGER_4TH_BIT_LARGE_FLAG | (i >> 16); // 000 101 00
1194
write(_b);
1195            write((i >> 8) & 0xFF);
1196            write(i & 0xFF);
1197        } else {
1198            // [263185, 1048576] ( [263184, 1048575] ) 20 bits
1199
i -= EncodingConstants.INTEGER_4TH_BIT_LARGE_LIMIT;
1200            _b |= EncodingConstants.INTEGER_4TH_BIT_LARGE_LARGE_FLAG; // 000 110 00
1201
write(_b);
1202            write(i >> 16);
1203            write((i >> 8) & 0xFF);
1204            write(i & 0xFF);
1205        }
1206    }
1207
1208    protected final void encodeNonEmptyUTF8StringAsOctetString(int b, String JavaDoc s, int[] constants) throws IOException JavaDoc {
1209        final char[] ch = s.toCharArray();
1210        encodeNonEmptyUTF8StringAsOctetString(b, ch, 0, ch.length, constants);
1211    }
1212
1213    protected final void encodeNonEmptyUTF8StringAsOctetString(int b, char ch[], int start, int length, int[] constants) throws IOException JavaDoc {
1214        length = encodeUTF8String(ch, start, length);
1215        encodeNonZeroOctetStringLength(b, length, constants);
1216        write(_encodingBuffer, length);
1217    }
1218
1219    protected final void encodeNonZeroOctetStringLength(int b, int length, int[] constants) throws IOException JavaDoc {
1220        if (length < constants[EncodingConstants.OCTET_STRING_LENGTH_SMALL_LIMIT]) {
1221            write(b | (length - 1));
1222        } else if (length < constants[EncodingConstants.OCTET_STRING_LENGTH_MEDIUM_LIMIT]) {
1223            write(b | constants[EncodingConstants.OCTET_STRING_LENGTH_MEDIUM_FLAG]);
1224            write(length - constants[EncodingConstants.OCTET_STRING_LENGTH_SMALL_LIMIT]);
1225        } else {
1226            write(b | constants[EncodingConstants.OCTET_STRING_LENGTH_LARGE_FLAG]);
1227            length -= constants[EncodingConstants.OCTET_STRING_LENGTH_MEDIUM_LIMIT];
1228            write(length >>> 24);
1229            write((length >> 16) & 0xFF);
1230            write((length >> 8) & 0xFF);
1231            write(length & 0xFF);
1232        }
1233    }
1234
1235    protected final void encodeNonZeroInteger(int b, int i, int[] constants) throws IOException JavaDoc {
1236        if (i < constants[EncodingConstants.INTEGER_SMALL_LIMIT]) {
1237            write(b | i);
1238        } else if (i < constants[EncodingConstants.INTEGER_MEDIUM_LIMIT]) {
1239            i -= constants[EncodingConstants.INTEGER_SMALL_LIMIT];
1240            write(b | constants[EncodingConstants.INTEGER_MEDIUM_FLAG] | (i >> 8));
1241            write(i & 0xFF);
1242        } else if (i < constants[EncodingConstants.INTEGER_LARGE_LIMIT]) {
1243            i -= constants[EncodingConstants.INTEGER_MEDIUM_LIMIT];
1244            write(b | constants[EncodingConstants.INTEGER_LARGE_FLAG] | (i >> 16));
1245            write((i >> 8) & 0xFF);
1246            write(i & 0xFF);
1247        } else if (i < EncodingConstants.INTEGER_MAXIMUM_SIZE) {
1248            i -= constants[EncodingConstants.INTEGER_LARGE_LIMIT];
1249            write(b | constants[EncodingConstants.INTEGER_LARGE_LARGE_FLAG]);
1250            write(i >> 16);
1251            write((i >> 8) & 0xFF);
1252            write(i & 0xFF);
1253        } else {
1254            throw new IOException JavaDoc(CommonResourceBundle.getInstance().getString("message.integerMaxSize", new Object JavaDoc[]{new Integer JavaDoc(EncodingConstants.INTEGER_MAXIMUM_SIZE)}));
1255        }
1256    }
1257
1258
1259
1260
1261
1262
1263
1264    protected final int encodeUTF8String(String JavaDoc s) throws IOException JavaDoc {
1265        final int length = s.length();
1266        if (length < _charBuffer.length) {
1267            s.getChars(0, length, _charBuffer, 0);
1268            return encodeUTF8String(_charBuffer, 0, length);
1269        } else {
1270            char[] ch = s.toCharArray();
1271            return encodeUTF8String(ch, 0, length);
1272        }
1273    }
1274    
1275    protected final int encodeUtf16String(String JavaDoc s) throws IOException JavaDoc {
1276        final int length = s.length();
1277        if (length < _charBuffer.length) {
1278            s.getChars(0, length, _charBuffer, 0);
1279            return encodeUtf16String(_charBuffer, 0, length);
1280        } else {
1281            char[] ch = s.toCharArray();
1282            return encodeUtf16String(ch, 0, length);
1283        }
1284    }
1285    
1286    protected final void mark() throws IOException JavaDoc {
1287        _markIndex = _octetBufferIndex;
1288    }
1289
1290    protected final void resetMark() throws IOException JavaDoc {
1291        _markIndex = -1;
1292    }
1293
1294    protected final void write(int i) throws IOException JavaDoc {
1295        if (_octetBufferIndex < _octetBuffer.length) {
1296            _octetBuffer[_octetBufferIndex++] = (byte)i;
1297        } else {
1298            if (_markIndex == -1) {
1299                _s.write(_octetBuffer);
1300                _octetBufferIndex = 1;
1301                _octetBuffer[0] = (byte)i;
1302            } else {
1303                resize(_octetBuffer.length * 3 / 2);
1304                _octetBuffer[_octetBufferIndex++] = (byte)i;
1305            }
1306        }
1307    }
1308
1309    protected final void write(byte[] b, int length) throws IOException JavaDoc {
1310        write(b, 0, length);
1311    }
1312
1313    protected final void write(byte[] b, int start, int length) throws IOException JavaDoc {
1314        if ((_octetBufferIndex + length) < _octetBuffer.length) {
1315            System.arraycopy(b, start, _octetBuffer, _octetBufferIndex, length);
1316            _octetBufferIndex += length;
1317        } else {
1318            if (_markIndex == -1) {
1319                _s.write(_octetBuffer, 0, _octetBufferIndex);
1320                _s.write(b, start, length);
1321                _octetBufferIndex = 0;
1322            } else {
1323                resize((_octetBuffer.length + length) * 3 / 2 + 1);
1324                System.arraycopy(b, start, _octetBuffer, _octetBufferIndex, length);
1325                _octetBufferIndex += length;
1326            }
1327        }
1328    }
1329
1330    protected final void writeToBuffer(byte[] b, int length) {
1331        ensureSize(length);
1332
1333        System.arraycopy(b, 0, _octetBuffer, _octetBufferIndex, length);
1334        _octetBufferIndex += length;
1335    }
1336
1337    protected final void ensureSize(int length) {
1338        if ((_octetBufferIndex + length) > _octetBuffer.length) {
1339            resize((_octetBufferIndex + length) * 3 / 2 + 1);
1340        }
1341    }
1342
1343    protected final void resize(int length) {
1344        byte[] b = new byte[length];
1345        System.arraycopy(_octetBuffer, 0, b, 0, _octetBufferIndex);
1346        _octetBuffer = b;
1347    }
1348
1349    protected final void _flush() throws IOException JavaDoc {
1350        if (_octetBufferIndex > 0) {
1351            _s.write(_octetBuffer, 0, _octetBufferIndex);
1352            _octetBufferIndex = 0;
1353        }
1354    }
1355
1356    protected class EncodingBufferOutputStream extends OutputStream JavaDoc {
1357
1358        public void write(int b) throws IOException JavaDoc {
1359            if (_encodingBufferIndex < _encodingBuffer.length) {
1360                _encodingBuffer[_encodingBufferIndex++] = (byte)b;
1361            } else {
1362                byte newbuf[] = new byte[Math.max(_encodingBuffer.length << 1, _encodingBufferIndex)];
1363                System.arraycopy(_encodingBuffer, 0, newbuf, 0, _encodingBufferIndex);
1364                _encodingBuffer = newbuf;
1365
1366                _encodingBuffer[_encodingBufferIndex++] = (byte)b;
1367            }
1368        }
1369
1370        public void write(byte b[], int off, int len) throws IOException JavaDoc {
1371            if ((off < 0) || (off > b.length) || (len < 0) ||
1372                ((off + len) > b.length) || ((off + len) < 0)) {
1373                throw new IndexOutOfBoundsException JavaDoc();
1374            } else if (len == 0) {
1375                return;
1376            }
1377            final int newoffset = _encodingBufferIndex + len;
1378            if (newoffset > _encodingBuffer.length) {
1379                byte newbuf[] = new byte[Math.max(_encodingBuffer.length << 1, newoffset)];
1380                System.arraycopy(_encodingBuffer, 0, newbuf, 0, _encodingBufferIndex);
1381                _encodingBuffer = newbuf;
1382            }
1383            System.arraycopy(b, off, _encodingBuffer, _encodingBufferIndex, len);
1384            _encodingBufferIndex = newoffset;
1385        }
1386
1387        public int getLength() {
1388            return _encodingBufferIndex;
1389        }
1390
1391        public void reset() {
1392            _encodingBufferIndex = 0;
1393        }
1394    }
1395
1396    protected EncodingBufferOutputStream _encodingBufferOutputStream = new EncodingBufferOutputStream();
1397
1398    protected byte[] _encodingBuffer = new byte[512];
1399
1400    protected int _encodingBufferIndex;
1401
1402    protected final void ensureEncodingBufferSizeForUtf8String(int length) {
1403        final int newLength = 4 * length;
1404        if (_encodingBuffer.length < newLength) {
1405            _encodingBuffer = new byte[newLength];
1406        }
1407    }
1408    
1409    protected final int encodeUTF8String(char[] ch, int start, int length) throws IOException JavaDoc {
1410        int bpos = 0;
1411
1412        // Make sure buffer is large enough
1413
ensureEncodingBufferSizeForUtf8String(length);
1414
1415        final int end = start + length;
1416        int c;
1417        while (end != start) {
1418            c = ch[start++];
1419            if (c < 0x80) {
1420                // 1 byte, 7 bits
1421
_encodingBuffer[bpos++] = (byte) c;
1422            } else if (c < 0x800) {
1423                // 2 bytes, 11 bits
1424
_encodingBuffer[bpos++] =
1425                    (byte) (0xC0 | (c >> 6)); // first 5
1426
_encodingBuffer[bpos++] =
1427                    (byte) (0x80 | (c & 0x3F)); // second 6
1428
} else if (c <= '\uFFFF') {
1429                if (!XMLChar.isHighSurrogate(c) && !XMLChar.isLowSurrogate(c)) {
1430                    // 3 bytes, 16 bits
1431
_encodingBuffer[bpos++] =
1432                        (byte) (0xE0 | (c >> 12)); // first 4
1433
_encodingBuffer[bpos++] =
1434                        (byte) (0x80 | ((c >> 6) & 0x3F)); // second 6
1435
_encodingBuffer[bpos++] =
1436                        (byte) (0x80 | (c & 0x3F)); // third 6
1437
} else {
1438                    // 4 bytes, high and low surrogate
1439
encodeCharacterAsUtf8FourByte(c, ch, start, end, bpos);
1440                    bpos += 4;
1441                    start++;
1442                }
1443            }
1444        }
1445
1446        return bpos;
1447    }
1448    
1449    protected final void encodeCharacterAsUtf8FourByte(int c, char[] ch, int chpos, int chend, int bpos) throws IOException JavaDoc {
1450        if (chpos == chend) {
1451            throw new IOException JavaDoc("");
1452        }
1453        
1454        final char d = ch[chpos];
1455        if (!XMLChar.isLowSurrogate(d)) {
1456            throw new IOException JavaDoc("");
1457        }
1458        
1459        final int uc = (((c & 0x3ff) << 10) | (d & 0x3ff)) + 0x10000;
1460        if (uc < 0 || uc >= 0x200000) {
1461            throw new IOException JavaDoc("");
1462        }
1463
1464        _encodingBuffer[bpos++] = (byte)(0xF0 | ((uc >> 18)));
1465        _encodingBuffer[bpos++] = (byte)(0x80 | ((uc >> 12) & 0x3F));
1466        _encodingBuffer[bpos++] = (byte)(0x80 | ((uc >> 6) & 0x3F));
1467        _encodingBuffer[bpos++] = (byte)(0x80 | (uc & 0x3F));
1468    }
1469        
1470    protected final void ensureEncodingBufferSizeForUtf16String(int length) {
1471        final int newLength = 2 * length;
1472        if (_encodingBuffer.length < newLength) {
1473            _encodingBuffer = new byte[newLength];
1474        }
1475    }
1476
1477    protected final int encodeUtf16String(char[] ch, int start, int length) throws IOException JavaDoc {
1478        int byteLength = 0;
1479
1480        // Make sure buffer is large enough
1481
ensureEncodingBufferSizeForUtf16String(length);
1482
1483        final int n = start + length;
1484        for (int i = start; i < n; i++) {
1485            final int c = (int) ch[i];
1486            _encodingBuffer[byteLength++] = (byte)(c >> 8);
1487            _encodingBuffer[byteLength++] = (byte)(c & 0xFF);
1488        }
1489
1490        return byteLength;
1491    }
1492    
1493    public static String JavaDoc getPrefixFromQualifiedName(String JavaDoc qName) {
1494        int i = qName.indexOf(':');
1495        String JavaDoc prefix = "";
1496        if (i != -1) {
1497            prefix = qName.substring(0, i);
1498        }
1499        return prefix;
1500    }
1501}
1502
Popular Tags