| 1 package org.jacorb.orb; 2 3 22 23 import java.io.IOException ; 24 import java.util.*; 25 26 import org.apache.avalon.framework.configuration.*; 27 import org.apache.avalon.framework.logger.*; 28 29 import org.jacorb.orb.giop.CodeSet; 30 import org.jacorb.util.ValueHandler; 31 import org.jacorb.ir.RepositoryID; 32 33 import org.omg.CORBA.BAD_PARAM ; 34 import org.omg.CORBA.INTERNAL ; 35 import org.omg.CORBA.MARSHAL ; 36 import org.omg.CORBA.NO_IMPLEMENT ; 37 import org.omg.CORBA.StructMember ; 38 import org.omg.CORBA.TCKind ; 39 import org.omg.CORBA.UnionMember ; 40 import org.omg.CORBA.ValueMember ; 41 import org.omg.CORBA.portable.IDLEntity ; 42 import org.omg.CORBA.TypeCodePackage.BadKind ; 43 import org.omg.CORBA.TypeCodePackage.Bounds ; 44 45 51 52 public class CDRInputStream 53 extends org.omg.CORBA_2_3.portable.InputStream  54 { 55 59 private int uniqueValue; 60 61 66 private Stack encaps_stack; 67 68 74 private Map recursiveTCMap; 75 76 88 private Map cachedTypecodes; 89 90 91 private int marked_pos; 92 private int marked_index; 93 94 private boolean closed; 95 96 97 private Logger logger; 98 private boolean useBOM; 99 private boolean cometInteropFix; 100 private boolean laxBooleanEncoding; 101 private boolean cacheTypecodes; 102 103 104 private int codeSet = CodeSet.getTCSDefault(); 105 private int codeSetW = CodeSet.getTCSWDefault(); 106 protected int giop_minor = 2; 108 114 private Map valueMap; 115 116 122 private int currentValueIndex; 123 124 130 private Map repIdMap; 131 132 138 private Map codebaseMap; 139 140 public boolean littleEndian = false; 141 142 143 protected byte[] buffer = null; 144 protected int pos = 0; 145 protected int index = 0; 146 147 148 private boolean chunkedValue = false; 149 150 151 private int valueNestingLevel = 0; 152 153 154 private int chunk_end_pos = -1; 156 157 162 private org.omg.CORBA.ORB orb = null; 163 164 public CDRInputStream(final org.omg.CORBA.ORB orb, final byte[] buf) 165 { 166 buffer = buf; 167 if (orb != null) 169 { 170 this.orb = orb; 171 if (orb instanceof org.jacorb.orb.ORB) 173 { 174 try 175 { 176 177 configure(((org.jacorb.orb.ORB)orb).getConfiguration()); 178 } 179 catch( ConfigurationException ce ) 180 { 181 throw new INTERNAL ("ConfigurationException: " + ce.getMessage()); 182 } 183 } 184 } 185 else 186 this.orb = org.omg.CORBA.ORB.init(); 187 } 188 189 public CDRInputStream(final org.omg.CORBA.ORB orb, 190 final byte[] buf, 191 final boolean littleEndian ) 192 { 193 this( orb, buf ); 194 this.littleEndian = littleEndian; 195 } 196 197 198 202 203 private void configure(Configuration configuration) 204 throws ConfigurationException 205 { 206 logger = 207 ((org.jacorb.config.Configuration)configuration).getNamedLogger("jacorb.orb.cdr"); 208 209 useBOM = 210 configuration.getAttribute("jacorb.use_bom","off").equals("on"); 211 cometInteropFix = 212 configuration.getAttribute("jacorb.interop.comet","off").equals("on"); 213 laxBooleanEncoding = 214 configuration.getAttribute("jacorb.interop.lax_boolean_encoding","off").equals("on"); 215 cacheTypecodes = 216 configuration.getAttribute("jacorb.cacheTypecodes","off").equals("on"); 217 } 218 219 220 221 222 228 private Stack getEncapsStack() 229 { 230 if (encaps_stack == null) 231 { 232 encaps_stack = new Stack(); 233 } 234 return encaps_stack; 235 } 236 237 238 243 private Map getRecursiveTCMap() 244 { 245 if (recursiveTCMap == null) 246 { 247 recursiveTCMap = new HashMap(); 248 } 249 return recursiveTCMap; 250 } 251 252 253 258 private Map getValueMap() 259 { 260 if (valueMap == null) 261 { 262 valueMap = new HashMap(); 265 } 266 return valueMap; 267 } 268 269 270 275 private Map getRepIdMap() 276 { 277 if (repIdMap == null) 278 { 279 repIdMap = new HashMap(); 280 } 281 return repIdMap; 282 } 283 284 285 291 private Map getCodebaseMap() 292 { 293 if (codebaseMap == null) 294 { 295 codebaseMap = new HashMap(); 296 } 297 return codebaseMap; 298 } 299 300 301 308 private org.omg.CORBA.TypeCode getCachedTypecode( String id ) 309 { 310 org.omg.CORBA.TypeCode result = null; 311 312 if ( cacheTypecodes ) 313 { 314 if ( cachedTypecodes == null ) 315 { 316 cachedTypecodes = new HashMap(); 317 } 318 else 319 { 320 result = ( org.omg.CORBA.TypeCode )cachedTypecodes.get( id ); 321 } 322 } 323 return result; 324 } 325 326 327 334 private void putCachedTypecode( String id, org.omg.CORBA.TypeCode result) 335 { 336 if ( cacheTypecodes ) 337 { 338 cachedTypecodes.put (id, result); 341 } 342 } 343 344 345 public void setGIOPMinor(final int giop_minor ) 346 { 347 this.giop_minor = giop_minor; 348 } 349 350 public int getGIOPMinor() 351 { 352 return giop_minor; 353 } 354 355 public void close() 356 throws IOException  357 { 358 if( closed ) 360 { 361 return; 362 } 363 364 BufferManager.getInstance().returnBuffer(buffer); 365 366 encaps_stack = null; 367 recursiveTCMap = null; 368 closed = true; 369 } 370 371 public org.omg.CORBA.ORB orb() 372 { 373 if (orb == null) orb = org.omg.CORBA.ORB.init(new String []{}, null); 374 return orb; 375 } 376 377 public void setCodeSet(final int codeSet, final int codeSetWide) 378 { 379 this.codeSet = codeSet; 380 this.codeSetW = codeSetWide; 381 } 382 383 private static final int _read4int 384 (final boolean _littleEndian, final byte[] _buffer, final int _pos) 385 { 386 if (_littleEndian) 387 return (((_buffer[_pos+3] & 0xff) << 24) + 388 ((_buffer[_pos+2] & 0xff) << 16) + 389 ((_buffer[_pos+1] & 0xff) << 8) + 390 ((_buffer[_pos] & 0xff) << 0)); 391 else 392 return (((_buffer[_pos] & 0xff) << 24) + 393 ((_buffer[_pos+1] & 0xff) << 16) + 394 ((_buffer[_pos+2] & 0xff) << 8) + 395 ((_buffer[_pos+3] & 0xff) << 0)); 396 } 397 398 private static final short _read2int 399 (final boolean _littleEndian, final byte[] _buffer, final int _pos) 400 { 401 if (_littleEndian) 402 return (short)(((_buffer[_pos+1] & 0xff) << 8) + 403 ((_buffer[_pos] & 0xff) << 0)); 404 else 405 return (short)(((_buffer[_pos ] & 0xff) << 8) + 406 ((_buffer[_pos + 1] & 0xff) << 0)); 407 } 408 409 private final int _read_long() 410 { 411 int result; 412 413 result = _read4int (littleEndian, buffer, pos); 414 415 index += 4; 416 pos += 4; 417 return result; 418 } 419 420 private final long _read_longlong() 421 { 422 if (littleEndian) 423 { 424 return ((long) _read_long() & 0xFFFFFFFFL) + ((long) _read_long() << 32); 425 } 426 else 427 { 428 return ((long) _read_long() << 32) + ((long) _read_long() & 0xFFFFFFFFL); 429 } 430 } 431 432 private final void handle_chunking() 433 { 434 int remainder = 4 - (index % 4); 435 int aligned_pos = (remainder != 4) ? pos + remainder : pos; 436 437 if (chunk_end_pos >= pos && chunk_end_pos <= aligned_pos) 438 { 439 chunk_end_pos = -1; 440 int saved_pos = pos; 441 int saved_index = index; 442 int tag = read_long(); 443 444 if (tag < 0) { 445 446 448 if ( ! (-tag <= valueNestingLevel)) 449 { 450 throw new INTERNAL  451 ( 452 "received end tag " + tag + 453 " with value nesting level " + 454 valueNestingLevel 455 ); 456 } 457 valueNestingLevel = - tag; 458 valueNestingLevel--; 459 460 if (valueNestingLevel > 0) 461 { 462 chunk_end_pos = pos; 463 handle_chunking(); 464 } 465 } 466 else if (tag < 0x7fffff00) 467 { 468 470 chunk_end_pos = pos + tag; 471 } 472 else { 474 476 pos = saved_pos; index = saved_index; 478 } 479 } 480 } 481 482 protected final void skip(final int distance) 483 { 484 pos += distance; 485 index += distance; 486 } 487 488 492 493 public final void closeEncapsulation() 494 { 495 if (encaps_stack == null) 496 { 497 throw new MARSHAL ( "Internal Error - closeEncapsulation failed" ); 498 } 499 500 EncapsInfo ei = (EncapsInfo)encaps_stack.pop(); 501 littleEndian = ei.littleEndian; 502 int size = ei.size; 503 int start = ei.start; 504 505 if( pos < start + size ) 506 pos = start + size; 507 508 index = ei.index + size; 509 } 510 511 515 516 public final int openEncapsulation() 517 { 518 boolean old_endian = littleEndian; 519 int _pos = pos; 520 int size = read_long(); 521 522 526 if (cometInteropFix && ((size < 0) || (size > buffer.length))) 527 { 528 int temp = 529 ( 530 ((size >> 24) & 0x000000FF) + 531 ((size >> 8) & 0x0000FF00) + 532 ((size << 8) & 0x00FF0000) + 533 ((size << 24) & 0xFF000000) 534 ); 535 536 if (logger.isDebugEnabled()) 537 { 538 logger.debug("Size of CDR encapsulation larger than buffer, swapping byte order\n" + 539 "Size of CDR encapsulation was " + size + ", is now " + temp); 540 } 541 542 size = temp; 543 } 544 547 548 if (encaps_stack == null) 549 { 550 encaps_stack = new Stack(); 551 } 552 encaps_stack.push(new EncapsInfo(old_endian, index, pos, size )); 553 554 openEncapsulatedArray(); 555 556 return size; 557 } 558 559 public final void openEncapsulatedArray() 560 { 561 563 resetIndex(); 564 littleEndian = read_boolean(); 565 } 566 567 568 573 public byte[] getBufferCopy() 574 { 575 byte[] result = new byte[buffer.length]; 576 System.arraycopy 577 ( 578 buffer, 579 0, 580 result, 581 0, 582 buffer.length 583 ); 584 return result; 585 } 586 587 596 public int read() 597 throws java.io.IOException  598 { 599 if( closed ) 600 throw new java.io.IOException ("Stream already closed!"); 601 602 if( available() < 1 ) 603 return -1; 604 605 ++index; 606 return buffer[pos++]; } 608 609 613 public int available() 614 { 615 return buffer.length - index; 616 } 617 618 622 public int read(final byte[] b) 623 throws java.io.IOException  624 { 625 return read(b, 0, b.length); 626 } 627 628 632 public int read(final byte[] b, final int off, final int len) 633 throws java.io.IOException  634 { 635 if( b == null ) 636 throw new NullPointerException (); 637 638 if( off < 0 || 639 len < 0 || 640 off + len > b.length ) 641 throw new IndexOutOfBoundsException (); 642 643 if( len == 0 ) 644 return 0; 645 646 if( available() < 1 ) 647 return -1; 648 649 if( closed ) 650 throw new java.io.IOException ("Stream already closed!"); 651 652 int min = ( len < available() ? len : available()); 653 System.arraycopy(buffer, index, b, off, min ); 654 pos += min; 655 index += min; 656 return min; 657 } 658 659 660 public final org.omg.CORBA.Any read_any() 661 { 662 org.omg.CORBA.TypeCode _tc = read_TypeCode(); 663 org.omg.CORBA.Any any = orb.create_any(); 664 any.read_value( this, _tc ); 665 return any; 666 } 667 668 public final boolean read_boolean() 669 { 670 handle_chunking(); 671 index++; 672 byte bb = buffer[pos++]; 673 674 if (bb == 0) 675 { 676 return false; 677 } 678 else 679 { 680 if (bb == 1) 681 { 682 return true; 683 } 684 else 685 { 686 if (laxBooleanEncoding) 687 { 688 return true; 691 } 692 else 693 { 694 throw new MARSHAL ("Unexpected boolean value: " + bb 695 + " pos: " + pos + " index: " + index); 696 } 697 } 698 } 699 } 700 701 702 703 public final void read_boolean_array 704 (final boolean[] value, final int offset, final int length) 705 { 706 handle_chunking(); 707 byte bb; 708 for (int j = offset; j < offset + length; j++) 709 { 710 index++; 711 bb = buffer[pos++]; 712 if (bb == 1) 713 { 714 value[j] = true; 715 } 716 else if (bb == 0) 717 { 718 value[j] = false; 719 } 720 else 721 { 722 throw new MARSHAL ("Unexpected boolean value: " + bb 723 + " pos: " + pos + " index: " + index); 724 } 725 } 726 } 727 728 public final char read_char() 729 { 730 handle_chunking(); 731 index++; 732 return (char)(0xff & buffer[pos++]); 733 } 734 735 public final void read_char_array 736 (final char[] value, final int offset, final int length) 737 { 738 handle_chunking(); 739 for (int j = offset; j < offset + length; j++) 740 { 741 index++; 742 value[j] = (char) (0xff & buffer[pos++]); 743 } 744 } 745 746 public final double read_double() 747 { 748 return Double.longBitsToDouble (read_longlong()); 749 } 750 751 public final void read_double_array 752 (final double[] value, final int offset, final int length) 753 { 754 if (length == 0) 755 return; 756 757 handle_chunking(); 758 759 int remainder = 8 - (index % 8); 760 if (remainder != 8) 761 { 762 index += remainder; 763 pos += remainder; 764 } 765 766 for (int j = offset; j < offset + length; j++) 767 { 768 value[j] = Double.longBitsToDouble (_read_longlong()); 769 } 770 } 771 772 public final java.math.BigDecimal read_fixed() 773 { 774 handle_chunking(); 775 776 StringBuffer sb = new StringBuffer (); 777 778 int b = buffer[pos++]; 779 int c = b & 0x0F; index++; 781 782 while(true) 783 { 784 c = (b & 0xF0) >>> 4; 785 sb.append(c ); 786 c = b & 0x0F; 787 if( c == 0xC || c == 0xD ) 788 break; 789 sb.append(c ); 790 b = buffer[pos++]; 791 index++; 792 } 793 794 java.math.BigDecimal result = 795 new java.math.BigDecimal ( new java.math.BigInteger ( sb.toString())); 796 797 if( c == 0xD ) 798 return result.negate(); 799 else 800 return result; 801 802 } 803 804 public final float read_float() 805 { 806 return Float.intBitsToFloat (read_long()); 807 } 808 809 public final void read_float_array 810 (final float[] value, final int offset, final int length) 811 { 812 if (length == 0) 813 return; 814 815 handle_chunking(); 816 817 int remainder = 4 - (index % 4); 818 if (remainder != 4) 819 { 820 index += remainder; 821 pos += remainder; 822 } 823 824 for (int j = offset; j < offset + length; j++) 825 { 826 value[j] = Float.intBitsToFloat (_read_long()); 827 } 828 } 829 830 public final int read_long() 831 { 832 handle_chunking(); 833 834 int result; 835 836 int remainder = 4 - (index % 4); 837 if (remainder != 4) 838 { 839 index += remainder; 840 pos += remainder; 841 } 842 843 result = _read4int (littleEndian, buffer, pos); 844 845 index += 4; 846 pos += 4; 847 return result; 848 } 849 850 public final void read_long_array 851 (final int[] value, final int offset, final int length) 852 { 853 if (length == 0) 854 return; 855 856 handle_chunking(); 857 858 int remainder = 4 - (index % 4); 859 if (remainder != 4) 860 { 861 index += remainder; 862 pos += remainder; 863 } 864 865 for (int j = offset; j < offset+length; j++) 866 { 867 value[j] = _read4int (littleEndian,buffer,pos); 868 pos += 4; 869 } 870 871 index += 4 * length; 872 } 873 874 875 public final long read_longlong() 876 { 877 handle_chunking(); 878 879 int remainder = 8 - (index % 8); 880 if (remainder != 8) 881 { 882 index += remainder; 883 pos += remainder; 884 } 885 886 if (littleEndian) 887 { 888 return ((long) _read_long() & 0xFFFFFFFFL) + ((long) _read_long() << 32); 889 } 890 else 891 { 892 return ((long) _read_long() << 32) + ((long) _read_long() & 0xFFFFFFFFL); 893 } 894 } 895 896 public final void read_longlong_array 897 (final long[] value, final int offset, final int length) 898 { 899 if (length == 0) 900 return; 901 902 handle_chunking(); 903 904 int remainder = 8 - (index % 8); 905 if (remainder != 8) 906 { 907 index += remainder; 908 pos += remainder; 909 } 910 911 if (littleEndian) 912 { 913 for(int j=offset; j < offset+length; j++) 914 { 915 value[j] = ( (long) _read_long() & 0xFFFFFFFFL) + 916 ((long) _read_long() << 32); 917 } 918 } 919 else 920 { 921 for(int j=offset; j < offset+length; j++) 922 { 923 value[j] = ((long) _read_long() << 32) + 924 ((long) _read_long() & 0xFFFFFFFFL); 925 } 926 } 927 928 } 930 931 public final org.omg.CORBA.Object read_Object() 932 { 933 handle_chunking(); 934 935 org.omg.IOP.IOR ior = org.omg.IOP.IORHelper.read(this); 936 ParsedIOR pior = new ParsedIOR( ior, (org.jacorb.orb.ORB)orb, logger ); 937 938 if( pior.isNull() ) 939 { 940 return null; 941 } 942 else 943 { 944 if( !(orb instanceof org.jacorb.orb.ORB)) 945 { 946 throw new MARSHAL ( "Cannot use the singleton ORB to receive object references, please initialize a full ORB instead."); 947 } 948 else 949 &nbs
|