From 3b3101d8b5ae4f08a16c0b7111da6cad41bbd282 Mon Sep 17 00:00:00 2001 From: mark Date: Tue, 15 Nov 2005 23:20:01 +0000 Subject: Imported GNU Classpath 0.19 + gcj-import-20051115. * sources.am: Regenerated. * Makefile.in: Likewise. * scripts/makemake.tcl: Use glob -nocomplain. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107049 138bc75d-0d04-0410-961f-82ee72b054a4 --- .../classpath/gnu/CORBA/CDR/AbstractCdrInput.java | 1768 ++++++++++++++++++++ .../classpath/gnu/CORBA/CDR/AbstractCdrOutput.java | 1047 ++++++++++++ .../classpath/gnu/CORBA/CDR/AbstractDataInput.java | 392 +++++ .../gnu/CORBA/CDR/AbstractDataOutput.java | 185 ++ libjava/classpath/gnu/CORBA/CDR/AligningInput.java | 131 ++ .../classpath/gnu/CORBA/CDR/AligningOutput.java | 148 ++ .../classpath/gnu/CORBA/CDR/ArrayValueHelper.java | 254 +++ .../gnu/CORBA/CDR/BigEndianInputStream.java | 2 +- .../gnu/CORBA/CDR/BigEndianOutputStream.java | 2 +- .../classpath/gnu/CORBA/CDR/BufferedCdrOutput.java | 156 ++ .../classpath/gnu/CORBA/CDR/BufferredCdrInput.java | 153 ++ .../gnu/CORBA/CDR/EncapsulationStream.java | 146 ++ libjava/classpath/gnu/CORBA/CDR/HeadlessInput.java | 749 +++++++++ libjava/classpath/gnu/CORBA/CDR/IDLTypeHelper.java | 169 ++ .../gnu/CORBA/CDR/LittleEndianInputStream.java | 2 +- .../gnu/CORBA/CDR/LittleEndianOutputStream.java | 2 +- .../gnu/CORBA/CDR/UnknownExceptionCtxHandler.java | 292 ++++ libjava/classpath/gnu/CORBA/CDR/VMVio.java | 101 ++ libjava/classpath/gnu/CORBA/CDR/Vio.java | 1459 ++++++++++++---- .../gnu/CORBA/CDR/abstractDataInputStream.java | 392 ----- .../gnu/CORBA/CDR/abstractDataOutputStream.java | 185 -- .../gnu/CORBA/CDR/aligningInputStream.java | 122 -- .../gnu/CORBA/CDR/aligningOutputStream.java | 121 -- libjava/classpath/gnu/CORBA/CDR/cdrBufInput.java | 115 -- libjava/classpath/gnu/CORBA/CDR/cdrBufOutput.java | 115 -- libjava/classpath/gnu/CORBA/CDR/cdrInput.java | 1672 ------------------ libjava/classpath/gnu/CORBA/CDR/cdrOutput.java | 1009 ----------- .../gnu/CORBA/CDR/encapsulatedOutput.java | 146 -- libjava/classpath/gnu/CORBA/CDR/gnuRuntime.java | 336 ++++ .../classpath/gnu/CORBA/CDR/gnuValueStream.java | 71 + libjava/classpath/gnu/CORBA/CDR/noHeaderInput.java | 166 -- 31 files changed, 7190 insertions(+), 4418 deletions(-) create mode 100644 libjava/classpath/gnu/CORBA/CDR/AbstractCdrInput.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/AbstractCdrOutput.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/AbstractDataInput.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/AbstractDataOutput.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/AligningInput.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/AligningOutput.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/ArrayValueHelper.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/BufferedCdrOutput.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/BufferredCdrInput.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/EncapsulationStream.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/HeadlessInput.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/IDLTypeHelper.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/UnknownExceptionCtxHandler.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/VMVio.java delete mode 100644 libjava/classpath/gnu/CORBA/CDR/abstractDataInputStream.java delete mode 100644 libjava/classpath/gnu/CORBA/CDR/abstractDataOutputStream.java delete mode 100644 libjava/classpath/gnu/CORBA/CDR/aligningInputStream.java delete mode 100644 libjava/classpath/gnu/CORBA/CDR/aligningOutputStream.java delete mode 100644 libjava/classpath/gnu/CORBA/CDR/cdrBufInput.java delete mode 100644 libjava/classpath/gnu/CORBA/CDR/cdrBufOutput.java delete mode 100644 libjava/classpath/gnu/CORBA/CDR/cdrInput.java delete mode 100644 libjava/classpath/gnu/CORBA/CDR/cdrOutput.java delete mode 100644 libjava/classpath/gnu/CORBA/CDR/encapsulatedOutput.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/gnuRuntime.java create mode 100644 libjava/classpath/gnu/CORBA/CDR/gnuValueStream.java delete mode 100644 libjava/classpath/gnu/CORBA/CDR/noHeaderInput.java (limited to 'libjava/classpath/gnu/CORBA/CDR') diff --git a/libjava/classpath/gnu/CORBA/CDR/AbstractCdrInput.java b/libjava/classpath/gnu/CORBA/CDR/AbstractCdrInput.java new file mode 100644 index 00000000000..866ec2cc945 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AbstractCdrInput.java @@ -0,0 +1,1768 @@ +/* AbstractCdrInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.BigDecimalHelper; +import gnu.CORBA.OrbFunctional; +import gnu.CORBA.GIOP.CharSets_OSF; +import gnu.CORBA.GIOP.CodeSetServiceContext; +import gnu.CORBA.IOR; +import gnu.CORBA.IorDelegate; +import gnu.CORBA.Minor; +import gnu.CORBA.TypeCodeHelper; +import gnu.CORBA.Unexpected; +import gnu.CORBA.Version; +import gnu.CORBA.gnuAny; +import gnu.CORBA.StubLocator; + +import org.omg.CORBA.Any; +import org.omg.CORBA.AnySeqHolder; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.BooleanSeqHolder; +import org.omg.CORBA.CharSeqHolder; +import org.omg.CORBA.DoubleSeqHolder; +import org.omg.CORBA.FloatSeqHolder; +import org.omg.CORBA.LongLongSeqHolder; +import org.omg.CORBA.LongSeqHolder; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.OctetSeqHolder; +import org.omg.CORBA.ShortSeqHolder; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.TypeCodePackage.Bounds; +import org.omg.CORBA.ULongLongSeqHolder; +import org.omg.CORBA.ULongSeqHolder; +import org.omg.CORBA.UShortSeqHolder; +import org.omg.CORBA.WCharSeqHolder; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.ObjectImpl; + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Serializable; + +import java.math.BigDecimal; + +/** + * A simple CORBA CDR (common data representation) input stream, reading data + * from the given {@link java.io.InputStream}. The primitive types are aligned + * on they natural boundaries by implementing the abstract method + * {@link #align(int boundary)}. + * + * The same class also implements {@link org.omg.CORBA.DataInputStream} to read + * the object content in a user defined way. + * + * TODO This class uses 16 bits per Unicode character only, as it was until jdk + * 1.4 inclusive. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public abstract class AbstractCdrInput + extends org.omg.CORBA_2_3.portable.InputStream + implements org.omg.CORBA.DataInputStream +{ + /** + * The runtime, associated with this stream. This field is only used when + * reading and writing value types and filled-in in gnu.CORBA.CDR.Vio. + */ + public transient gnuRuntime runtime; + + /** + * The message, explaining that the exception has been thrown due unexpected + * end of the input stream. This usually happens the server and client + * disagree on communication or data representation rules. + */ + protected static final String UNEXP_EOF = "Unexpected end of stream"; + + /** + * This instance is used to convert primitive data types into the byte + * sequences. + */ + protected AbstractDataInput b; + + /** + * The input stream, from where the data are actually being read. + */ + protected java.io.InputStream actual_stream; + + /** + * The associated orb, if any. + */ + protected ORB orb; + + /** + * The GIOP version. + */ + protected Version giop = new Version(1, 2); + + /** + * The code set information. + */ + protected CodeSetServiceContext codeset = CodeSetServiceContext.STANDARD; + + /** + * The name of the currently used narrow charset, null if the native narrow + * charset is used. + */ + private String narrow_charset = null; + + /** + * The name of the currently used wide charset, null if the native wide + * charset is used. + */ + private String wide_charset = null; + + /** + * True if the native code set is used for narrow characters. If the set is + * native, no the intermediate Reader object is instantiated when writing + * characters. + */ + private boolean narrow_native; + + /** + * True if the native code set is used for wide characters. If the set is + * native, no the intermediate Reader object is instantiated when writing + * characters. + */ + private boolean wide_native; + + /** + * If true, the stream expect the multi-byte data in the form "less + * significant byte first" (Little Endian). This is the opposite to the java + * standard (Big Endian). + */ + private boolean little_endian; + + /** + * Creates the stream. The stream reads Big Endian by default. + * + * @param readFrom a stream to read CORBA input from. + */ + public AbstractCdrInput(java.io.InputStream readFrom) + { + setInputStream(readFrom); + setCodeSet(CodeSetServiceContext.STANDARD); + } + + /** + * Creates the stream, requiring the subsequent call of + * {@link #setInputStream(java.io.InputStream)}. + */ + public AbstractCdrInput() + { + setCodeSet(CodeSetServiceContext.STANDARD); + } + + /** + * Set the Big Endian or Little Endian encoding. The stream reads Big Endian + * by default. + * + * @param use_little_endian if true, the stream expect the multi-byte data in + * the form "less significant byte first" (Little Endian). This is the + * opposite to the java standard (Big Endian). + */ + public void setBigEndian(boolean use_big_endian) + { + little_endian = !use_big_endian; + setInputStream(actual_stream); + } + + /** + * Get the used encoding. + * + * @param true for Big Endian, false for Little Endian. + */ + public boolean isBigEndian() + { + return !little_endian; + } + + /** + * Clone all important settings to another stream. + */ + public void cloneSettings(AbstractCdrInput stream) + { + stream.setBigEndian(isBigEndian()); + stream.setCodeSet(getCodeSet()); + stream.setVersion(giop); + stream.setOrb(orb); + } + + /** + * Set the input stream that receives the CORBA input. + * + * @param readFrom the stream. + */ + public void setInputStream(java.io.InputStream readFrom) + { + if (little_endian) + b = new LittleEndianInputStream(readFrom); + else + b = new BigEndianInputStream(readFrom); + + actual_stream = readFrom; + } + + /** + * Set the alignment offset, if the index of the first byte in the stream is + * different from 0. + */ + public abstract void setOffset(int offset); + + /** + * Set the orb, associated with this stream. + * + * @param an_orb + */ + public void setOrb(ORB an_orb) + { + orb = an_orb; + } + + /** + * Set the GIOP version. Some data types are written differently for the + * different versions. The default version is 1.0 . + */ + public void setVersion(Version giop_version) + { + giop = giop_version; + } + + /** + * Align the curretn position at the given natural boundary. + */ + public abstract void align(int boundary); + + /** + * Reads the CORBA unsigned long (java int), returning the value in the + * sufficiently large java long. + */ + public long gnu_read_ulong() + { + try + { + long l = b.readInt(); + l &= 0xFFFFFFF; + return l; + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the unsigned short integer value and return it as java int, + * sufficiently large to hold all values. + */ + public int gnu_read_ushort() + { + try + { + align(2); + return b.readUnsignedShort(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Return the associated {@link ORB}. + * + * @return the associated {@link ORB} or null is no such is set. + */ + public ORB orb() + { + return orb; + } + + /** + * Read a single byte directly from the buffer. + */ + public int read() + throws java.io.IOException + { + try + { + return b.read(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + } + + /** + * Read bytes directly from the buffer. + */ + public int read(byte[] x, int ofs, int len) + throws java.io.IOException + { + try + { + return b.read(x, ofs, len); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + } + + /** + * Read bytes directly from the buffer. + */ + public int read(byte[] x) + throws java.io.IOException + { + try + { + return b.read(x); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + } + + /** + * Read the CORBA object. The object to read is represented in the form of the + * plain (not a string-encoded) IOR profile without the heading endian + * indicator. The responsible method for reading such data is + * {@link IOR.read_no_endian}. + * + * The returned object is usually casted into the given type using the .narrow + * method of its helper, despite in some cases the direct cast would also + * work. + * + * The null objects are recognised from the empty profile set. For such + * objects, null is returned. + * + * @return the loaded and constructed object. + */ + public org.omg.CORBA.Object read_Object() + { + try + { + IOR ior = new IOR(); + ior._read_no_endian(this); + + if (ior.Id == null) + return null; + + // Check maybe this is a remote reference to the local object. + // This is only possible if we access the repository of the + // connected object. + if (orb instanceof OrbFunctional) + { + OrbFunctional forb = (OrbFunctional) orb; + org.omg.CORBA.Object local = forb.find_local_object(ior); + if (local != null) + return local; + } + + // Search for the available stubs. + ObjectImpl impl = StubLocator.search(orb, ior); + try + { + if (impl._get_delegate() == null) + impl._set_delegate(new IorDelegate(orb, ior)); + } + catch (BAD_OPERATION ex) + { + // Some colaborants may throw this exception + // in response to the attempt to get the unset delegate. + impl._set_delegate(new IorDelegate(orb, ior)); + } + + return impl; + } + catch (IOException ex) + { + MARSHAL bad = new MARSHAL(); + bad.minor = Minor.IOR; + bad.initCause(ex); + throw bad; + } + } + + /** + * Read the type code. The type code format is defined in the CORBA + * documenation. + */ + public TypeCode read_TypeCode() + { + try + { + return TypeCodeHelper.read(this); + } + + catch (Bounds ex) + { + throw new Unexpected(); + } + catch (BadKind ex) + { + throw new Unexpected(); + } + } + + /** + * Read the CORBA {@link Any}. This method first reads the type code, then + * delegates the functionality to {@link Any#read_value}. + */ + public Any read_any() + { + TypeCode ty = read_TypeCode(); + gnuAny any = new gnuAny(); + any.read_value(this, ty); + return any; + } + + /** + * Read the boolean, treating any non zero byte as true, zero byte as false. + */ + public boolean read_boolean() + { + try + { + return b.read() == 0 ? false : true; + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the array of boolean. + */ + public void read_boolean_array(boolean[] x, int offs, int len) + { + try + { + for (int i = offs; i < offs + len; i++) + { + x[i] = b.read() == 0 ? false : true; + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read a character using narrow charset encoding. Depending form which + * encoding is set, this still can be Unicode or ever wider. + */ + public char read_char() + { + try + { + if (narrow_native) + return (char) b.read(); + else + return (char) new InputStreamReader((InputStream) b, narrow_charset).read(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read a character array, using narrow charset encoding. + */ + public void read_char_array(char[] x, int offset, int length) + { + try + { + if (narrow_native) + { + for (int i = offset; i < offset + length; i++) + x[i] = (char) b.read(); + } + else + { + InputStreamReader reader = new InputStreamReader((InputStream) b, + narrow_charset); + reader.read(x, offset, length); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the double value, IEEE 754 format. + */ + public double read_double() + { + try + { + align(8); + return b.readDouble(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(); + } + } + + /** + * Read the array of double values, IEEE 754 format. + */ + public void read_double_array(double[] x, int offs, int len) + { + try + { + align(8); + for (int i = offs; i < offs + len; i++) + { + x[i] = b.readDouble(); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the encapsulated stream. If the encapsulated sequence appears to be in + * the Little endian format, the flag of the returned stream is set to read + * Little endian. + */ + public BufferredCdrInput read_encapsulation() + { + try + { + int l = read_long(); + + byte[] r = new byte[l]; + int n = 0; + reading: while (n < r.length) + { + n += read(r, n, r.length - n); + } + + BufferredCdrInput capsule = new BufferredCdrInput(r); + capsule.setOrb(orb); + + int endian = capsule.read_octet(); + + if (endian != 0) + { + capsule.setBigEndian(false); + } + + return capsule; + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the CORBA fixed (the end of the fixed can be determined + * by its last byte). The scale is always assumed to be zero. + */ + public BigDecimal read_fixed() + { + try + { + return BigDecimalHelper.read(this, 0); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the float value, IEEE 754 format. + */ + public float read_float() + { + try + { + align(4); + return b.readFloat(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read an array of float values, IEEE 754 format. + */ + public void read_float_array(float[] x, int offs, int len) + { + try + { + align(4); + for (int i = offs; i < offs + len; i++) + { + x[i] = b.readFloat(); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the CORBA long (java int), high byte first. + */ + public int read_long() + { + try + { + align(4); + return b.readInt(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read an array of CORBA longs (java ints). + */ + public void read_long_array(int[] x, int offs, int len) + { + try + { + align(4); + for (int i = offs; i < offs + len; i++) + { + x[i] = b.readInt(); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the CORBA long long (java long). + */ + public long read_longlong() + { + try + { + align(8); + return b.readLong(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read an array of CORBA long longs (java longs). + */ + public void read_longlong_array(long[] x, int offs, int len) + { + try + { + align(8); + for (int i = offs; i < offs + len; i++) + { + x[i] = b.readLong(); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read a single byte. + */ + public byte read_octet() + { + try + { + return b.readByte(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the byte array. + */ + public void read_octet_array(byte[] x, int offs, int len) + { + try + { + b.read(x, offs, len); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the length of the byte array as CORBA long and then the array itseld. + */ + public byte[] read_sequence() + { + try + { + int l = read_long(); + byte[] buf = new byte[l]; + if (l > 0) + { + b.readFully(buf); + } + return buf; + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the CORBA short integer. + */ + public short read_short() + { + try + { + align(2); + return b.readShort(); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read the array of CORBA short integer values. + */ + public void read_short_array(short[] x, int offs, int len) + { + try + { + align(2); + for (int i = offs; i < offs + len; i++) + { + x[i] = b.readShort(); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Read a singe byte string. The method firs reads the byte array and then + * calls a constructor to create a string from this array. The character + * encoding, if previously set, is taken into consideration. + * + * @return a loaded string. + */ + public String read_string() + { + int n = 0; + try + { + align(4); + + n = b.readInt(); + byte[] s = new byte[n]; + b.read(s); + + // Discard the null terminator. + if (narrow_charset == null) + return new String(s, 0, n - 1); + else + return new String(s, 0, n - 1, narrow_charset); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + catch (IOException ex) + { + throw new Unexpected(); + } + catch (NegativeArraySizeException nex) + { + MARSHAL m = new MARSHAL("Input stream broken, got " + n + "(0x" + + Integer.toHexString(n) + ") as a string size"); + m.minor = Minor.Negative; + throw m; + } + } + + /** + * Reads the CORBA unsigned long (java int), delegating functionality to + * {@link #read_long}. + */ + public int read_ulong() + { + return read_long(); + } + + /** + * Reads the array of CORBA unsigned long (java integer) values, delegating + * functionality to {@link #real_long_array}. + */ + public void read_ulong_array(int[] x, int offs, int len) + { + read_long_array(x, offs, len); + } + + /** + * Read the CORBA unsigned long long value, delegating functionality to + * {@link #read_longlong}. There is no way to return values over the limit of + * the java signed long in other way than returning the negative value. + */ + public long read_ulonglong() + { + return read_longlong(); + } + + /** + * Reads the array of CORBA long long (java long) values, delegating + * functionality to {@link #real_longlong_array}. + */ + public void read_ulonglong_array(long[] x, int offs, int len) + { + read_longlong_array(x, offs, len); + } + + /** + * Read the unsigned short integer value. Due strange specification, the + * returned value must be the short type as well, so the the best solution + * seems just to delegete functionality to read_short. + */ + public short read_ushort() + { + return read_short(); + } + + /** + * Read an array of unsigned short values, delegating the functionality to + * {@link read_short_array}. + */ + public void read_ushort_array(short[] x, int offs, int len) + { + read_short_array(x, offs, len); + } + + /** + * Reads the wide character using the encoding, specified in the wide_charset. + */ + public char read_wchar() + { + try + { + if (giop.until_inclusive(1, 1)) + { + align(2); + + if (wide_native) + return (char) b.readShort(); + else + return (char) new InputStreamReader((InputStream) b, wide_charset).read(); + } + else + { + int l = b.read(); + if (l == 2 && wide_native) + return b.readChar(); + else if (l <= 0) + { + MARSHAL m = new MARSHAL("wchar size " + l); + m.minor = Minor.Negative; + throw m; + } + else + { + byte[] bytes = new byte[l]; + b.readFully(bytes); + String cs; + + if (bytes.length > 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) + cs = new String(bytes, 2, bytes.length - 2, wide_charset); + else if (bytes.length > 2 && bytes[0] == 0xFF + && bytes[1] == 0xFE) + { + // Litle endian detected - swap bytes. + byte t; + for (int i = 3; i < bytes.length; i = i + 2) + { + t = bytes[i]; + bytes[i - 1] = bytes[i]; + bytes[i] = t; + } + cs = new String(bytes, 2, bytes.length - 2, wide_charset); + } + else + cs = new String(bytes, wide_charset); + + return cs.charAt(0); + } + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + catch (IOException ex) + { + throw new Unexpected(); + } + } + + /** + * Read an array of "wide chars", each representing a two byte Unicode + * character, high byte first. + */ + public void read_wchar_array(char[] x, int offset, int length) + { + try + { + if (giop.until_inclusive(1, 1)) + align(2); + + if (wide_native) + { + for (int i = offset; i < offset + length; i++) + x[i] = (char) b.readShort(); + } + else + { + InputStreamReader reader = new InputStreamReader((InputStream) b, + wide_charset); + reader.read(x, offset, length); + } + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Reads the string in wide character format (ussually UTF-16, Unicode). Takes + * the currently set charset into consideration. + * + * If the native (UTF-16) encoding is used of the GIOP protocol is before 1.2, + * delegates functionality to "plain" {@link #read_wstring_UTF_16}. + */ + public String read_wstring() + { + // Native encoding or word oriented data. + if (wide_native || giop.until_inclusive(1, 1)) + return read_wstring_UTF_16(); + try + { + align(4); + + int n = b.readInt(); + byte[] s = new byte[n]; + b.read(s); + + return new String(s, 0, n, wide_charset); + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Reads first length of the string and the all characters as an Unicode + * (UTF-16) characters. Mind that GIOP 1.1 has the extra null character at the + * end that must be discarded. + */ + public String read_wstring_UTF_16() + { + try + { + int p = 0; + int n = read_long(); + + if (n<0) + { + MARSHAL m = new MARSHAL("Negative string size"); + m.minor = Minor.Negative; + throw m; + } + + // The null terminator that is no longer present since 1.2 . + int nt = giop.since_inclusive(1, 2) ? 0 : 1; + + // Convert bytes to shorts. + n = n / 2; + + // Empty string. + if (n == 0) + return ""; + + char[] s = new char[n]; + + for (int i = 0; i < s.length; i++) + s[i] = (char) b.readShort(); + + // Check for the byte order marker here. + if (s[0] == 0xFEFF) + { + // Big endian encoding - do nothing, but move the pointer + // one position forward. + p = 1; + } + else if (s[0] == 0xFFFE) + { + // Little endian encoding, swap the bytes and move one + // position forward. + p = 1; + + for (int i = p; i < s.length; i++) + s[i] = swap(s[i]); + } + + // Discard the null terminator and, if needed, the endian marker. + String r = new String(s, p, n - nt - p); + return r; + } + catch (EOFException ex) + { + MARSHAL t = new MARSHAL(UNEXP_EOF); + t.minor = Minor.EOF; + t.initCause(ex); + throw t; + } + + catch (IOException ex) + { + throw new Unexpected(ex); + } + } + + /** + * Swap bytes in the character. + */ + public static char swap(char x) + { + int hi; + int lo; + + lo = x & 0xFF; + hi = (x >> 8) & 0xFF; + + return (char) ((lo << 8) | hi); + } + + /** + * Set the current code set context. + */ + public void setCodeSet(CodeSetServiceContext a_codeset) + { + this.codeset = a_codeset; + narrow_charset = CharSets_OSF.getName(codeset.char_data); + wide_charset = CharSets_OSF.getName(codeset.wide_char_data); + + narrow_native = CharSets_OSF.NATIVE_CHARACTER == codeset.char_data; + wide_native = CharSets_OSF.NATIVE_WIDE_CHARACTER == codeset.wide_char_data; + } + + /** + * Get the current code set context. + */ + public CodeSetServiceContext getCodeSet() + { + return codeset; + } + + /** + * Read the object that is an instance of the given class. The current + * implementation delegates functionality to the parameterless + * {@link readObject()}. + * + * @param klass a class of that this object the instance is. + * + * @return the returned object. + */ + public org.omg.CORBA.Object read_Object(Class klass) + { + return read_Object(); + } + + /** + * Read a value type structure from the stream. + * + * OMG specification states the writing format is outside the scope of GIOP + * definition. This implementation uses java serialization mechanism, calling + * {@link ObjectInputStream#readObject} + * + * @return an value type structure, unmarshaled from the stream + */ + public Serializable read_Value() + { + return read_value(); + } + + /** + * Read the abstract interface. An abstract interface can be either CORBA + * value type or CORBA object and is returned as an abstract java.lang.Object. + * + * As specified in OMG specification, this reads a single boolean and then + * delegates either to {@link #read_Object()} (for false) or to + * {@link #read_Value()} (for true). + * + * @return an abstract interface, unmarshaled from the stream + */ + public java.lang.Object read_Abstract() + { + return read_abstract_interface(); + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_char_array(CharSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_char_array(holder.value, offset, length); + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_wchar_array(WCharSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_wchar_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the char array to fit the newly read + * values. + * + * @param holder_value the existing char array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private char[] ensureArray(char[] holder_value, int offset, int length) + { + if (holder_value == null) + return new char[offset + length]; + else if (holder_value.length < offset + length) + { + char[] value = new char[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_ulong_array(ULongSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_ulong_array(holder.value, offset, length); + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_long_array(LongSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_ulong_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the int array to fit the newly read values. + * + * @param holder_value the existing int array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private int[] ensureArray(int[] holder_value, int offset, int length) + { + if (holder_value == null) + return new int[offset + length]; + else if (holder_value.length < offset + length) + { + int[] value = new int[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_float_array(FloatSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_float_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the float array to fit the newly read + * values. + * + * @param holder_value the existing float array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private float[] ensureArray(float[] holder_value, int offset, int length) + { + if (holder_value == null) + return new float[offset + length]; + else if (holder_value.length < offset + length) + { + float[] value = new float[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_double_array(DoubleSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_double_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the double array to fit the newly read + * values. + * + * @param holder_value the existing double array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private double[] ensureArray(double[] holder_value, int offset, int length) + { + if (holder_value == null) + return new double[offset + length]; + else if (holder_value.length < offset + length) + { + double[] value = new double[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_short_array(ShortSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_short_array(holder.value, offset, length); + } + + /** {@inheritDoc} */ + public void read_ushort_array(UShortSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_ushort_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the short array to fit the newly read + * values. + * + * @param holder_value the existing short array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private short[] ensureArray(short[] holder_value, int offset, int length) + { + if (holder_value == null) + return new short[offset + length]; + else if (holder_value.length < offset + length) + { + short[] value = new short[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_octet_array(OctetSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_octet_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the byte array to fit the newly read + * values. + * + * @param holder_value the existing byte array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private byte[] ensureArray(byte[] holder_value, int offset, int length) + { + if (holder_value == null) + return new byte[offset + length]; + else if (holder_value.length < offset + length) + { + byte[] value = new byte[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_longlong_array(LongLongSeqHolder holder, int offset, + int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_longlong_array(holder.value, offset, length); + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_ulonglong_array(ULongLongSeqHolder holder, int offset, + int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_ulonglong_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the array of longs to fit the newly read + * values. + * + * @param holder_value the existing array, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private long[] ensureArray(long[] holder_value, int offset, int length) + { + if (holder_value == null) + return new long[offset + length]; + else if (holder_value.length < offset + length) + { + long[] value = new long[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_boolean_array(BooleanSeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + read_boolean_array(holder.value, offset, length); + } + + /** + * If required, allocate or resize the array of booleans to fit the newly read + * values. + * + * @param holder_value the existing array of booleans, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private boolean[] ensureArray(boolean[] holder_value, int offset, int length) + { + if (holder_value == null) + return new boolean[offset + length]; + else if (holder_value.length < offset + length) + { + boolean[] value = new boolean[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * Read an array. In OMG specification is written that if the data does not + * fit into the holder value field, that array must be resized. The + * implementation follows this rule. If the holder value field contains null, + * it is newly instantiated. + */ + public void read_any_array(AnySeqHolder holder, int offset, int length) + { + holder.value = ensureArray(holder.value, offset, length); + for (int i = offset; i < offset + length; i++) + { + holder.value[i] = read_any(); + } + } + + /** + * If required, allocate or resize the array of Anys to fit the newly read + * values. + * + * @param holder_value the existing array of Anys, may be null. + * @param offset the required offset to read. + * @param length the length of the new sequence. + * + * @return the allocated or resized array, same array if no such operations + * are required. + */ + private Any[] ensureArray(Any[] holder_value, int offset, int length) + { + if (holder_value == null) + return new Any[offset + length]; + else if (holder_value.length < offset + length) + { + Any[] value = new Any[offset + length]; + System.arraycopy(holder_value, 0, value, 0, holder_value.length); + return value; + } + else + return holder_value; + } + + /** + * This method is required to represent the DataInputStream as a value type + * object. + * + * @return a single entity "IDL:omg.org/CORBA/DataInputStream:1.0", always. + */ + public String[] _truncatable_ids() + { + return new String[] { "IDL:omg.org/CORBA/DataInputStream:1.0" }; + } +} \ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/AbstractCdrOutput.java b/libjava/classpath/gnu/CORBA/CDR/AbstractCdrOutput.java new file mode 100644 index 00000000000..7b4d5ec58ff --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AbstractCdrOutput.java @@ -0,0 +1,1047 @@ +/* AbstractCdrOutput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.BigDecimalHelper; +import gnu.CORBA.IOR; +import gnu.CORBA.IorProvider; +import gnu.CORBA.Minor; +import gnu.CORBA.TypeCodeHelper; +import gnu.CORBA.Unexpected; +import gnu.CORBA.Version; +import gnu.CORBA.GIOP.CharSets_OSF; +import gnu.CORBA.GIOP.CodeSetServiceContext; +import gnu.CORBA.typecodes.PrimitiveTypeCode; + +import org.omg.CORBA.Any; +import org.omg.CORBA.BAD_OPERATION; +import org.omg.CORBA.Context; +import org.omg.CORBA.ContextList; +import org.omg.CORBA.DataInputStream; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.ORB; +import org.omg.CORBA.TCKind; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.UserException; +import org.omg.CORBA.TypeCodePackage.BadKind; +import org.omg.CORBA.portable.Delegate; +import org.omg.CORBA.portable.ObjectImpl; +import org.omg.CORBA.portable.OutputStream; +import org.omg.CORBA.portable.Streamable; + +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * A simple CORBA CDR (common data representation) + * output stream, writing data into the + * given {@link java.io.OutputStream}. + * + * The same class also implements the {@link DataInputStream}, + * providing support for writing the value type objects + * in a user defined way. + * + * TODO This class uses 16 bits per Unicode character only, as it was until + * jdk 1.4 inclusive. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public abstract class AbstractCdrOutput + extends org.omg.CORBA_2_3.portable.OutputStream + implements org.omg.CORBA.DataOutputStream +{ + /** + * The runtime, associated with this stream. This field is only used when + * reading and writing value types and filled-in in gnu.CORBA.CDR.Vio. + */ + public transient gnuRuntime runtime; + + /** + * This instance is used to convert primitive data types into the + * byte sequences. + */ + protected AbstractDataOutput b; + + /** + * The associated orb, if any. + */ + protected ORB orb; + + /** + * The GIOP version. + */ + protected Version giop = new Version(1, 2); + + /** + * The code set information. + */ + protected CodeSetServiceContext codeset; + + /** + * The name of the currently used narrow charset. + */ + private String narrow_charset; + + /** + * The name of the currently used wide charset, null if + * the native wide charset is used. + */ + private String wide_charset; + + /** + * True if the native code set is used for narrow characters. + * If the set is native, no the intermediate Reader object + * is instantiated when writing characters. + */ + private boolean narrow_native; + + /** + * True if the native code set is used for wide characters. + * If the set is native, no the intermediate Reader object + * is instantiated when writing characters. + */ + private boolean wide_native; + + /** + * If true, the Little Endian encoding is used to write the + * data. Otherwise, the Big Endian encoding is used. + */ + private boolean little_endian; + + /** + * The stream whre the data are actually written. + */ + private java.io.OutputStream actual_stream; + + /** + * Creates the stream. + * + * @param writeTo a stream to write CORBA output to. + */ + public AbstractCdrOutput(java.io.OutputStream writeTo) + { + setOutputStream(writeTo); + setCodeSet(CodeSetServiceContext.STANDARD); + } + + /** + * Creates the stream, requiring the subsequent call + * of {@link #setOutputStream(java.io.OutputStream)}. + */ + public AbstractCdrOutput() + { + setCodeSet(CodeSetServiceContext.STANDARD); + } + + /** + * Set the alignment offset, if the index of the first byte in the + * stream is different from 0. + */ + public abstract void setOffset(int an_offset); + + /** + * Clone all important settings to another stream. + */ + public void cloneSettings(AbstractCdrOutput stream) + { + stream.setBigEndian(!little_endian); + stream.setCodeSet(getCodeSet()); + stream.setVersion(giop); + stream.setOrb(orb); + } + + /** + * Set the current code set context. + */ + public void setCodeSet(CodeSetServiceContext a_codeset) + { + this.codeset = a_codeset; + narrow_charset = CharSets_OSF.getName(codeset.char_data); + wide_charset = CharSets_OSF.getName(codeset.wide_char_data); + + narrow_native = CharSets_OSF.NATIVE_CHARACTER == codeset.char_data; + wide_native = CharSets_OSF.NATIVE_WIDE_CHARACTER == codeset.wide_char_data; + } + + /** + * Get the current code set context. + */ + public CodeSetServiceContext getCodeSet() + { + return codeset; + } + + /** + * Set the orb, associated with this stream. + * @param an_orb + */ + public void setOrb(ORB an_orb) + { + orb = an_orb; + } + + /** + * Set the output stream that receives the CORBA output. + * + * @param writeTo the stream. + */ + public void setOutputStream(java.io.OutputStream writeTo) + { + if (little_endian) + b = new LittleEndianOutputStream(writeTo); + else + b = new BigEndianOutputStream(writeTo); + + actual_stream = writeTo; + } + + /** + * Set the GIOP version. Some data types are written differently + * for the different versions. The default version is 1.0 . + */ + public void setVersion(Version giop_version) + { + giop = giop_version; + } + + /** + * Specify if the stream should use the Big Endian (usual for java) + * or Little Encoding. The default is Big Endian. + * + * @param use_big_endian if true, use Big Endian, if false, + * use Little Endian. + */ + public void setBigEndian(boolean use_big_endian) + { + little_endian = !use_big_endian; + setOutputStream(actual_stream); + } + + /** + * Align the curretn position at the given natural boundary. + */ + public abstract void align(int boundary); + + /** + * Create the encapsulation stream, associated with the current + * stream. The encapsulated stream must be closed. When being + * closed, the encapsulation stream writes its buffer into + * this stream using the CORBA CDR encapsulation rules. + * + * It is not allowed to write to the current stream directly + * before the encapsulation stream is closed. + * + * The encoding (Big/Little Endian) inside the encapsulated + * sequence is the same as used into the parent stream. + * + * @return the encapsulated stream. + */ + public AbstractCdrOutput createEncapsulation() + { + return new EncapsulationStream(this, !little_endian); + } + + /** + * Return the associated {@link ORB}. + * @return the associated {@link ORB} or null is no such is set. + */ + public ORB orb() + { + return orb; + } + + /** + * Write a single byte. + * @param a byte to write (low 8 bits are written). + */ + public void write(int n) + { + try + { + b.write(n); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Write bytes directly into the underlying stream. + */ + public void write(byte[] x) + throws java.io.IOException + { + b.write(x); + } + + /** + * Write bytes directly into the underlying stream. + */ + public void write(byte[] x, int ofs, int len) + throws java.io.IOException + { + b.write(x, ofs, len); + } + + /** + * Following the specification, this is not implemented. + * Override to get the functionality. + */ + public void write_Context(Context context, ContextList contexts) + { + throw new NO_IMPLEMENT(); + } + + /** + * Read the CORBA object. The object is written form of the plain (not a + * string-encoded) IOR profile without the heading endian indicator. The + * responsible method for reading such data is {@link IOR.write_no_endian}. + * + * The null value is written as defined in OMG specification (zero length + * string, followed by an empty set of profiles). + */ + public void write_Object(org.omg.CORBA.Object x) + { + ORB w_orb = orb; + if (x instanceof IorProvider) + { + ((IorProvider) x).getIor()._write_no_endian(this); + return; + } + else if (x == null) + { + IOR.write_null(this); + return; + } + else if (x instanceof ObjectImpl) + { + Delegate d = ((ObjectImpl) x)._get_delegate(); + + if (d instanceof IorProvider) + { + ((IorProvider) d).getIor()._write_no_endian(this); + return; + } + else + { + ORB d_orb = d.orb(x); + if (d_orb != null) + w_orb = d_orb; + } + } + + // Either this is not an ObjectImpl or it has the + // unexpected delegate. Try to convert via ORBs + // object_to_string(). + if (w_orb != null) + { + IOR ior = IOR.parse(w_orb.object_to_string(x)); + ior._write_no_endian(this); + return; + } + else + throw new BAD_OPERATION( + "Please set the ORB for this stream, cannot write " + + x.getClass().getName()); + } + + /** + * Write the TypeCode. This implementation delegates functionality + * to {@link cdrTypeCode}. + * + * @param x a TypeCode to write. + */ + public void write_TypeCode(TypeCode x) + { + try + { + TypeCodeHelper.write(this, x); + } + catch (UserException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes an instance of the CORBA {@link Any}. + * This method writes the typecode, followed + * by value itself. In Any contains null + * (value not set), the {@link TCKind#tk_null} + * is written. + * + * @param x the {@link Any} to write. + */ + public void write_any(Any x) + { + Streamable value = x.extract_Streamable(); + if (value != null) + { + write_TypeCode(x.type()); + value._write(this); + } + else + { + PrimitiveTypeCode p = new PrimitiveTypeCode(TCKind.tk_null); + write_TypeCode(p); + } + } + + /** + * Writes a single byte, 0 for false, + * 1 for true. + * + * @param x the value to write + */ + public void write_boolean(boolean x) + { + try + { + b.write(x ? 1 : 0); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the boolean array. + * + * @param x array + * @param ofs offset + * @param len length. + */ + public void write_boolean_array(boolean[] x, int ofs, int len) + { + try + { + for (int i = ofs; i < ofs + len; i++) + { + b.write(x [ i ] ? 1 : 0); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the lower byte of the passed parameter. + * @param x the char to write + * + * It is effective to write more characters at once. + */ + public void write_char(char x) + { + try + { + if (narrow_native) + b.write(x); + else + { + OutputStreamWriter ow = + new OutputStreamWriter((OutputStream) b, narrow_charset); + ow.write(x); + ow.flush(); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the lower bytes of the passed array members. + * + * @param chars an array + * @param offsets offset + * @param length length + */ + public void write_char_array(char[] chars, int offset, int length) + { + try + { + if (narrow_native) + { + for (int i = offset; i < offset + length; i++) + { + b.write(chars [ i ]); + } + } + else + { + OutputStreamWriter ow = + new OutputStreamWriter((OutputStream) b, narrow_charset); + ow.write(chars, offset, length); + ow.flush(); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the double value (IEEE 754 format). + */ + public void write_double(double x) + { + try + { + align(8); + b.writeDouble(x); + } + catch (Exception ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the array of double values. + */ + public void write_double_array(double[] x, int ofs, int len) + { + try + { + align(8); + for (int i = ofs; i < ofs + len; i++) + { + b.writeDouble(x [ i ]); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes CORBA fixed, storing all digits but not the scale. + * The end of the record on fixed can + * be determined from its last byte. + */ + public void write_fixed(BigDecimal fixed) + { + try + { + BigDecimalHelper.write(this, fixed); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + catch (BadKind ex) + { + Unexpected.error(ex); + } + } + + /** + * Write the float value (IEEE 754 format). + */ + public void write_float(float x) + { + try + { + align(4); + b.writeFloat(x); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes an array of the float values. + */ + public void write_float_array(float[] x, int ofs, int len) + { + try + { + align(4); + for (int i = ofs; i < ofs + len; i++) + { + b.writeFloat(x [ i ]); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the integer value (CORBA long, four bytes, high byte first). + * @param x the value to write. + */ + public void write_long(int x) + { + try + { + align(4); + b.writeInt(x); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the array of integer (CORBA long) values. + * + * @param x value + * @param ofs offset + * @param len length + */ + public void write_long_array(int[] x, int ofs, int len) + { + try + { + align(4); + for (int i = ofs; i < ofs + len; i++) + { + b.writeInt(x [ i ]); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the long (CORBA long long) value, 8 bytes, + * high byte first. + * + * @param x the value to write. + */ + public void write_longlong(long x) + { + try + { + align(8); + b.writeLong(x); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the array of longs (CORBA long longs) values. + * + * @param x value + * @param ofs offset + * @param len length + */ + public void write_longlong_array(long[] x, int ofs, int len) + { + try + { + align(8); + for (int i = ofs; i < ofs + len; i++) + { + b.writeLong(x [ i ]); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes this byte. + * @param x + */ + public void write_octet(byte x) + { + try + { + b.writeByte(x); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the array of bytes (CORBA octets) values. + * + * @param x value + * @param ofs offset + * @param len length + */ + public void write_octet_array(byte[] x, int ofs, int len) + { + try + { + b.write(x, ofs, len); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes first the size of array, and then the byte array using + * the {@link java.io.OutputStream#write(byte[]) }. The sequence + * being written is preceeded by the int, representing the array + * length. + */ + public void write_sequence(byte[] buf) + { + try + { + write_long(buf.length); + write(buf); + } + catch (IOException ex) + { + MARSHAL t = new MARSHAL(); + t.minor = Minor.CDR; + t.initCause(ex); + throw t; + } + } + + /** + * Writes the contents of the provided stream. + * The sequence being written is preceeded by the int, + * representing the stream buffer length (the number of + * bytes being subsequently written). + */ + public void write_sequence(BufferedCdrOutput from) + { + try + { + write_long(from.buffer.size()); + from.buffer.writeTo(this); + } + catch (IOException ex) + { + MARSHAL t = new MARSHAL(); + t.minor = Minor.CDR; + t.initCause(ex); + throw t; + } + } + + /** + * Writes the two byte integer (short), high byte first. + * + * @param x the integer to write. + */ + public void write_short(short x) + { + try + { + align(2); + b.writeShort(x); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the array of short (two byte integer) values. + * + * @param x value + * @param ofs offset + * @param len length + */ + public void write_short_array(short[] x, int ofs, int len) + { + try + { + align(2); + for (int i = ofs; i < ofs + len; i++) + { + b.writeShort(x [ i ]); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the string. This implementation first calls + * String.getBytes() and then writes the length of the returned + * array (as CORBA ulong) and the returned array itself. + * + * The encoding information, if previously set, is taken + * into consideration. + * + * @param x the string to write. + */ + public void write_string(String x) + { + try + { + byte[] ab = x.getBytes(narrow_charset); + write_long(ab.length + 1); + write(ab); + + // write null terminator. + write(0); + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the CORBA unsigned long in the same way as CORBA long. + */ + public void write_ulong(int x) + { + write_long(x); + } + + /** + * Writes the array of CORBA unsigned longs in the same way as + * array of ordinary longs. + */ + public void write_ulong_array(int[] x, int ofs, int len) + { + write_long_array(x, ofs, len); + } + + /** + * Write the unsigned long long in the same way as an ordinary long long. + * + * @param x a value to write. + */ + public void write_ulonglong(long x) + { + write_longlong(x); + } + + /** + * Write the array of unsingel long longs in the same way + * an an array of the ordinary long longs. + */ + public void write_ulonglong_array(long[] x, int ofs, int len) + { + write_longlong_array(x, ofs, len); + } + + /** + * Write the unsigned short in the same way as an ordinary short. + */ + public void write_ushort(short x) + { + write_short(x); + } + + /** + * Write an array of unsigned short integersin the same way + * as an array of ordinary short integers. + */ + public void write_ushort_array(short[] x, int ofs, int len) + { + write_short_array(x, ofs, len); + } + + /** + * Writes the character as two byte short integer (Unicode value), high byte + * first. Writes in Big Endian, but never writes the endian indicator. + * + * The character is always written using the native UTF-16BE charset because + * its size under arbitrary encoding is not evident. + */ + public void write_wchar(char x) + { + try + { + if (giop.until_inclusive(1, 1)) + { + align(2); + + if (wide_native) + b.writeShort(x); + else + { + OutputStreamWriter ow = new OutputStreamWriter( + (OutputStream) b, wide_charset); + ow.write(x); + ow.flush(); + } + } + else if (wide_native) + { + b.writeByte(2); + b.writeChar(x); + } + else + { + String encoded = new String(new char[] { x }); + byte[] bytes = encoded.getBytes(wide_charset); + b.write(bytes.length + 2); + b.write(bytes); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Write the array of wide chars. + * + * @param chars the array of wide chars + * @param offset offset + * @param length length + * + * The char array is always written using the native UTF-16BE charset because + * the character size under arbitrary encoding is not evident. + */ + public void write_wchar_array(char[] chars, int offset, int length) + { + try + { + if (giop.until_inclusive(1, 1)) + align(2); + + if (wide_native) + { + for (int i = offset; i < offset + length; i++) + { + b.writeShort(chars [ i ]); + } + } + else + { + OutputStreamWriter ow = + new OutputStreamWriter((OutputStream) b, wide_charset); + ow.write(chars, offset, length); + ow.flush(); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** + * Writes the length of the string in bytes (not characters) and + * then all characters as two byte unicode chars. Adds the + * Big Endian indicator, 0xFFFE, at the beginning and null wide char at + * the end. + * + * @param x the string to write. + */ + public void write_wstring(String x) + { + try + { + if (giop.since_inclusive(1, 2)) + { + byte[] bytes = x.getBytes(wide_charset); + write_sequence(bytes); + } + else + { + // Encoding with null terminator always in UTF-16. + // The wide null terminator needs extra two bytes. + write_long(2 * x.length() + 2); + + for (int i = 0; i < x.length(); i++) + { + b.writeShort(x.charAt(i)); + } + + // Write null terminator. + b.writeShort(0); + } + } + catch (IOException ex) + { + Unexpected.error(ex); + } + } + + /** {@inheritDoc} */ + public void write_any_array(Any[] anys, int offset, int length) + { + for (int i = offset; i < offset + length; i++) + { + write_any(anys [ i ]); + } + } + + public String[] _truncatable_ids() + { + /**@todo Implement this org.omg.CORBA.portable.ValueBase abstract method*/ + throw new java.lang.UnsupportedOperationException("Method _truncatable_ids() not yet implemented."); + } + + /** {@inheritDoc} */ + public void write_Abstract(java.lang.Object value) + { + write_abstract_interface(value); + } + + /** {@inheritDoc} */ + public void write_Value(Serializable value) + { + write_value(value); + } +} \ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/AbstractDataInput.java b/libjava/classpath/gnu/CORBA/CDR/AbstractDataInput.java new file mode 100644 index 00000000000..4d120fa2c0c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AbstractDataInput.java @@ -0,0 +1,392 @@ +/* AbstractDataInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.IOException; + +/** + * Some data input stream that can be either Big or + * Little Endian. + * + * This class reuses code from GNU Classpath DataInputStream. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * @author Warren Levy (warrenl@cygnus.com) + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public interface AbstractDataInput +{ + /** + * This method reads bytes from the underlying stream into the specified + * byte array buffer. It will attempt to fill the buffer completely, but + * may return a short count if there is insufficient data remaining to be + * read to fill the buffer. + * + * @param b The buffer into which bytes will be read. + * + * @return The actual number of bytes read, or -1 if end of stream reached + * before reading any bytes. + * + * @exception IOException If an error occurs. + */ + int read(byte[] b) + throws IOException; + + /** + * This method reads bytes from the underlying stream into the specified + * byte array buffer. It will attempt to read len bytes and + * will start storing them at position off into the buffer. + * This method can return a short count if there is insufficient data + * remaining to be read to complete the desired read length. + * + * @param b The buffer into which bytes will be read. + * @param off The offset into the buffer to start storing bytes. + * @param len The requested number of bytes to read. + * + * @return The actual number of bytes read, or -1 if end of stream reached + * before reading any bytes. + * + * @exception IOException If an error occurs. + */ + int read(byte[] b, int off, int len) + throws IOException; + + /** + * This method reads a Java boolean value from an input stream. It does + * so by reading a single byte of data. If that byte is zero, then the + * value returned is false. If the byte is non-zero, then + * the value returned is true. + *

+ * This method can read a boolean written by an object + * implementing the writeBoolean() method in the + * DataOutput interface. + * + * @return The boolean value read + * + * @exception EOFException If end of file is reached before reading + * the boolean + * @exception IOException If any other error occurs + * + * @see DataOutput#writeBoolean + */ + boolean readBoolean() + throws IOException; + + /** + * This method reads a Java byte value from an input stream. The value + * is in the range of -128 to 127. + *

+ * This method can read a byte written by an object + * implementing the writeByte() method in the + * DataOutput interface. + * + * @return The byte value read + * + * @exception EOFException If end of file is reached before reading the byte + * @exception IOException If any other error occurs + * + * @see DataOutput#writeByte + */ + byte readByte() + throws IOException; + + /** + * This method reads a Java char value from an input stream. + * It operates by reading two bytes from the stream and converting them to + * a single 16-bit Java char. The two bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + *

+ * As an example, if byte1 and byte2 + * represent the first and second byte read from the stream + * respectively, they will be transformed to a char in + * the following manner: + *

+ * (char)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF) + *

+ * This method can read a char written by an object + * implementing the writeChar() method in the + * DataOutput interface. + * + * @return The char value read + * + * @exception EOFException If end of file is reached before reading the char + * @exception IOException If any other error occurs + * + * @see DataOutput#writeChar + */ + char readChar() + throws IOException; + + /** + * This method reads a Java double value from an input stream. It operates + * by first reading a long value from the stream by calling the + * readLong() method in this interface, then converts + * that long to a double using the + * longBitsToDouble method in the class + * java.lang.Double + *

+ * This method can read a double written by an object + * implementing the writeDouble() method in the + * DataOutput interface. + * + * @return The double value read + * + * @exception EOFException If end of file is reached before reading + * the double + * @exception IOException If any other error occurs + * + * @see DataOutput#writeDouble + * @see java.lang.Double#longBitsToDouble + */ + double readDouble() + throws IOException; + + /** + * This method reads a Java float value from an input stream. It + * operates by first reading an int value from the + * stream by calling the readInt() method in this + * interface, then converts that int to a + * float using the intBitsToFloat method + * in the class java.lang.Float + *

+ * This method can read a float written by an object + * implementing the writeFloat() method in the + * DataOutput interface. + * + * @return The float value read + * + * @exception EOFException If end of file is reached before reading the float + * @exception IOException If any other error occurs + * + * @see DataOutput#writeFloat + * @see java.lang.Float#intBitsToFloat + */ + float readFloat() + throws IOException; + + /** + * This method reads raw bytes into the passed array until the array is + * full. Note that this method blocks until the data is available and + * throws an exception if there is not enough data left in the stream to + * fill the buffer. Note also that zero length buffers are permitted. + * In this case, the method will return immediately without reading any + * bytes from the stream. + * + * @param b The buffer into which to read the data + * + * @exception EOFException If end of file is reached before filling the + * buffer + * @exception IOException If any other error occurs + */ + void readFully(byte[] b) + throws IOException; + + /** + * This method reads a Java int value from an input stream + * It operates by reading four bytes from the stream and converting them to + * a single Java int. The bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + *

+ * As an example, if byte1 through byte4 represent + * the first four bytes read from the stream, they will be + * transformed to an int in the following manner: + *

+ * (int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + + * ((byte3 & 0xFF)<< 8) + (byte4 & 0xFF))) + *

+ * The value returned is in the range of -2147483648 to 2147483647. + *

+ * This method can read an int written by an object + * implementing the writeInt() method in the + * DataOutput interface. + * + * @return The int value read + * + * @exception EOFException If end of file is reached before reading the int + * @exception IOException If any other error occurs + * + * @see DataOutput#writeInt + */ + int readInt() + throws IOException; + + /** + * This method reads a Java long value from an input stream + * It operates by reading eight bytes from the stream and converting them to + * a single Java long. The bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + *

+ * As an example, if byte1 through byte8 represent + * the first eight bytes read from the stream, they will be + * transformed to an long in the following manner: + *

+ * (long)(((byte1 & 0xFF) << 56) + ((byte2 & 0xFF) << 48) + + * ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) + + * ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) + + * ((byte7 & 0xFF) << 8) + (byte8 & 0xFF))) + * + *

+ * The value returned is in the range of -9223372036854775808 to + * 9223372036854775807. + *

+ * This method can read an long written by an object + * implementing the writeLong() method in the + * DataOutput interface. + * + * @return The long value read + * + * @exception EOFException If end of file is reached before reading the long + * @exception IOException If any other error occurs + * + * @see DataOutput#writeLong + */ + long readLong() + throws IOException; + + /** + * This method reads a signed 16-bit value into a Java in from the + * stream. It operates by reading two bytes from the stream and + * converting them to a single 16-bit Java short. The + * two bytes are stored most significant byte first (i.e., "big + * endian") regardless of the native host byte ordering. + *

+ * As an example, if byte1 and byte2 + * represent the first and second byte read from the stream + * respectively, they will be transformed to a short. in + * the following manner: + *

+ * (short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)) + *

+ * The value returned is in the range of -32768 to 32767. + *

+ * This method can read a short written by an object + * implementing the writeShort() method in the + * DataOutput interface. + * + * @return The short value read + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort + */ + short readShort() + throws IOException; + + /** + * This method reads 8 unsigned bits into a Java int + * value from the stream. The value returned is in the range of 0 to + * 255. + *

+ * This method can read an unsigned byte written by an object + * implementing the writeUnsignedByte() method in the + * DataOutput interface. + * + * @return The unsigned bytes value read as a Java int. + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeByte + */ + int readUnsignedByte() + throws IOException; + + /** + * This method reads 16 unsigned bits into a Java int value from the stream. + * It operates by reading two bytes from the stream and converting them to + * a single Java int The two bytes are stored most + * significant byte first (i.e., "big endian") regardless of the native + * host byte ordering. + *

+ * As an example, if byte1 and byte2 + * represent the first and second byte read from the stream + * respectively, they will be transformed to an int in + * the following manner: + *

+ * (int)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF)) + *

+ * The value returned is in the range of 0 to 65535. + *

+ * This method can read an unsigned short written by an object + * implementing the writeUnsignedShort() method in the + * DataOutput interface. + * + * @return The unsigned short value read as a Java int + * + * @exception EOFException If end of file is reached before reading the value + * @exception IOException If any other error occurs + * + * @see DataOutput#writeShort + */ + int readUnsignedShort() + throws IOException; + + /** + * Read a single byte. + * + * @return a byte, extracted from the stream or -1 if + * EOF has been reached. + * @throws IOException + */ + public int read() + throws IOException; + + /** + * This method attempts to skip and discard the specified number of bytes + * in the input stream. It may actually skip fewer bytes than requested. + * This method will not skip any bytes if passed a negative number of bytes + * to skip. + * + * @param n The requested number of bytes to skip. + * + * @return The requested number of bytes to skip. + * + * @exception IOException If an error occurs. + * @specnote The JDK docs claim that this returns the number of bytes + * actually skipped. The JCL claims that this method can throw an + * EOFException. Neither of these appear to be true in the JDK 1.3's + * implementation. This tries to implement the actual JDK behaviour. + */ + int skipBytes(int n) + throws IOException; +} \ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/AbstractDataOutput.java b/libjava/classpath/gnu/CORBA/CDR/AbstractDataOutput.java new file mode 100644 index 00000000000..e37c0cb7ddd --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AbstractDataOutput.java @@ -0,0 +1,185 @@ +/* AbstractDataOutput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.IOException; + +/** + * An abstract data output stream that could write data in either + * Big Endian or Little Endian format. + * + * This class reuses code from GNU Classpath DataOutputStream. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * @author Warren Levy (warrenl@cygnus.com) + * @author Aaron M. Renn (arenn@urbanophile.com) + */ +public interface AbstractDataOutput +{ + /** + * This method flushes any unwritten bytes to the underlying stream. + * + * @exception IOException If an error occurs. + */ + void flush() + throws IOException; + + /** + * This method writes the specified byte (passed as an int) + * to the underlying output stream. + * + * @param value The byte to write, passed as an int. + * + * @exception IOException If an error occurs. + */ + void write(int value) + throws IOException; + + /** + * This method writes len bytes from the specified byte array + * buf starting at position offset into the + * buffer to the underlying output stream. + * + * @param buf The byte array to write from. + * @param offset The index into the byte array to start writing from. + * @param len The number of bytes to write. + * + * @exception IOException If an error occurs. + */ + void write(byte[] buf, int offset, int len) + throws IOException; + + /** + * Write the complete byte array. + * @throws IOException + */ + void write(byte[] buf) + throws IOException; + + /** + * This method writes a Java boolean value to an output stream. If + * value is true, a byte with the value of + * 1 will be written, otherwise a byte with the value of 0 will be + * written. + * + * The value written can be read using the readBoolean + * method in DataInput. + * + * @param value The boolean value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeBoolean(boolean value) + throws IOException; + + /** + * This method writes a Java byte value to an output stream. The + * byte to be written will be in the lowest 8 bits of the + * int value passed. + * + * The value written can be read using the readByte or + * readUnsignedByte methods in DataInput. + * + * @param value The byte to write to the stream, passed as + * the low eight bits of an int. + * + * @exception IOException If an error occurs + */ + void writeByte(int value) + throws IOException; + + /** + * This method writes a Java short value to an output stream. The + * char to be written will be in the lowest 16 bits of the int + * value passed. + * + * @exception IOException If an error occurs + */ + void writeShort(int value) + throws IOException; + + /** + * This method writes a Java char value to an output stream. The + * char to be written will be in the lowest 16 bits of the int + * value passed. + * + * @exception IOException If an error occurs + */ + void writeChar(int value) + throws IOException; + + /** + * This method writes a Java int value to an output stream. + * + * @param value The int value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeInt(int value) + throws IOException; + + /** + * This method writes a Java long value to an output stream. + * + * @param value The long value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeLong(long value) + throws IOException; + + /** + * This method writes a Java float value to the stream. + * @param value The float value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeFloat(float value) + throws IOException; + + /** + * This method writes a Java double value to the stream. + * + * @param value The double value to write to the stream + * + * @exception IOException If an error occurs + */ + void writeDouble(double value) + throws IOException; +} \ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/AligningInput.java b/libjava/classpath/gnu/CORBA/CDR/AligningInput.java new file mode 100644 index 00000000000..e2710628a52 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AligningInput.java @@ -0,0 +1,131 @@ +/* AligningInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.ByteArrayInputStream; + +import org.omg.CORBA.BAD_PARAM; + +/** + * The input stream with the possibility to align on the + * word (arbitrary size) boundary. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class AligningInput + extends ByteArrayInputStream +{ + /** + * The alignment offset. + */ + private int offset = 0; + + /** + * Create a stream, reading form the given buffer. + * + * @param a_buffer a buffer to read from. + */ + public AligningInput(byte[] a_buffer) + { + super(a_buffer); + } + + /** + * Set the alignment offset, if the index of the first byte in the + * stream is different from 0. + */ + public void setOffset(int an_offset) + { + offset = an_offset; + } + + /** + * Skip several bytes, aligning the internal pointer on the + * selected boundary. + * + * @throws BAD_PARAM, minor code 0, the alignment is not possible, + * usually due the wrong parameter value. + */ + public void align(int alignment) + { + try + { + int d = (pos + offset) % alignment; + if (d > 0) + { + skip(alignment - d); + } + } + catch (Exception ex) + { + BAD_PARAM p = new BAD_PARAM("Unable to align at " + alignment); + p.initCause(ex); + throw p; + } + } + + /** + * Get the byte buffer, from where the data are read. + */ + public byte[] getBuffer() + { + return buf; + } + + /** + * Get the current position in the buffer. + * + * @return The position in the buffer, taking offset into consideration. + */ + public int getPosition() + { + return pos + offset; + } + + /** + * Jump to the given position, taking offset into consideration. + */ + public void seek(int position) + { + if (position < offset || position > (count+offset)) + throw new ArrayIndexOutOfBoundsException(position + + " is out of valid ["+offset+".." + (count+offset) + "[ range"); + pos = position - offset; + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/AligningOutput.java b/libjava/classpath/gnu/CORBA/CDR/AligningOutput.java new file mode 100644 index 00000000000..135f75af6a7 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/AligningOutput.java @@ -0,0 +1,148 @@ +/* AligningOutput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.ByteArrayOutputStream; + +import org.omg.CORBA.BAD_PARAM; + +/** + * The input stream with the possibility to align on the + * word (arbitrary size) boundary. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class AligningOutput + extends ByteArrayOutputStream +{ + /** + * The alignment offset. + */ + private int offset = 0; + + /** + * Create a stream with the default intial buffer size. + */ + public AligningOutput() + { + } + + /** + * Create a stream with the given intial buffer size. + */ + public AligningOutput(int initial_size) + { + super(initial_size); + } + + /** + * Set the alignment offset, if the index of the first byte in the + * stream is different from 0. + */ + public void setOffset(int an_offset) + { + offset = an_offset; + } + + /** + * Skip several bytes, aligning the internal pointer on the + * selected boundary. + * + * @throws BAD_PARAM, minor code 0, the alignment is not possible, + * usually due the wrong parameter value. + */ + public void align(int alignment) + { + try + { + int d = (count + offset) % alignment; + if (d > 0) + { + skip(alignment - d); + } + } + catch (Exception ex) + { + BAD_PARAM p = new BAD_PARAM("Unable to align at " + alignment); + p.initCause(ex); + throw p; + } + } + + /** + * Write the specified number of zero bytes. + * + * @param bytes the number of zero bytes to write. + */ + public void skip(int bytes) + { + for (int i = 0; i < bytes; i++) + { + write(0); + } + } + + /** + * Get the current position in the buffer. + * + * @return The position in the buffer, taking offset into consideration. + */ + public int getPosition() + { + return size()+offset; + } + + /** + * Seek to the given position (not in use). + */ + public void seek(int position) + { + count = position - offset; + } + + /** + * Get the buffer without copying it. Use with care. + */ + public byte[] getBuffer() + { + return buf; + } + + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/ArrayValueHelper.java b/libjava/classpath/gnu/CORBA/CDR/ArrayValueHelper.java new file mode 100644 index 00000000000..7a4d9c5aa8f --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/ArrayValueHelper.java @@ -0,0 +1,254 @@ +/* ArrayValueHelper.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.ObjectCreator; + +import org.omg.CORBA.BooleanSeqHelper; +import org.omg.CORBA.CharSeqHelper; +import org.omg.CORBA.DoubleSeqHelper; +import org.omg.CORBA.FloatSeqHelper; +import org.omg.CORBA.LongLongSeqHelper; +import org.omg.CORBA.LongSeqHelper; +import org.omg.CORBA.OctetSeqHelper; +import org.omg.CORBA.ShortSeqHelper; +import org.omg.CORBA.portable.BoxedValueHelper; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +import java.io.Serializable; +import java.lang.reflect.Array; +import java.rmi.Remote; + +import javax.rmi.CORBA.Util; +import javax.rmi.CORBA.ValueHandler; + +/** + * Writes arrays as a boxed value types. A single instance is used to write a + * single array. This class is only used with RMI/IIOP, to handle array boxed + * values. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +class ArrayValueHelper + implements BoxedValueHelper +{ + /** + * The value handler (one for all instances). + */ + static ValueHandler handler = Util.createValueHandler(); + + /** + * A class of the array being written. + */ + Class arrayClass; + + /** + * The array component class. + */ + Class component; + + /** + * The array component repository Id. + */ + String componentId; + + /** + * If true, the array members are written as objects rather than as values. + * True for Remotes and CORBA objects. + */ + boolean written_as_object() + { + return org.omg.CORBA.Object.class.isAssignableFrom(component) + || Remote.class.isAssignableFrom(component); + } + + /** + * Creates the instance of the helper to write this specific array class. + */ + ArrayValueHelper(Class an_arrayClass) + { + arrayClass = an_arrayClass; + } + + /** + * Get the array repository Id that will be the RMI repository id. + */ + public String get_id() + { + return ObjectCreator.getRepositoryId(arrayClass); + } + + /** + * Read the array from the input stream. + */ + public Serializable read_value(InputStream input) + { + if (input instanceof HeadlessInput) + { + ((HeadlessInput) input).subsequentCalls = true; + } + + component = arrayClass.getComponentType(); + + if (component.equals(byte.class)) + return OctetSeqHelper.read(input); + else if (component.equals(String.class)) + { + // String array is optimized because this may be frequent. + String[] s = new String[input.read_long()]; + + for (int i = 0; i < s.length; i++) + s[i] = (String) Vio.read(input, Vio.m_StringValueHelper); + return s; + } + else if (component.equals(int.class)) + return LongSeqHelper.read(input); + else if (component.equals(long.class)) + return LongLongSeqHelper.read(input); + else if (component.equals(double.class)) + return DoubleSeqHelper.read(input); + else if (component.equals(float.class)) + return FloatSeqHelper.read(input); + else if (component.equals(boolean.class)) + return BooleanSeqHelper.read(input); + else if (component.equals(short.class)) + return ShortSeqHelper.read(input); + else if (component.equals(char.class)) + return CharSeqHelper.read(input); + else + { + // Read others, use reflection. + int n = input.read_long(); + + gnuValueStream s = null; + + Serializable array = (Serializable) Array.newInstance(component, n); + if (written_as_object()) + for (int i = 0; i < n; i++) + { + gnuRuntime g; + int position; + if (input instanceof gnuValueStream) + { + s = (gnuValueStream) input; + g = s.getRunTime(); + position = s.getPosition(); + } + else + { + g = null; + position = -1; + } + + if (input instanceof HeadlessInput) + ((HeadlessInput) input).subsequentCalls = true; + + Object o = handler.readValue(input, position, component, null, g); + Array.set(array, i, o); + } + else + for (int i = 0; i < n; i++) + Array.set(array, i, Vio.read(input, component)); + return array; + } + } + + /** + * Write the array to the input stream. + */ + public void write_value(OutputStream output, Serializable value) + { + if (output instanceof gnuValueStream) + { + gnuRuntime r = ((gnuValueStream) output).getRunTime(); + if (r != null) + r.target = null; + } + + if (value instanceof byte[]) + OctetSeqHelper.write(output, (byte[]) value); + else if (value instanceof String[]) + { + String[] s = (String[]) value; + output.write_long(s.length); + for (int i = 0; i < s.length; i++) + Vio.write(output, s[i], Vio.m_StringValueHelper); + } + else if (value instanceof int[]) + LongSeqHelper.write(output, (int[]) value); + else if (value instanceof long[]) + LongLongSeqHelper.write(output, (long[]) value); + else if (value instanceof double[]) + DoubleSeqHelper.write(output, (double[]) value); + else if (value instanceof float[]) + FloatSeqHelper.write(output, (float[]) value); + else if (value instanceof boolean[]) + BooleanSeqHelper.write(output, (boolean[]) value); + else if (value instanceof short[]) + ShortSeqHelper.write(output, (short[]) value); + else if (value instanceof char[]) + CharSeqHelper.write(output, (char[]) value); + else + { + // Write others, use reflection. + component = arrayClass.getComponentType(); + + int n = Array.getLength(value); + output.write_long(n); + if (written_as_object()) + for (int i = 0; i < n; i++) + { + Object o = Array.get(value, i); + if (o == null) + output.write_Object(null); + else + // CORBA objects have another notation. + handler.writeValue(output, (Serializable) o); + } + else + { + for (int i = 0; i < n; i++) + Vio.write(output, (Serializable) Array.get(value, i), + component); + } + + } + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/BigEndianInputStream.java b/libjava/classpath/gnu/CORBA/CDR/BigEndianInputStream.java index bc019396adb..1559d75a41e 100644 --- a/libjava/classpath/gnu/CORBA/CDR/BigEndianInputStream.java +++ b/libjava/classpath/gnu/CORBA/CDR/BigEndianInputStream.java @@ -49,7 +49,7 @@ import java.io.InputStream; */ public class BigEndianInputStream extends DataInputStream - implements abstractDataInputStream + implements AbstractDataInput { /** * Delegates to the parent constructor. diff --git a/libjava/classpath/gnu/CORBA/CDR/BigEndianOutputStream.java b/libjava/classpath/gnu/CORBA/CDR/BigEndianOutputStream.java index e0aa7da773e..7d3b02ec950 100644 --- a/libjava/classpath/gnu/CORBA/CDR/BigEndianOutputStream.java +++ b/libjava/classpath/gnu/CORBA/CDR/BigEndianOutputStream.java @@ -50,7 +50,7 @@ import java.io.OutputStream; */ public class BigEndianOutputStream extends DataOutputStream - implements abstractDataOutputStream + implements AbstractDataOutput { /** * Delegate functionality to the parent constructor. diff --git a/libjava/classpath/gnu/CORBA/CDR/BufferedCdrOutput.java b/libjava/classpath/gnu/CORBA/CDR/BufferedCdrOutput.java new file mode 100644 index 00000000000..69bf95beb66 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/BufferedCdrOutput.java @@ -0,0 +1,156 @@ +/* BufferedCdrOutput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.ByteArrayOutputStream; + +/** + * A CORBA output stream, writing data into the internal buffer ({@link ByteArrayOutputStream}). + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class BufferedCdrOutput + extends AbstractCdrOutput + implements gnuValueStream +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The byte buffer. + */ + public final AligningOutput buffer; + + /** + * Creates the instance with the given initial buffer size. + * + * @param bufSize the buffer size. + */ + public BufferedCdrOutput(int bufSize) + { + buffer = new AligningOutput(bufSize); + setOutputStream(buffer); + } + + /** + * Creates the instance with the default buffer size. + */ + public BufferedCdrOutput() + { + buffer = new AligningOutput(); + setOutputStream(buffer); + } + + /** + * Set the alignment offset, if the index of the first byte in the stream is + * different from 0. + */ + public void setOffset(int an_offset) + { + buffer.setOffset(an_offset); + } + + /** + * Align the curretn position at the given natural boundary. + */ + public void align(int boundary) + { + buffer.align(boundary); + } + + /** + * Return the input stream that reads the previously written values. + */ + public org.omg.CORBA.portable.InputStream create_input_stream() + { + BufferredCdrInput in = new BufferredCdrInput(buffer.toByteArray()); + in.setOrb(orb); + + in.setVersion(giop); + in.setCodeSet(getCodeSet()); + + return in; + } + + /** + * Resets (clears) the buffer. + */ + public void reset() + { + buffer.reset(); + setOutputStream(buffer); + } + + /** + * Get the current position in the buffer. + * + * @return The position in the buffer, taking offset into consideration. + */ + public int getPosition() + { + return buffer.getPosition(); + } + + /** + * Get the associated RunTime. + */ + public gnuRuntime getRunTime() + { + return runtime; + } + + /** + * Replace the instance of RunTime. + */ + public void setRunTime(gnuRuntime a_runtime) + { + runtime = a_runtime; + } + + /** + * Seek to the given position. + */ + public void seek(int position) + { + buffer.seek(position); + } + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/BufferredCdrInput.java b/libjava/classpath/gnu/CORBA/CDR/BufferredCdrInput.java new file mode 100644 index 00000000000..f0159a88dac --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/BufferredCdrInput.java @@ -0,0 +1,153 @@ +/* BufferredCdrInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + + +/** + * The CDR input stream that reads data from the byte buffer. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class BufferredCdrInput + extends AbstractCdrInput + implements gnuValueStream +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The byte array input stream to read data from. + */ + public final AligningInput buffer; + + /** + * Creates the CDR input stream that reads from the given buffer + * array. + * + * @param a_buffer an array to read from. + */ + public BufferredCdrInput(byte[] a_buffer) + { + buffer = new AligningInput(a_buffer); + setInputStream(buffer); + } + + /** + * Set the alignment offset, if the index of the first byte in the + * stream is different from 0. + */ + public void setOffset(int offset) + { + buffer.setOffset(offset); + } + + /** + * Skip several bytes, aligning the internal pointer on the + * selected boundary. + */ + public void align(int alignment) + { + buffer.align(alignment); + } + + /** + * Mark the current position. + * @param ahead + */ + public synchronized void mark(int ahead) + { + buffer.mark(ahead); + } + + /** + * Checks if marking is supported. + * @return + */ + public boolean markSupported() + { + return buffer.markSupported(); + } + + /** + * Resets the stream to the previously marked position. + */ + public void reset() + { + buffer.reset(); + setInputStream(buffer); + } + + /** + * Get the current position in the buffer. + * + * @return The position in the buffer, taking offset into consideration. + */ + public int getPosition() + { + return buffer.getPosition(); + } + + /** + * Jump to the given position, taking offset into consideration. + */ + public void seek(int position) + { + buffer.seek(position); + setInputStream(buffer); + } + + /** + * Get the associated RunTime. + */ + public gnuRuntime getRunTime() + { + return runtime; + } + + /** + * Replace the instance of RunTime. + */ + public void setRunTime(gnuRuntime a_runtime) + { + runtime = a_runtime; + } + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/EncapsulationStream.java b/libjava/classpath/gnu/CORBA/CDR/EncapsulationStream.java new file mode 100644 index 00000000000..4945d9c906a --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/EncapsulationStream.java @@ -0,0 +1,146 @@ +/* EncapsulationOutput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import java.io.IOException; + +/** + * The encapsulated data, as they are defined by CORBA specification. + * This includes the extra 0 byte (Big endian) in the beginning. + * When written to the parent steam, the encapsulated data are preceeded + * by the data length in bytes. + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + */ +public class EncapsulationStream + extends AbstractCdrOutput +{ + /** + * The Big Endian (most siginificant byte first flag). + */ + public static final byte BIG_ENDIAN = 0; + + /** + * The Little Endian (least siginificant byte first flag). + */ + public static final byte LITTLE_ENDIAN = 1; + + /** + * The byte buffer. + */ + public final AligningOutput buffer; + + /** + * The stream, where the data are being encapsulated. + */ + public final org.omg.CORBA.portable.OutputStream parent; + + /** + * Create the EncapsulationOutput with the given parent stream + * and the specified encoding. + */ + public EncapsulationStream(org.omg.CORBA.portable.OutputStream _parent, + boolean use_big_endian) + { + super(); + buffer = new AligningOutput(); + setOutputStream(buffer); + parent = _parent; + write(use_big_endian?BIG_ENDIAN:LITTLE_ENDIAN); + } + + /** + * Set the alignment offset, if the index of the first byte in the + * stream is different from 0. + */ + public void setOffset(int an_offset) + { + buffer.setOffset(an_offset); + } + + /** + * Align the curretn position at the given natural boundary. + */ + public void align(int boundary) + { + buffer.align(boundary); + } + + /** + * Writes the content of the encapsulated output into the parent + * buffer. + */ + public void close() + { + try + { + parent.write_long(buffer.size()); + buffer.writeTo(parent); + } + catch (IOException ex) + { + InternalError err = new InternalError(); + err.initCause(ex); + throw err; + } + } + + /** + * Return the input stream that reads the previously written values. + */ + public org.omg.CORBA.portable.InputStream create_input_stream() + { + BufferredCdrInput in = new BufferredCdrInput(buffer.toByteArray()); + in.setOrb(orb); + + in.setVersion(giop); + in.setCodeSet(getCodeSet()); + + return in; + } + + /** + * Resets (clears) the buffer. + */ + public void reset() + { + buffer.reset(); + setOutputStream(buffer); + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/HeadlessInput.java b/libjava/classpath/gnu/CORBA/CDR/HeadlessInput.java new file mode 100644 index 00000000000..0c18dafb195 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/HeadlessInput.java @@ -0,0 +1,749 @@ +/* HeadlessInput.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.Minor; + +import org.omg.CORBA.Any; +import org.omg.CORBA.AnySeqHolder; +import org.omg.CORBA.BooleanSeqHolder; +import org.omg.CORBA.CharSeqHolder; +import org.omg.CORBA.Context; +import org.omg.CORBA.DataInputStream; +import org.omg.CORBA.DoubleSeqHolder; +import org.omg.CORBA.FloatSeqHolder; +import org.omg.CORBA.LongLongSeqHolder; +import org.omg.CORBA.LongSeqHolder; +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.ORB; +import org.omg.CORBA.OctetSeqHolder; +import org.omg.CORBA.Principal; +import org.omg.CORBA.ShortSeqHolder; +import org.omg.CORBA.TypeCode; +import org.omg.CORBA.ULongLongSeqHolder; +import org.omg.CORBA.ULongSeqHolder; +import org.omg.CORBA.UShortSeqHolder; +import org.omg.CORBA.WCharSeqHolder; +import org.omg.CORBA.portable.BoxedValueHelper; +import org.omg.CORBA.portable.InputStream; + +import java.io.IOException; +import java.io.Serializable; +import java.math.BigDecimal; + +/** + * Substitutes the main stream in factories when the header is already behind. + * Overrides methods that may be invoked from the factory, forcing not to read + * the header if called first time on this stream. + * + * This stream reverts to default behavior if one or more call are made (reading + * value types that are nested fields of the value type). + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class HeadlessInput + extends org.omg.CORBA_2_3.portable.InputStream + implements DataInputStream, gnuValueStream +{ + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * Indicates that no positional information is available. + */ + static final int NONE = -1; + + /** + * If true, this is not the first call. + */ + public boolean subsequentCalls; + + /** + * The enclosed stream. + */ + final BufferredCdrInput stream; + + /** + * Create an instance, reading from the given buffer. + * + * @param a_stram a stream from where the data will be read. + * @param inheritSettings a stream from that endian and other settings are + * inherited. + */ + public HeadlessInput(BufferredCdrInput a_stream, InputStream inheritSettings) + { + stream = a_stream; + + if (inheritSettings instanceof AbstractCdrInput) + { + AbstractCdrInput t = (AbstractCdrInput) inheritSettings; + t.cloneSettings(stream); + } + else if (stream.orb() == null) + stream.setOrb(inheritSettings.orb()); + + if (inheritSettings instanceof gnuValueStream + && stream.getRunTime() == null) + { + stream.setRunTime(((gnuValueStream) inheritSettings).getRunTime()); + } + } + + /** + * Tries to read using boxed value helper. + */ + public Serializable read_value(BoxedValueHelper helper) + { + if (subsequentCalls) + return stream.read_value(helper); + else + { + subsequentCalls = true; + return helper.read_value(this); + } + } + + /** + * Tries to locate a factory using repository id. + */ + public Serializable read_value(String repository_id) + { + if (subsequentCalls) + return stream.read_value(repository_id); + else + { + subsequentCalls = true; + Serializable value = (Serializable) Vio.readValue(this, NONE, null, + null, repository_id, null, null); + return value; + } + } + + /** + * Try to read when having an unitialised value. + */ + public Serializable read_value(Serializable value) + { + if (subsequentCalls) + return stream.read_value(value); + else + { + subsequentCalls = true; + value = (Serializable) Vio.readValue(this, NONE, value, null, null, + null, null); + return value; + } + } + + /** + * Try to read when having an unitialised value. + */ + public Serializable read_value(Class clz) + { + if (subsequentCalls) + return stream.read_value(clz); + else + { + try + { + subsequentCalls = true; + Serializable value = (Serializable) Vio.instantiateAnyWay(clz); + value = (Serializable) Vio.readValue(this, NONE, value, null, null, + null, null); + return value; + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL("Can't read an instance of " + + clz.getName()); + m.minor = Minor.Value; + m.initCause(ex); + throw m; + } + } + } + + /** + * Delegates functionality to the underlying stream. + */ + public int available() + throws IOException + { + return stream.available(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void close() + throws IOException + { + stream.close(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void mark(int readlimit) + { + stream.mark(readlimit); + } + + /** + * Delegates functionality to the underlying stream. + */ + public boolean markSupported() + { + return stream.markSupported(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public ORB orb() + { + return stream.orb(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Object read_abstract_interface() + { + return stream.read_abstract_interface(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Object read_abstract_interface(Class clz) + { + return stream.read_abstract_interface(clz); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Any read_any() + { + return stream.read_any(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_boolean_array(boolean[] value, int offset, int length) + { + stream.read_boolean_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public boolean read_boolean() + { + return stream.read_boolean(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_char_array(char[] value, int offset, int length) + { + stream.read_char_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public char read_char() + { + return stream.read_char(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Context read_Context() + { + return stream.read_Context(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_double_array(double[] value, int offset, int length) + { + stream.read_double_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public double read_double() + { + return stream.read_double(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public BigDecimal read_fixed() + { + return stream.read_fixed(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_float_array(float[] value, int offset, int length) + { + stream.read_float_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public float read_float() + { + return stream.read_float(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_long_array(int[] value, int offset, int length) + { + stream.read_long_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int read_long() + { + return stream.read_long(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_longlong_array(long[] value, int offset, int length) + { + stream.read_longlong_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public long read_longlong() + { + return stream.read_longlong(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public org.omg.CORBA.Object read_Object() + { + return stream.read_Object(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public org.omg.CORBA.Object read_Object(Class klass) + { + return stream.read_Object(klass); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_octet_array(byte[] value, int offset, int length) + { + stream.read_octet_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public byte read_octet() + { + return stream.read_octet(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Principal read_Principal() + { + return stream.read_Principal(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_short_array(short[] value, int offset, int length) + { + stream.read_short_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public short read_short() + { + return stream.read_short(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public String read_string() + { + return stream.read_string(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public TypeCode read_TypeCode() + { + return stream.read_TypeCode(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ulong_array(int[] value, int offset, int length) + { + stream.read_ulong_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int read_ulong() + { + return stream.read_ulong(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ulonglong_array(long[] value, int offset, int length) + { + stream.read_ulonglong_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public long read_ulonglong() + { + return stream.read_ulonglong(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ushort_array(short[] value, int offset, int length) + { + stream.read_ushort_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public short read_ushort() + { + return stream.read_ushort(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Serializable read_value() + { + return read_value((Serializable) null); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_wchar_array(char[] value, int offset, int length) + { + stream.read_wchar_array(value, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public char read_wchar() + { + return stream.read_wchar(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public String read_wstring() + { + return stream.read_wstring(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int read() + throws IOException + { + return stream.read(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int read(byte[] b, int off, int len) + throws IOException + { + return stream.read(b, off, len); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int read(byte[] b) + throws IOException + { + return stream.read(b); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void reset() + throws IOException + { + stream.reset(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public long skip(long n) + throws IOException + { + return stream.skip(n); + } + + /** + * Get a string representation. + */ + public String toString() + { + return "HeadlessInput+" + stream.toString(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public String[] _truncatable_ids() + { + return stream._truncatable_ids(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public Object read_Abstract() + { + return stream.read_Abstract(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_any_array(AnySeqHolder holder, int offset, int length) + { + stream.read_any_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_boolean_array(BooleanSeqHolder holder, int offset, int length) + { + stream.read_boolean_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_char_array(CharSeqHolder holder, int offset, int length) + { + stream.read_char_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_double_array(DoubleSeqHolder holder, int offset, int length) + { + stream.read_double_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_float_array(FloatSeqHolder holder, int offset, int length) + { + stream.read_float_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_long_array(LongSeqHolder holder, int offset, int length) + { + stream.read_long_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_longlong_array(LongLongSeqHolder holder, int offset, + int length) + { + stream.read_longlong_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_octet_array(OctetSeqHolder holder, int offset, int length) + { + stream.read_octet_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_short_array(ShortSeqHolder holder, int offset, int length) + { + stream.read_short_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ulong_array(ULongSeqHolder holder, int offset, int length) + { + stream.read_ulong_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ulonglong_array(ULongLongSeqHolder holder, int offset, + int length) + { + stream.read_ulonglong_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_ushort_array(UShortSeqHolder holder, int offset, int length) + { + stream.read_ushort_array(holder, offset, length); + } + + /** + * Delegates functionality to read_value. + */ + public Serializable read_Value() + { + return read_value(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public void read_wchar_array(WCharSeqHolder holder, int offset, int length) + { + stream.read_wchar_array(holder, offset, length); + } + + /** + * Delegates functionality to the underlying stream. + */ + public int getPosition() + { + return stream.getPosition(); + } + + /** + * Delegates functionality to the underlying stream. + */ + public gnuRuntime getRunTime() + { + return stream.runtime; + } + + /** + * Replace the instance of RunTime. + */ + public void setRunTime(gnuRuntime a_runtime) + { + stream.runtime = a_runtime; + } + + /** + * Delegates functionality to the underlying stream. + */ + public void seek(int position) + { + stream.seek(position); + } + +} \ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/IDLTypeHelper.java b/libjava/classpath/gnu/CORBA/CDR/IDLTypeHelper.java new file mode 100644 index 00000000000..3259a48770c --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/IDLTypeHelper.java @@ -0,0 +1,169 @@ +/* IDLTypeHelper.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.Minor; + +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.portable.BoxedValueHelper; +import org.omg.CORBA.portable.InputStream; +import org.omg.CORBA.portable.OutputStream; + +import java.io.Serializable; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +/** + * Handles case when the CORBA IDL type with the known helper is wrapped into + * Value type. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class IDLTypeHelper + implements BoxedValueHelper +{ + /** + * A helper class. + */ + protected Class helper; + + /** + * Argument values for Helper.id(). + */ + static final Object[] ARGS_ID_V = new Object[0]; + + /** + * Argument types for Helper.id()). + */ + static final Class[] ARGS_ID = new Class[0]; + + /** + * Argument types for Helper.read. + */ + static final Class[] ARGS_READ = new Class[] { org.omg.CORBA.portable.InputStream.class }; + + /** + * Create an IDLTypeHelper that works via given helper class. + */ + public IDLTypeHelper(Class a_helperClass) + { + helper = a_helperClass; + } + + /** + * Get the Id, returned by this helper (use reflection). + */ + public String get_id() + { + try + { + Method m = helper.getMethod("id", ARGS_ID); + return (String) m.invoke(null, ARGS_ID_V); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(msg() + " id()"); + m.minor = Minor.Boxed; + m.initCause(ex); + throw m; + } + } + + /** + * Read an instance from the stream. + */ + public Serializable read_value(InputStream input) + { + try + { + Method m = helper.getMethod("read", ARGS_READ); + return (Serializable) m.invoke(null, new Object[] { input }); + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(msg() + " read(..)"); + m.minor = Minor.Boxed; + m.initCause(ex); + throw m; + } + } + + /** + * Write the instance to the stream. + */ + public void write_value(OutputStream output, Serializable value) + { + try + { + Method[] m = helper.getMethods(); + + for (int i = 0; i < m.length; i++) + { + if (m[i].getName().equals("write") + && ((m[i].getModifiers() & Modifier.STATIC) != 0)) + { + Class[] p = m[i].getParameterTypes(); + + if (p.length == 2 && OutputStream.class.isAssignableFrom(p[0]) + && p[1].isAssignableFrom(value.getClass())) + { + m[i].invoke(null, new Object[] { output, value }); + return; + } + } + } + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL(msg() + " write(..)"); + m.minor = Minor.Boxed; + m.initCause(ex); + throw m; + } + } + + /** + * Create the start of message for exceptions. + */ + String msg() + { + return "Failed calling " + helper.getName() + " method: "; + } + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/LittleEndianInputStream.java b/libjava/classpath/gnu/CORBA/CDR/LittleEndianInputStream.java index b71a9a4f66d..02cfa08ae8e 100644 --- a/libjava/classpath/gnu/CORBA/CDR/LittleEndianInputStream.java +++ b/libjava/classpath/gnu/CORBA/CDR/LittleEndianInputStream.java @@ -55,7 +55,7 @@ import java.io.PushbackInputStream; */ public class LittleEndianInputStream extends FilterInputStream - implements abstractDataInputStream + implements AbstractDataInput { // Byte buffer, used to make primitive read calls more efficient. byte[] buf = new byte[ 8 ]; diff --git a/libjava/classpath/gnu/CORBA/CDR/LittleEndianOutputStream.java b/libjava/classpath/gnu/CORBA/CDR/LittleEndianOutputStream.java index a6d56cfa6d0..6791a82e7c3 100644 --- a/libjava/classpath/gnu/CORBA/CDR/LittleEndianOutputStream.java +++ b/libjava/classpath/gnu/CORBA/CDR/LittleEndianOutputStream.java @@ -55,7 +55,7 @@ import java.io.OutputStream; */ public class LittleEndianOutputStream extends FilterOutputStream - implements abstractDataOutputStream + implements AbstractDataOutput { /** * This method initializes an instance of DataOutputStream to diff --git a/libjava/classpath/gnu/CORBA/CDR/UnknownExceptionCtxHandler.java b/libjava/classpath/gnu/CORBA/CDR/UnknownExceptionCtxHandler.java new file mode 100644 index 00000000000..314dd8eb948 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/UnknownExceptionCtxHandler.java @@ -0,0 +1,292 @@ +/* UnknownExceptionCtxHandler.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.Minor; +import gnu.CORBA.ObjectCreator; +import gnu.CORBA.GIOP.ServiceContext; + +import org.omg.CORBA.MARSHAL; +import org.omg.CORBA.NO_IMPLEMENT; +import org.omg.CORBA.StringValueHelper; +import org.omg.CORBA.portable.OutputStream; + +import java.lang.reflect.Constructor; +import java.util.StringTokenizer; + +import javax.rmi.CORBA.Util; + +/** + * Reads the data about an unknown exception from the UnknownExceptionInfo. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class UnknownExceptionCtxHandler + extends Vio +{ + /** + * Encode exception and add its recored to the message service contexts. + */ + public static ServiceContext[] addExceptionContext(ServiceContext[] current, + Throwable exception, Object details) + { + try + { + ServiceContext[] c = new ServiceContext[current.length + 1]; + if (current.length > 0) + System.arraycopy(current, 0, c, 0, current.length); + + BufferedCdrOutput output = new BufferedCdrOutput(); + + if (details instanceof OutputStream) + output.setOrb(((OutputStream) output).orb()); + + if (details instanceof AbstractCdrOutput) + ((AbstractCdrOutput) details).cloneSettings(output); + + write(output, exception); + + ServiceContext xc = new ServiceContext(); + xc.context_id = ServiceContext.UnknownExceptionInfo; + xc.context_data = output.buffer.toByteArray(); + c[current.length] = xc; + return c; + } + catch (Exception ex) + { + ex.printStackTrace(); + return current; + } + } + + /** + * Write data about unknown exception. + */ + public static void write(BufferedCdrOutput output, Throwable t) + { + t.fillInStackTrace(); + output.write_Value(t); + } + + /** + * Read the data about an unknown exception from the UnknownExceptionInfo. + * Following the documentation, this must be just value type, but it seems + * that in Sun's implementation is is not, as starts from 0x0. For value type, + * this would be null. + * + * TODO Implement reading and writing in Sun format, making Classpath IIOP + * interoperable with Sun's implementation. Current inmplementation reads and + * reproduces the exception class type only. + * + * @param input the input stream to read the context (orb and other settings + * are inherited from the main stream that received the message). + * + * @param contexts all service contexts that were present in the message. + * + * @return the Throwable, extracted from context, on null, if this has failed. + */ + public static Throwable read(BufferredCdrInput input, ServiceContext[] contexts) + { + input.mark(Integer.MAX_VALUE); + + int h = input.read_long(); + if (h == 0) + { + // This block reads exception info in the Sun specific format. + // (currently we read the exception name only). + try + { + // We may need to jump back if the value is read via value + // factory. + input.mark(512); + + int value_tag = input.read_long(); + checkTag(value_tag); + + String codebase = null; + String[] ids = null; + String id = null; + + // Check for the agreed null value. + if (value_tag == vt_NULL) + return null; + else if (value_tag == vt_INDIRECTION) + return (Throwable) readIndirection(input); + else + { + // Read the value. + if ((value_tag & vf_CODEBASE) != 0) + { + // The codebase is present. The codebase is a space + // separated list of URLs from where the implementing + // code can be downloaded. + codebase = read_string(input); + } + + if ((value_tag & vf_MULTIPLE_IDS) != 0) + { + // Multiple supported repository ids are present. + ids = read_string_array(input); + } + else if ((value_tag & vf_ID) != 0) + { + // Single supported repository id is present. + id = read_string(input); + } + } + + java.lang.Object ox = createInstance(id, ids, codebase); + + return (Throwable) ox; + } + catch (Exception ex) + { + ex.printStackTrace(); + return null; + } + } + else + { + input.reset(); + // Read as defined in OMG documentation. + return (Throwable) input.read_Value(); + } + } + + /** + * Load exception by name and create the instance. The reason why this is + * different from Vio is because some exceptions have no parameterless + * constructor, but have a constructor with the string parameter instead. + */ + static Object createInstance(String id, String[] ids, String codebase) + { + Object o = _createInstance(id, codebase); + + if (ids != null) + for (int i = 0; i < ids.length && o == null; i++) + o = _createInstance(ids[i], codebase); + return o; + } + + static Object _createInstance(String id, String codebase) + { + if (id == null) + return null; + if (id.equals(StringValueHelper.id())) + return ""; + StringTokenizer st = new StringTokenizer(id, ":"); + + String prefix = st.nextToken(); + if (prefix.equalsIgnoreCase("IDL")) + return ObjectCreator.Idl2Object(id); + else if (prefix.equalsIgnoreCase("RMI")) + { + String className = st.nextToken(); + String hashCode = st.nextToken(); + String sid = null; + if (st.hasMoreElements()) + sid = st.nextToken(); + + try + { + Class objectClass = Util.loadClass(className, codebase, + Vio.class.getClassLoader()); + + String rid = ObjectCreator.getRepositoryId(objectClass); + + if (!rid.equals(id)) + { + // If direct string comparison fails, compare by meaning. + StringTokenizer st2 = new StringTokenizer(rid, ":"); + if (!st2.nextToken().equals("RMI")) + throw new InternalError("RMI format expected: '" + rid + "'"); + if (!st2.nextToken().equals(className)) + throwIt("Class name mismatch", id, rid, null); + + try + { + long h1 = Long.parseLong(hashCode, 16); + long h2 = Long.parseLong(st2.nextToken(), 16); + if (h1 != h2) + throwIt("Hashcode mismatch", id, rid, null); + + if (sid != null && st2.hasMoreTokens()) + { + long s1 = Long.parseLong(hashCode, 16); + long s2 = Long.parseLong(st2.nextToken(), 16); + if (s1 != s2) + throwIt("serialVersionUID mismatch", id, rid, null); + } + } + catch (NumberFormatException e) + { + throwIt("Invalid hashcode or svuid format: ", id, rid, e); + } + } + + // Some RemoteExceptions have no public parameterless constructor, + // but they have constructor taking string as parameter. + try + { + return objectClass.newInstance(); + } + catch (Exception ex) + { + // Try instantiate passing string as parameter. + Constructor c = objectClass.getConstructor(new Class[] { String.class }); + return c.newInstance(new Object[] { "" }); + } + } + catch (MARSHAL m) + { + m.minor = Minor.Instantiation; + throw m; + } + catch (Exception ex) + { + MARSHAL m = new MARSHAL("Unable to instantiate " + id); + m.minor = Minor.Instantiation; + m.initCause(ex); + throw m; + } + } + else + throw new NO_IMPLEMENT("Unsupported prefix " + prefix + ":"); + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/VMVio.java b/libjava/classpath/gnu/CORBA/CDR/VMVio.java new file mode 100644 index 00000000000..9b719fd7c50 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/VMVio.java @@ -0,0 +1,101 @@ +/* VMVio.java -- Native operations, required by value IO. + Copyright (C) 2005 Free Software Foundation, Inc. + + This file is part of GNU Classpath. + + GNU Classpath is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + GNU Classpath is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Classpath; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA. + + Linking this library statically or dynamically with other modules is + making a combined work based on this library. Thus, the terms and + conditions of the GNU General Public License cover the whole + combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent + modules, and to copy and distribute the resulting executable under + terms of your choice, provided that you also meet, for each linked + independent module, the terms and conditions of the license of that + module. An independent module is a module which is not derived from + or based on this library. If you modify this library, you may extend + this exception to your version of the library, but you are not + obligated to do so. If you do not wish to do so, delete this + exception statement from your version. */ + +/** + * This is a temporary replacement for the native call that would allocate + * objects without public constructors. The replacement only allocates + * objects with public parameterless constructor and objects with public + * constructor taking string (like some Throwables). + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) + * + * TODO FIXME replace by native call like in VMObjectInputStream. + * Required modification of Classpath the build system. + */ + + +package gnu.CORBA.CDR; + +import java.lang.reflect.Constructor; + +public class VMVio +{ + /** + * Allocates a new Object of type clazz but without running the default + * constructor on it. It then calls the given constructor on it. The given + * constructor method comes from the constr_clazz which is a super class of + * the given clazz. + */ + public static Object allocateObject(Class clazz, Class constr_clazz, + Constructor constructor) + throws InstantiationException + { + try + { + Constructor c = clazz.getConstructor(new Class[0]); + c.setAccessible(true); + return c.newInstance(new Object[0]); + } + catch (Exception ex) + { + try + { + Constructor c = clazz.getConstructor(new Class[] { String.class }); + return c.newInstance(new Object[] { "" }); + } + catch (Exception ex2) + { + Constructor c[] = clazz.getConstructors(); + + for (int i = 0; i < c.length; i++) + { + try + { + c[i].setAccessible(true); + Class[] args = c[i].getParameterTypes(); + return c[i].newInstance(new Object[args.length]); + } + catch (Exception ex3) + { + // Try another one. + } + } + } + throw new InstantiationException(clazz.getName()); + } + } +} diff --git a/libjava/classpath/gnu/CORBA/CDR/Vio.java b/libjava/classpath/gnu/CORBA/CDR/Vio.java index 0a37132b26f..fd878cb3555 100644 --- a/libjava/classpath/gnu/CORBA/CDR/Vio.java +++ b/libjava/classpath/gnu/CORBA/CDR/Vio.java @@ -1,4 +1,4 @@ -/* gnuValueBaseHelper.java -- +/* Vio.java -- Value type IO operations. Copyright (C) 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,6 +38,7 @@ exception statement from your version. */ package gnu.CORBA.CDR; +import gnu.CORBA.Minor; import gnu.CORBA.ObjectCreator; import org.omg.CORBA.CustomMarshal; @@ -46,106 +47,144 @@ import org.omg.CORBA.DataOutputStream; import org.omg.CORBA.MARSHAL; import org.omg.CORBA.NO_IMPLEMENT; import org.omg.CORBA.StringSeqHelper; +import org.omg.CORBA.StringValueHelper; +import org.omg.CORBA.SystemException; +import org.omg.CORBA.WStringValueHelper; import org.omg.CORBA.portable.BoxedValueHelper; import org.omg.CORBA.portable.InputStream; import org.omg.CORBA.portable.OutputStream; import org.omg.CORBA.portable.Streamable; import org.omg.CORBA.portable.ValueFactory; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.util.StringTokenizer; -import java.lang.reflect.Method; +import javax.rmi.CORBA.Util; +import javax.rmi.CORBA.ValueHandler; /** * A specialised class for reading and writing the value types. - * - * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + * + * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) */ public abstract class Vio { /** - * If true, wrap value type data into chunks. This decrease the - * performance, but is required for the interoperability with - * Sun's CORBA implementation. Chunking may increase the security, - * as there is more control on the number of bytes being transferred. - * + * If true, wrap value type data into chunks. This decrease the performance, + * and is not required for interoperability with jdk 1.5, but is left in the + * implementation as the optional mode for solving possible interoperability + * problems with non-Sun CORBA implementations. + * * The current implementation would accept both single chunk or multiple - * chunks, but will always send a single chunk. + * chunks, but will always send a single chunk (if true) or unchunked data (if + * false). */ - public static boolean USE_CHUNKING = true; + public static boolean USE_CHUNKING = false; /** - * The first field in the value record. The last octet may contain - * additional flags (vf_CODEBASE, vf_ID and vf_MULTIPLE_IDS). The tag - * value is different for the indirections (vt_INDIRECTION) and - * nulls (vt_NULL). + * The first field in the value record. The last octet may contain additional + * flags (vf_CODEBASE, vf_ID and vf_MULTIPLE_IDS). The tag value is different + * for the indirections (vt_INDIRECTION) and nulls (vt_NULL). */ public static final int vt_VALUE_TAG = 0x7fffff00; /** - * The value tag flag, indicating that the codebase URL is present - * in the value tag record. + * The value tag flag, indicating that the codebase URL is present in the + * value tag record. */ public static final int vf_CODEBASE = 0x1; /** - * The value tag flag, indicating that a single repository id is present - * in the value tag record. + * The value tag flag, indicating that a single repository id is present in + * the value tag record. */ public static final int vf_ID = 0x2; /** - * The value tag flag, indicating, that there are multiple repository - * ids present in the record. If this flag is set, the flag vf_ID must - * also be set, resulting the value of the least significant byte 0x6. + * The value tag flag, indicating, that there are multiple repository ids + * present in the record. If this flag is set, the flag vf_ID must also be + * set, resulting the value of the least significant byte 0x6. */ public static final int vf_MULTIPLE_IDS = 0x4; /** * The value tag flag, indicating the presence of chunking. Each chunk is - * preceeded by a positive int, indicating the number of bytes in the chunk. - * A sequence of chunks is terminated by a non positive int. + * preceeded by a positive int, indicating the number of bytes in the chunk. A + * sequence of chunks is terminated by a non positive int. */ public static final int vf_CHUNKING = 0x8; /** * The indirection tag value. Such tag must be followed by the CORBA long, * indicating the offset in the CORBA message, where the indirected - * information is present. This offset is assumed zero at the position - * where the mentioned CORBA long starts and can refer both forward - * (positive values) and backward (negative values). + * information is present. This offset is assumed zero at the position where + * the mentioned CORBA long starts and can refer both forward (positive + * values) and backward (negative values). */ public static final int vt_INDIRECTION = 0xffffffff; /** - * This tag value means that the value object being transferred is equal - * to null. + * This tag value means that the value object being transferred is equal to + * null. */ public static final int vt_NULL = 0x0; /** - * Read the value base from the given input stream. Determines the - * required class from the repository id. This includes operations - * that are not required when an unitialised instance or at least - * class of the value type is known. Hence it may be faster to use - * the alternative methods, read(InputStream, Class) or - * read(InputStream, Serializable). - * + * The size of CORBA long (java int). + */ + static final int INT_SIZE = 4; + + /** + * The String value helper (one instance is sufficient). + */ + public static final WStringValueHelper m_StringValueHelper = new WStringValueHelper(); + + /** + * An instance of the value handler. + */ + static ValueHandler handler = Util.createValueHandler(); + + /** + * Read the value base from the given input stream. Determines the required + * class from the repository id. This includes operations that are not + * required when an unitialised instance or at least class of the value type + * is known. Hence it may be faster to use the alternative methods, + * read(InputStream, Class) or read(InputStream, Serializable). + * * @param input a stream to read from. - * + * @param repository_id a repository id of the object being read, may be null. + * * @return the loaded value. - * + * * @throws MARSHAL if the reading has failed due any reason. */ public static Serializable read(InputStream input) { - // Explicitly prevent the stream from closing as we may need - // to read the subsequent bytes as well. Stream may be auto-closed - // in its finalizer. + return read(input, (String) null); + } + + /** + * Read the value base from the given input stream. Determines the required + * class from the repository id. This includes operations that are not + * required when an unitialised instance or at least class of the value type + * is known. Hence it may be faster to use the alternative methods, + * read(InputStream, Class) or read(InputStream, Serializable). + * + * @param an_input a stream to read from. + * @param repository_id a repository id of the object being read, may be null. + * + * @return the loaded value. + * + * @throws MARSHAL if the reading has failed due any reason. + */ + public static Serializable read(InputStream input, String repository_id) + { try { + final int position = getCurrentPosition(input); // We may need to jump back if the value is read via value factory. input.mark(512); @@ -154,18 +193,13 @@ public abstract class Vio String codebase = null; String[] ids = null; - String id = null; - - // The existing implementing object. - java.lang.Object ox = null; + String id = repository_id; // Check for the agreed null value. if (value_tag == vt_NULL) return null; else if (value_tag == vt_INDIRECTION) - - // TODO FIXME Implement support for indirections. - throw new NO_IMPLEMENT("Indirections unsupported"); + return readIndirection(input); else { // Read the value. @@ -174,152 +208,173 @@ public abstract class Vio // The codebase is present. The codebase is a space // separated list of URLs from where the implementing // code can be downloaded. - codebase = input.read_string(); + codebase = read_string(input); } if ((value_tag & vf_MULTIPLE_IDS) != 0) { // Multiple supported repository ids are present. - ids = StringSeqHelper.read(input); - for (int i = 0; (i < ids.length) && (ox == null); i++) - { - ox = ObjectCreator.Idl2Object(ids [ i ]); - - if (ox == null) - { - // Try to find the value factory. - ValueFactory f = - ((org.omg.CORBA_2_3.ORB) input.orb()).lookup_value_factory(ids [ i ]); - - if (f != null) - { - // Reset, as the value factory reads from beginning. - input.reset(); - return f.read_value((org.omg.CORBA_2_3.portable.InputStream) input); - } - } - } + ids = read_string_array(input); } else if ((value_tag & vf_ID) != 0) { // Single supported repository id is present. - id = input.read_string(); - ox = ObjectCreator.Idl2Object(id); - - if (ox == null) - { - // Try to find the value factory. - ValueFactory f = - ((org.omg.CORBA_2_3.ORB) input.orb()).lookup_value_factory(id); - - if (f != null) - { - input.reset(); - return f.read_value((org.omg.CORBA_2_3.portable.InputStream) input); - } - } + id = read_string(input); } } - if (ox == null) - throw new MARSHAL("Unable to instantiate the value type"); + BoxedValueHelper helper = getHelper(null, id); + // The existing implementing object. + java.lang.Object ox = null; + + if (helper != null) + ox = null; // Helper will care about the instantiating. + else if (id.equals(WStringValueHelper.id())) + helper = m_StringValueHelper; else - { - read_instance(input, ox, value_tag, null); - return (Serializable) ox; - } + ox = createInstance(id, ids, codebase); + return (Serializable) read_instance(input, position, ox, value_tag, + helper, id, ids, codebase); } catch (Exception ex) { - throw new MARSHAL(ex + ":" + ex.getMessage()); + MARSHAL m = new MARSHAL(); + m.minor = Minor.Value; + m.initCause(ex); + throw m; } } /** - * Read the value base from the given input stream when - * the value base class is available. Hence there is no need - * to guess it from the repository id. - * + * Read the value base from the given input stream when the value base class + * is available. Hence there is no need to guess it from the repository id. + * * @param input a stream to read from. * @param value_class the class of the value being read. - * + * * @return the loaded value. - * + * * @throws MARSHAL if the reading has failed due any reason. */ public static Serializable read(InputStream input, Class value_class) { - // Explicitly prevent the stream from closing as we may need - // to read the subsequent bytes as well. Stream may be auto-closed - // in its finalizer. + final int position = getCurrentPosition(input); + + String id = null; + String[] ids = null; + String codebase = null; + try { int value_tag = input.read_long(); checkTag(value_tag); - // The existing implementing object. - java.lang.Object ox = value_class.newInstance(); - // Check for the agreed null value. if (value_tag == vt_NULL) return null; else if (value_tag == vt_INDIRECTION) - - // TODO FIXME Implement support for indirections. - throw new NO_IMPLEMENT("Indirections unsupported"); + return readIndirection(input); else { // Read the value. if ((value_tag & vf_CODEBASE) != 0) { - // The codebase is present, but skip it. - input.read_string(); + // The codebase is present. + codebase = read_string(input); } if ((value_tag & vf_MULTIPLE_IDS) != 0) { - // Multiple supported repository ids are present, but skip them. - StringSeqHelper.read(input); + // Multiple supported repository ids are present. + ids = read_string_array(input); } else if ((value_tag & vf_ID) != 0) { - // Single supported repository id is present, but skip it. - input.read_string(); + // Single supported repository id is present. + id = read_string(input); } } - read_instance(input, ox, value_tag, null); + BoxedValueHelper vHelper = id != null ? getHelper(value_class, id) + : getHelper(value_class, ids); + + java.lang.Object ox; + + if (vHelper == null) + { + try + { + ox = createInstance(id, ids, codebase); + } + catch (Exception e) + { + ox = null; + } + + if (ox != null) + { + if (value_class != null + && !value_class.isAssignableFrom(ox.getClass())) + { + MARSHAL m = new MARSHAL(ox.getClass() + " is not a " + + value_class.getName()); + m.minor = Minor.ClassCast; + throw m; + } + } + } + else + ox = null; + + ox = read_instance(input, position, ox, value_tag, vHelper, id, ids, + codebase); return (Serializable) ox; } + catch (MARSHAL m) + { + throw m; + } + catch (SystemException sysEx) + { + // OK. + throw sysEx; + } catch (Exception ex) { - throw new MARSHAL(ex + ":" + ex.getMessage()); + MARSHAL m = new MARSHAL("Cant read " + value_class); + m.minor = Minor.Value; + m.initCause(ex); + throw m; } } /** - * Read the value base from the given input stream when - * the unitialised instance is available. Hence there is no need - * to guess the class from the repository id and then to instantiate - * an instance. - * + * Read the value base from the given input stream when the unitialised + * instance is available. Hence there is no need to guess the class from the + * repository id and then to instantiate an instance. + * * @param input a stream to read from. - * - * @param value_instance an pre-created instance of the value. If the - * helper is not null, this parameter is ignored an should be null. - * - * @param helper a helper to create an instance and read the object- - * specific part of the record. If the value_instance is used instead, - * this parameter should be null. - * + * + * @param value_instance an pre-created instance of the value. If the helper + * is not null, this parameter is ignored an should be null. + * + * @param helper a helper to create an instance and read the object- specific + * part of the record. If the value_instance is used instead, this parameter + * should be null. + * * @return the loaded value. - * + * * @throws MARSHAL if the reading has failed due any reason. */ public static Object read(InputStream input, Object value_instance, - Object helper - ) + BoxedValueHelper helper) { + final int position = getCurrentPosition(input); + + String id = null; + String[] ids = null; + String codebase = null; + try { int value_tag = input.read_long(); @@ -329,207 +384,396 @@ public abstract class Vio if (value_tag == vt_NULL) return null; else if (value_tag == vt_INDIRECTION) - - // TODO FIXME Implement support for indirections. - throw new NO_IMPLEMENT("Indirections unsupported"); + return readIndirection(input); else { // Read the value. if ((value_tag & vf_CODEBASE) != 0) { - // The codebase is present, but skip it. - input.read_string(); + // The codebase is present. + codebase = read_string(input); } if ((value_tag & vf_MULTIPLE_IDS) != 0) { - // Multiple supported repository ids are present, but skip them. - StringSeqHelper.read(input); + // Multiple supported repository ids are present. + ids = read_string_array(input); } else if ((value_tag & vf_ID) != 0) { - // Single supported repository id is present, but skip it. - input.read_string(); + // Single supported repository id is present. + id = read_string(input); } } - value_instance = - read_instance(input, value_instance, value_tag, helper); + Class value_class = value_instance == null ? null + : value_instance.getClass(); + + if (helper == null) + helper = id != null ? getHelper(value_class, id) : getHelper( + value_class, ids); + + value_instance = read_instance(input, position, value_instance, + value_tag, helper, id, ids, codebase); return value_instance; } catch (Exception ex) { - throw new MARSHAL(ex + ":" + ex.getMessage()); + MARSHAL m = new MARSHAL(); + m.minor = Minor.Value; + m.initCause(ex); + throw m; } } /** - * Read using provided boxed value helper. This method expects - * the full value type header, followed by contents, that are - * delegated to the provided helper. It handles null. - * + * Read using provided boxed value helper. This method expects the full value + * type header, followed by contents, that are delegated to the provided + * helper. It handles null. + * * @param input the stream to read from. - * @param helper the helper that reads the type-specific part of - * the content. - * - * @return the value, created by the helper, or null if the - * header indicates that null was previously written. + * @param helper the helper that reads the type-specific part of the content. + * + * @return the value, created by the helper, or null if the header indicates + * that null was previously written. */ - public static Serializable read(InputStream input, Object helper) + public static Serializable read(InputStream input, BoxedValueHelper helper) { return (Serializable) read(input, null, helper); } /** - * Fill in the instance fields by the data from the input stream. - * The method assumes that the value header, if any, is already - * behind. The information from the stream is stored into the - * passed ox parameter. - * + * Fill in the instance fields by the data from the input stream. The method + * assumes that the value header, if any, is already behind. The information + * from the stream is stored into the passed ox parameter. + * * @param input an input stream to read from. - * + * * @param value a pre-instantiated value type object, must be either - * Streamable or CustomMarshal. If the helper is used, this parameter - * is ignored and should be null. - * + * Streamable or CustomMarshal. If the helper is used, this parameter is + * ignored and should be null. + * * @param value_tag the tag that must be read previously. - * @param helper the helper for read object specific part; may be - * null to read in using other methods. - * + * @param helper the helper for read object specific part; may be null to read + * in using other methods. + * * @return the value that was read. */ - private static Object read_instance(InputStream input, Object value, - int value_tag, Object helper - ) + static Object read_instance(InputStream input, final int position, + Object value, int value_tag, BoxedValueHelper helper, String id, + String[] ids, String codebase) { + if (helper != m_StringValueHelper && id != null) + if (id.equals(StringValueHelper.id())) + { + value = null; + helper = m_StringValueHelper; + } + try { if ((value_tag & vf_CHUNKING) != 0) { - ByteArrayOutputStream bout = null; - int n = -1; - - // Read all chunks. - int chunk_size = input.read_long(); - if (chunk_size < 0) - throw new MARSHAL("Invalid first chunk size " + chunk_size); - - byte[] r = new byte[ chunk_size ]; - - while (chunk_size > 0) - { - if (r.length < chunk_size) - r = new byte[ chunk_size + 256 ]; - - n = 0; - reading: - while (n < chunk_size) - n += input.read(r, n, r.length - n); - - // Read the size of the next chunk. - chunk_size = input.read_long(); - - // If the value is non negative, there is more than one chunk. - // Accumulate chunks in the buffer. - // The last chunk (or the only chunk, if only one chunk is - // present) is not written in the buffer. It is stored in the - // array r, avoiding unnecessary buffer operations. - if (chunk_size > 0) - { - bout = new ByteArrayOutputStream(2 * chunk_size); - bout.write(r, 0, chunk_size); - } - } + BufferedCdrOutput output = createBuffer(input, 1024); + // Read the current (not a nested one) value in this spec case. + readNestedValue(value_tag, input, output, -1); + BufferredCdrInput ci = new BufferredCdrInput(output.buffer.getBuffer()); + ci.setRunTime(output.getRunTime()); - if (bout != null) - { - // More than one chunk was present. - // Add the last chunk. - bout.write(r, 0, n); - input = new noHeaderInput(bout.toByteArray()); - } - else - { - // Only one chunk was present. - input = new noHeaderInput(r); - } + input = new HeadlessInput(ci, input); } else { - if (input instanceof cdrBufInput) + if (input instanceof BufferredCdrInput) { // Highly probable case. - input = - new noHeaderInput(((cdrBufInput) input).buffer.getBuffer()); + input = new HeadlessInput((BufferredCdrInput) input, null); + } + else if (input instanceof HeadlessInput) + { + // There is no need to instantiate one more HeadlessInput + // as we can just reset. + ((HeadlessInput) input).subsequentCalls = false; } else { - cdrBufOutput bout = new cdrBufOutput(); + BufferedCdrOutput bout = new BufferedCdrOutput(); int c; while ((c = input.read()) >= 0) bout.write((byte) c); - input = new noHeaderInput(bout.buffer.toByteArray()); + input = new HeadlessInput( + (BufferredCdrInput) bout.create_input_stream(), input); } } } catch (IOException ex) { MARSHAL m = new MARSHAL("Unable to read chunks"); + m.minor = Minor.Value; m.initCause(ex); throw m; } - // The user-defines io operations are implemented. - if (value instanceof CustomMarshal) + return readValue(input, position, value, helper, id, ids, codebase); + } + + /** + * Create a buffer, inheriting critical settings from the passed input stream. + */ + private static BufferedCdrOutput createBuffer(InputStream input, int proposed_size) + { + BufferedCdrOutput bout; + bout = new BufferedCdrOutput(2 * proposed_size + 256); + + if (input instanceof BufferredCdrInput) { - CustomMarshal marsh = (CustomMarshal) value; - try + BufferredCdrInput in = (BufferredCdrInput) input; + bout.setBigEndian(in.isBigEndian()); + } + + if (input instanceof gnuValueStream) + bout.setRunTime(((gnuValueStream) input).getRunTime()); + else + bout.setRunTime(new gnuRuntime(null, null)); + return bout; + } + + /** + * Read the chunked nested value from the given input stream, transferring the + * contents to the given output stream. + * + * @param value_tag the value tag of the value being read. + * @param input the input stream from where the remainder of the nested value + * must be read. + * @param output the output stream where the unchunked nested value must be + * copied. + * + * @return the tag that ended the nested value. + */ + public static int readNestedValue(int value_tag, InputStream input, + BufferedCdrOutput output, int level) + throws IOException + { + String id = null; + if (level < -1) + { + // For the first level, this information is already behind. + output.write_long(value_tag - vf_CHUNKING); + + // The nested value should be aways chunked. + if ((value_tag & vf_CHUNKING) == 0) + { + MARSHAL m = new MARSHAL("readNestedValue: must be chunked"); + m.minor = Minor.Chunks; + throw m; + } + else if (value_tag == vt_NULL) + { + MARSHAL m = new MARSHAL("readNestedValue: nul"); + m.minor = Minor.Chunks; + throw m; + } + else if (value_tag == vt_INDIRECTION) { - marsh.unmarshal((DataInputStream) input); + MARSHAL m = new MARSHAL("readNestedValue: indirection"); + m.minor = Minor.Chunks; + throw m; } - catch (ClassCastException ex) + else { - incorrect_plug_in(ex); + // Read the value. + if ((value_tag & vf_CODEBASE) != 0) + { + String codebase = read_string(input); + write_string(output, codebase); + } + + if ((value_tag & vf_MULTIPLE_IDS) != 0) + { + // Multiple supported repository ids are present. + String[] ids = read_string_array(input); + id = ids[0]; + write_string_array(output, ids); + } + else if ((value_tag & vf_ID) != 0) + { + id = read_string(input); + write_string(output, id); + } } } + + int n = -1; + + // Read all chunks. + int chunk_size; + + byte[] r = null; + + while (true) + { + // Read the size of the next chunk or it may also be the + // header of the nested value. + chunk_size = input.read_long(); + + // End of chunk terminator. + if (chunk_size < 0 && chunk_size >= level) + return chunk_size; + else if (chunk_size >= 0x7FFFFF00) + { + int onInput = getCurrentPosition(input) - 4; + int onOutput = output.getPosition(); + output.getRunTime().redirect(onInput, onOutput); + // Value over 0x7FFFFF00 indicates that the nested value + // starts here. Read the nested value, storing it into the output. + // First parameter is actually the value tag. + chunk_size = readNestedValue(chunk_size, input, output, level - 1); + if (chunk_size < 0 && chunk_size >= level) + return chunk_size; + } + else + { + // The chunk follows. + if (r == null || r.length < chunk_size) + r = new byte[chunk_size + 256]; + + n = 0; + reading: while (n < chunk_size) + n += input.read(r, n, chunk_size - n); + output.write(r, 0, n); + } + } + } + + /** + * Read the value (the header must be behind). + */ + public static Serializable readValue(InputStream input, final int position, + Object value, BoxedValueHelper helper, String id, String[] ids, + String codebase) + { + gnuRuntime g; + gnuValueStream c = ((gnuValueStream) input); + if (c.getRunTime() == null) + { + g = new gnuRuntime(codebase, value); + c.setRunTime(g); + } + else + { + g = c.getRunTime(); + g.addCodeBase(codebase); + g.target = (Serializable) value; + } + if (value != null) + g.objectWritten(value, position); + + if (input instanceof HeadlessInput) + ((HeadlessInput) input).subsequentCalls = false; + + boolean ok = true; + + // The user-defined io operations are implemented. + if (value instanceof CustomMarshal) + { + CustomMarshal marsh = (CustomMarshal) value; + marsh.unmarshal((DataInputStream) input); + } else // The IDL-generated io operations are implemented. if (value instanceof Streamable) { ((Streamable) value)._read(input); } - else if (helper instanceof BoxedValueHelper) - value = ((BoxedValueHelper) helper).read_value(input); - else if (helper instanceof ValueFactory) - value = - ((ValueFactory) helper).read_value((org.omg.CORBA_2_3.portable.InputStream) input); + else if (helper != null) + { + // If helper is non-null the value should normally be null. + value = helper.read_value(input); + g.objectWritten(value, position); + } else + { + ok = false; + ValueFactory factory = null; + org.omg.CORBA_2_3.ORB orb = (org.omg.CORBA_2_3.ORB) input.orb(); - // Stating the interfaces that the USER should use. - throw new MARSHAL("The " + value.getClass().getName() + - " must implement either StreamableValue or CustomValue." - ); + if (id != null) + factory = orb.lookup_value_factory(id); - // The negative end of state marker is expected from OMG standard. - // If the chunking is used, this marker is already extracted. - if ((value_tag & vf_CHUNKING) == 0) + if (factory == null && ids != null) + { + for (int i = 0; i < ids.length && factory == null; i++) + { + factory = orb.lookup_value_factory(ids[i]); + } + } + + if (factory != null) + { + value = factory.read_value((org.omg.CORBA_2_3.portable.InputStream) input); + ok = true; + } + } + + if (!ok && value instanceof Serializable) + // Delegate to ValueHandler { - int eor = input.read_long(); - if (eor >= 0) - throw new MARSHAL("End of state marker has an invalid value " + eor); + if (ids != null && ids.length > 0) + id = ids[0]; + + value = handler.readValue(input, position, value.getClass(), id, g); + ok = true; } - return value; + if (!ok) + { + if (value != null) + { + MARSHAL m = new MARSHAL(value.getClass().getName() + + " must be Streamable, CustomMarshal or Serializable"); + m.minor = Minor.UnsupportedValue; + throw m; + } + else + { + MARSHAL m = new MARSHAL("Unable to instantiate " + id + ":" + list(ids) + + " helper " + helper); + m.minor = Minor.UnsupportedValue; + throw m; + } + } + else + return (Serializable) value; + } + + /** + * Conveniency method to list ids in exception reports. + */ + static String list(String[] s) + { + if (s == null) + return "null"; + else + { + StringBuffer b = new StringBuffer("{"); + for (int i = 0; i < s.length; i++) + { + b.append(s[i]); + b.append(" "); + } + b.append("}"); + return b.toString(); + } } /** * Write the value base into the given stream. - * + * * @param output a stream to write to. - * + * * @param value a value type object, must be either Streamable or * CustomMarshal. - * + * * @throws MARSHAL if the writing failed due any reason. */ public static void write(OutputStream output, Serializable value) @@ -537,45 +781,82 @@ public abstract class Vio // Write null if this is a null value. if (value == null) output.write_long(vt_NULL); + else if (value instanceof String) + write(output, value, m_StringValueHelper); else - write(output, value, ObjectCreator.toIDL(value.getClass().getName())); - } - - /** - * Write the value base into the given stream, stating that it is an - * instance of the given class. The written record has no repository - * id and requires to supply a class or initialised instance for reading - * rather than an actual class it is. - * - * This results writing a different repository id. - * - * If the passed value implements the {@link CustomMarshal}, - * the helper uses {@link CustomMarshal#marshal} - * to write the content in a user defined way. Otherwise, - * this implementation initialises the {@link ObjectOutputStream} - * and writes through it. - * + write(output, value, value.getClass()); + } + + /** + * Write the value base into the given stream, stating that it is an instance + * of the given class. + * * @param output a stream to write to. - * + * * @param value a value to write. - * + * * @throws MARSHAL if the writing failed due any reason. */ public static void write(OutputStream output, Serializable value, - Class substitute - ) + Class substitute) { // Write null if this is a null value. if (value == null) output.write_long(vt_NULL); + else if (value instanceof String || substitute == String.class) + writeString(output, value); + else + { + String vId = ObjectCreator.getRepositoryId(value.getClass()); + if (substitute == null || value.getClass().equals(substitute)) + write_instance(output, value, vId, getHelper(value.getClass(), vId)); + else + { + String vC = ObjectCreator.getRepositoryId(substitute); + String[] ids = new String[] { vId, vC }; + BoxedValueHelper h = getHelper(substitute.getClass(), ids); + // If the helper is available, it is also responsible for + // providing the repository Id. Otherwise, write both + // ids. + if (h == null) + write_instance(output, value, ids, null); + else + write_instance(output, value, h.get_id(), null); + } + } + } + /** + * Write the value base into the given stream, supplementing it with an array + * of the provided repository ids plus the repository id, derived from the + * passed value. + * + * @param output a stream to write to. + * + * @param value a value to write. + * + * @throws MARSHAL if the writing failed due any reason. + */ + public static void write(OutputStream output, Serializable value, + String[] multiple_ids) + { + // Write null if this is a null value. + if (value == null) + output.write_long(vt_NULL); else - write(output, value, ObjectCreator.toIDL(substitute.getName())); + { + String[] ids = new String[multiple_ids.length + 1]; + ids[0] = ObjectCreator.getRepositoryId(value.getClass()); + System.arraycopy(multiple_ids, 0, ids, 1, multiple_ids.length); + BoxedValueHelper h = getHelper(value.getClass(), ids); + write_instance(output, value, ids, h); + } } /** - * Write value when its repository Id is explicitly given. - * + * Write value when its repository Id is explicitly given. Only this Id is + * written, the type of value is not taken into consideration. + * * @param output an output stream to write into. * @param value a value to write. * @param id a value repository id. @@ -585,172 +866,608 @@ public abstract class Vio if (value == null) output.write_long(vt_NULL); else - write_instance(output, value, id, null); + write_instance(output, value, id, getHelper(value.getClass(), id)); } /** - * Write standard value type header, followed by contents, produced - * by the boxed value helper. - * + * Write standard value type header, followed by contents, produced by the + * boxed value helper. + * * @param output the stream to write to. * @param value the value to write, can be null. - * @param helper the helper that writes the value content if it is - * not null. + * @param helper the helper that writes the value content if it is not null + * (must be provided for this method). */ public static void write(OutputStream output, Serializable value, - Object helper - ) + BoxedValueHelper helper) { + if (helper == null) + throw new AssertionError("Helper must be provided"); if (value == null) output.write_long(vt_NULL); else + write_instance(output, value, helper.get_id(), helper); + } + + /** + * Write the parameter that is surely a string and not null. + */ + private static void writeString(OutputStream output, Serializable string) + { + write_instance(output, string, m_StringValueHelper.get_id(), + m_StringValueHelper); + } + + /** + * Write value when its repository Id is explicitly given. Does not handle + * null. + * + * @param output an output stream to write into. + * @param value a value to write. + * @param id a value repository id (can be either single string or string + * array). + * @param helper a helper, writing object - specifical part. Can be null if + * the value should be written using other methods. + */ + static void write_instance(OutputStream output, Serializable value, + Object ids, BoxedValueHelper helper) + { + gnuValueStream rout = null; + gnuRuntime runtime = null; + + try { - String id; + if (output instanceof gnuValueStream) + { + int position; + rout = (gnuValueStream) output; + runtime = rout.getRunTime(); + + if (runtime == null) + { + runtime = new gnuRuntime(null, value); + rout.setRunTime(runtime); + rout.getRunTime().objectWritten(value, + position = rout.getPosition()); + } + else if (runtime.target == value) + { + if (!writeSelf(output, value)) + throw new InternalError("Recursive helper call for " + + value.getClass().getName()); + return; + } + else + { + position = runtime.isWrittenAt(value); + if (position >= 0) + { + // The object was already written. + output.write_long(vt_INDIRECTION); + output.write_long(position - rout.getPosition()); + // Replacing object write data by indirection reference. + return; + } + else + { + runtime.objectWritten(value, position = rout.getPosition()); + } + } + } + + int value_tag = vt_VALUE_TAG; + + if (ids instanceof String) + value_tag |= vf_ID; + else if (ids instanceof String[]) + // OMG standard requires to set both flags. + value_tag |= vf_MULTIPLE_IDS | vf_ID; - if (helper instanceof BoxedValueHelper) - id = ((BoxedValueHelper) helper).get_id(); + int chunkSizeLocation; + + OutputStream outObj; + + if (USE_CHUNKING) + { + // Wrap the value being written into one chunk (makes sense only for + // compatibility reasons). + outObj = output; + value_tag |= vf_CHUNKING; + } + else + outObj = output; + + output.write_long(value_tag); + + if ((value_tag & vf_MULTIPLE_IDS) != 0) + write_string_array(output, (String[]) ids); + else if ((value_tag & vf_ID) != 0) + write_string(output, (String) ids); + + if (USE_CHUNKING) + { + // So far, write 0x55555555 instead of the chunk size (alignment may + // take place). + output.write_long(0x55555555); + // If the chunking is involved, the chunk size must be written here. + chunkSizeLocation = rout.getPosition() - INT_SIZE; + } else - id = ""; + // Not in use for this case. + chunkSizeLocation = -1; + + writeValue(outObj, value, helper); - write_instance(output, value, id, helper); + if (USE_CHUNKING) + { + // Write the chunk size where the place for it was reserved. + int chunkSize = rout.getPosition() - chunkSizeLocation - INT_SIZE; + int current = rout.getPosition(); + rout.seek(chunkSizeLocation); + output.write_long(chunkSize); + rout.seek(current); + + // The end of record marker. + output.write_long(-1); + } + } + finally + { + if (runtime != null) + runtime.target = null; } } /** - * Write value when its repository Id is explicitly given. - * Does not handle null. - * - * @param output an output stream to write into. - * @param value a value to write. - * @param id a value repository id. - * @param helper a helper, writing object - specifica part. Can be null - * if the value should be written unsing other methods. + * Write value (after header). */ - private static void write_instance(OutputStream output, Serializable value, - String id, Object helper - ) + static void writeValue(OutputStream output, Serializable value, + BoxedValueHelper helper) { - // This implementation always writes a single repository id. - // It never writes multiple repository ids and currently does not use - // a codebase. - int value_tag = vt_VALUE_TAG | vf_ID; + ((gnuValueStream) output).getRunTime().target = value; + if (helper != null) + helper.write_value(output, value); + else if (!writeSelf(output, value)) + { + // Try to find helper via class loader. + boolean ok = false; - OutputStream outObj; - cdrBufOutput out = null; + if (!ok) + { + if (output instanceof BufferedCdrOutput) + { + BufferedCdrOutput b = (BufferedCdrOutput) output; + if (b.runtime == null) + b.runtime = new gnuRuntime(null, value); + } - if (USE_CHUNKING) + handler.writeValue(output, value); + } + } + } + + /** + * Try to write value supposing that it implements self-streamable interfaces. + * Return false if it does not or true on success. + */ + static boolean writeSelf(OutputStream output, Serializable value) + { + // User defined write method is present. + if (value instanceof CustomMarshal) { - out = new cdrBufOutput(); - out.setOrb(output.orb()); - outObj = out; - value_tag |= vf_CHUNKING; + ((CustomMarshal) value).marshal((DataOutputStream) output); + return true; } - else - outObj = output; + else if (value instanceof Streamable) + { + ((Streamable) value)._write(output); + return true; + } + return false; + } - output.write_long(value_tag); - output.write_string(id); + /** + * Read the indirection data and return the object that was already written to + * this stream. + * + * @param an_input the input stream, must be BufferredCdrInput. + */ + static Serializable readIndirection(InputStream an_input) + { + if (!(an_input instanceof gnuValueStream)) + throw new NO_IMPLEMENT(gnuValueStream.class.getName() + + " expected as parameter"); - if (helper instanceof BoxedValueHelper) + gnuValueStream in = (gnuValueStream) an_input; + + int current_pos = in.getPosition(); + + int offset = an_input.read_long(); + if (offset > -INT_SIZE) { - ((BoxedValueHelper) helper).write_value(outObj, value); + MARSHAL m = new MARSHAL("Indirection tag refers to " + offset + + " (must be less than -" + INT_SIZE + ")"); + m.minor = Minor.Offset; + throw m; } - else - // User defince write method is present. - if (value instanceof CustomMarshal) + + int stored_at = current_pos + offset; + + if (in.getRunTime() == null) + { + MARSHAL m = new MARSHAL(stored_at + " offset " + offset + ": not written"); + m.minor = Minor.Value; + throw m; + } + + return (Serializable) in.getRunTime().isObjectWrittenAt(stored_at, offset); + } + + /** + * Check the passed value tag for correctness. + * + * @param value_tag a tag to check, must be between 0x7fffff00 and 0x7fffffff + * + * @throws MARSHAL if the tag is outside this interval. + */ + static void checkTag(int value_tag) + { + if ((value_tag < 0x7fffff00 || value_tag > 0x7fffffff) + && value_tag != vt_NULL && value_tag != vt_INDIRECTION) + { + MARSHAL m = new MARSHAL("Invalid value record, unsupported header tag: " + + value_tag + " (0x" + Integer.toHexString(value_tag) + ")"); + m.minor = Minor.ValueHeaderTag; + throw m; + } + + if ((value_tag & vf_MULTIPLE_IDS) != 0 && (value_tag & vf_ID) == 0) { + MARSHAL m = new MARSHAL("Invalid value record header flag combination (0x" + + Integer.toHexString(value_tag) + ")"); + m.minor = Minor.ValueHeaderFlags; + throw m; + } + } + + /** + * Throw MARSHAL. + */ + static void throwIt(String msg, String id1, String id2, Throwable e) + throws MARSHAL + { + MARSHAL m = new MARSHAL(msg + ":'" + id1 + "' versus '" + id2 + "'"); + if (e != null) + m.initCause(e); + m.minor = Minor.Value; + throw m; + } + + /** + * Load class by name and create the instance. + */ + static Object createInstance(String id, String[] ids, String codebase) + { + Object o = null; + + if (id != null) + o = _createInstance(id, codebase); + + if (ids != null) + for (int i = 0; i < ids.length && o == null; i++) + o = _createInstance(ids[i], codebase); + return o; + } + + static Object _createInstance(String id, String codebase) + { + if (id == null) + return null; + if (id.equals(StringValueHelper.id())) + return ""; + StringTokenizer st = new StringTokenizer(id, ":"); + + String prefix = st.nextToken(); + if (prefix.equalsIgnoreCase("IDL")) + return ObjectCreator.Idl2Object(id); + else if (prefix.equalsIgnoreCase("RMI")) + { + String className = st.nextToken(); + String hashCode = st.nextToken(); + String sid = null; + if (st.hasMoreElements()) + sid = st.nextToken(); + try { - ((CustomMarshal) value).marshal((DataOutputStream) outObj); + Class objectClass = Util.loadClass(className, codebase, + Vio.class.getClassLoader()); + + String rid = ObjectCreator.getRepositoryId(objectClass); + + if (!rid.equals(id)) + { + // If direct string comparison fails, compare by meaning. + StringTokenizer st2 = new StringTokenizer(rid, ":"); + if (!st2.nextToken().equals("RMI")) + throw new InternalError("RMI format expected: '" + rid + "'"); + if (!st2.nextToken().equals(className)) + throwIt("Class name mismatch", id, rid, null); + + try + { + long h1 = Long.parseLong(hashCode, 16); + long h2 = Long.parseLong(st2.nextToken(), 16); + if (h1 != h2) + throwIt("Hashcode mismatch", id, rid, null); + + if (sid != null && st2.hasMoreTokens()) + { + long s1 = Long.parseLong(hashCode, 16); + long s2 = Long.parseLong(st2.nextToken(), 16); + if (s1 != s2) + throwIt("serialVersionUID mismatch", id, rid, null); + } + } + catch (NumberFormatException e) + { + throwIt("Invalid hashcode or svuid format: ", id, rid, e); + } + } + + // Low - level instantiation required here. + return instantiateAnyWay(objectClass); } - catch (ClassCastException ex) + catch (Exception ex) { - incorrect_plug_in(ex); + MARSHAL m = new MARSHAL("Unable to instantiate " + id); + m.minor = Minor.Instantiation; + m.initCause(ex); + throw m; } } - else if (value instanceof Streamable) + else + throw new NO_IMPLEMENT("Unsupported prefix " + prefix + ":"); + } + + /** + * Read string, expecting the probable indirection. + */ + static String read_string(InputStream input) + { + gnuValueStream g = (gnuValueStream) input; + int previous = g.getPosition(); + int l = input.read_long(); + if (l != vt_INDIRECTION) { - ((Streamable) value)._write(outObj); + g.seek(previous); + String s = input.read_string(); + if (g.getRunTime() == null) + g.setRunTime(new gnuRuntime(null, null)); + g.getRunTime().singleIdWritten(s, previous); + return s; } else { - // Try to find helper via class loader. - boolean ok = false; - try + gnuRuntime r = g.getRunTime(); + int base = g.getPosition(); + int delta = input.read_long(); + if (r == null) { - Class helperClass = Class.forName(ObjectCreator.toHelperName(id)); - - // It will be the helper for the encapsulated boxed value, not the - // for the global boxed value type itself. - Method write = - helperClass.getMethod("write", - new Class[] - { - org.omg.CORBA.portable.OutputStream.class, value.getClass() - } - ); - write.invoke(null, new Object[] { outObj, value }); - ok = true; + previous = g.getPosition(); + g.seek(base + delta); + String indir = input.read_string(); + g.seek(previous); + return indir; } - catch (Exception ex) + else { - ok = false; + return (String) r.isObjectWrittenAt(base + delta, delta); } + } + } - // Stating the interfaces that the USER should use. - if (!ok) - throw new MARSHAL("The " + value.getClass().getName() + - " must implement either StreamableValue" + " or CustomValue." - ); + /** + * Read string array, expecting the probable indirection. + */ + static String[] read_string_array(InputStream input) + { + gnuValueStream g = (gnuValueStream) input; + int previous = g.getPosition(); + int l = input.read_long(); + if (l != vt_INDIRECTION) + { + g.seek(previous); + String[] s = StringSeqHelper.read(input); + if (g.getRunTime() == null) + g.setRunTime(new gnuRuntime(null, null)); + g.getRunTime().objectWritten(s, previous); + return s; } + else + { + gnuRuntime r = g.getRunTime(); + int base = g.getPosition(); + int delta = input.read_long(); + if (r == null) + { + previous = g.getPosition(); + g.seek(base + delta); + String[] indir = StringSeqHelper.read(input); + g.seek(previous); + return indir; + } + else + { + return (String[]) r.isObjectWrittenAt(base + delta, delta); + } + } + } - if (USE_CHUNKING) + /** + * Write repository Id, probably shared. + */ + static void write_string(OutputStream output, String id) + { + if (output instanceof gnuValueStream) { - output.write_long(out.buffer.size()); - try + gnuValueStream b = (gnuValueStream) output; + if (b != null) + { + int written = b.getRunTime().idWrittenAt(id); + if (written >= 0) + { + // Reuse existing id record. + output.write_long(vt_INDIRECTION); + int p = b.getPosition(); + output.write_long(written - p); + } + else + { + b.getRunTime().singleIdWritten(id, b.getPosition()); + output.write_string(id); + } + } + } + else + output.write_string(id); + } + + /** + * Write repository Id, probably shared. + */ + static void write_string_array(OutputStream output, String[] ids) + { + if (output instanceof gnuValueStream) + { + gnuValueStream b = (gnuValueStream) output; + if (b != null) { - out.buffer.writeTo(output); + int written = b.getRunTime().idWrittenAt(ids); + if (written >= 0) + { + // Reuse existing id record. + output.write_long(vt_INDIRECTION); + int p = b.getPosition(); + output.write_long(written - p); + } + else + { + b.getRunTime().multipleIdsWritten(ids, b.getPosition()); + StringSeqHelper.write(output, ids); + } } - catch (IOException ex) + } + else + StringSeqHelper.write(output, ids); + } + + /** + * Get the helper that could write the given object, or null if no pre-defined + * helper available for this object. + */ + public static BoxedValueHelper getHelper(Class x, Object ids) + { + if (x != null && x.equals(String.class)) + return m_StringValueHelper; + else if (x != null && x.isArray()) + return new ArrayValueHelper(x); + else if (ids instanceof String) + return locateHelper((String) ids); + else if (ids instanceof String[]) + { + String[] ia = (String[]) ids; + BoxedValueHelper h; + for (int i = 0; i < ia.length; i++) { - MARSHAL m = new MARSHAL(); - m.initCause(ex); - throw m; + h = locateHelper(ia[i]); + if (h != null) + return h; } + return null; } + else + return null; + } - // The end of record marker, required by OMG standard. - output.write_long(-1); + /** + * Get the helper that could write the given object, or null if no pre-defined + * helper available for this object. + */ + public static BoxedValueHelper getHelper(Class x, String id) + { + if (x != null && x.equals(String.class)) + return m_StringValueHelper; + else if (x != null && x.isArray()) + return new ArrayValueHelper(x); + else + return locateHelper(id); } /** - * This can be called if the alternative CORBA implementation - * is incorrectly plugged in. - * - * @throws NO_IMPLEMENT, always. + * Try to locate helper from the repository id. */ - static void incorrect_plug_in(Throwable ex) throws NO_IMPLEMENT + static BoxedValueHelper locateHelper(String id) { - NO_IMPLEMENT no = new NO_IMPLEMENT("Incorrect CORBA plug-in"); - no.initCause(ex); - throw no; + if (id != null) + { + if (id.equals(m_StringValueHelper.get_id())) + return m_StringValueHelper; + else + // Try to locate helper for IDL type. + if (id.startsWith("IDL:")) + { + try + { + Class helperClass = ObjectCreator.findHelper(id); + if (BoxedValueHelper.class.isAssignableFrom(helperClass)) + return (BoxedValueHelper) helperClass.newInstance(); + else if (helperClass != null) + return new IDLTypeHelper(helperClass); + else + return null; + } + catch (Exception ex) + { + return null; + } + } + } + return null; } /** - * Check the passed value tag for correctness. - * - * @param value_tag a tag to check, must be between 0x7fffff00 and 0x7fffffff - * - * @throws MARSHAL if the tag is outside this interval. + * Get the current position. */ - private static final void checkTag(int value_tag) + static int getCurrentPosition(InputStream x) { - if ((value_tag < 0x7fffff00 || value_tag > 0x7fffffff) && - value_tag != vt_NULL && - value_tag != vt_INDIRECTION - ) - throw new MARSHAL("Invalid value record, unsupported header tag: " + - value_tag - ); + if (x instanceof gnuValueStream) + return ((gnuValueStream) x).getPosition(); + else + return 0; + } + + /** + * Instantiate an instance of this class anyway; also in the case when it has + * no parameterless or any other constructor. The fields will be assigned + * while reading the class from the stream. + * + * @param clazz a class for that the instance should be instantiated. + */ + public static Object instantiateAnyWay(Class clazz) + throws Exception + { + Class first_nonserial = clazz; + + while (Serializable.class.isAssignableFrom(first_nonserial) + || Modifier.isAbstract(first_nonserial.getModifiers())) + first_nonserial = first_nonserial.getSuperclass(); + + final Class local_constructor_class = first_nonserial; + + Constructor constructor = local_constructor_class.getDeclaredConstructor(new Class[0]); + + return VMVio.allocateObject(clazz, constructor.getDeclaringClass(), + constructor); } } \ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/abstractDataInputStream.java b/libjava/classpath/gnu/CORBA/CDR/abstractDataInputStream.java deleted file mode 100644 index be926254dd0..00000000000 --- a/libjava/classpath/gnu/CORBA/CDR/abstractDataInputStream.java +++ /dev/null @@ -1,392 +0,0 @@ -/* abstractDataInputStream.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.CORBA.CDR; - -import java.io.IOException; - -/** - * Some data input stream that can be either Big or - * Little Endian. - * - * This class reuses code from GNU Classpath DataInputStream. - * - * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) - * @author Warren Levy (warrenl@cygnus.com) - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public interface abstractDataInputStream -{ - /** - * This method reads bytes from the underlying stream into the specified - * byte array buffer. It will attempt to fill the buffer completely, but - * may return a short count if there is insufficient data remaining to be - * read to fill the buffer. - * - * @param b The buffer into which bytes will be read. - * - * @return The actual number of bytes read, or -1 if end of stream reached - * before reading any bytes. - * - * @exception IOException If an error occurs. - */ - int read(byte[] b) - throws IOException; - - /** - * This method reads bytes from the underlying stream into the specified - * byte array buffer. It will attempt to read len bytes and - * will start storing them at position off into the buffer. - * This method can return a short count if there is insufficient data - * remaining to be read to complete the desired read length. - * - * @param b The buffer into which bytes will be read. - * @param off The offset into the buffer to start storing bytes. - * @param len The requested number of bytes to read. - * - * @return The actual number of bytes read, or -1 if end of stream reached - * before reading any bytes. - * - * @exception IOException If an error occurs. - */ - int read(byte[] b, int off, int len) - throws IOException; - - /** - * This method reads a Java boolean value from an input stream. It does - * so by reading a single byte of data. If that byte is zero, then the - * value returned is false. If the byte is non-zero, then - * the value returned is true. - *

- * This method can read a boolean written by an object - * implementing the writeBoolean() method in the - * DataOutput interface. - * - * @return The boolean value read - * - * @exception EOFException If end of file is reached before reading - * the boolean - * @exception IOException If any other error occurs - * - * @see DataOutput#writeBoolean - */ - boolean readBoolean() - throws IOException; - - /** - * This method reads a Java byte value from an input stream. The value - * is in the range of -128 to 127. - *

- * This method can read a byte written by an object - * implementing the writeByte() method in the - * DataOutput interface. - * - * @return The byte value read - * - * @exception EOFException If end of file is reached before reading the byte - * @exception IOException If any other error occurs - * - * @see DataOutput#writeByte - */ - byte readByte() - throws IOException; - - /** - * This method reads a Java char value from an input stream. - * It operates by reading two bytes from the stream and converting them to - * a single 16-bit Java char. The two bytes are stored most - * significant byte first (i.e., "big endian") regardless of the native - * host byte ordering. - *

- * As an example, if byte1 and byte2 - * represent the first and second byte read from the stream - * respectively, they will be transformed to a char in - * the following manner: - *

- * (char)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF) - *

- * This method can read a char written by an object - * implementing the writeChar() method in the - * DataOutput interface. - * - * @return The char value read - * - * @exception EOFException If end of file is reached before reading the char - * @exception IOException If any other error occurs - * - * @see DataOutput#writeChar - */ - char readChar() - throws IOException; - - /** - * This method reads a Java double value from an input stream. It operates - * by first reading a long value from the stream by calling the - * readLong() method in this interface, then converts - * that long to a double using the - * longBitsToDouble method in the class - * java.lang.Double - *

- * This method can read a double written by an object - * implementing the writeDouble() method in the - * DataOutput interface. - * - * @return The double value read - * - * @exception EOFException If end of file is reached before reading - * the double - * @exception IOException If any other error occurs - * - * @see DataOutput#writeDouble - * @see java.lang.Double#longBitsToDouble - */ - double readDouble() - throws IOException; - - /** - * This method reads a Java float value from an input stream. It - * operates by first reading an int value from the - * stream by calling the readInt() method in this - * interface, then converts that int to a - * float using the intBitsToFloat method - * in the class java.lang.Float - *

- * This method can read a float written by an object - * implementing the writeFloat() method in the - * DataOutput interface. - * - * @return The float value read - * - * @exception EOFException If end of file is reached before reading the float - * @exception IOException If any other error occurs - * - * @see DataOutput#writeFloat - * @see java.lang.Float#intBitsToFloat - */ - float readFloat() - throws IOException; - - /** - * This method reads raw bytes into the passed array until the array is - * full. Note that this method blocks until the data is available and - * throws an exception if there is not enough data left in the stream to - * fill the buffer. Note also that zero length buffers are permitted. - * In this case, the method will return immediately without reading any - * bytes from the stream. - * - * @param b The buffer into which to read the data - * - * @exception EOFException If end of file is reached before filling the - * buffer - * @exception IOException If any other error occurs - */ - void readFully(byte[] b) - throws IOException; - - /** - * This method reads a Java int value from an input stream - * It operates by reading four bytes from the stream and converting them to - * a single Java int. The bytes are stored most - * significant byte first (i.e., "big endian") regardless of the native - * host byte ordering. - *

- * As an example, if byte1 through byte4 represent - * the first four bytes read from the stream, they will be - * transformed to an int in the following manner: - *

- * (int)(((byte1 & 0xFF) << 24) + ((byte2 & 0xFF) << 16) + - * ((byte3 & 0xFF)<< 8) + (byte4 & 0xFF))) - *

- * The value returned is in the range of -2147483648 to 2147483647. - *

- * This method can read an int written by an object - * implementing the writeInt() method in the - * DataOutput interface. - * - * @return The int value read - * - * @exception EOFException If end of file is reached before reading the int - * @exception IOException If any other error occurs - * - * @see DataOutput#writeInt - */ - int readInt() - throws IOException; - - /** - * This method reads a Java long value from an input stream - * It operates by reading eight bytes from the stream and converting them to - * a single Java long. The bytes are stored most - * significant byte first (i.e., "big endian") regardless of the native - * host byte ordering. - *

- * As an example, if byte1 through byte8 represent - * the first eight bytes read from the stream, they will be - * transformed to an long in the following manner: - *

- * (long)(((byte1 & 0xFF) << 56) + ((byte2 & 0xFF) << 48) + - * ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) + - * ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) + - * ((byte7 & 0xFF) << 8) + (byte8 & 0xFF))) - * - *

- * The value returned is in the range of -9223372036854775808 to - * 9223372036854775807. - *

- * This method can read an long written by an object - * implementing the writeLong() method in the - * DataOutput interface. - * - * @return The long value read - * - * @exception EOFException If end of file is reached before reading the long - * @exception IOException If any other error occurs - * - * @see DataOutput#writeLong - */ - long readLong() - throws IOException; - - /** - * This method reads a signed 16-bit value into a Java in from the - * stream. It operates by reading two bytes from the stream and - * converting them to a single 16-bit Java short. The - * two bytes are stored most significant byte first (i.e., "big - * endian") regardless of the native host byte ordering. - *

- * As an example, if byte1 and byte2 - * represent the first and second byte read from the stream - * respectively, they will be transformed to a short. in - * the following manner: - *

- * (short)(((byte1 & 0xFF) << 8) | (byte2 & 0xFF)) - *

- * The value returned is in the range of -32768 to 32767. - *

- * This method can read a short written by an object - * implementing the writeShort() method in the - * DataOutput interface. - * - * @return The short value read - * - * @exception EOFException If end of file is reached before reading the value - * @exception IOException If any other error occurs - * - * @see DataOutput#writeShort - */ - short readShort() - throws IOException; - - /** - * This method reads 8 unsigned bits into a Java int - * value from the stream. The value returned is in the range of 0 to - * 255. - *

- * This method can read an unsigned byte written by an object - * implementing the writeUnsignedByte() method in the - * DataOutput interface. - * - * @return The unsigned bytes value read as a Java int. - * - * @exception EOFException If end of file is reached before reading the value - * @exception IOException If any other error occurs - * - * @see DataOutput#writeByte - */ - int readUnsignedByte() - throws IOException; - - /** - * This method reads 16 unsigned bits into a Java int value from the stream. - * It operates by reading two bytes from the stream and converting them to - * a single Java int The two bytes are stored most - * significant byte first (i.e., "big endian") regardless of the native - * host byte ordering. - *

- * As an example, if byte1 and byte2 - * represent the first and second byte read from the stream - * respectively, they will be transformed to an int in - * the following manner: - *

- * (int)(((byte1 & 0xFF) << 8) + (byte2 & 0xFF)) - *

- * The value returned is in the range of 0 to 65535. - *

- * This method can read an unsigned short written by an object - * implementing the writeUnsignedShort() method in the - * DataOutput interface. - * - * @return The unsigned short value read as a Java int - * - * @exception EOFException If end of file is reached before reading the value - * @exception IOException If any other error occurs - * - * @see DataOutput#writeShort - */ - int readUnsignedShort() - throws IOException; - - /** - * Read a single byte. - * - * @return a byte, extracted from the stream or -1 if - * EOF has been reached. - * @throws IOException - */ - public int read() - throws IOException; - - /** - * This method attempts to skip and discard the specified number of bytes - * in the input stream. It may actually skip fewer bytes than requested. - * This method will not skip any bytes if passed a negative number of bytes - * to skip. - * - * @param n The requested number of bytes to skip. - * - * @return The requested number of bytes to skip. - * - * @exception IOException If an error occurs. - * @specnote The JDK docs claim that this returns the number of bytes - * actually skipped. The JCL claims that this method can throw an - * EOFException. Neither of these appear to be true in the JDK 1.3's - * implementation. This tries to implement the actual JDK behaviour. - */ - int skipBytes(int n) - throws IOException; -} \ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/abstractDataOutputStream.java b/libjava/classpath/gnu/CORBA/CDR/abstractDataOutputStream.java deleted file mode 100644 index 2f9b8c419fc..00000000000 --- a/libjava/classpath/gnu/CORBA/CDR/abstractDataOutputStream.java +++ /dev/null @@ -1,185 +0,0 @@ -/* abstractDataOutputStream.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.CORBA.CDR; - -import java.io.IOException; - -/** - * An abstract data output stream that could write data in either - * Big Endian or Little Endian format. - * - * This class reuses code from GNU Classpath DataOutputStream. - * - * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) - * @author Warren Levy (warrenl@cygnus.com) - * @author Aaron M. Renn (arenn@urbanophile.com) - */ -public interface abstractDataOutputStream -{ - /** - * This method flushes any unwritten bytes to the underlying stream. - * - * @exception IOException If an error occurs. - */ - void flush() - throws IOException; - - /** - * This method writes the specified byte (passed as an int) - * to the underlying output stream. - * - * @param value The byte to write, passed as an int. - * - * @exception IOException If an error occurs. - */ - void write(int value) - throws IOException; - - /** - * This method writes len bytes from the specified byte array - * buf starting at position offset into the - * buffer to the underlying output stream. - * - * @param buf The byte array to write from. - * @param offset The index into the byte array to start writing from. - * @param len The number of bytes to write. - * - * @exception IOException If an error occurs. - */ - void write(byte[] buf, int offset, int len) - throws IOException; - - /** - * Write the complete byte array. - * @throws IOException - */ - void write(byte[] buf) - throws IOException; - - /** - * This method writes a Java boolean value to an output stream. If - * value is true, a byte with the value of - * 1 will be written, otherwise a byte with the value of 0 will be - * written. - * - * The value written can be read using the readBoolean - * method in DataInput. - * - * @param value The boolean value to write to the stream - * - * @exception IOException If an error occurs - */ - void writeBoolean(boolean value) - throws IOException; - - /** - * This method writes a Java byte value to an output stream. The - * byte to be written will be in the lowest 8 bits of the - * int value passed. - * - * The value written can be read using the readByte or - * readUnsignedByte methods in DataInput. - * - * @param value The byte to write to the stream, passed as - * the low eight bits of an int. - * - * @exception IOException If an error occurs - */ - void writeByte(int value) - throws IOException; - - /** - * This method writes a Java short value to an output stream. The - * char to be written will be in the lowest 16 bits of the int - * value passed. - * - * @exception IOException If an error occurs - */ - void writeShort(int value) - throws IOException; - - /** - * This method writes a Java char value to an output stream. The - * char to be written will be in the lowest 16 bits of the int - * value passed. - * - * @exception IOException If an error occurs - */ - void writeChar(int value) - throws IOException; - - /** - * This method writes a Java int value to an output stream. - * - * @param value The int value to write to the stream - * - * @exception IOException If an error occurs - */ - void writeInt(int value) - throws IOException; - - /** - * This method writes a Java long value to an output stream. - * - * @param value The long value to write to the stream - * - * @exception IOException If an error occurs - */ - void writeLong(long value) - throws IOException; - - /** - * This method writes a Java float value to the stream. - * @param value The float value to write to the stream - * - * @exception IOException If an error occurs - */ - void writeFloat(float value) - throws IOException; - - /** - * This method writes a Java double value to the stream. - * - * @param value The double value to write to the stream - * - * @exception IOException If an error occurs - */ - void writeDouble(double value) - throws IOException; -} \ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/aligningInputStream.java b/libjava/classpath/gnu/CORBA/CDR/aligningInputStream.java deleted file mode 100644 index a719b32ee1e..00000000000 --- a/libjava/classpath/gnu/CORBA/CDR/aligningInputStream.java +++ /dev/null @@ -1,122 +0,0 @@ -/* aligningInputStream.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.CORBA.CDR; - -import java.io.ByteArrayInputStream; - -import org.omg.CORBA.BAD_PARAM; - -/** - * The input stream with the possibility to align on the - * word (arbitrary size) boundary. - * - * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) - */ -public class aligningInputStream - extends ByteArrayInputStream -{ - /** - * The alignment offset. - */ - private int offset = 0; - - /** - * Create a stream, reading form the given buffer. - * - * @param a_buffer a buffer to read from. - */ - public aligningInputStream(byte[] a_buffer) - { - super(a_buffer); - } - - /** - * Create a stream, reading from the given buffer region. - * - * @param a_buffer a buffer to read from. - * @param offset the offset of the region. - * @param length thr length of the region. - */ - public aligningInputStream(byte[] a_buffer, int offset, int length) - { - super(a_buffer, offset, length); - } - - /** - * Set the alignment offset, if the index of the first byte in the - * stream is different from 0. - */ - public void setOffset(int an_offset) - { - offset = an_offset; - } - - /** - * Skip several bytes, aligning the internal pointer on the - * selected boundary. - * - * @throws BAD_PARAM, minor code 0, the alignment is not possible, - * usually due the wrong parameter value. - */ - public void align(int alignment) - { - try - { - int d = (pos + offset) % alignment; - if (d > 0) - { - skip(alignment - d); - } - } - catch (Exception ex) - { - BAD_PARAM p = new BAD_PARAM("Unable to align at " + alignment); - p.initCause(ex); - throw p; - } - } - - /** - * Get the byte buffer, from where the data are read. - */ - public byte[] getBuffer() - { - return buf; - } -} diff --git a/libjava/classpath/gnu/CORBA/CDR/aligningOutputStream.java b/libjava/classpath/gnu/CORBA/CDR/aligningOutputStream.java deleted file mode 100644 index 8a682c1fd6d..00000000000 --- a/libjava/classpath/gnu/CORBA/CDR/aligningOutputStream.java +++ /dev/null @@ -1,121 +0,0 @@ -/* aligningOutputStream.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.CORBA.CDR; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; - -import org.omg.CORBA.BAD_PARAM; - -/** - * The input stream with the possibility to align on the - * word (arbitrary size) boundary. - * - * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) - */ -public class aligningOutputStream - extends ByteArrayOutputStream -{ - /** - * The alignment offset. - */ - private int offset = 0; - - /** - * Create a stream with the default intial buffer size. - */ - public aligningOutputStream() - { - } - - /** - * Create a stream with the given intial buffer size. - */ - public aligningOutputStream(int initial_size) - { - super(initial_size); - } - - /** - * Set the alignment offset, if the index of the first byte in the - * stream is different from 0. - */ - public void setOffset(int an_offset) - { - offset = an_offset; - } - - /** - * Skip several bytes, aligning the internal pointer on the - * selected boundary. - * - * @throws BAD_PARAM, minor code 0, the alignment is not possible, - * usually due the wrong parameter value. - */ - public void align(int alignment) - { - try - { - int d = (count + offset) % alignment; - if (d > 0) - { - skip(alignment - d); - } - } - catch (Exception ex) - { - BAD_PARAM p = new BAD_PARAM("Unable to align at " + alignment); - p.initCause(ex); - throw p; - } - } - - /** - * Write the specified number of zero bytes. - * - * @param bytes the number of zero bytes to write. - */ - public void skip(int bytes) - { - for (int i = 0; i < bytes; i++) - { - write(0); - } - } -} diff --git a/libjava/classpath/gnu/CORBA/CDR/cdrBufInput.java b/libjava/classpath/gnu/CORBA/CDR/cdrBufInput.java deleted file mode 100644 index 3cab7216c3b..00000000000 --- a/libjava/classpath/gnu/CORBA/CDR/cdrBufInput.java +++ /dev/null @@ -1,115 +0,0 @@ -/* cdrBufInput.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.CORBA.CDR; - - -/** - * The CDR input stream that reads data from the byte buffer. - * - * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) - * - * TODO character encoding. Now the encoding can be set, but it is ignored. - * If you take this task, scan 'TODO character encoding' for - * relevant places. - */ -public class cdrBufInput - extends cdrInput -{ - /** - * The byte array input stream to read data from. - */ - public final aligningInputStream buffer; - - /** - * Creates the CDR input stream that reads from the given buffer - * array. - * - * @param a_buffer an array to read from. - */ - public cdrBufInput(byte[] a_buffer) - { - buffer = new aligningInputStream(a_buffer); - setInputStream(buffer); - } - - /** - * Set the alignment offset, if the index of the first byte in the - * stream is different from 0. - */ - public void setOffset(int offset) - { - buffer.setOffset(offset); - } - - /** - * Skip several bytes, aligning the internal pointer on the - * selected boundary. - */ - public void align(int alignment) - { - buffer.align(alignment); - } - - /** - * Mark the current position. - * @param ahead - */ - public synchronized void mark(int ahead) - { - buffer.mark(ahead); - } - - /** - * Checks if marking is supported. - * @return - */ - public boolean markSupported() - { - return buffer.markSupported(); - } - - /** - * Resets the stream to the previously marked position. - */ - public void reset() - { - buffer.reset(); - setInputStream(buffer); - } -} diff --git a/libjava/classpath/gnu/CORBA/CDR/cdrBufOutput.java b/libjava/classpath/gnu/CORBA/CDR/cdrBufOutput.java deleted file mode 100644 index 47f5f176b39..00000000000 --- a/libjava/classpath/gnu/CORBA/CDR/cdrBufOutput.java +++ /dev/null @@ -1,115 +0,0 @@ -/* cdrBufOutput.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.CORBA.CDR; - -import java.io.ByteArrayOutputStream; - -/** - * A CORBA output stream, writing data into the internal - * buffer ({@link ByteArrayOutputStream}). - * - * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) - */ -public class cdrBufOutput - extends cdrOutput -{ - /** - * The byte buffer. - */ - public final aligningOutputStream buffer; - - /** - * Creates the instance with the given initial buffer size. - * @param bufSize the buffer size. - */ - public cdrBufOutput(int bufSize) - { - buffer = new aligningOutputStream(bufSize); - setOutputStream(buffer); - } - - /** - * Creates the instance with the default buffer size. - */ - public cdrBufOutput() - { - buffer = new aligningOutputStream(); - setOutputStream(buffer); - } - - /** - * Set the alignment offset, if the index of the first byte in the - * stream is different from 0. - */ - public void setOffset(int an_offset) - { - buffer.setOffset(an_offset); - } - - /** - * Align the curretn position at the given natural boundary. - */ - public void align(int boundary) - { - buffer.align(boundary); - } - - /** - * Return the input stream that reads the previously written values. - */ - public org.omg.CORBA.portable.InputStream create_input_stream() - { - cdrBufInput in = new cdrBufInput(buffer.toByteArray()); - in.setOrb(orb); - - in.setVersion(giop); - in.setCodeSet(getCodeSet()); - - return in; - } - - /** - * Resets (clears) the buffer. - */ - public void reset() - { - buffer.reset(); - setOutputStream(buffer); - } -} diff --git a/libjava/classpath/gnu/CORBA/CDR/cdrInput.java b/libjava/classpath/gnu/CORBA/CDR/cdrInput.java deleted file mode 100644 index 69f9c8c5837..00000000000 --- a/libjava/classpath/gnu/CORBA/CDR/cdrInput.java +++ /dev/null @@ -1,1672 +0,0 @@ -/* cdrInput.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.CORBA.CDR; - -import gnu.CORBA.BigDecimalHelper; -import gnu.CORBA.Functional_ORB; -import gnu.CORBA.GIOP.CharSets_OSF; -import gnu.CORBA.GIOP.cxCodeSet; -import gnu.CORBA.IOR; -import gnu.CORBA.IOR_Delegate; -import gnu.CORBA.TypeCodeHelper; -import gnu.CORBA.Unexpected; -import gnu.CORBA.Version; -import gnu.CORBA.gnuAny; -import gnu.CORBA.stubFinder; - -import org.omg.CORBA.Any; -import org.omg.CORBA.AnySeqHolder; -import org.omg.CORBA.BAD_OPERATION; -import org.omg.CORBA.BooleanSeqHolder; -import org.omg.CORBA.CharSeqHolder; -import org.omg.CORBA.DoubleSeqHolder; -import org.omg.CORBA.FloatSeqHolder; -import org.omg.CORBA.LongLongSeqHolder; -import org.omg.CORBA.LongSeqHolder; -import org.omg.CORBA.MARSHAL; -import org.omg.CORBA.ORB; -import org.omg.CORBA.OctetSeqHolder; -import org.omg.CORBA.ShortSeqHolder; -import org.omg.CORBA.TypeCode; -import org.omg.CORBA.TypeCodePackage.BadKind; -import org.omg.CORBA.TypeCodePackage.Bounds; -import org.omg.CORBA.ULongLongSeqHolder; -import org.omg.CORBA.ULongSeqHolder; -import org.omg.CORBA.UShortSeqHolder; -import org.omg.CORBA.WCharSeqHolder; -import org.omg.CORBA.portable.InputStream; -import org.omg.CORBA.portable.ObjectImpl; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Serializable; - -import java.math.BigDecimal; - -/** - * A simple CORBA CDR (common data representation) - * input stream, reading data from the - * given {@link java.io.InputStream}. The primitive types - * are aligned on they natural boundaries by implementing the - * abstract method {@link #align(int boundary)}. - * - * The same class also implements {@link org.omg.CORBA.DataInputStream} to - * read the object content in a user defined way. - * - * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) - */ -public abstract class cdrInput - extends org.omg.CORBA_2_3.portable.InputStream - implements org.omg.CORBA.DataInputStream -{ - /** - * The message, explaining that the exception has been thrown due - * unexpected end of the input stream. This usually happens the - * server and client disagree on communication or data representation - * rules. - */ - protected static final String UNEXP_EOF = "Unexpected end of stream"; - - /** - * This instance is used to convert primitive data types into the - * byte sequences. - */ - protected abstractDataInputStream b; - - /** - * The input stream, from where the data are actually - * being read. - */ - protected java.io.InputStream actual_stream; - - /** - * The associated orb, if any. - */ - protected ORB orb; - - /** - * The GIOP version. - */ - protected Version giop = new Version(1, 2); - - /** - * The code set information. - */ - protected cxCodeSet codeset = cxCodeSet.STANDARD; - - /** - * The name of the currently used narrow charset, null if - * the native narrow charset is used. - */ - private String narrow_charset = null; - - /** - * The name of the currently used wide charset, null if - * the native wide charset is used. - */ - private String wide_charset = null; - - /** - * True if the native code set is used for narrow characters. - * If the set is native, no the intermediate Reader object - * is instantiated when writing characters. - */ - private boolean narrow_native; - - /** - * True if the native code set is used for wide characters. - * If the set is native, no the intermediate Reader object - * is instantiated when writing characters. - */ - private boolean wide_native; - - /** - * If true, the stream expect - * the multi-byte data in the form "less significant byte - * first" (Little Endian). This is the opposite to the - * java standard (Big Endian). - */ - private boolean little_endian; - - /** - * Creates the stream. The stream reads Big Endian by - * default. - * - * @param readFrom a stream to read CORBA input from. - */ - public cdrInput(java.io.InputStream readFrom) - { - setInputStream(readFrom); - setCodeSet(cxCodeSet.STANDARD); - } - - /** - * Creates the stream, requiring the subsequent call - * of {@link #setInputStream(java.io.InputStream)}. - */ - public cdrInput() - { - setCodeSet(cxCodeSet.STANDARD); - } - - /** - * Set the Big Endian or Little Endian encoding. - * The stream reads Big Endian by default. - * - * @param use_little_endian if true, the stream expect - * the multi-byte data in the form "less significant byte - * first" (Little Endian). This is the opposite to the - * java standard (Big Endian). - */ - public void setBigEndian(boolean use_big_endian) - { - little_endian = !use_big_endian; - setInputStream(actual_stream); - } - - /** - * Set the input stream that receives the CORBA input. - * - * @param readFrom the stream. - */ - public void setInputStream(java.io.InputStream readFrom) - { - if (little_endian) - b = new LittleEndianInputStream(readFrom); - else - b = new BigEndianInputStream(readFrom); - - actual_stream = readFrom; - } - - /** - * Set the alignment offset, if the index of the first byte in the - * stream is different from 0. - */ - public abstract void setOffset(int offset); - - /** - * Set the orb, associated with this stream. - * @param an_orb - */ - public void setOrb(ORB an_orb) - { - orb = an_orb; - } - - /** - * Set the GIOP version. Some data types are written differently - * for the different versions. The default version is 1.0 . - */ - public void setVersion(Version giop_version) - { - giop = giop_version; - } - - /** - * Align the curretn position at the given natural boundary. - */ - public abstract void align(int boundary); - - /** - * Reads the CORBA unsigned long (java int), returning the - * value in the sufficiently large java long. - */ - public long gnu_read_ulong() - { - try - { - long l = b.readInt(); - l &= 0xFFFFFFF; - return l; - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the unsigned short integer value and return it as java - * int, sufficiently large to hold all values. - */ - public int gnu_read_ushort() - { - try - { - align(2); - return b.readUnsignedShort(); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Return the associated {@link ORB}. - * @return the associated {@link ORB} or null is no such is set. - */ - public ORB orb() - { - return orb; - } - - /** - * Read a single byte directly from the buffer. - */ - public int read() - throws java.io.IOException - { - try - { - return b.read(); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - } - - /** - * Read bytes directly from the buffer. - */ - public int read(byte[] x, int ofs, int len) - throws java.io.IOException - { - try - { - return b.read(x, ofs, len); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - } - - /** - * Read bytes directly from the buffer. - */ - public int read(byte[] x) - throws java.io.IOException - { - try - { - return b.read(x); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - } - - /** - * Read the CORBA object. The object to read is represented in the - * form of the plain (not a string-encoded) IOR profile without the - * heading endian indicator. The responsible method for reading such - * data is {@link IOR.read_no_endian}. - * - * The returned object is usually casted into the given type using - * the .narrow method of its helper, despite in some cases the direct - * cast would also work. - * - * The null objects are recognised from the empty profile set. - * For such objects, null is returned. - * - * @return the loaded and constructed object. - */ - public org.omg.CORBA.Object read_Object() - { - try - { - IOR ior = new IOR(); - ior._read_no_endian(this); - - if (ior.Id == null) - return null; - - // Check maybe this is a remote reference to the local object. - // This is only possible if we access the repository of the - // connected object. - if (orb instanceof Functional_ORB) - { - Functional_ORB forb = (Functional_ORB) orb; - org.omg.CORBA.Object local = forb.find_local_object(ior); - if (local != null) - return local; - } - - // Search for the available stubs. - ObjectImpl impl = stubFinder.search(orb, ior); - try - { - if (impl._get_delegate() == null) - impl._set_delegate(new IOR_Delegate(orb, ior)); - } - catch (BAD_OPERATION ex) - { - // Some colaborants may throw this exception - // in response to the attempt to get the unset delegate. - impl._set_delegate(new IOR_Delegate(orb, ior)); - } - - return impl; - } - catch (IOException ex) - { - BAD_OPERATION bad = new BAD_OPERATION(); - bad.initCause(ex); - throw bad; - } - } - - /** - * Read the type code. The type code format is defined in the - * CORBA documenation. - */ - public TypeCode read_TypeCode() - { - try - { - return TypeCodeHelper.read(this); - } - - catch (Bounds ex) - { - throw new Unexpected(); - } - catch (BadKind ex) - { - throw new Unexpected(); - } - } - - /** - * Read the CORBA {@link Any}. This method first reads the - * type code, then delegates the functionality - * to {@link Any#read_value}. - */ - public Any read_any() - { - TypeCode ty = read_TypeCode(); - gnuAny any = new gnuAny(); - any.read_value(this, ty); - return any; - } - - /** - * Read the boolean, treating any non zero byte as true, - * zero byte as false. - */ - public boolean read_boolean() - { - try - { - return b.read() == 0 ? false : true; - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the array of boolean. - */ - public void read_boolean_array(boolean[] x, int offs, int len) - { - try - { - for (int i = offs; i < offs + len; i++) - { - x [ i ] = b.read() == 0 ? false : true; - } - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read a character using narrow charset encoding. Depending form - * which encoding is set, this still can be Unicode or ever wider. - */ - public char read_char() - { - try - { - if (narrow_native) - return (char) b.read(); - else - return (char) new InputStreamReader((InputStream) b, narrow_charset).read(); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read a character array, using narrow charset encoding. - */ - public void read_char_array(char[] x, int offset, int length) - { - try - { - if (narrow_native) - { - for (int i = offset; i < offset + length; i++) - x [ i ] = (char) b.read(); - } - else - { - InputStreamReader reader = - new InputStreamReader((InputStream) b, narrow_charset); - reader.read(x, offset, length); - } - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the double value, IEEE 754 format. - */ - public double read_double() - { - try - { - align(8); - return b.readDouble(); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(); - } - } - - /** - * Read the array of double values, IEEE 754 format. - */ - public void read_double_array(double[] x, int offs, int len) - { - try - { - align(8); - for (int i = offs; i < offs + len; i++) - { - x [ i ] = b.readDouble(); - } - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the encapsulated stream. - * If the encapsulated sequence appears to be in the - * Little endian format, the flag of the returned stream - * is set to read Little endian. - */ - public cdrBufInput read_encapsulation() - { - try - { - int l = read_long(); - - byte[] r = new byte[ l ]; - int n = 0; - reading: - while (n < r.length) - { - n += read(r, n, r.length - n); - } - - cdrBufInput capsule = new cdrBufInput(r); - capsule.setOrb(orb); - - int endian = capsule.read_octet(); - - if (endian != 0) - { - capsule.setBigEndian(false); - } - - return capsule; - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the CORBA fixed (the end of the fixed - * can be determined by its last byte). The scale is always - * assumed to be zero. - */ - public BigDecimal read_fixed() - { - try - { - return BigDecimalHelper.read(this, 0); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the float value, IEEE 754 format. - */ - public float read_float() - { - try - { - align(4); - return b.readFloat(); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read an array of float values, IEEE 754 format. - */ - public void read_float_array(float[] x, int offs, int len) - { - try - { - align(4); - for (int i = offs; i < offs + len; i++) - { - x [ i ] = b.readFloat(); - } - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the CORBA long (java int), high byte first. - */ - public int read_long() - { - try - { - align(4); - return b.readInt(); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read an array of CORBA longs (java ints). - */ - public void read_long_array(int[] x, int offs, int len) - { - try - { - align(4); - for (int i = offs; i < offs + len; i++) - { - x [ i ] = b.readInt(); - } - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the CORBA long long (java long). - */ - public long read_longlong() - { - try - { - align(8); - return b.readLong(); - } - catch (EOFException ex) - { - throw new MARSHAL(UNEXP_EOF); - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read an array of CORBA long longs (java longs). - */ - public void read_longlong_array(long[] x, int offs, int len) - { - try - { - align(8); - for (int i = offs; i < offs + len; i++) - { - x [ i ] = b.readLong(); - } - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read a single byte. - */ - public byte read_octet() - { - try - { - return b.readByte(); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the byte array. - */ - public void read_octet_array(byte[] x, int offs, int len) - { - try - { - b.read(x, offs, len); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the length of the byte array as CORBA long and then - * the array itseld. - */ - public byte[] read_sequence() - { - try - { - int l = read_long(); - byte[] b = new byte[ l ]; - if (l > 0) - { - read(b); - } - return b; - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the CORBA short integer. - */ - public short read_short() - { - try - { - align(2); - return b.readShort(); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read the array of CORBA short integer values. - */ - public void read_short_array(short[] x, int offs, int len) - { - try - { - align(2); - for (int i = offs; i < offs + len; i++) - { - x [ i ] = b.readShort(); - } - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Read a singe byte string. The method firs reads the - * byte array and then calls a constructor to create a - * string from this array. The character encoding, if - * previously set, is taken into consideration. - * - * @return a loaded string. - */ - public String read_string() - { - try - { - align(4); - - int n = b.readInt(); - byte[] s = new byte[ n ]; - b.read(s); - - // Discard the null terminator. - if (narrow_charset == null) - return new String(s, 0, n - 1); - else - return new String(s, 0, n - 1, narrow_charset); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(); - } - } - - /** - * Reads the CORBA unsigned long (java int), delegating - * functionality to {@link #read_long}. - */ - public int read_ulong() - { - return read_long(); - } - - /** - * Reads the array of CORBA unsigned long (java integer) values, - * delegating functionality to - * {@link #real_long_array}. - */ - public void read_ulong_array(int[] x, int offs, int len) - { - read_long_array(x, offs, len); - } - - /** - * Read the CORBA unsigned long long value, - * delegating functionality to {@link #read_longlong}. - * There is no way to return values over the limit of - * the java signed long in other way than returning - * the negative value. - */ - public long read_ulonglong() - { - return read_longlong(); - } - - /** - * Reads the array of CORBA long long (java long) values, - * delegating functionality to - * {@link #real_longlong_array}. - */ - public void read_ulonglong_array(long[] x, int offs, int len) - { - read_longlong_array(x, offs, len); - } - - /** - * Read the unsigned short integer value. Due strange specification, - * the returned value must be the short type as well, so the - * the best solution seems just to delegete functionality to - * read_short. - */ - public short read_ushort() - { - return read_short(); - } - - /** - * Read an array of unsigned short values, delegating the - * functionality to {@link read_short_array}. - */ - public void read_ushort_array(short[] x, int offs, int len) - { - read_short_array(x, offs, len); - } - - /** - * Reads the wide character using the encoding, specified in the - * wide_charset. - */ - public char read_wchar() - { - try - { - if (giop.until_inclusive(1, 1)) - align(2); - - if (wide_native) - return (char) b.readShort(); - else - return (char) new InputStreamReader((InputStream) b, wide_charset).read(); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - catch (IOException ex) - { - throw new Unexpected(); - } - } - - /** - * Read an array of "wide chars", each representing a two byte - * Unicode character, high byte first. - */ - public void read_wchar_array(char[] x, int offset, int length) - { - try - { - if (giop.until_inclusive(1, 1)) - align(2); - - if (wide_native) - { - for (int i = offset; i < offset + length; i++) - x [ i ] = (char) b.readShort(); - } - else - { - InputStreamReader reader = - new InputStreamReader((InputStream) b, wide_charset); - reader.read(x, offset, length); - } - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Reads the string in wide character format - * (ussually UTF-16, Unicode). Takes the currently set charset - * into consideration. - * - * If the native (UTF-16) encoding is used - * of the GIOP protocol is before 1.2, delegates functionality - * to "plain" {@link #read_wstring_UTF_16}. - */ - public String read_wstring() - { - // Native encoding or word oriented data. - if (wide_native || giop.until_inclusive(1, 1)) - return read_wstring_UTF_16(); - try - { - align(4); - - int n = b.readInt(); - byte[] s = new byte[ n ]; - b.read(s); - - return new String(s, 0, n, wide_charset); - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Reads first length of the string and the all characters as an - * Unicode (UTF-16) characters. Mind that GIOP 1.1 has the extra - * null character at the end that must be discarded. - */ - public String read_wstring_UTF_16() - { - try - { - int p = 0; - int n = read_long(); - - // The null terminator that is no longer present since 1.2 . - int nt = giop.since_inclusive(1, 2) ? 0 : 1; - - // Convert bytes to shorts. - n = n / 2; - - char[] s = new char[ n ]; - - for (int i = 0; i < s.length; i++) - s [ i ] = (char) b.readShort(); - - // Check for the byte order marker here. - if (s [ 0 ] == 0xFEFF) - { - // Big endian encoding - do nothing, but move the pointer - // one position forward. - p = 1; - } - else if (s [ 0 ] == 0xFFFE) - { - // Little endian encoding, swap the bytes and move one - // position forward. - p = 1; - - for (int i = p; i < s.length; i++) - s [ i ] = swap(s [ i ]); - } - - // Discard the null terminator and, if needed, the endian marker. - String r = new String(s, p, n - nt - p); - return r; - } - catch (EOFException ex) - { - MARSHAL t = new MARSHAL(UNEXP_EOF); - t.initCause(ex); - throw t; - } - - catch (IOException ex) - { - throw new Unexpected(ex); - } - } - - /** - * Swap bytes in the character. - */ - public static char swap(char x) - { - int hi; - int lo; - - lo = x & 0xFF; - hi = (x >> 8) & 0xFF; - - return (char) ((lo << 8) | hi); - } - - /** - * Set the current code set context. - */ - public void setCodeSet(cxCodeSet a_codeset) - { - this.codeset = a_codeset; - narrow_charset = CharSets_OSF.getName(codeset.char_data); - wide_charset = CharSets_OSF.getName(codeset.wide_char_data); - - narrow_native = CharSets_OSF.NATIVE_CHARACTER == codeset.char_data; - wide_native = CharSets_OSF.NATIVE_WIDE_CHARACTER == codeset.wide_char_data; - } - - /** - * Get the current code set context. - */ - public cxCodeSet getCodeSet() - { - return codeset; - } - - /** - * Read the object that is an instance of the given class. The current - * implementation delegates functionality to the parameterless - * {@link readObject()}. - * - * @param klass a class of that this object the instance is. - * - * @return the returned object. - */ - public org.omg.CORBA.Object read_Object(Class klass) - { - return read_Object(); - } - - /** - * Read a value type structure from the stream. - * - * OMG specification states the writing format is outside the scope - * of GIOP definition. This implementation uses java serialization - * mechanism, calling {@link ObjectInputStream#readObject} - * - * @return an value type structure, unmarshaled from the stream - */ - public Serializable read_Value() - { - return read_value(); - } - - /** - * Read the abstract interface. An abstract interface can be either - * CORBA value type or CORBA object and is returned as an abstract - * java.lang.Object. - * - * As specified in OMG specification, this reads a single - * boolean and then delegates either to {@link #read_Object()} (for false) - * or to {@link #read_Value()} (for true). - * - * @return an abstract interface, unmarshaled from the stream - */ - public java.lang.Object read_Abstract() - { - return read_abstract_interface(); - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_char_array(CharSeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - read_char_array(holder.value, offset, length); - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_wchar_array(WCharSeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - read_wchar_array(holder.value, offset, length); - } - - /** - * If required, allocate or resize the char array to fit the newly - * read values. - * - * @param holder_value the existing char array, may be null. - * @param offset the required offset to read. - * @param length the length of the new sequence. - * - * @return the allocated or resized array, same array if no such operations - * are required. - */ - private char[] ensureArray(char[] holder_value, int offset, int length) - { - if (holder_value == null) - return new char[ offset + length ]; - else if (holder_value.length < offset + length) - { - char[] value = new char[ offset + length ]; - System.arraycopy(holder_value, 0, value, 0, holder_value.length); - return value; - } - else - return holder_value; - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_ulong_array(ULongSeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - read_ulong_array(holder.value, offset, length); - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_long_array(LongSeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - read_ulong_array(holder.value, offset, length); - } - - /** - * If required, allocate or resize the int array to fit the newly - * read values. - * - * @param holder_value the existing int array, may be null. - * @param offset the required offset to read. - * @param length the length of the new sequence. - * - * @return the allocated or resized array, same array if no such operations - * are required. - */ - private int[] ensureArray(int[] holder_value, int offset, int length) - { - if (holder_value == null) - return new int[ offset + length ]; - else if (holder_value.length < offset + length) - { - int[] value = new int[ offset + length ]; - System.arraycopy(holder_value, 0, value, 0, holder_value.length); - return value; - } - else - return holder_value; - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_float_array(FloatSeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - read_float_array(holder.value, offset, length); - } - - /** - * If required, allocate or resize the float array to fit the newly - * read values. - * - * @param holder_value the existing float array, may be null. - * @param offset the required offset to read. - * @param length the length of the new sequence. - * - * @return the allocated or resized array, same array if no such operations - * are required. - */ - private float[] ensureArray(float[] holder_value, int offset, int length) - { - if (holder_value == null) - return new float[ offset + length ]; - else if (holder_value.length < offset + length) - { - float[] value = new float[ offset + length ]; - System.arraycopy(holder_value, 0, value, 0, holder_value.length); - return value; - } - else - return holder_value; - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_double_array(DoubleSeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - read_double_array(holder.value, offset, length); - } - - /** - * If required, allocate or resize the double array to fit the newly - * read values. - * - * @param holder_value the existing double array, may be null. - * @param offset the required offset to read. - * @param length the length of the new sequence. - * - * @return the allocated or resized array, same array if no such operations - * are required. - */ - private double[] ensureArray(double[] holder_value, int offset, int length) - { - if (holder_value == null) - return new double[ offset + length ]; - else if (holder_value.length < offset + length) - { - double[] value = new double[ offset + length ]; - System.arraycopy(holder_value, 0, value, 0, holder_value.length); - return value; - } - else - return holder_value; - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_short_array(ShortSeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - read_short_array(holder.value, offset, length); - } - - /** {@inheritDoc} */ - public void read_ushort_array(UShortSeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - read_ushort_array(holder.value, offset, length); - } - - /** - * If required, allocate or resize the short array to fit the newly - * read values. - * - * @param holder_value the existing short array, may be null. - * @param offset the required offset to read. - * @param length the length of the new sequence. - * - * @return the allocated or resized array, same array if no such operations - * are required. - */ - private short[] ensureArray(short[] holder_value, int offset, int length) - { - if (holder_value == null) - return new short[ offset + length ]; - else if (holder_value.length < offset + length) - { - short[] value = new short[ offset + length ]; - System.arraycopy(holder_value, 0, value, 0, holder_value.length); - return value; - } - else - return holder_value; - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_octet_array(OctetSeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - read_octet_array(holder.value, offset, length); - } - - /** - * If required, allocate or resize the byte array to fit the newly - * read values. - * - * @param holder_value the existing byte array, may be null. - * @param offset the required offset to read. - * @param length the length of the new sequence. - * - * @return the allocated or resized array, same array if no such operations - * are required. - */ - private byte[] ensureArray(byte[] holder_value, int offset, int length) - { - if (holder_value == null) - return new byte[ offset + length ]; - else if (holder_value.length < offset + length) - { - byte[] value = new byte[ offset + length ]; - System.arraycopy(holder_value, 0, value, 0, holder_value.length); - return value; - } - else - return holder_value; - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_longlong_array(LongLongSeqHolder holder, int offset, - int length - ) - { - holder.value = ensureArray(holder.value, offset, length); - read_longlong_array(holder.value, offset, length); - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_ulonglong_array(ULongLongSeqHolder holder, int offset, - int length - ) - { - holder.value = ensureArray(holder.value, offset, length); - read_ulonglong_array(holder.value, offset, length); - } - - /** - * If required, allocate or resize the array of longs to fit the newly - * read values. - * - * @param holder_value the existing array, may be null. - * @param offset the required offset to read. - * @param length the length of the new sequence. - * - * @return the allocated or resized array, same array if no such operations - * are required. - */ - private long[] ensureArray(long[] holder_value, int offset, int length) - { - if (holder_value == null) - return new long[ offset + length ]; - else if (holder_value.length < offset + length) - { - long[] value = new long[ offset + length ]; - System.arraycopy(holder_value, 0, value, 0, holder_value.length); - return value; - } - else - return holder_value; - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_boolean_array(BooleanSeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - read_boolean_array(holder.value, offset, length); - } - - /** - * If required, allocate or resize the array of booleans to fit the newly - * read values. - * - * @param holder_value the existing array of booleans, may be null. - * @param offset the required offset to read. - * @param length the length of the new sequence. - * - * @return the allocated or resized array, same array if no such operations - * are required. - */ - private boolean[] ensureArray(boolean[] holder_value, int offset, int length) - { - if (holder_value == null) - return new boolean[ offset + length ]; - else if (holder_value.length < offset + length) - { - boolean[] value = new boolean[ offset + length ]; - System.arraycopy(holder_value, 0, value, 0, holder_value.length); - return value; - } - else - return holder_value; - } - - /** - * Read an array. In OMG specification is written that if the data does - * not fit into the holder value field, that array must be resized. - * The implementation follows this rule. If the holder value field - * contains null, it is newly instantiated. - */ - public void read_any_array(AnySeqHolder holder, int offset, int length) - { - holder.value = ensureArray(holder.value, offset, length); - for (int i = offset; i < offset + length; i++) - { - holder.value [ i ] = read_any(); - } - } - - /** - * If required, allocate or resize the array of Anys to fit the newly - * read values. - * - * @param holder_value the existing array of Anys, may be null. - * @param offset the required offset to read. - * @param length the length of the new sequence. - * - * @return the allocated or resized array, same array if no such operations - * are required. - */ - private Any[] ensureArray(Any[] holder_value, int offset, int length) - { - if (holder_value == null) - return new Any[ offset + length ]; - else if (holder_value.length < offset + length) - { - Any[] value = new Any[ offset + length ]; - System.arraycopy(holder_value, 0, value, 0, holder_value.length); - return value; - } - else - return holder_value; - } - - /** - * This method is required to represent the DataInputStream as a value - * type object. - * - * @return a single entity "IDL:omg.org/CORBA/DataInputStream:1.0", - * always. - */ - public String[] _truncatable_ids() - { - return new String[] { "IDL:omg.org/CORBA/DataInputStream:1.0" }; - } -} \ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java b/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java deleted file mode 100644 index 85f341c912d..00000000000 --- a/libjava/classpath/gnu/CORBA/CDR/cdrOutput.java +++ /dev/null @@ -1,1009 +0,0 @@ -/* cdrOutput.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.CORBA.CDR; - -import gnu.CORBA.BigDecimalHelper; -import gnu.CORBA.GIOP.CharSets_OSF; -import gnu.CORBA.GIOP.cxCodeSet; -import gnu.CORBA.Poa.gnuServantObject; -import gnu.CORBA.IOR; -import gnu.CORBA.Simple_delegate; -import gnu.CORBA.TypeCodeHelper; -import gnu.CORBA.Unexpected; -import gnu.CORBA.Version; -import gnu.CORBA.primitiveTypeCode; - -import org.omg.CORBA.Any; -import org.omg.CORBA.BAD_OPERATION; -import org.omg.CORBA.Context; -import org.omg.CORBA.ContextList; -import org.omg.CORBA.MARSHAL; -import org.omg.CORBA.NO_IMPLEMENT; -import org.omg.CORBA.ORB; -import org.omg.CORBA.TCKind; -import org.omg.CORBA.TypeCode; -import org.omg.CORBA.TypeCodePackage.BadKind; -import org.omg.CORBA.UserException; -import org.omg.CORBA.portable.Delegate; -import org.omg.CORBA.portable.ObjectImpl; -import org.omg.CORBA.portable.OutputStream; -import org.omg.CORBA.portable.Streamable; - -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Serializable; - -import java.math.BigDecimal; - -/** - * A simple CORBA CDR (common data representation) - * output stream, writing data into the - * given {@link java.io.OutputStream}. - * - * The same class also implements the {@link DataInputStream}, - * providing support for writing the value type objects - * in a user defined way. - * - * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) - */ -public abstract class cdrOutput - extends org.omg.CORBA_2_3.portable.OutputStream - implements org.omg.CORBA.DataOutputStream -{ - /** - * This instance is used to convert primitive data types into the - * byte sequences. - */ - protected abstractDataOutputStream b; - - /** - * The associated orb, if any. - */ - protected ORB orb; - - /** - * The GIOP version. - */ - protected Version giop = new Version(1, 2); - - /** - * The code set information. - */ - protected cxCodeSet codeset; - - /** - * The name of the currently used narrow charset. - */ - private String narrow_charset; - - /** - * The name of the currently used wide charset, null if - * the native wide charset is used. - */ - private String wide_charset; - - /** - * True if the native code set is used for narrow characters. - * If the set is native, no the intermediate Reader object - * is instantiated when writing characters. - */ - private boolean narrow_native; - - /** - * True if the native code set is used for wide characters. - * If the set is native, no the intermediate Reader object - * is instantiated when writing characters. - */ - private boolean wide_native; - - /** - * If true, the Little Endian encoding is used to write the - * data. Otherwise, the Big Endian encoding is used. - */ - private boolean little_endian; - - /** - * The stream whre the data are actually written. - */ - private java.io.OutputStream actual_stream; - - /** - * Creates the stream. - * - * @param writeTo a stream to write CORBA output to. - */ - public cdrOutput(java.io.OutputStream writeTo) - { - setOutputStream(writeTo); - setCodeSet(cxCodeSet.STANDARD); - } - - /** - * Creates the stream, requiring the subsequent call - * of {@link #setOutputStream(java.io.OutputStream)}. - */ - public cdrOutput() - { - setCodeSet(cxCodeSet.STANDARD); - } - - /** - * Set the alignment offset, if the index of the first byte in the - * stream is different from 0. - */ - public abstract void setOffset(int an_offset); - - /** - * Set the current code set context. - */ - public void setCodeSet(cxCodeSet a_codeset) - { - this.codeset = a_codeset; - narrow_charset = CharSets_OSF.getName(codeset.char_data); - wide_charset = CharSets_OSF.getName(codeset.wide_char_data); - - narrow_native = CharSets_OSF.NATIVE_CHARACTER == codeset.char_data; - wide_native = CharSets_OSF.NATIVE_WIDE_CHARACTER == codeset.wide_char_data; - } - - /** - * Get the current code set context. - */ - public cxCodeSet getCodeSet() - { - return codeset; - } - - /** - * Set the orb, associated with this stream. - * @param an_orb - */ - public void setOrb(ORB an_orb) - { - orb = an_orb; - } - - /** - * Set the output stream that receives the CORBA output. - * - * @param writeTo the stream. - */ - public void setOutputStream(java.io.OutputStream writeTo) - { - if (little_endian) - b = new LittleEndianOutputStream(writeTo); - else - b = new BigEndianOutputStream(writeTo); - - actual_stream = writeTo; - } - - /** - * Set the GIOP version. Some data types are written differently - * for the different versions. The default version is 1.0 . - */ - public void setVersion(Version giop_version) - { - giop = giop_version; - } - - /** - * Specify if the stream should use the Big Endian (usual for java) - * or Little Encoding. The default is Big Endian. - * - * @param use_big_endian if true, use Big Endian, if false, - * use Little Endian. - */ - public void setBigEndian(boolean use_big_endian) - { - little_endian = !use_big_endian; - setOutputStream(actual_stream); - } - - /** - * Align the curretn position at the given natural boundary. - */ - public abstract void align(int boundary); - - /** - * Create the encapsulation stream, associated with the current - * stream. The encapsulated stream must be closed. When being - * closed, the encapsulation stream writes its buffer into - * this stream using the CORBA CDR encapsulation rules. - * - * It is not allowed to write to the current stream directly - * before the encapsulation stream is closed. - * - * The encoding (Big/Little Endian) inside the encapsulated - * sequence is the same as used into the parent stream. - * - * @return the encapsulated stream. - */ - public cdrOutput createEncapsulation() - { - return new encapsulatedOutput(this, !little_endian); - } - - /** - * Return the associated {@link ORB}. - * @return the associated {@link ORB} or null is no such is set. - */ - public ORB orb() - { - return orb; - } - - /** - * Write a single byte. - * @param a byte to write (low 8 bits are written). - */ - public void write(int n) - { - try - { - b.write(n); - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Write bytes directly into the underlying stream. - */ - public void write(byte[] x) - throws java.io.IOException - { - b.write(x); - } - - /** - * Write bytes directly into the underlying stream. - */ - public void write(byte[] x, int ofs, int len) - throws java.io.IOException - { - b.write(x, ofs, len); - } - - /** - * Following the specification, this is not implemented. - * Override to get the functionality. - */ - public void write_Context(Context context, ContextList contexts) - { - throw new NO_IMPLEMENT(); - } - - /** - * Read the CORBA object. The object is written - * form of the plain (not a string-encoded) IOR profile without the - * heading endian indicator. The responsible method for reading such - * data is {@link IOR.write_no_endian}. - * - * The null value is written as defined in OMG specification - * (zero length string, followed by an empty set of profiles). - */ - public void write_Object(org.omg.CORBA.Object x) - { - if (x == null) - { - IOR.write_null(this); - return; - } - else if (x instanceof gnuServantObject) - { - // The ORB may be different if several ORBs coexist - // in the same machine. - gnuServantObject g = (gnuServantObject) x; - IOR ior = g.orb.getLocalIor(x); - ior._write_no_endian(this); - return; - } - else if (x instanceof ObjectImpl) - { - Delegate d = ((ObjectImpl) x)._get_delegate(); - - if (d instanceof Simple_delegate) - { - Simple_delegate ido = (Simple_delegate) d; - ido.getIor()._write_no_endian(this); - return; - } - } - - // Either this is not an ObjectImpl or it has the - // unexpected delegate. Try to convert via ORBs - // object_to_string(). - if (orb != null) - { - IOR ior = IOR.parse(orb.object_to_string(x)); - ior._write_no_endian(this); - return; - } - else - throw new BAD_OPERATION("Please set the ORB for this stream."); - } - - /** - * Write the TypeCode. This implementation delegates functionality - * to {@link cdrTypeCode}. - * - * @param x a TypeCode to write. - */ - public void write_TypeCode(TypeCode x) - { - try - { - TypeCodeHelper.write(this, x); - } - catch (UserException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes an instance of the CORBA {@link Any}. - * This method writes the typecode, followed - * by value itself. In Any contains null - * (value not set), the {@link TCKind#tk_null} - * is written. - * - * @param x the {@link Any} to write. - */ - public void write_any(Any x) - { - Streamable value = x.extract_Streamable(); - if (value != null) - { - write_TypeCode(x.type()); - value._write(this); - } - else - { - primitiveTypeCode p = new primitiveTypeCode(TCKind.tk_null); - write_TypeCode(p); - } - } - - /** - * Writes a single byte, 0 for false, - * 1 for true. - * - * @param x the value to write - */ - public void write_boolean(boolean x) - { - try - { - b.write(x ? 1 : 0); - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the boolean array. - * - * @param x array - * @param ofs offset - * @param len length. - */ - public void write_boolean_array(boolean[] x, int ofs, int len) - { - try - { - for (int i = ofs; i < ofs + len; i++) - { - b.write(x [ i ] ? 1 : 0); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the lower byte of the passed parameter. - * @param x the char to write - * - * It is effective to write more characters at once. - */ - public void write_char(char x) - { - try - { - if (narrow_native) - b.write(x); - else - { - OutputStreamWriter ow = - new OutputStreamWriter((OutputStream) b, narrow_charset); - ow.write(x); - ow.flush(); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the lower bytes of the passed array members. - * - * @param chars an array - * @param offsets offset - * @param length length - */ - public void write_char_array(char[] chars, int offset, int length) - { - try - { - if (narrow_native) - { - for (int i = offset; i < offset + length; i++) - { - b.write(chars [ i ]); - } - } - else - { - OutputStreamWriter ow = - new OutputStreamWriter((OutputStream) b, narrow_charset); - ow.write(chars, offset, length); - ow.flush(); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the double value (IEEE 754 format). - */ - public void write_double(double x) - { - try - { - align(8); - b.writeDouble(x); - } - catch (Exception ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the array of double values. - */ - public void write_double_array(double[] x, int ofs, int len) - { - try - { - align(8); - for (int i = ofs; i < ofs + len; i++) - { - b.writeDouble(x [ i ]); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes CORBA fixed, storing all digits but not the scale. - * The end of the record on fixed can - * be determined from its last byte. - */ - public void write_fixed(BigDecimal fixed) - { - try - { - BigDecimalHelper.write(this, fixed); - } - catch (IOException ex) - { - Unexpected.error(ex); - } - catch (BadKind ex) - { - Unexpected.error(ex); - } - } - - /** - * Write the float value (IEEE 754 format). - */ - public void write_float(float x) - { - try - { - align(4); - b.writeFloat(x); - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes an array of the float values. - */ - public void write_float_array(float[] x, int ofs, int len) - { - try - { - align(4); - for (int i = ofs; i < ofs + len; i++) - { - b.writeFloat(x [ i ]); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the integer value (CORBA long, four bytes, high byte first). - * @param x the value to write. - */ - public void write_long(int x) - { - try - { - align(4); - b.writeInt(x); - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the array of integer (CORBA long) values. - * - * @param x value - * @param ofs offset - * @param len length - */ - public void write_long_array(int[] x, int ofs, int len) - { - try - { - align(4); - for (int i = ofs; i < ofs + len; i++) - { - b.writeInt(x [ i ]); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the long (CORBA long long) value, 8 bytes, - * high byte first. - * - * @param x the value to write. - */ - public void write_longlong(long x) - { - try - { - align(8); - b.writeLong(x); - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the array of longs (CORBA long longs) values. - * - * @param x value - * @param ofs offset - * @param len length - */ - public void write_longlong_array(long[] x, int ofs, int len) - { - try - { - align(8); - for (int i = ofs; i < ofs + len; i++) - { - b.writeLong(x [ i ]); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes this byte. - * @param x - */ - public void write_octet(byte x) - { - try - { - b.writeByte(x); - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the array of bytes (CORBA octets) values. - * - * @param x value - * @param ofs offset - * @param len length - */ - public void write_octet_array(byte[] x, int ofs, int len) - { - try - { - b.write(x, ofs, len); - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes first the size of array, and then the byte array using - * the {@link java.io.OutputStream#write(byte[]) }. The sequence - * being written is preceeded by the int, representing the array - * length. - */ - public void write_sequence(byte[] buf) - { - try - { - write_long(buf.length); - write(buf); - } - catch (IOException ex) - { - MARSHAL t = new MARSHAL(); - t.initCause(ex); - throw t; - } - } - - /** - * Writes the contents of the provided stream. - * The sequence being written is preceeded by the int, - * representing the stream buffer length (the number of - * bytes being subsequently written). - */ - public void write_sequence(cdrBufOutput from) - { - try - { - write_long(from.buffer.size()); - from.buffer.writeTo(this); - } - catch (IOException ex) - { - MARSHAL t = new MARSHAL(); - t.initCause(ex); - throw t; - } - } - - /** - * Writes the two byte integer (short), high byte first. - * - * @param x the integer to write. - */ - public void write_short(short x) - { - try - { - align(2); - b.writeShort(x); - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the array of short (two byte integer) values. - * - * @param x value - * @param ofs offset - * @param len length - */ - public void write_short_array(short[] x, int ofs, int len) - { - try - { - align(2); - for (int i = ofs; i < ofs + len; i++) - { - b.writeShort(x [ i ]); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the string. This implementation first calls - * String.getBytes() and then writes the length of the returned - * array (as CORBA ulong) and the returned array itself. - * - * The encoding information, if previously set, is taken - * into consideration. - * - * @param x the string to write. - */ - public void write_string(String x) - { - try - { - byte[] ab = x.getBytes(narrow_charset); - write_long(ab.length + 1); - write(ab); - - // write null terminator. - write(0); - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the CORBA unsigned long in the same way as CORBA long. - */ - public void write_ulong(int x) - { - write_long(x); - } - - /** - * Writes the array of CORBA unsigned longs in the same way as - * array of ordinary longs. - */ - public void write_ulong_array(int[] x, int ofs, int len) - { - write_long_array(x, ofs, len); - } - - /** - * Write the unsigned long long in the same way as an ordinary long long. - * - * @param x a value to write. - */ - public void write_ulonglong(long x) - { - write_longlong(x); - } - - /** - * Write the array of unsingel long longs in the same way - * an an array of the ordinary long longs. - */ - public void write_ulonglong_array(long[] x, int ofs, int len) - { - write_longlong_array(x, ofs, len); - } - - /** - * Write the unsigned short in the same way as an ordinary short. - */ - public void write_ushort(short x) - { - write_short(x); - } - - /** - * Write an array of unsigned short integersin the same way - * as an array of ordinary short integers. - */ - public void write_ushort_array(short[] x, int ofs, int len) - { - write_short_array(x, ofs, len); - } - - /** - * Writes the character as two byte short integer (Unicode value), - * high byte first. Writes in Big Endian, but never writes the - * endian indicator. - * - * The character is always written using the native UTF-16BE charset - * because its size under arbitrary encoding is not evident. - */ - public void write_wchar(char x) - { - try - { - if (giop.until_inclusive(1, 1)) - align(2); - - if (wide_native) - b.writeShort(x); - else - { - OutputStreamWriter ow = - new OutputStreamWriter((OutputStream) b, wide_charset); - ow.write(x); - ow.flush(); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Write the array of wide chars. - * - * @param chars the array of wide chars - * @param offset offset - * @param length length - * - * The char array is always written using the native UTF-16BE charset - * because the character size under arbitrary encoding is not evident. - */ - public void write_wchar_array(char[] chars, int offset, int length) - { - try - { - if (giop.until_inclusive(1, 1)) - align(2); - - if (wide_native) - { - for (int i = offset; i < offset + length; i++) - { - b.writeShort(chars [ i ]); - } - } - else - { - OutputStreamWriter ow = - new OutputStreamWriter((OutputStream) b, wide_charset); - ow.write(chars, offset, length); - ow.flush(); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** - * Writes the length of the string in bytes (not characters) and - * then all characters as two byte unicode chars. Adds the - * Big Endian indicator, 0xFFFE, at the beginning and null wide char at - * the end. - * - * @param x the string to write. - */ - public void write_wstring(String x) - { - try - { - if (giop.since_inclusive(1, 2)) - { - byte[] bytes = x.getBytes(wide_charset); - write_sequence(bytes); - } - else - { - // Encoding with null terminator always in UTF-16. - // The wide null terminator needs extra two bytes. - write_long(2 * x.length() + 2); - - for (int i = 0; i < x.length(); i++) - { - b.writeShort(x.charAt(i)); - } - - // Write null terminator. - b.writeShort(0); - } - } - catch (IOException ex) - { - Unexpected.error(ex); - } - } - - /** {@inheritDoc} */ - public void write_any_array(Any[] anys, int offset, int length) - { - for (int i = offset; i < offset + length; i++) - { - write_any(anys [ i ]); - } - } - - public String[] _truncatable_ids() - { - /**@todo Implement this org.omg.CORBA.portable.ValueBase abstract method*/ - throw new java.lang.UnsupportedOperationException("Method _truncatable_ids() not yet implemented."); - } - - /** {@inheritDoc} */ - public void write_Abstract(java.lang.Object value) - { - write_Abstract(value); - } - - /** {@inheritDoc} */ - public void write_Value(Serializable value) - { - write_Value(value); - } -} \ No newline at end of file diff --git a/libjava/classpath/gnu/CORBA/CDR/encapsulatedOutput.java b/libjava/classpath/gnu/CORBA/CDR/encapsulatedOutput.java deleted file mode 100644 index 3350291bc73..00000000000 --- a/libjava/classpath/gnu/CORBA/CDR/encapsulatedOutput.java +++ /dev/null @@ -1,146 +0,0 @@ -/* EncapsulationOutput.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.CORBA.CDR; - -import java.io.IOException; - -/** - * The encapsulated data, as they are defined by CORBA specification. - * This includes the extra 0 byte (Big endian) in the beginning. - * When written to the parent steam, the encapsulated data are preceeded - * by the data length in bytes. - * - * @author Audrius Meskauskas (AudriusA@Bioinformatics.org) - */ -public class encapsulatedOutput - extends cdrOutput -{ - /** - * The Big Endian (most siginificant byte first flag). - */ - public static final byte BIG_ENDIAN = 0; - - /** - * The Little Endian (least siginificant byte first flag). - */ - public static final byte LITTLE_ENDIAN = 1; - - /** - * The byte buffer. - */ - public final aligningOutputStream buffer; - - /** - * The stream, where the data are being encapsulated. - */ - public final org.omg.CORBA.portable.OutputStream parent; - - /** - * Create the EncapsulationOutput with the given parent stream - * and the specified encoding. - */ - public encapsulatedOutput(org.omg.CORBA.portable.OutputStream _parent, - boolean use_big_endian) - { - super(); - buffer = new aligningOutputStream(); - setOutputStream(buffer); - parent = _parent; - write(use_big_endian?BIG_ENDIAN:LITTLE_ENDIAN); - } - - /** - * Set the alignment offset, if the index of the first byte in the - * stream is different from 0. - */ - public void setOffset(int an_offset) - { - buffer.setOffset(an_offset); - } - - /** - * Align the curretn position at the given natural boundary. - */ - public void align(int boundary) - { - buffer.align(boundary); - } - - /** - * Writes the content of the encapsulated output into the parent - * buffer. - */ - public void close() - { - try - { - parent.write_long(buffer.size()); - buffer.writeTo(parent); - } - catch (IOException ex) - { - InternalError err = new InternalError(); - err.initCause(ex); - throw err; - } - } - - /** - * Return the input stream that reads the previously written values. - */ - public org.omg.CORBA.portable.InputStream create_input_stream() - { - cdrBufInput in = new cdrBufInput(buffer.toByteArray()); - in.setOrb(orb); - - in.setVersion(giop); - in.setCodeSet(getCodeSet()); - - return in; - } - - /** - * Resets (clears) the buffer. - */ - public void reset() - { - buffer.reset(); - setOutputStream(buffer); - } -} diff --git a/libjava/classpath/gnu/CORBA/CDR/gnuRuntime.java b/libjava/classpath/gnu/CORBA/CDR/gnuRuntime.java new file mode 100644 index 00000000000..774c92816ae --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/gnuRuntime.java @@ -0,0 +1,336 @@ +/* gnuRuntime.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +import gnu.CORBA.Minor; + +import org.omg.CORBA.LocalObject; +import org.omg.CORBA.MARSHAL; + +import java.io.Serializable; +import java.util.Comparator; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; +import java.util.TreeSet; + +/** + * Our implementation of the sending context runtime. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public class gnuRuntime + extends LocalObject + implements org.omg.SendingContext.RunTime +{ + /** + * The data entry about the object that was written. + */ + static class Entry + { + /** + * The stream position, where the object was written. + */ + int at; + + /** + * The object that was written. + */ + Object object; + + public String toString() + { + return object + "[" + at + "] "+object.getClass().getName(); + } + } + + /** + * The instruction that the actual object is stored at different location. + * Used when processing chunked data where positions shifts due removing the + * chunking tags. + */ + static class Redirection + extends Entry + { + public String toString() + { + return "->" + at; + } + } + + /** + * Use serialVersionUID for interoperability. + */ + private static final long serialVersionUID = 1; + + /** + * The history of the written objects, maps object to records. The different + * objects must be treated as different regardless that .equals returns. + */ + private Map sh_objects = new IdentityHashMap(); + + /** + * The written repository Ids that can be shared. + */ + private Map sh_ids = new TreeMap(new Comparator() + { + public int compare(Object a, Object b) + { + if (a instanceof String && b instanceof String) + // Comparing string with string. + return ((String) a).compareTo((String) b); + else if (a instanceof String[] && b instanceof String[]) + { + // Comparing array with array. + String[] sa = (String[]) a; + String[] sb = (String[]) b; + + if (sa.length != sb.length) + return sa.length - sb.length; + else + { + int c; + for (int i = 0; i < sa.length; i++) + { + c = sa[i].compareTo(sb[i]); + if (c != 0) + return c; + } + return 0; + } + } + else + // Comparing string with array. + return a instanceof String ? 1 : -1; + } + }); + + /** + * The history of the written objects, maps positions to records. The + * different objects must be treated as different regardless that .equals + * returns. + */ + private Map positions = new HashMap(); + + /** + * The Codebase. + */ + private String codebase; + + /** + * The pre-created instance of the object being written (avoid + * re-instantiation). + */ + public Serializable target; + + /** + * Create Runtime. + * + * @param a_id a repository Id, if only one Id was specified in the stream. + * @param a_ids a repository Ids, if the multiple Ids were specified in te + * stream. + * @param a_codabase a codebase, if it was specified in the stream. + */ + public gnuRuntime(String a_codebase, Object a_target) + { + if (a_target instanceof Serializable) + target = (Serializable) a_target; + + codebase = a_codebase; + } + + /** + * Mark the given object as written at the given position. + */ + public void objectWritten(Object object, int at) + { + if (object == null || at < 0) + return; // No positional information provided. + if (sh_objects.containsKey(object)) + throw new AssertionError("Repetetive writing of the same object " + + object + " at " + at + dump()); + + Entry e = new Entry(); + e.at = at; + e.object = object; + + sh_objects.put(object, e); + positions.put(new Integer(at), e); + } + + /** + * Check if the object is already written. + * + * @return the position, at that the object is allready written or -1 if it is + * not yet written. + */ + public int isWrittenAt(Object x) + { + Entry e = (Entry) sh_objects.get(x); + return e == null ? -1 : e.at; + } + + /** + * Set redirection, indicating that the object, searched at the p_searched + * position can be actually found at the p_present position. + */ + public void redirect(int p_searched, int p_present) + { + Redirection redirection = new Redirection(); + redirection.at = p_present; + positions.put(new Integer(p_searched), redirection); + } + + /** + * Get the object, written at the given position. This returs both shared + * objects and repository Ids. + * + * @return the position, at that the object is allready written. + * + * @throws MARSHAL if there is no object written at that position. + */ + public Object isObjectWrittenAt(int x, int offset) + { + Entry e = (Entry) positions.get(new Integer(x)); + if (e instanceof Redirection) + return isObjectWrittenAt(e.at, offset); + else if (e != null) + return e.object; + else + { + MARSHAL m = new MARSHAL("No object was written at " + x + + " (offset " + offset + ") r " + this + dump()); + m.minor = Minor.Graph; + throw m; + } + } + + /** + * Mark the given object as written at the given position. + */ + public void singleIdWritten(String id, int at) + { + if (sh_ids.containsKey(id)) + throw new InternalError("Repetetive writing of the same string " + + id + dump()); + + Entry e = new Entry(); + e.at = at; + e.object = id; + + sh_ids.put(id, e); + positions.put(new Integer(at), e); + } + + /** + * Mark the given object as written at the given position. + */ + public void multipleIdsWritten(String[] ids, int at) + { + if (sh_ids.containsKey(ids)) + throw new InternalError("Repetetive writing of the same string " + + ids + dump()); + + Entry e = new Entry(); + e.at = at; + e.object = ids; + + sh_ids.put(ids, e); + positions.put(new Integer(at), e); + } + + /** + * Check if the object is already written. + * + * @return the position, at that the object is allready written or -1 if it is + * not yet written. + */ + public int idWrittenAt(Object x) + { + Entry e = (Entry) sh_ids.get(x); + return e == null ? -1 : e.at; + } + + /** + * Get the codebase. + */ + public String getCodeBase() + { + return codebase; + } + + /** + * Set the codebase, preserving the old value if the passed parameter is null + * and forming the space delimited list if both new and old values are not + * null. + */ + public void addCodeBase(String base) + { + if (base != null) + { + if (codebase == null) + codebase = base; + else + codebase = codebase + " " + base; + } + } + + /** + * Dump all objects that are currently stored. + */ + public String dump() + { + StringBuffer b = new StringBuffer(" Stream content: \n"); + + // Sort by position. + TreeSet t = new TreeSet(positions.keySet()); + Iterator p = t.iterator(); + + while (p.hasNext()) + { + Object k = p.next(); + b.append(" " + k + ": " + ((Entry) positions.get(k)).toString() + + "\n"); + } + return b.toString(); + } + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/gnuValueStream.java b/libjava/classpath/gnu/CORBA/CDR/gnuValueStream.java new file mode 100644 index 00000000000..663c9901861 --- /dev/null +++ b/libjava/classpath/gnu/CORBA/CDR/gnuValueStream.java @@ -0,0 +1,71 @@ +/* gnuValueStream.java -- + Copyright (C) 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.CORBA.CDR; + +/** + * A stream, implementing this interface, provides methods to get/set a position + * and get the RunTime. + * + * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) + */ +public interface gnuValueStream +{ + /** + * Get the current position in the buffer. + * + * @return The position in the buffer, taking offset into consideration. + */ + public int getPosition(); + + /** + * Jump to the given position, taking offset into consideration. + */ + public void seek(int position); + + /** + * Get the RunTime information. + */ + public gnuRuntime getRunTime(); + + /** + * Replace the instance of RunTime. + */ + public void setRunTime(gnuRuntime a_runtime); + +} diff --git a/libjava/classpath/gnu/CORBA/CDR/noHeaderInput.java b/libjava/classpath/gnu/CORBA/CDR/noHeaderInput.java deleted file mode 100644 index 0c787ddc2df..00000000000 --- a/libjava/classpath/gnu/CORBA/CDR/noHeaderInput.java +++ /dev/null @@ -1,166 +0,0 @@ -/* noHeaderInput.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.CORBA.CDR; - -import org.omg.CORBA.CustomMarshal; -import org.omg.CORBA.DataInputStream; -import org.omg.CORBA.MARSHAL; -import org.omg.CORBA.portable.BoxedValueHelper; -import org.omg.CORBA.portable.Streamable; -import org.omg.CORBA.portable.ValueFactory; - -import java.io.Serializable; - -/** - * Substitutes the main stream in factories when the header is already - * behind. Overrides methods that may be invoked from the factory, - * forcing not to read the header if called first time on this stream. - * - * This stream reverts to default behavior if one or more call are - * made (reading value types that are nested fields of the value type). - * - * @author Audrius Meskauskas, Lithuania (AudriusA@Bioinformatics.org) - */ -class noHeaderInput - extends cdrBufInput - implements DataInputStream -{ - /** - * If true, this is not the first call. - */ - boolean notFirst; - - /** - * Create an instance, reading from the given buffer. - */ - public noHeaderInput(byte[] buffer) - { - super(buffer); - } - - /** - * Read when knowning the class instance. - */ - public Serializable read_value(Class clz) - { - if (notFirst) - return super.read_value(clz); - else - { - try - { - notFirst = true; - return read_value((Serializable) clz.newInstance()); - } - catch (Exception ex) - { - MARSHAL m = new MARSHAL("Unable to create an instance"); - m.initCause(ex); - throw m; - } - } - } - - /** - * Tries to read using boxed value helper. - */ - public Serializable read_value(BoxedValueHelper helper) - { - if (notFirst) - return super.read_value(helper); - else - { - notFirst = true; - return helper.read_value(this); - } - } - - /** - * Tries to locate a factory using repository id. - */ - public Serializable read_value(String repository_id) - { - if (notFirst) - return super.read_value(repository_id); - else - { - notFirst = true; - - ValueFactory factory = - ((org.omg.CORBA_2_3.ORB) orb()).lookup_value_factory(repository_id); - if (factory == null) - throw new MARSHAL("No factory"); - return factory.read_value(this); - } - } - - /** - * Try to read when having an unitialised value. - */ - public Serializable read_value(Serializable value) - { - if (notFirst) - return super.read_value(value); - else - { - notFirst = true; - - // The user-defines io operations are implemented. - if (value instanceof CustomMarshal) - { - CustomMarshal marsh = (CustomMarshal) value; - try - { - marsh.unmarshal((DataInputStream) this); - } - catch (ClassCastException ex) - { - Vio.incorrect_plug_in(ex); - } - } - else - // The IDL-generated io operations are implemented. - if (value instanceof Streamable) - { - ((Streamable) value)._read(this); - } - return value; - } - } -} \ No newline at end of file -- cgit v1.2.3