Source for gnu.CORBA.CDR.AbstractCdrInput

   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:    */
 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:    */
 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:    */
 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:    */
 213:   public boolean isBigEndian()
 214:   {
 215:     return !little_endian;
 216:   }
 217: 
 218:   /**
 219:    * Clone all important settings to another stream.
 220:    */
 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:    */
 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:    */
 248:   public abstract void setOffset(int offset);
 249: 
 250:   /**
 251:    * Set the orb, associated with this stream.
 252:    *
 253:    * @param an_orb
 254:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 329:   public ORB orb()
 330:   {
 331:     return orb;
 332:   }
 333: 
 334:   /**
 335:    * Read a single byte directly from the buffer.
 336:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
 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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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} */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
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:    */
1764:   public String[] _truncatable_ids()
1765:   {
1766:     return new String[] { "IDL:omg.org/CORBA/DataInputStream:1.0" };
1767:   }
1768: }