1 /* AbstractCdrInput.java -- 2 Copyright (C) 2005 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package gnu.CORBA.CDR; 40 41 import gnu.CORBA.BigDecimalHelper; 42 import gnu.CORBA.OrbFunctional; 43 import gnu.CORBA.GIOP.CharSets_OSF; 44 import gnu.CORBA.GIOP.CodeSetServiceContext; 45 import gnu.CORBA.IOR; 46 import gnu.CORBA.IorDelegate; 47 import gnu.CORBA.Minor; 48 import gnu.CORBA.TypeCodeHelper; 49 import gnu.CORBA.Unexpected; 50 import gnu.CORBA.Version; 51 import gnu.CORBA.gnuAny; 52 import gnu.CORBA.StubLocator; 53 54 import org.omg.CORBA.Any; 55 import org.omg.CORBA.AnySeqHolder; 56 import org.omg.CORBA.BAD_OPERATION; 57 import org.omg.CORBA.BooleanSeqHolder; 58 import org.omg.CORBA.CharSeqHolder; 59 import org.omg.CORBA.DoubleSeqHolder; 60 import org.omg.CORBA.FloatSeqHolder; 61 import org.omg.CORBA.LongLongSeqHolder; 62 import org.omg.CORBA.LongSeqHolder; 63 import org.omg.CORBA.MARSHAL; 64 import org.omg.CORBA.ORB; 65 import org.omg.CORBA.OctetSeqHolder; 66 import org.omg.CORBA.ShortSeqHolder; 67 import org.omg.CORBA.TypeCode; 68 import org.omg.CORBA.TypeCodePackage.BadKind; 69 import org.omg.CORBA.TypeCodePackage.Bounds; 70 import org.omg.CORBA.ULongLongSeqHolder; 71 import org.omg.CORBA.ULongSeqHolder; 72 import org.omg.CORBA.UShortSeqHolder; 73 import org.omg.CORBA.WCharSeqHolder; 74 import org.omg.CORBA.portable.InputStream; 75 import org.omg.CORBA.portable.ObjectImpl; 76 77 import java.io.EOFException; 78 import java.io.IOException; 79 import java.io.InputStreamReader; 80 import java.io.Serializable; 81 82 import java.math.BigDecimal; 83 84 /** 85 * A simple CORBA CDR (common data representation) input stream, reading data 86 * from the given {@link java.io.InputStream}. The primitive types are aligned 87 * on they natural boundaries by implementing the abstract method 88 * {@link #align(int boundary)}. 89 * 90 * The same class also implements {@link org.omg.CORBA.DataInputStream} to read 91 * the object content in a user defined way. 92 * 93 * TODO This class uses 16 bits per Unicode character only, as it was until jdk 94 * 1.4 inclusive. 95 * 96 * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) 97 */ 98 public abstract class AbstractCdrInput 99 extends org.omg.CORBA_2_3.portable.InputStream 100 implements org.omg.CORBA.DataInputStream 101 { 102 /** 103 * The runtime, associated with this stream. This field is only used when 104 * reading and writing value types and filled-in in gnu.CORBA.CDR.Vio. 105 */ 106 public transient gnuRuntime runtime; 107 108 /** 109 * The message, explaining that the exception has been thrown due unexpected 110 * end of the input stream. This usually happens the server and client 111 * disagree on communication or data representation rules. 112 */ 113 protected static final String UNEXP_EOF = "Unexpected end of stream"; 114 115 /** 116 * This instance is used to convert primitive data types into the byte 117 * sequences. 118 */ 119 protected AbstractDataInput b; 120 121 /** 122 * The input stream, from where the data are actually being read. 123 */ 124 protected java.io.InputStream actual_stream; 125 126 /** 127 * The associated orb, if any. 128 */ 129 protected ORB orb; 130 131 /** 132 * The GIOP version. 133 */ 134 protected Version giop = new Version(1, 2); 135 136 /** 137 * The code set information. 138 */ 139 protected CodeSetServiceContext codeset = CodeSetServiceContext.STANDARD; 140 141 /** 142 * The name of the currently used narrow charset, null if the native narrow 143 * charset is used. 144 */ 145 private String narrow_charset = null; 146 147 /** 148 * The name of the currently used wide charset, null if the native wide 149 * charset is used. 150 */ 151 private String wide_charset = null; 152 153 /** 154 * True if the native code set is used for narrow characters. If the set is 155 * native, no the intermediate Reader object is instantiated when writing 156 * characters. 157 */ 158 private boolean narrow_native; 159 160 /** 161 * True if the native code set is used for wide characters. If the set is 162 * native, no the intermediate Reader object is instantiated when writing 163 * characters. 164 */ 165 private boolean wide_native; 166 167 /** 168 * If true, the stream expect the multi-byte data in the form "less 169 * significant byte first" (Little Endian). This is the opposite to the java 170 * standard (Big Endian). 171 */ 172 private boolean little_endian; 173 174 /** 175 * Creates the stream. The stream reads Big Endian by default. 176 * 177 * @param readFrom a stream to read CORBA input from. 178 */ AbstractCdrInput(java.io.InputStream readFrom)179 public AbstractCdrInput(java.io.InputStream readFrom) 180 { 181 setInputStream(readFrom); 182 setCodeSet(CodeSetServiceContext.STANDARD); 183 } 184 185 /** 186 * Creates the stream, requiring the subsequent call of 187 * {@link #setInputStream(java.io.InputStream)}. 188 */ AbstractCdrInput()189 public AbstractCdrInput() 190 { 191 setCodeSet(CodeSetServiceContext.STANDARD); 192 } 193 194 /** 195 * Set the Big Endian or Little Endian encoding. The stream reads Big Endian 196 * by default. 197 * 198 * @param use_big_endian if true, the stream expect the multi-byte data in 199 * the form "most significant byte first" (Big Endian). This is the 200 * java standard. 201 */ setBigEndian(boolean use_big_endian)202 public void setBigEndian(boolean use_big_endian) 203 { 204 little_endian = !use_big_endian; 205 setInputStream(actual_stream); 206 } 207 208 /** 209 * Get the used encoding. 210 * 211 * @return true for Big Endian, false for Little Endian. 212 */ isBigEndian()213 public boolean isBigEndian() 214 { 215 return !little_endian; 216 } 217 218 /** 219 * Clone all important settings to another stream. 220 */ cloneSettings(AbstractCdrInput stream)221 public void cloneSettings(AbstractCdrInput stream) 222 { 223 stream.setBigEndian(isBigEndian()); 224 stream.setCodeSet(getCodeSet()); 225 stream.setVersion(giop); 226 stream.setOrb(orb); 227 } 228 229 /** 230 * Set the input stream that receives the CORBA input. 231 * 232 * @param readFrom the stream. 233 */ setInputStream(java.io.InputStream readFrom)234 public void setInputStream(java.io.InputStream readFrom) 235 { 236 if (little_endian) 237 b = new LittleEndianInputStream(readFrom); 238 else 239 b = new BigEndianInputStream(readFrom); 240 241 actual_stream = readFrom; 242 } 243 244 /** 245 * Set the alignment offset, if the index of the first byte in the stream is 246 * different from 0. 247 */ setOffset(int offset)248 public abstract void setOffset(int offset); 249 250 /** 251 * Set the orb, associated with this stream. 252 * 253 * @param an_orb 254 */ setOrb(ORB an_orb)255 public void setOrb(ORB an_orb) 256 { 257 orb = an_orb; 258 } 259 260 /** 261 * Set the GIOP version. Some data types are written differently for the 262 * different versions. The default version is 1.0 . 263 */ setVersion(Version giop_version)264 public void setVersion(Version giop_version) 265 { 266 giop = giop_version; 267 } 268 269 /** 270 * Align the curretn position at the given natural boundary. 271 */ align(int boundary)272 public abstract void align(int boundary); 273 274 /** 275 * Reads the CORBA unsigned long (java int), returning the value in the 276 * sufficiently large java long. 277 */ gnu_read_ulong()278 public long gnu_read_ulong() 279 { 280 try 281 { 282 long l = b.readInt(); 283 l &= 0xFFFFFFF; 284 return l; 285 } 286 catch (EOFException ex) 287 { 288 MARSHAL t = new MARSHAL(UNEXP_EOF); 289 t.minor = Minor.EOF; 290 t.initCause(ex); 291 throw t; 292 } 293 catch (IOException ex) 294 { 295 throw new Unexpected(ex); 296 } 297 } 298 299 /** 300 * Read the unsigned short integer value and return it as java int, 301 * sufficiently large to hold all values. 302 */ gnu_read_ushort()303 public int gnu_read_ushort() 304 { 305 try 306 { 307 align(2); 308 return b.readUnsignedShort(); 309 } 310 catch (EOFException ex) 311 { 312 MARSHAL t = new MARSHAL(UNEXP_EOF); 313 t.minor = Minor.EOF; 314 t.initCause(ex); 315 throw t; 316 } 317 318 catch (IOException ex) 319 { 320 throw new Unexpected(ex); 321 } 322 } 323 324 /** 325 * Return the associated {@link ORB}. 326 * 327 * @return the associated {@link ORB} or null is no such is set. 328 */ orb()329 public ORB orb() 330 { 331 return orb; 332 } 333 334 /** 335 * Read a single byte directly from the buffer. 336 */ read()337 public int read() 338 throws java.io.IOException 339 { 340 try 341 { 342 return b.read(); 343 } 344 catch (EOFException ex) 345 { 346 MARSHAL t = new MARSHAL(UNEXP_EOF); 347 t.minor = Minor.EOF; 348 t.initCause(ex); 349 throw t; 350 } 351 } 352 353 /** 354 * Read bytes directly from the buffer. 355 */ read(byte[] x, int ofs, int len)356 public int read(byte[] x, int ofs, int len) 357 throws java.io.IOException 358 { 359 try 360 { 361 return b.read(x, ofs, len); 362 } 363 catch (EOFException ex) 364 { 365 MARSHAL t = new MARSHAL(UNEXP_EOF); 366 t.minor = Minor.EOF; 367 t.initCause(ex); 368 throw t; 369 } 370 } 371 372 /** 373 * Read bytes directly from the buffer. 374 */ read(byte[] x)375 public int read(byte[] x) 376 throws java.io.IOException 377 { 378 try 379 { 380 return b.read(x); 381 } 382 catch (EOFException ex) 383 { 384 MARSHAL t = new MARSHAL(UNEXP_EOF); 385 t.minor = Minor.EOF; 386 t.initCause(ex); 387 throw t; 388 } 389 } 390 391 /** 392 * Read the CORBA object. The object to read is represented in the form of the 393 * plain (not a string-encoded) IOR profile without the heading endian 394 * indicator. The responsible method for reading such data is 395 * {@link IOR.read_no_endian}. 396 * 397 * The returned object is usually casted into the given type using the .narrow 398 * method of its helper, despite in some cases the direct cast would also 399 * work. 400 * 401 * The null objects are recognised from the empty profile set. For such 402 * objects, null is returned. 403 * 404 * @return the loaded and constructed object. 405 */ read_Object()406 public org.omg.CORBA.Object read_Object() 407 { 408 try 409 { 410 IOR ior = new IOR(); 411 ior._read_no_endian(this); 412 413 if (ior.Id == null) 414 return null; 415 416 // Check maybe this is a remote reference to the local object. 417 // This is only possible if we access the repository of the 418 // connected object. 419 if (orb instanceof OrbFunctional) 420 { 421 OrbFunctional forb = (OrbFunctional) orb; 422 org.omg.CORBA.Object local = forb.find_local_object(ior); 423 if (local != null) 424 return local; 425 } 426 427 // Search for the available stubs. 428 ObjectImpl impl = StubLocator.search(orb, ior); 429 try 430 { 431 if (impl._get_delegate() == null) 432 impl._set_delegate(new IorDelegate(orb, ior)); 433 } 434 catch (BAD_OPERATION ex) 435 { 436 // Some colaborants may throw this exception 437 // in response to the attempt to get the unset delegate. 438 impl._set_delegate(new IorDelegate(orb, ior)); 439 } 440 441 return impl; 442 } 443 catch (IOException ex) 444 { 445 MARSHAL bad = new MARSHAL(); 446 bad.minor = Minor.IOR; 447 bad.initCause(ex); 448 throw bad; 449 } 450 } 451 452 /** 453 * Read the type code. The type code format is defined in the CORBA 454 * documenation. 455 */ read_TypeCode()456 public TypeCode read_TypeCode() 457 { 458 try 459 { 460 return TypeCodeHelper.read(this); 461 } 462 463 catch (Bounds ex) 464 { 465 throw new Unexpected(); 466 } 467 catch (BadKind ex) 468 { 469 throw new Unexpected(); 470 } 471 } 472 473 /** 474 * Read the CORBA {@link Any}. This method first reads the type code, then 475 * delegates the functionality to {@link Any#read_value}. 476 */ read_any()477 public Any read_any() 478 { 479 TypeCode ty = read_TypeCode(); 480 gnuAny any = new gnuAny(); 481 any.read_value(this, ty); 482 return any; 483 } 484 485 /** 486 * Read the boolean, treating any non zero byte as true, zero byte as false. 487 */ read_boolean()488 public boolean read_boolean() 489 { 490 try 491 { 492 return b.read() == 0 ? false : true; 493 } 494 catch (EOFException ex) 495 { 496 MARSHAL t = new MARSHAL(UNEXP_EOF); 497 t.minor = Minor.EOF; 498 t.initCause(ex); 499 throw t; 500 } 501 catch (IOException ex) 502 { 503 throw new Unexpected(ex); 504 } 505 } 506 507 /** 508 * Read the array of boolean. 509 */ read_boolean_array(boolean[] x, int offs, int len)510 public void read_boolean_array(boolean[] x, int offs, int len) 511 { 512 try 513 { 514 for (int i = offs; i < offs + len; i++) 515 { 516 x[i] = b.read() == 0 ? false : true; 517 } 518 } 519 catch (EOFException ex) 520 { 521 MARSHAL t = new MARSHAL(UNEXP_EOF); 522 t.minor = Minor.EOF; 523 t.initCause(ex); 524 throw t; 525 } 526 527 catch (IOException ex) 528 { 529 throw new Unexpected(ex); 530 } 531 } 532 533 /** 534 * Read a character using narrow charset encoding. Depending form which 535 * encoding is set, this still can be Unicode or ever wider. 536 */ read_char()537 public char read_char() 538 { 539 try 540 { 541 if (narrow_native) 542 return (char) b.read(); 543 else 544 return (char) new InputStreamReader((InputStream) b, narrow_charset).read(); 545 } 546 catch (EOFException ex) 547 { 548 MARSHAL t = new MARSHAL(UNEXP_EOF); 549 t.minor = Minor.EOF; 550 t.initCause(ex); 551 throw t; 552 } 553 554 catch (IOException ex) 555 { 556 throw new Unexpected(ex); 557 } 558 } 559 560 /** 561 * Read a character array, using narrow charset encoding. 562 */ read_char_array(char[] x, int offset, int length)563 public void read_char_array(char[] x, int offset, int length) 564 { 565 try 566 { 567 if (narrow_native) 568 { 569 for (int i = offset; i < offset + length; i++) 570 x[i] = (char) b.read(); 571 } 572 else 573 { 574 InputStreamReader reader = new InputStreamReader((InputStream) b, 575 narrow_charset); 576 reader.read(x, offset, length); 577 } 578 } 579 catch (EOFException ex) 580 { 581 MARSHAL t = new MARSHAL(UNEXP_EOF); 582 t.minor = Minor.EOF; 583 t.initCause(ex); 584 throw t; 585 } 586 587 catch (IOException ex) 588 { 589 throw new Unexpected(ex); 590 } 591 } 592 593 /** 594 * Read the double value, IEEE 754 format. 595 */ read_double()596 public double read_double() 597 { 598 try 599 { 600 align(8); 601 return b.readDouble(); 602 } 603 catch (EOFException ex) 604 { 605 MARSHAL t = new MARSHAL(UNEXP_EOF); 606 t.minor = Minor.EOF; 607 t.initCause(ex); 608 throw t; 609 } 610 611 catch (IOException ex) 612 { 613 throw new Unexpected(); 614 } 615 } 616 617 /** 618 * Read the array of double values, IEEE 754 format. 619 */ read_double_array(double[] x, int offs, int len)620 public void read_double_array(double[] x, int offs, int len) 621 { 622 try 623 { 624 align(8); 625 for (int i = offs; i < offs + len; i++) 626 { 627 x[i] = b.readDouble(); 628 } 629 } 630 catch (EOFException ex) 631 { 632 MARSHAL t = new MARSHAL(UNEXP_EOF); 633 t.minor = Minor.EOF; 634 t.initCause(ex); 635 throw t; 636 } 637 638 catch (IOException ex) 639 { 640 throw new Unexpected(ex); 641 } 642 } 643 644 /** 645 * Read the encapsulated stream. If the encapsulated sequence appears to be in 646 * the Little endian format, the flag of the returned stream is set to read 647 * Little endian. 648 */ read_encapsulation()649 public BufferredCdrInput read_encapsulation() 650 { 651 try 652 { 653 int l = read_long(); 654 655 byte[] r = new byte[l]; 656 int n = 0; 657 while (n < r.length) 658 { 659 n += read(r, n, r.length - n); 660 } 661 662 BufferredCdrInput capsule = new BufferredCdrInput(r); 663 capsule.setOrb(orb); 664 665 int endian = capsule.read_octet(); 666 667 if (endian != 0) 668 { 669 capsule.setBigEndian(false); 670 } 671 672 return capsule; 673 } 674 catch (EOFException ex) 675 { 676 MARSHAL t = new MARSHAL(UNEXP_EOF); 677 t.minor = Minor.EOF; 678 t.initCause(ex); 679 throw t; 680 } 681 682 catch (IOException ex) 683 { 684 throw new Unexpected(ex); 685 } 686 } 687 688 /** 689 * Read the CORBA fixed (the end of the <code>fixed</code> can be determined 690 * by its last byte). The scale is always assumed to be zero. 691 */ read_fixed()692 public BigDecimal read_fixed() 693 { 694 try 695 { 696 return BigDecimalHelper.read(this, 0); 697 } 698 catch (EOFException ex) 699 { 700 MARSHAL t = new MARSHAL(UNEXP_EOF); 701 t.minor = Minor.EOF; 702 t.initCause(ex); 703 throw t; 704 } 705 706 catch (IOException ex) 707 { 708 throw new Unexpected(ex); 709 } 710 } 711 712 /** 713 * Read the float value, IEEE 754 format. 714 */ read_float()715 public float read_float() 716 { 717 try 718 { 719 align(4); 720 return b.readFloat(); 721 } 722 catch (EOFException ex) 723 { 724 MARSHAL t = new MARSHAL(UNEXP_EOF); 725 t.minor = Minor.EOF; 726 t.initCause(ex); 727 throw t; 728 } 729 730 catch (IOException ex) 731 { 732 throw new Unexpected(ex); 733 } 734 } 735 736 /** 737 * Read an array of float values, IEEE 754 format. 738 */ read_float_array(float[] x, int offs, int len)739 public void read_float_array(float[] x, int offs, int len) 740 { 741 try 742 { 743 align(4); 744 for (int i = offs; i < offs + len; i++) 745 { 746 x[i] = b.readFloat(); 747 } 748 } 749 catch (EOFException ex) 750 { 751 MARSHAL t = new MARSHAL(UNEXP_EOF); 752 t.minor = Minor.EOF; 753 t.initCause(ex); 754 throw t; 755 } 756 757 catch (IOException ex) 758 { 759 throw new Unexpected(ex); 760 } 761 } 762 763 /** 764 * Read the CORBA long (java int), high byte first. 765 */ read_long()766 public int read_long() 767 { 768 try 769 { 770 align(4); 771 return b.readInt(); 772 } 773 catch (EOFException ex) 774 { 775 MARSHAL t = new MARSHAL(UNEXP_EOF); 776 t.minor = Minor.EOF; 777 t.initCause(ex); 778 throw t; 779 } 780 781 catch (IOException ex) 782 { 783 throw new Unexpected(ex); 784 } 785 } 786 787 /** 788 * Read an array of CORBA longs (java ints). 789 */ read_long_array(int[] x, int offs, int len)790 public void read_long_array(int[] x, int offs, int len) 791 { 792 try 793 { 794 align(4); 795 for (int i = offs; i < offs + len; i++) 796 { 797 x[i] = b.readInt(); 798 } 799 } 800 catch (EOFException ex) 801 { 802 MARSHAL t = new MARSHAL(UNEXP_EOF); 803 t.minor = Minor.EOF; 804 t.initCause(ex); 805 throw t; 806 } 807 808 catch (IOException ex) 809 { 810 throw new Unexpected(ex); 811 } 812 } 813 814 /** 815 * Read the CORBA long long (java long). 816 */ read_longlong()817 public long read_longlong() 818 { 819 try 820 { 821 align(8); 822 return b.readLong(); 823 } 824 catch (EOFException ex) 825 { 826 MARSHAL t = new MARSHAL(UNEXP_EOF); 827 t.minor = Minor.EOF; 828 throw t; 829 } 830 831 catch (IOException ex) 832 { 833 throw new Unexpected(ex); 834 } 835 } 836 837 /** 838 * Read an array of CORBA long longs (java longs). 839 */ read_longlong_array(long[] x, int offs, int len)840 public void read_longlong_array(long[] x, int offs, int len) 841 { 842 try 843 { 844 align(8); 845 for (int i = offs; i < offs + len; i++) 846 { 847 x[i] = b.readLong(); 848 } 849 } 850 catch (EOFException ex) 851 { 852 MARSHAL t = new MARSHAL(UNEXP_EOF); 853 t.minor = Minor.EOF; 854 t.initCause(ex); 855 throw t; 856 } 857 858 catch (IOException ex) 859 { 860 throw new Unexpected(ex); 861 } 862 } 863 864 /** 865 * Read a single byte. 866 */ read_octet()867 public byte read_octet() 868 { 869 try 870 { 871 return b.readByte(); 872 } 873 catch (EOFException ex) 874 { 875 MARSHAL t = new MARSHAL(UNEXP_EOF); 876 t.minor = Minor.EOF; 877 t.initCause(ex); 878 throw t; 879 } 880 881 catch (IOException ex) 882 { 883 throw new Unexpected(ex); 884 } 885 } 886 887 /** 888 * Read the byte array. 889 */ read_octet_array(byte[] x, int offs, int len)890 public void read_octet_array(byte[] x, int offs, int len) 891 { 892 try 893 { 894 b.read(x, offs, len); 895 } 896 catch (EOFException ex) 897 { 898 MARSHAL t = new MARSHAL(UNEXP_EOF); 899 t.minor = Minor.EOF; 900 t.initCause(ex); 901 throw t; 902 } 903 904 catch (IOException ex) 905 { 906 throw new Unexpected(ex); 907 } 908 } 909 910 /** 911 * Read the length of the byte array as CORBA long and then the array itseld. 912 */ read_sequence()913 public byte[] read_sequence() 914 { 915 try 916 { 917 int l = read_long(); 918 byte[] buf = new byte[l]; 919 if (l > 0) 920 { 921 b.readFully(buf); 922 } 923 return buf; 924 } 925 catch (EOFException ex) 926 { 927 MARSHAL t = new MARSHAL(UNEXP_EOF); 928 t.minor = Minor.EOF; 929 t.initCause(ex); 930 throw t; 931 } 932 933 catch (IOException ex) 934 { 935 throw new Unexpected(ex); 936 } 937 } 938 939 /** 940 * Read the CORBA short integer. 941 */ read_short()942 public short read_short() 943 { 944 try 945 { 946 align(2); 947 return b.readShort(); 948 } 949 catch (EOFException ex) 950 { 951 MARSHAL t = new MARSHAL(UNEXP_EOF); 952 t.minor = Minor.EOF; 953 t.initCause(ex); 954 throw t; 955 } 956 957 catch (IOException ex) 958 { 959 throw new Unexpected(ex); 960 } 961 } 962 963 /** 964 * Read the array of CORBA short integer values. 965 */ read_short_array(short[] x, int offs, int len)966 public void read_short_array(short[] x, int offs, int len) 967 { 968 try 969 { 970 align(2); 971 for (int i = offs; i < offs + len; i++) 972 { 973 x[i] = b.readShort(); 974 } 975 } 976 catch (EOFException ex) 977 { 978 MARSHAL t = new MARSHAL(UNEXP_EOF); 979 t.minor = Minor.EOF; 980 t.initCause(ex); 981 throw t; 982 } 983 984 catch (IOException ex) 985 { 986 throw new Unexpected(ex); 987 } 988 } 989 990 /** 991 * Read a singe byte string. The method firs reads the byte array and then 992 * calls a constructor to create a string from this array. The character 993 * encoding, if previously set, is taken into consideration. 994 * 995 * @return a loaded string. 996 */ read_string()997 public String read_string() 998 { 999 int n = 0; 1000 try 1001 { 1002 align(4); 1003 1004 n = b.readInt(); 1005 byte[] s = new byte[n]; 1006 b.read(s); 1007 1008 // Discard the null terminator. 1009 if (narrow_charset == null) 1010 return new String(s, 0, n - 1); 1011 else 1012 return new String(s, 0, n - 1, narrow_charset); 1013 } 1014 catch (EOFException ex) 1015 { 1016 MARSHAL t = new MARSHAL(UNEXP_EOF); 1017 t.minor = Minor.EOF; 1018 t.initCause(ex); 1019 throw t; 1020 } 1021 catch (IOException ex) 1022 { 1023 throw new Unexpected(); 1024 } 1025 catch (NegativeArraySizeException nex) 1026 { 1027 MARSHAL m = new MARSHAL("Input stream broken, got " + n + "(0x" 1028 + Integer.toHexString(n) + ") as a string size"); 1029 m.minor = Minor.Negative; 1030 throw m; 1031 } 1032 } 1033 1034 /** 1035 * Reads the CORBA unsigned long (java int), delegating functionality to 1036 * {@link #read_long}. 1037 */ read_ulong()1038 public int read_ulong() 1039 { 1040 return read_long(); 1041 } 1042 1043 /** 1044 * Reads the array of CORBA unsigned long (java integer) values, delegating 1045 * functionality to {@link #real_long_array}. 1046 */ read_ulong_array(int[] x, int offs, int len)1047 public void read_ulong_array(int[] x, int offs, int len) 1048 { 1049 read_long_array(x, offs, len); 1050 } 1051 1052 /** 1053 * Read the CORBA unsigned long long value, delegating functionality to 1054 * {@link #read_longlong}. There is no way to return values over the limit of 1055 * the java signed long in other way than returning the negative value. 1056 */ read_ulonglong()1057 public long read_ulonglong() 1058 { 1059 return read_longlong(); 1060 } 1061 1062 /** 1063 * Reads the array of CORBA long long (java long) values, delegating 1064 * functionality to {@link #real_longlong_array}. 1065 */ read_ulonglong_array(long[] x, int offs, int len)1066 public void read_ulonglong_array(long[] x, int offs, int len) 1067 { 1068 read_longlong_array(x, offs, len); 1069 } 1070 1071 /** 1072 * Read the unsigned short integer value. Due strange specification, the 1073 * returned value must be the short type as well, so the the best solution 1074 * seems just to delegete functionality to read_short. 1075 */ read_ushort()1076 public short read_ushort() 1077 { 1078 return read_short(); 1079 } 1080 1081 /** 1082 * Read an array of unsigned short values, delegating the functionality to 1083 * {@link read_short_array}. 1084 */ read_ushort_array(short[] x, int offs, int len)1085 public void read_ushort_array(short[] x, int offs, int len) 1086 { 1087 read_short_array(x, offs, len); 1088 } 1089 1090 /** 1091 * Reads the wide character using the encoding, specified in the wide_charset. 1092 */ read_wchar()1093 public char read_wchar() 1094 { 1095 try 1096 { 1097 if (giop.until_inclusive(1, 1)) 1098 { 1099 align(2); 1100 1101 if (wide_native) 1102 return (char) b.readShort(); 1103 else 1104 return (char) new InputStreamReader((InputStream) b, wide_charset).read(); 1105 } 1106 else 1107 { 1108 int l = b.read(); 1109 if (l == 2 && wide_native) 1110 return b.readChar(); 1111 else if (l <= 0) 1112 { 1113 MARSHAL m = new MARSHAL("wchar size " + l); 1114 m.minor = Minor.Negative; 1115 throw m; 1116 } 1117 else 1118 { 1119 byte[] bytes = new byte[l]; 1120 b.readFully(bytes); 1121 String cs; 1122 1123 if (bytes.length > 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) 1124 cs = new String(bytes, 2, bytes.length - 2, wide_charset); 1125 else if (bytes.length > 2 && bytes[0] == 0xFF 1126 && bytes[1] == 0xFE) 1127 { 1128 // Litle endian detected - swap bytes. 1129 byte t; 1130 for (int i = 3; i < bytes.length; i = i + 2) 1131 { 1132 t = bytes[i]; 1133 bytes[i - 1] = bytes[i]; 1134 bytes[i] = t; 1135 } 1136 cs = new String(bytes, 2, bytes.length - 2, wide_charset); 1137 } 1138 else 1139 cs = new String(bytes, wide_charset); 1140 1141 return cs.charAt(0); 1142 } 1143 } 1144 } 1145 catch (EOFException ex) 1146 { 1147 MARSHAL t = new MARSHAL(UNEXP_EOF); 1148 t.minor = Minor.EOF; 1149 t.initCause(ex); 1150 throw t; 1151 } 1152 catch (IOException ex) 1153 { 1154 throw new Unexpected(); 1155 } 1156 } 1157 1158 /** 1159 * Read an array of "wide chars", each representing a two byte Unicode 1160 * character, high byte first. 1161 */ read_wchar_array(char[] x, int offset, int length)1162 public void read_wchar_array(char[] x, int offset, int length) 1163 { 1164 try 1165 { 1166 if (giop.until_inclusive(1, 1)) 1167 align(2); 1168 1169 if (wide_native) 1170 { 1171 for (int i = offset; i < offset + length; i++) 1172 x[i] = (char) b.readShort(); 1173 } 1174 else 1175 { 1176 InputStreamReader reader = new InputStreamReader((InputStream) b, 1177 wide_charset); 1178 reader.read(x, offset, length); 1179 } 1180 } 1181 catch (EOFException ex) 1182 { 1183 MARSHAL t = new MARSHAL(UNEXP_EOF); 1184 t.minor = Minor.EOF; 1185 t.initCause(ex); 1186 throw t; 1187 } 1188 1189 catch (IOException ex) 1190 { 1191 throw new Unexpected(ex); 1192 } 1193 } 1194 1195 /** 1196 * Reads the string in wide character format (ussually UTF-16, Unicode). Takes 1197 * the currently set charset into consideration. 1198 * 1199 * If the native (UTF-16) encoding is used of the GIOP protocol is before 1.2, 1200 * delegates functionality to "plain" {@link #read_wstring_UTF_16}. 1201 */ read_wstring()1202 public String read_wstring() 1203 { 1204 // Native encoding or word oriented data. 1205 if (wide_native || giop.until_inclusive(1, 1)) 1206 return read_wstring_UTF_16(); 1207 try 1208 { 1209 align(4); 1210 1211 int n = b.readInt(); 1212 byte[] s = new byte[n]; 1213 b.read(s); 1214 1215 return new String(s, 0, n, wide_charset); 1216 } 1217 catch (EOFException ex) 1218 { 1219 MARSHAL t = new MARSHAL(UNEXP_EOF); 1220 t.minor = Minor.EOF; 1221 t.initCause(ex); 1222 throw t; 1223 } 1224 1225 catch (IOException ex) 1226 { 1227 throw new Unexpected(ex); 1228 } 1229 } 1230 1231 /** 1232 * Reads first length of the string and the all characters as an Unicode 1233 * (UTF-16) characters. Mind that GIOP 1.1 has the extra null character at the 1234 * end that must be discarded. 1235 */ read_wstring_UTF_16()1236 public String read_wstring_UTF_16() 1237 { 1238 try 1239 { 1240 int p = 0; 1241 int n = read_long(); 1242 1243 if (n<0) 1244 { 1245 MARSHAL m = new MARSHAL("Negative string size"); 1246 m.minor = Minor.Negative; 1247 throw m; 1248 } 1249 1250 // The null terminator that is no longer present since 1.2 . 1251 int nt = giop.since_inclusive(1, 2) ? 0 : 1; 1252 1253 // Convert bytes to shorts. 1254 n = n / 2; 1255 1256 // Empty string. 1257 if (n == 0) 1258 return ""; 1259 1260 char[] s = new char[n]; 1261 1262 for (int i = 0; i < s.length; i++) 1263 s[i] = (char) b.readShort(); 1264 1265 // Check for the byte order marker here. 1266 if (s[0] == 0xFEFF) 1267 { 1268 // Big endian encoding - do nothing, but move the pointer 1269 // one position forward. 1270 p = 1; 1271 } 1272 else if (s[0] == 0xFFFE) 1273 { 1274 // Little endian encoding, swap the bytes and move one 1275 // position forward. 1276 p = 1; 1277 1278 for (int i = p; i < s.length; i++) 1279 s[i] = swap(s[i]); 1280 } 1281 1282 // Discard the null terminator and, if needed, the endian marker. 1283 String r = new String(s, p, n - nt - p); 1284 return r; 1285 } 1286 catch (EOFException ex) 1287 { 1288 MARSHAL t = new MARSHAL(UNEXP_EOF); 1289 t.minor = Minor.EOF; 1290 t.initCause(ex); 1291 throw t; 1292 } 1293 1294 catch (IOException ex) 1295 { 1296 throw new Unexpected(ex); 1297 } 1298 } 1299 1300 /** 1301 * Swap bytes in the character. 1302 */ swap(char x)1303 public static char swap(char x) 1304 { 1305 int hi; 1306 int lo; 1307 1308 lo = x & 0xFF; 1309 hi = (x >> 8) & 0xFF; 1310 1311 return (char) ((lo << 8) | hi); 1312 } 1313 1314 /** 1315 * Set the current code set context. 1316 */ setCodeSet(CodeSetServiceContext a_codeset)1317 public void setCodeSet(CodeSetServiceContext a_codeset) 1318 { 1319 this.codeset = a_codeset; 1320 narrow_charset = CharSets_OSF.getName(codeset.char_data); 1321 wide_charset = CharSets_OSF.getName(codeset.wide_char_data); 1322 1323 narrow_native = CharSets_OSF.NATIVE_CHARACTER == codeset.char_data; 1324 wide_native = CharSets_OSF.NATIVE_WIDE_CHARACTER == codeset.wide_char_data; 1325 } 1326 1327 /** 1328 * Get the current code set context. 1329 */ getCodeSet()1330 public CodeSetServiceContext getCodeSet() 1331 { 1332 return codeset; 1333 } 1334 1335 /** 1336 * Read the object that is an instance of the given class. The current 1337 * implementation delegates functionality to the parameterless 1338 * {@link readObject()}. 1339 * 1340 * @param klass a class of that this object the instance is. 1341 * 1342 * @return the returned object. 1343 */ read_Object(Class klass)1344 public org.omg.CORBA.Object read_Object(Class klass) 1345 { 1346 return read_Object(); 1347 } 1348 1349 /** 1350 * Read a value type structure from the stream. 1351 * 1352 * OMG specification states the writing format is outside the scope of GIOP 1353 * definition. This implementation uses java serialization mechanism, calling 1354 * {@link ObjectInputStream#readObject} 1355 * 1356 * @return an value type structure, unmarshaled from the stream 1357 */ read_Value()1358 public Serializable read_Value() 1359 { 1360 return read_value(); 1361 } 1362 1363 /** 1364 * Read the abstract interface. An abstract interface can be either CORBA 1365 * value type or CORBA object and is returned as an abstract java.lang.Object. 1366 * 1367 * As specified in OMG specification, this reads a single boolean and then 1368 * delegates either to {@link #read_Object()} (for false) or to 1369 * {@link #read_Value()} (for true). 1370 * 1371 * @return an abstract interface, unmarshaled from the stream 1372 */ read_Abstract()1373 public java.lang.Object read_Abstract() 1374 { 1375 return read_abstract_interface(); 1376 } 1377 1378 /** 1379 * Read an array. In OMG specification is written that if the data does not 1380 * fit into the holder value field, that array must be resized. The 1381 * implementation follows this rule. If the holder value field contains null, 1382 * it is newly instantiated. 1383 */ read_char_array(CharSeqHolder holder, int offset, int length)1384 public void read_char_array(CharSeqHolder holder, int offset, int length) 1385 { 1386 holder.value = ensureArray(holder.value, offset, length); 1387 read_char_array(holder.value, offset, length); 1388 } 1389 1390 /** 1391 * Read an array. In OMG specification is written that if the data does not 1392 * fit into the holder value field, that array must be resized. The 1393 * implementation follows this rule. If the holder value field contains null, 1394 * it is newly instantiated. 1395 */ read_wchar_array(WCharSeqHolder holder, int offset, int length)1396 public void read_wchar_array(WCharSeqHolder holder, int offset, int length) 1397 { 1398 holder.value = ensureArray(holder.value, offset, length); 1399 read_wchar_array(holder.value, offset, length); 1400 } 1401 1402 /** 1403 * If required, allocate or resize the char array to fit the newly read 1404 * values. 1405 * 1406 * @param holder_value the existing char array, may be null. 1407 * @param offset the required offset to read. 1408 * @param length the length of the new sequence. 1409 * 1410 * @return the allocated or resized array, same array if no such operations 1411 * are required. 1412 */ ensureArray(char[] holder_value, int offset, int length)1413 private char[] ensureArray(char[] holder_value, int offset, int length) 1414 { 1415 if (holder_value == null) 1416 return new char[offset + length]; 1417 else if (holder_value.length < offset + length) 1418 { 1419 char[] value = new char[offset + length]; 1420 System.arraycopy(holder_value, 0, value, 0, holder_value.length); 1421 return value; 1422 } 1423 else 1424 return holder_value; 1425 } 1426 1427 /** 1428 * Read an array. In OMG specification is written that if the data does not 1429 * fit into the holder value field, that array must be resized. The 1430 * implementation follows this rule. If the holder value field contains null, 1431 * it is newly instantiated. 1432 */ read_ulong_array(ULongSeqHolder holder, int offset, int length)1433 public void read_ulong_array(ULongSeqHolder holder, int offset, int length) 1434 { 1435 holder.value = ensureArray(holder.value, offset, length); 1436 read_ulong_array(holder.value, offset, length); 1437 } 1438 1439 /** 1440 * Read an array. In OMG specification is written that if the data does not 1441 * fit into the holder value field, that array must be resized. The 1442 * implementation follows this rule. If the holder value field contains null, 1443 * it is newly instantiated. 1444 */ read_long_array(LongSeqHolder holder, int offset, int length)1445 public void read_long_array(LongSeqHolder holder, int offset, int length) 1446 { 1447 holder.value = ensureArray(holder.value, offset, length); 1448 read_ulong_array(holder.value, offset, length); 1449 } 1450 1451 /** 1452 * If required, allocate or resize the int array to fit the newly read values. 1453 * 1454 * @param holder_value the existing int array, may be null. 1455 * @param offset the required offset to read. 1456 * @param length the length of the new sequence. 1457 * 1458 * @return the allocated or resized array, same array if no such operations 1459 * are required. 1460 */ ensureArray(int[] holder_value, int offset, int length)1461 private int[] ensureArray(int[] holder_value, int offset, int length) 1462 { 1463 if (holder_value == null) 1464 return new int[offset + length]; 1465 else if (holder_value.length < offset + length) 1466 { 1467 int[] value = new int[offset + length]; 1468 System.arraycopy(holder_value, 0, value, 0, holder_value.length); 1469 return value; 1470 } 1471 else 1472 return holder_value; 1473 } 1474 1475 /** 1476 * Read an array. In OMG specification is written that if the data does not 1477 * fit into the holder value field, that array must be resized. The 1478 * implementation follows this rule. If the holder value field contains null, 1479 * it is newly instantiated. 1480 */ read_float_array(FloatSeqHolder holder, int offset, int length)1481 public void read_float_array(FloatSeqHolder holder, int offset, int length) 1482 { 1483 holder.value = ensureArray(holder.value, offset, length); 1484 read_float_array(holder.value, offset, length); 1485 } 1486 1487 /** 1488 * If required, allocate or resize the float array to fit the newly read 1489 * values. 1490 * 1491 * @param holder_value the existing float array, may be null. 1492 * @param offset the required offset to read. 1493 * @param length the length of the new sequence. 1494 * 1495 * @return the allocated or resized array, same array if no such operations 1496 * are required. 1497 */ ensureArray(float[] holder_value, int offset, int length)1498 private float[] ensureArray(float[] holder_value, int offset, int length) 1499 { 1500 if (holder_value == null) 1501 return new float[offset + length]; 1502 else if (holder_value.length < offset + length) 1503 { 1504 float[] value = new float[offset + length]; 1505 System.arraycopy(holder_value, 0, value, 0, holder_value.length); 1506 return value; 1507 } 1508 else 1509 return holder_value; 1510 } 1511 1512 /** 1513 * Read an array. In OMG specification is written that if the data does not 1514 * fit into the holder value field, that array must be resized. The 1515 * implementation follows this rule. If the holder value field contains null, 1516 * it is newly instantiated. 1517 */ read_double_array(DoubleSeqHolder holder, int offset, int length)1518 public void read_double_array(DoubleSeqHolder holder, int offset, int length) 1519 { 1520 holder.value = ensureArray(holder.value, offset, length); 1521 read_double_array(holder.value, offset, length); 1522 } 1523 1524 /** 1525 * If required, allocate or resize the double array to fit the newly read 1526 * values. 1527 * 1528 * @param holder_value the existing double array, may be null. 1529 * @param offset the required offset to read. 1530 * @param length the length of the new sequence. 1531 * 1532 * @return the allocated or resized array, same array if no such operations 1533 * are required. 1534 */ ensureArray(double[] holder_value, int offset, int length)1535 private double[] ensureArray(double[] holder_value, int offset, int length) 1536 { 1537 if (holder_value == null) 1538 return new double[offset + length]; 1539 else if (holder_value.length < offset + length) 1540 { 1541 double[] value = new double[offset + length]; 1542 System.arraycopy(holder_value, 0, value, 0, holder_value.length); 1543 return value; 1544 } 1545 else 1546 return holder_value; 1547 } 1548 1549 /** 1550 * Read an array. In OMG specification is written that if the data does not 1551 * fit into the holder value field, that array must be resized. The 1552 * implementation follows this rule. If the holder value field contains null, 1553 * it is newly instantiated. 1554 */ read_short_array(ShortSeqHolder holder, int offset, int length)1555 public void read_short_array(ShortSeqHolder holder, int offset, int length) 1556 { 1557 holder.value = ensureArray(holder.value, offset, length); 1558 read_short_array(holder.value, offset, length); 1559 } 1560 1561 /** {@inheritDoc} */ read_ushort_array(UShortSeqHolder holder, int offset, int length)1562 public void read_ushort_array(UShortSeqHolder holder, int offset, int length) 1563 { 1564 holder.value = ensureArray(holder.value, offset, length); 1565 read_ushort_array(holder.value, offset, length); 1566 } 1567 1568 /** 1569 * If required, allocate or resize the short array to fit the newly read 1570 * values. 1571 * 1572 * @param holder_value the existing short array, may be null. 1573 * @param offset the required offset to read. 1574 * @param length the length of the new sequence. 1575 * 1576 * @return the allocated or resized array, same array if no such operations 1577 * are required. 1578 */ ensureArray(short[] holder_value, int offset, int length)1579 private short[] ensureArray(short[] holder_value, int offset, int length) 1580 { 1581 if (holder_value == null) 1582 return new short[offset + length]; 1583 else if (holder_value.length < offset + length) 1584 { 1585 short[] value = new short[offset + length]; 1586 System.arraycopy(holder_value, 0, value, 0, holder_value.length); 1587 return value; 1588 } 1589 else 1590 return holder_value; 1591 } 1592 1593 /** 1594 * Read an array. In OMG specification is written that if the data does not 1595 * fit into the holder value field, that array must be resized. The 1596 * implementation follows this rule. If the holder value field contains null, 1597 * it is newly instantiated. 1598 */ read_octet_array(OctetSeqHolder holder, int offset, int length)1599 public void read_octet_array(OctetSeqHolder holder, int offset, int length) 1600 { 1601 holder.value = ensureArray(holder.value, offset, length); 1602 read_octet_array(holder.value, offset, length); 1603 } 1604 1605 /** 1606 * If required, allocate or resize the byte array to fit the newly read 1607 * values. 1608 * 1609 * @param holder_value the existing byte array, may be null. 1610 * @param offset the required offset to read. 1611 * @param length the length of the new sequence. 1612 * 1613 * @return the allocated or resized array, same array if no such operations 1614 * are required. 1615 */ ensureArray(byte[] holder_value, int offset, int length)1616 private byte[] ensureArray(byte[] holder_value, int offset, int length) 1617 { 1618 if (holder_value == null) 1619 return new byte[offset + length]; 1620 else if (holder_value.length < offset + length) 1621 { 1622 byte[] value = new byte[offset + length]; 1623 System.arraycopy(holder_value, 0, value, 0, holder_value.length); 1624 return value; 1625 } 1626 else 1627 return holder_value; 1628 } 1629 1630 /** 1631 * Read an array. In OMG specification is written that if the data does not 1632 * fit into the holder value field, that array must be resized. The 1633 * implementation follows this rule. If the holder value field contains null, 1634 * it is newly instantiated. 1635 */ read_longlong_array(LongLongSeqHolder holder, int offset, int length)1636 public void read_longlong_array(LongLongSeqHolder holder, int offset, 1637 int length) 1638 { 1639 holder.value = ensureArray(holder.value, offset, length); 1640 read_longlong_array(holder.value, offset, length); 1641 } 1642 1643 /** 1644 * Read an array. In OMG specification is written that if the data does not 1645 * fit into the holder value field, that array must be resized. The 1646 * implementation follows this rule. If the holder value field contains null, 1647 * it is newly instantiated. 1648 */ read_ulonglong_array(ULongLongSeqHolder holder, int offset, int length)1649 public void read_ulonglong_array(ULongLongSeqHolder holder, int offset, 1650 int length) 1651 { 1652 holder.value = ensureArray(holder.value, offset, length); 1653 read_ulonglong_array(holder.value, offset, length); 1654 } 1655 1656 /** 1657 * If required, allocate or resize the array of longs to fit the newly read 1658 * values. 1659 * 1660 * @param holder_value the existing array, may be null. 1661 * @param offset the required offset to read. 1662 * @param length the length of the new sequence. 1663 * 1664 * @return the allocated or resized array, same array if no such operations 1665 * are required. 1666 */ ensureArray(long[] holder_value, int offset, int length)1667 private long[] ensureArray(long[] holder_value, int offset, int length) 1668 { 1669 if (holder_value == null) 1670 return new long[offset + length]; 1671 else if (holder_value.length < offset + length) 1672 { 1673 long[] value = new long[offset + length]; 1674 System.arraycopy(holder_value, 0, value, 0, holder_value.length); 1675 return value; 1676 } 1677 else 1678 return holder_value; 1679 } 1680 1681 /** 1682 * Read an array. In OMG specification is written that if the data does not 1683 * fit into the holder value field, that array must be resized. The 1684 * implementation follows this rule. If the holder value field contains null, 1685 * it is newly instantiated. 1686 */ read_boolean_array(BooleanSeqHolder holder, int offset, int length)1687 public void read_boolean_array(BooleanSeqHolder holder, int offset, int length) 1688 { 1689 holder.value = ensureArray(holder.value, offset, length); 1690 read_boolean_array(holder.value, offset, length); 1691 } 1692 1693 /** 1694 * If required, allocate or resize the array of booleans to fit the newly read 1695 * values. 1696 * 1697 * @param holder_value the existing array of booleans, may be null. 1698 * @param offset the required offset to read. 1699 * @param length the length of the new sequence. 1700 * 1701 * @return the allocated or resized array, same array if no such operations 1702 * are required. 1703 */ ensureArray(boolean[] holder_value, int offset, int length)1704 private boolean[] ensureArray(boolean[] holder_value, int offset, int length) 1705 { 1706 if (holder_value == null) 1707 return new boolean[offset + length]; 1708 else if (holder_value.length < offset + length) 1709 { 1710 boolean[] value = new boolean[offset + length]; 1711 System.arraycopy(holder_value, 0, value, 0, holder_value.length); 1712 return value; 1713 } 1714 else 1715 return holder_value; 1716 } 1717 1718 /** 1719 * Read an array. In OMG specification is written that if the data does not 1720 * fit into the holder value field, that array must be resized. The 1721 * implementation follows this rule. If the holder value field contains null, 1722 * it is newly instantiated. 1723 */ read_any_array(AnySeqHolder holder, int offset, int length)1724 public void read_any_array(AnySeqHolder holder, int offset, int length) 1725 { 1726 holder.value = ensureArray(holder.value, offset, length); 1727 for (int i = offset; i < offset + length; i++) 1728 { 1729 holder.value[i] = read_any(); 1730 } 1731 } 1732 1733 /** 1734 * If required, allocate or resize the array of Anys to fit the newly read 1735 * values. 1736 * 1737 * @param holder_value the existing array of Anys, may be null. 1738 * @param offset the required offset to read. 1739 * @param length the length of the new sequence. 1740 * 1741 * @return the allocated or resized array, same array if no such operations 1742 * are required. 1743 */ ensureArray(Any[] holder_value, int offset, int length)1744 private Any[] ensureArray(Any[] holder_value, int offset, int length) 1745 { 1746 if (holder_value == null) 1747 return new Any[offset + length]; 1748 else if (holder_value.length < offset + length) 1749 { 1750 Any[] value = new Any[offset + length]; 1751 System.arraycopy(holder_value, 0, value, 0, holder_value.length); 1752 return value; 1753 } 1754 else 1755 return holder_value; 1756 } 1757 1758 /** 1759 * This method is required to represent the DataInputStream as a value type 1760 * object. 1761 * 1762 * @return a single entity "IDL:omg.org/CORBA/DataInputStream:1.0", always. 1763 */ _truncatable_ids()1764 public String[] _truncatable_ids() 1765 { 1766 return new String[] { "IDL:omg.org/CORBA/DataInputStream:1.0" }; 1767 } 1768 } 1769