| 1 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 ; 51 import java.io.OutputStream ; 52 import java.util.HashMap ; 53 import java.util.Map ; 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 ; 62 63 public abstract class Encoder extends DefaultHandler implements FastInfosetSerializer { 64 65 public static final String CHARACTER_ENCODING_SCHEME_SYSTEM_PROPERTY = 67 "com.sun.xml.fastinfoset.serializer.character-encoding-scheme"; 68 69 protected static String _characterEncodingSchemeSystemDefault = UTF_8; 70 71 static { 72 String 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 (); 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 _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 111 public Encoder() { 112 setCharacterEncodingScheme(_characterEncodingSchemeSystemDefault); 113 } 114 115 public void reset() { 116 _terminate = false; 117 } 118 119 public void setCharacterEncodingScheme(String 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 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 (); 139 } 140 } 141 142 public Map getRegisteredEncodingAlgorithms() { 143 return _registeredEncodingAlgorithms; 144 } 145 146 public void setExternalVocabulary(ReferencedVocabulary referencedVocabulary) { 147 throw new UnsupportedOperationException (); 148 } 149 150 public void setIntitialVocabulary(Vocabulary initialVocabulary) { 151 throw new UnsupportedOperationException (); 152 } 153 154 public void setDynamicVocabulary(Vocabulary dynamicVocabulary) { 155 throw new UnsupportedOperationException (); 156 } 157 158 public Vocabulary getDynamicVocabulary() { 159 throw new UnsupportedOperationException (); 160 } 161 162 public Vocabulary getFinalVocabulary() { 163 throw new UnsupportedOperationException (); 164 } 165 166 167 168 public void setOutputStream(OutputStream 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 { 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 { 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 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 } 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 { 251 encodeElementTermination(); 252 encodeTermination(); 253 _flush(); 254 _s.flush(); 255 } 256 257 protected final void encodeElementTermination() throws IOException { 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 { 271 if (_terminate) { 272 write(_b); 273 _terminate = false; 274 } 275 } 276 277 protected final void encodeNamespaceAttribute(String prefix, String uri) throws IOException { 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 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 { 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 { 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 { 312 _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 _b = id << 2; 320 321 encodeNonEmptyFourBitCharacterStringOnSeventhBit(table, ch, start, length); 322 } 323 324 protected final void encodeAlphabetCharacters(String alphabet, char[] ch, int start, int length) throws FastInfosetException, IOException { 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 _b = (id & 0x3F) << 2; 339 340 encodeNonEmptyNBitCharacterStringOnSeventhBit(alphabet, ch, start, length); 341 } 342 343 protected final void encodeProcessingInstruction(String target, String data) throws IOException { 344 write(EncodingConstants.PROCESSING_INSTRUCTION); 345 346 encodeIdentifyingNonEmptyStringOnFirstBit(target, _v.otherNCName); 348 349 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 { 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 { 362 write(EncodingConstants.COMMENT); 363 364 boolean addToTable = (length < characterContentChunkSizeContraint) ? true : false; 365 encodeNonIdentifyingStringOnFirstBit(ch, start, length, _v.otherString, addToTable, false); 366 } 367 368 371 protected final void encodeElementQualifiedNameOnThirdBit(String namespaceURI, String prefix, String localName) throws IOException { 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 391 protected final void encodeLiteralElementQualifiedNameOnThirdBit(String namespaceURI, String prefix, String localName, 392 LocalNameQualifiedNamesMap.Entry entry) throws IOException { 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 (CommonResourceBundle.getInstance().getString("message.namespaceURINotIndexed", new Object []{namespaceURI})); 402 } 403 404 if (prefix != "") { 405 prefixIndex = _v.prefix.get(prefix); 406 if (prefixIndex == KeyIntMap.NOT_PRESENT) { 407 throw new IOException (CommonResourceBundle.getInstance().getString("message.prefixNotIndexed", new Object []{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 440 protected final void encodeAttributeQualifiedNameOnSecondBit(String namespaceURI, String prefix, String localName) throws IOException { 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 460 protected final boolean encodeLiteralAttributeQualifiedNameOnSecondBit(String namespaceURI, String prefix, String localName, 461 LocalNameQualifiedNamesMap.Entry entry) throws IOException { 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 (CommonResourceBundle.getInstance().getString("message.namespaceURINotIndexed", new Object []{namespaceURI})); 472 } 473 } 474 475 if (prefix != "") { 476 prefixIndex = _v.prefix.get(prefix); 477 if (prefixIndex == KeyIntMap.NOT_PRESENT) { 478 throw new IOException (CommonResourceBundle.getInstance().getString("message.prefixNotIndexed", new Object []{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 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 521 protected final void encodeNonIdentifyingStringOnFirstBit(String s, StringIntMap map, boolean addToTable) throws IOException { 522 if (s == null || s.length() == 0) { 523 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 544 protected final void encodeNonIdentifyingStringOnFirstBit(String s, CharArrayIntMap map, boolean addToTable) throws IOException { 545 if (s == null || s.length() == 0) { 546 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 569 protected final void encodeNonIdentifyingStringOnFirstBit(char[] array, int start, int length, CharArrayIntMap map, 570 boolean addToTable, boolean clone) throws IOException { 571 if (length == 0) { 572 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 593 protected final void encodeNonIdentifyingStringOnFirstBit(String URI, int id, Object data) throws FastInfosetException, IOException { 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 []{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 (CommonResourceBundle.getInstance().getString("message.CDATA")); 645 default: 646 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.UnsupportedBuiltInAlgorithm", new Object []{new Integer (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 { 662 write (EncodingConstants.NISTRING_ENCODING_ALGORITHM_FLAG | 664 ((id & 0xF0) >> 4)); 665 666 _b = (id & 0x0F) << 4; 668 669 encodeNonZeroOctetStringLengthOnFifthBit(length); 671 672 write(d, start, length); 673 } 674 675 protected final void encodeAIIObjectAlgorithmData(String URI, int id, Object data, EncodingAlgorithm ea) throws FastInfosetException, IOException { 676 write (EncodingConstants.NISTRING_ENCODING_ALGORITHM_FLAG | 678 ((id & 0xF0) >> 4)); 679 680 _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 o, int start, int length) throws IOException { 690 write (EncodingConstants.NISTRING_ENCODING_ALGORITHM_FLAG | 692 ((id & 0xF0) >> 4)); 693 694 _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 711 protected final void encodeNonIdentifyingStringOnThirdBit(char[] array, int start, int length, 712 CharArrayIntMap map, boolean addToTable, boolean clone) throws IOException { 713 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 URI, int id, Object data) throws FastInfosetException, IOException { 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 []{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 |