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_little_endian if true, the stream expect the multi-byte data in
199    * the form "less significant byte first" (Little Endian). This is the
200    * opposite to the java standard (Big Endian).
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    * @param 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         reading: 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 }