- /*
- * @(#)TypeCodeImpl.java 1.91 03/01/23
- *
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
- package com.sun.corba.se.internal.corba;
- import org.omg.CORBA.*;
- import org.omg.CORBA.TypeCodePackage.*;
- import org.omg.CORBA_2_3.portable.InputStream;
- import org.omg.CORBA_2_3.portable.OutputStream;
- import com.sun.corba.se.internal.core.*;
- import com.sun.corba.se.internal.iiop.CDRInputStream;
- import com.sun.corba.se.internal.iiop.CDROutputStream;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Collections;
- import java.util.ArrayList;
- import java.io.IOException;
- import java.io.PrintStream;
- import java.io.ByteArrayOutputStream;
- import java.math.BigDecimal;
- import java.math.BigInteger;
- class WrapperInputStream extends org.omg.CORBA_2_3.portable.InputStream implements TypeCodeReader
- {
- private CDRInputStream stream;
- private Map typeMap = null;
- private int startPos = 0;
- public WrapperInputStream(CDRInputStream s) {
- super();
- stream = s;
- startPos = stream.getPosition();
- }
- public int read() throws IOException { return stream.read(); }
- public int read(byte b[]) throws IOException { return stream.read(b); }
- public int read(byte b[], int off, int len) throws IOException {
- return stream.read(b, off, len);
- }
- public long skip(long n) throws IOException { return stream.skip(n); }
- public int available() throws IOException { return stream.available(); }
- public void close() throws IOException { stream.close(); }
- public void mark(int readlimit) { stream.mark(readlimit); }
- public void reset() { stream.reset(); }
- public boolean markSupported() { return stream.markSupported(); }
- public int getPosition() { return stream.getPosition(); }
- public void consumeEndian() { stream.consumeEndian(); }
- public boolean read_boolean() { return stream.read_boolean(); }
- public char read_char() { return stream.read_char(); }
- public char read_wchar() { return stream.read_wchar(); }
- public byte read_octet() { return stream.read_octet(); }
- public short read_short() { return stream.read_short(); }
- public short read_ushort() { return stream.read_ushort(); }
- public int read_long() { return stream.read_long(); }
- public int read_ulong() { return stream.read_ulong(); }
- public long read_longlong() { return stream.read_longlong(); }
- public long read_ulonglong() { return stream.read_ulonglong(); }
- public float read_float() { return stream.read_float(); }
- public double read_double() { return stream.read_double(); }
- public String read_string() { return stream.read_string(); }
- public String read_wstring() { return stream.read_wstring(); }
- public void read_boolean_array(boolean[] value, int offset, int length) {
- stream.read_boolean_array(value, offset, length);
- }
- public void read_char_array(char[] value, int offset, int length) {
- stream.read_char_array(value, offset, length);
- }
- public void read_wchar_array(char[] value, int offset, int length) {
- stream.read_wchar_array(value, offset, length);
- }
- public void read_octet_array(byte[] value, int offset, int length) {
- stream.read_octet_array(value, offset, length);
- }
- public void read_short_array(short[] value, int offset, int length) {
- stream.read_short_array(value, offset, length);
- }
- public void read_ushort_array(short[] value, int offset, int length) {
- stream.read_ushort_array(value, offset, length);
- }
- public void read_long_array(int[] value, int offset, int length) {
- stream.read_long_array(value, offset, length);
- }
- public void read_ulong_array(int[] value, int offset, int length) {
- stream.read_ulong_array(value, offset, length);
- }
- public void read_longlong_array(long[] value, int offset, int length) {
- stream.read_longlong_array(value, offset, length);
- }
- public void read_ulonglong_array(long[] value, int offset, int length) {
- stream.read_ulonglong_array(value, offset, length);
- }
- public void read_float_array(float[] value, int offset, int length) {
- stream.read_float_array(value, offset, length);
- }
- public void read_double_array(double[] value, int offset, int length) {
- stream.read_double_array(value, offset, length);
- }
- public org.omg.CORBA.Object read_Object() { return stream.read_Object(); }
- public java.io.Serializable read_value() {return stream.read_value();}
- public TypeCode read_TypeCode() { return stream.read_TypeCode(); }
- public Any read_any() { return stream.read_any(); }
- public Principal read_Principal() { return stream.read_Principal(); }
- public java.math.BigDecimal read_fixed() { return stream.read_fixed(); }
- public org.omg.CORBA.Context read_Context() { return stream.read_Context(); }
- public org.omg.CORBA.ORB orb() { return stream.orb(); }
- public void addTypeCodeAtPosition(TypeCodeImpl tc, int position) {
- if (typeMap == null) {
- //if (TypeCodeImpl.debug) System.out.println("Creating typeMap");
- typeMap = new HashMap(16);
- }
- //if (TypeCodeImpl.debug) System.out.println(this + " adding tc " + tc + " at position " + position);
- typeMap.put(new Integer(position), tc);
- }
- public TypeCodeImpl getTypeCodeAtPosition(int position) {
- if (typeMap == null)
- return null;
- //if (TypeCodeImpl.debug) System.out.println("Getting tc " + (TypeCodeImpl)typeMap.get(new Integer(position)) +
- //" at position " + position);
- return (TypeCodeImpl)typeMap.get(new Integer(position));
- }
- public void setEnclosingInputStream(InputStream enclosure) {
- // WrapperInputStream has no enclosure
- }
- public TypeCodeReader getTopLevelStream() {
- // WrapperInputStream has no enclosure
- return this;
- }
- public int getTopLevelPosition() {
- //if (TypeCodeImpl.debug) System.out.println("WrapperInputStream.getTopLevelPosition " +
- //"returning getPosition " + getPosition() + " - startPos " + startPos +
- //" = " + (getPosition() - startPos));
- return getPosition() - startPos;
- }
- public void performORBVersionSpecificInit() {
- // This is never actually called on a WrapperInputStream, but
- // exists to satisfy the interface requirement.
- stream.performORBVersionSpecificInit();
- }
- public void resetCodeSetConverters() {
- stream.resetCodeSetConverters();
- }
- //public void printBuffer() { stream.printBuffer(); }
- public void printTypeMap() {
- System.out.println("typeMap = {");
- List sortedKeys = new ArrayList(typeMap.keySet());
- Collections.sort(sortedKeys);
- Iterator i = sortedKeys.iterator();
- while (i.hasNext()) {
- Integer pos = (Integer)i.next();
- TypeCodeImpl tci = (TypeCodeImpl)typeMap.get(pos);
- System.out.println(" key = " + pos.intValue() + ", value = " + tci.description());
- }
- System.out.println("}");
- }
- }
- interface TypeCodeReader extends MarshalInputStream {
- public void addTypeCodeAtPosition(TypeCodeImpl tc, int position);
- public TypeCodeImpl getTypeCodeAtPosition(int position);
- public void setEnclosingInputStream(InputStream enclosure);
- public TypeCodeReader getTopLevelStream();
- public int getTopLevelPosition();
- // for debugging
- //public void printBuffer();
- public int getPosition();
- public void printTypeMap();
- }
- class TypeCodeInputStream extends EncapsInputStream implements TypeCodeReader
- {
- private Map typeMap = null;
- private InputStream enclosure = null;
- private boolean isEncapsulation = false;
- public TypeCodeInputStream(org.omg.CORBA.ORB orb, byte[] data, int size) {
- super(orb, data, size);
- }
- public TypeCodeInputStream(org.omg.CORBA.ORB orb, byte[] data, int size,
- boolean littleEndian) {
- super(orb, data, size, littleEndian);
- }
- public void addTypeCodeAtPosition(TypeCodeImpl tc, int position) {
- if (typeMap == null) {
- //if (TypeCodeImpl.debug) System.out.println("Creating typeMap");
- typeMap = new HashMap(16);
- }
- //if (TypeCodeImpl.debug) System.out.println(this + " adding tc " + tc + " at position " + position);
- typeMap.put(new Integer(position), tc);
- }
- public TypeCodeImpl getTypeCodeAtPosition(int position) {
- if (typeMap == null)
- return null;
- //if (TypeCodeImpl.debug) {
- //System.out.println("Getting tc " + (TypeCode)typeMap.get(new Integer(position)) +
- //" at position " + position);
- //}
- return (TypeCodeImpl)typeMap.get(new Integer(position));
- }
- public void setEnclosingInputStream(InputStream enclosure) {
- this.enclosure = enclosure;
- }
- public TypeCodeReader getTopLevelStream() {
- if (enclosure == null)
- return this;
- if (enclosure instanceof TypeCodeReader)
- return ((TypeCodeReader)enclosure).getTopLevelStream();
- return this;
- }
- public int getTopLevelPosition() {
- if (enclosure != null && enclosure instanceof TypeCodeReader) {
- // The enclosed stream has to consider if the enclosing stream
- // had to read the enclosed stream completely when creating it.
- // This is why the size of the enclosed stream needs to be substracted.
- int topPos = ((TypeCodeReader)enclosure).getTopLevelPosition();
- // Substract getBufferLength from the parents pos because it read this stream
- // from its own when creating it
- int pos = topPos - getBufferLength() + getPosition();
- //if (TypeCodeImpl.debug) {
- //System.out.println("TypeCodeInputStream.getTopLevelPosition using getTopLevelPosition " + topPos +
- //(isEncapsulation ? " - encaps length 4" : "") +
- //" - getBufferLength() " + getBufferLength() +
- //" + getPosition() " + getPosition() + " = " + pos);
- //}
- return pos;
- }
- //if (TypeCodeImpl.debug) {
- //System.out.println("TypeCodeInputStream.getTopLevelPosition returning getPosition() = " +
- //getPosition() + " because enclosure is " + enclosure);
- //}
- return getPosition();
- }
- public static TypeCodeInputStream readEncapsulation(InputStream is, org.omg.CORBA.ORB _orb) {
- // _REVISIT_ Would be nice if we didn't have to copy the buffer!
- TypeCodeInputStream encap;
- int encapLength = is.read_long();
- // read off part of the buffer corresponding to the encapsulation
- byte[] encapBuffer = new byte[encapLength];
- is.read_octet_array(encapBuffer, 0, encapBuffer.length);
- // create an encapsulation using the marshal buffer
- if (is instanceof CDRInputStream) {
- encap = new TypeCodeInputStream(_orb, encapBuffer, encapBuffer.length,
- ((CDRInputStream)is).isLittleEndian());
- } else {
- encap = new TypeCodeInputStream(_orb, encapBuffer, encapBuffer.length);
- }
- encap.setEnclosingInputStream(is);
- encap.makeEncapsulation();
- //if (TypeCodeImpl.debug) {
- //System.out.println("Created TypeCodeInputStream " + encap + " with parent " + is);
- //encap.printBuffer();
- //}
- return encap;
- }
- protected void makeEncapsulation() {
- // first entry in an encapsulation is the endianess
- consumeEndian();
- isEncapsulation = true;
- }
- public void printTypeMap() {
- System.out.println("typeMap = {");
- Iterator i = typeMap.keySet().iterator();
- while (i.hasNext()) {
- Integer pos = (Integer)i.next();
- TypeCodeImpl tci = (TypeCodeImpl)typeMap.get(pos);
- System.out.println(" key = " + pos.intValue() + ", value = " + tci.description());
- }
- System.out.println("}");
- }
- }
- final class TypeCodeOutputStream extends EncapsOutputStream {
- private OutputStream enclosure = null;
- private Map typeMap = null;
- private boolean isEncapsulation = false;
- public TypeCodeOutputStream(org.omg.CORBA.ORB orb) {
- super(orb, false);
- }
- public TypeCodeOutputStream(org.omg.CORBA.ORB orb, boolean littleEndian) {
- super(orb, littleEndian);
- }
- public org.omg.CORBA.portable.InputStream create_input_stream()
- {
- //return new TypeCodeInputStream(orb(), getByteBuffer(), getIndex(), isLittleEndian());
- TypeCodeInputStream tcis = new TypeCodeInputStream(orb(), getByteBuffer(), getIndex(), isLittleEndian());
- //if (TypeCodeImpl.debug) {
- //System.out.println("Created TypeCodeInputStream " + tcis + " with no parent");
- //tcis.printBuffer();
- //}
- return tcis;
- }
- public void setEnclosingOutputStream(OutputStream enclosure) {
- this.enclosure = enclosure;
- }
- /*
- public boolean isEncapsulatedIn(TypeCodeOutputStream outerEnclosure) {
- if (outerEnclosure == this)
- return true;
- if (enclosure == null)
- return false;
- if (enclosure instanceof TypeCodeOutputStream)
- return ((TypeCodeOutputStream)enclosure).isEncapsulatedIn(outerEnclosure);
- // Last chance! Recursion ends with first non TypeCodeOutputStream.
- return (enclosure == outerEnclosure);
- }
- */
- public TypeCodeOutputStream getTopLevelStream() {
- if (enclosure == null)
- return this;
- if (enclosure instanceof TypeCodeOutputStream)
- return ((TypeCodeOutputStream)enclosure).getTopLevelStream();
- return this;
- }
- public int getTopLevelPosition() {
- if (enclosure != null && enclosure instanceof TypeCodeOutputStream) {
- int pos = ((TypeCodeOutputStream)enclosure).getTopLevelPosition() + getPosition();
- // Add four bytes for the encaps length, not another 4 for the byte order
- // which is included in getPosition().
- if (isEncapsulation) pos += 4;
- //if (TypeCodeImpl.debug) {
- //System.out.println("TypeCodeOutputStream.getTopLevelPosition using getTopLevelPosition " +
- //((TypeCodeOutputStream)enclosure).getTopLevelPosition() +
- //" + getPosition() " + getPosition() +
- //(isEncapsulation ? " + encaps length 4" : "") +
- //" = " + pos);
- //}
- return pos;
- }
- //if (TypeCodeImpl.debug) {
- //System.out.println("TypeCodeOutputStream.getTopLevelPosition returning getPosition() = " +
- //getPosition() + ", enclosure is " + enclosure);
- //}
- return getPosition();
- }
- public void addIDAtPosition(String id, int position) {
- if (typeMap == null)
- typeMap = new HashMap(16);
- //if (TypeCodeImpl.debug) System.out.println(this + " adding id " + id + " at position " + position);
- typeMap.put(id, new Integer(position));
- }
- public int getPositionForID(String id) {
- if (typeMap == null)
- throw new MARSHAL("Referenced type of indirect type not marshaled!");
- //if (TypeCodeImpl.debug) System.out.println("Getting position " + ((Integer)typeMap.get(id)).intValue() +
- //" for id " + id);
- return ((Integer)typeMap.get(id)).intValue();
- }
- public void writeRawBuffer(org.omg.CORBA.portable.OutputStream s, int firstLong) {
- // Writes this streams buffer to the given OutputStream
- // without byte order flag and length as is the case for encapsulations.
- // Make sure to align s to 4 byte boundaries.
- // Unfortunately we can't do just this:
- // s.alignAndReserve(4, 4);
- // So we have to take the first four bytes given in firstLong and write them
- // with a call to write_long which will trigger the alignment.
- // Then write the rest of the byte array.
- //if (TypeCodeImpl.debug) {
- //System.out.println(this + ".writeRawBuffer(" + s + ", " + firstLong + ")");
- //if (s instanceof CDROutputStream) {
- //System.out.println("Parent position before writing kind = " + ((CDROutputStream)s).getIndex());
- //}
- //}
- s.write_long(firstLong);
- //if (TypeCodeImpl.debug) {
- //if (s instanceof CDROutputStream) {
- //System.out.println("Parent position after writing kind = " + ((CDROutputStream)s).getIndex());
- //}
- //}
- s.write_octet_array(getByteBuffer(), 4, getIndex() - 4);
- //if (TypeCodeImpl.debug) {
- //if (s instanceof CDROutputStream) {
- //System.out.println("Parent position after writing all " + getIndex() + " bytes = " + ((CDROutputStream)s).getIndex());
- //}
- //}
- }
- public TypeCodeOutputStream createEncapsulation(org.omg.CORBA.ORB _orb) {
- TypeCodeOutputStream encap = new TypeCodeOutputStream(_orb, isLittleEndian());
- encap.setEnclosingOutputStream(this);
- encap.makeEncapsulation();
- //if (TypeCodeImpl.debug) System.out.println("Created TypeCodeOutputStream " + encap + " with parent " + this);
- return encap;
- }
- protected void makeEncapsulation() {
- // first entry in an encapsulation is the endianess
- putEndian();
- isEncapsulation = true;
- }
- public static TypeCodeOutputStream wrapOutputStream(OutputStream os) {
- boolean littleEndian = ((os instanceof CDROutputStream) ? ((CDROutputStream)os).isLittleEndian() : false);
- TypeCodeOutputStream wrapper = new TypeCodeOutputStream(os.orb(), littleEndian);
- wrapper.setEnclosingOutputStream(os);
- //if (TypeCodeImpl.debug) System.out.println("Created TypeCodeOutputStream " + wrapper + " with parent " + os);
- return wrapper;
- }
- public int getPosition() {
- return getIndex();
- }
- public int getRealIndex(int index) {
- int topPos = getTopLevelPosition();
- //if (TypeCodeImpl.debug) System.out.println("TypeCodeOutputStream.getRealIndex using getTopLevelPosition " +
- //topPos + " instead of getPosition " + getPosition());
- return topPos;
- }
- /*
- protected void printBuffer() {
- super.printBuffer();
- }
- */
- byte[] getTypeCodeBuffer() {
- // Returns the buffer trimmed of the trailing zeros and without the
- // known _kind value at the beginning.
- byte[] theBuffer = getByteBuffer();
- //System.out.println("outBuffer length = " + (getIndex() - 4));
- byte[] tcBuffer = new byte[getIndex() - 4];
- System.arraycopy(theBuffer, 4, tcBuffer, 0, getIndex() - 4);
- return tcBuffer;
- }
- public void printTypeMap() {
- System.out.println("typeMap = {");
- Iterator i = typeMap.keySet().iterator();
- while (i.hasNext()) {
- String id = (String)i.next();
- Integer pos = (Integer)typeMap.get(id);
- System.out.println(" key = " + id + ", value = " + pos);
- }
- System.out.println("}");
- }
- }
- // no chance of subclasses, so no problems with runtime helper lookup
- public final class TypeCodeImpl extends TypeCode
- {
- //static final boolean debug = false;
- // the predefined typecode constants
- private static final TypeCodeImpl primitiveConstants[] = {
- new TypeCodeImpl(TCKind._tk_null), // tk_null
- new TypeCodeImpl(TCKind._tk_void), // tk_void
- new TypeCodeImpl(TCKind._tk_short), // tk_short
- new TypeCodeImpl(TCKind._tk_long), // tk_long
- new TypeCodeImpl(TCKind._tk_ushort), // tk_ushort
- new TypeCodeImpl(TCKind._tk_ulong), // tk_ulong
- new TypeCodeImpl(TCKind._tk_float), // tk_float
- new TypeCodeImpl(TCKind._tk_double), // tk_double
- new TypeCodeImpl(TCKind._tk_boolean), // tk_boolean
- new TypeCodeImpl(TCKind._tk_char), // tk_char
- new TypeCodeImpl(TCKind._tk_octet), // tk_octet
- new TypeCodeImpl(TCKind._tk_any), // tk_any
- new TypeCodeImpl(TCKind._tk_TypeCode), // tk_typecode
- new TypeCodeImpl(TCKind._tk_Principal), // tk_principal
- new TypeCodeImpl(TCKind._tk_objref), // tk_objref
- null, // tk_struct
- null, // tk_union
- null, // tk_enum
- new TypeCodeImpl(TCKind._tk_string), // tk_string
- null, // tk_sequence
- null, // tk_array
- null, // tk_alias
- null, // tk_except
- new TypeCodeImpl(TCKind._tk_longlong), // tk_longlong
- new TypeCodeImpl(TCKind._tk_ulonglong), // tk_ulonglong
- new TypeCodeImpl(TCKind._tk_longdouble), // tk_longdouble
- new TypeCodeImpl(TCKind._tk_wchar), // tk_wchar
- new TypeCodeImpl(TCKind._tk_wstring), // tk_wstring
- new TypeCodeImpl(TCKind._tk_fixed), // tk_fixed
- new TypeCodeImpl(TCKind._tk_value), // tk_value
- new TypeCodeImpl(TCKind._tk_value_box), // tk_value_box
- new TypeCodeImpl(TCKind._tk_native), // tk_native
- new TypeCodeImpl(TCKind._tk_abstract_interface) // tk_abstract_interface
- };
- // the indirection TCKind, needed for recursive typecodes.
- protected static final int tk_indirect = 0xFFFFFFFF;
- // typecode encodings have three different categories that determine
- // how the encoding should be done.
- private static final int EMPTY = 0; // no parameters
- private static final int SIMPLE = 1; // simple parameters.
- private static final int COMPLEX = 2; // complex parameters. need to
- // use CDR encapsulation for
- // parameters
- // a table storing the encoding category for the various typecodes.
- private static final int typeTable[] = {
- EMPTY, // tk_null
- EMPTY, // tk_void
- EMPTY, // tk_short
- EMPTY, // tk_long
- EMPTY, // tk_ushort
- EMPTY, // tk_ulong
- EMPTY, // tk_float
- EMPTY, // tk_double
- EMPTY, // tk_boolean
- EMPTY, // tk_char
- EMPTY, // tk_octet
- EMPTY, // tk_any
- EMPTY, // tk_typecode
- EMPTY, // tk_principal
- COMPLEX, // tk_objref
- COMPLEX, // tk_struct
- COMPLEX, // tk_union
- COMPLEX, // tk_enum
- SIMPLE, // tk_string
- COMPLEX, // tk_sequence
- COMPLEX, // tk_array
- COMPLEX, // tk_alias
- COMPLEX, // tk_except
- EMPTY, // tk_longlong
- EMPTY, // tk_ulonglong
- EMPTY, // tk_longdouble
- EMPTY, // tk_wchar
- SIMPLE, // tk_wstring
- SIMPLE, // tk_fixed
- COMPLEX, // tk_value
- COMPLEX, // tk_value_box
- COMPLEX, // tk_native
- COMPLEX // tk_abstract_interface
- };
- // Maps TCKind values to names
- private static final String[] kindNames = {
- "null",
- "void",
- "short",
- "long",
- "ushort",
- "ulong",
- "float",
- "double",
- "boolean",
- "char",
- "octet",
- "any",
- "typecode",
- "principal",
- "objref",
- "struct",
- "union",
- "enum",
- "string",
- "sequence",
- "array",
- "alias",
- "exception",
- "longlong",
- "ulonglong",
- "longdouble",
- "wchar",
- "wstring",
- "fixed",
- "value",
- "valueBox",
- "native",
- "abstractInterface"
- };
- private int _kind = 0; // the typecode kind
- // data members for representing the various kinds of typecodes.
- private String _id = ""; // the typecode repository id
- private String _name = ""; // the typecode name
- private int _memberCount = 0; // member count
- private String _memberNames[] = null; // names of members
- private TypeCodeImpl _memberTypes[] = null; // types of members
- private AnyImpl _unionLabels[] = null; // values of union labels
- private TypeCodeImpl _discriminator = null; // union discriminator type
- private int _defaultIndex = -1; // union default index
- private int _length = 0; // string/seq/array length
- private TypeCodeImpl _contentType = null; // seq/array/alias type
- // fixed
- private short _digits = 0;
- private short _scale = 0;
- // value type
- // _REVISIT_ We might want to keep references to the ValueMember classes
- // passed in at initialization instead of copying the relevant data.
- // Is the data immutable? What about StructMember, UnionMember etc.?
- private short _type_modifier = -1; // VM_NONE, VM_CUSTOM,
- // VM_ABSTRACT, VM_TRUNCATABLE
- private TypeCodeImpl _concrete_base = null; // concrete base type
- private short _memberAccess[] = null; // visibility of ValueMember
- // recursive sequence support
- private TypeCodeImpl _parent = null; // the enclosing type code
- private int _parentOffset = 0; // the level of enclosure
- // recursive type code support
- private TypeCodeImpl _indirectType = null;
- // caches the byte buffer written in write_value for quick remarshaling...
- private byte[] outBuffer = null;
- // ... but only if caching is enabled
- private boolean cachingEnabled = false;
- // the ORB instance: may be instanceof ORBSingleton or ORB
- private org.omg.CORBA.ORB _orb;
- ///////////////////////////////////////////////////////////////////////////
- // Constructors...
- public TypeCodeImpl(org.omg.CORBA.ORB orb)
- {
- // initialized to tk_null
- _orb = orb;
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb, TypeCode tc)
- // to handle conversion of "remote" typecodes into "native" style.
- // also see the 'convertToNative(ORB orb, TypeCode tc)' function
- {
- // the orb object
- _orb = orb;
- // This is a protection against misuse of this constructor.
- // Should only be used if tc is not an instance of this class!
- // Otherwise we run into problems with recursive/indirect type codes.
- // _REVISIT_ We should make this constructor private
- if (tc instanceof TypeCodeImpl) {
- TypeCodeImpl tci = (TypeCodeImpl)tc;
- if (tci._kind == tk_indirect)
- throw new BAD_TYPECODE();
- if (tci._kind == TCKind._tk_sequence && tci._contentType == null)
- throw new BAD_TYPECODE();
- }
- // set up kind
- _kind = tc.kind().value();
- try {
- // set up parameters
- switch (_kind) {
- case TCKind._tk_value:
- _type_modifier = tc.type_modifier();
- // concrete base may be null
- TypeCode tccb = tc.concrete_base_type();
- if (tccb != null) {
- _concrete_base = convertToNative(_orb, tccb);
- } else {
- _concrete_base = null;
- }
- //_memberAccess = tc._memberAccess;
- // Need to reconstruct _memberAccess using member_count() and member_visibility()
- _memberAccess = new short[tc.member_count()];
- for (int i=0; i < tc.member_count(); i++) {
- _memberAccess[i] = tc.member_visibility(i);
- }
- case TCKind._tk_except:
- case TCKind._tk_struct:
- case TCKind._tk_union:
- // set up member types
- _memberTypes = new TypeCodeImpl[tc.member_count()];
- for (int i=0; i < tc.member_count(); i++) {
- _memberTypes[i] = convertToNative(_orb, tc.member_type(i));
- _memberTypes[i].setParent(this);
- }
- case TCKind._tk_enum:
- // set up member names
- _memberNames = new String[tc.member_count()];
- for (int i=0; i < tc.member_count(); i++) {
- _memberNames[i] = tc.member_name(i);
- }
- // set up member count
- _memberCount = tc.member_count();
- case TCKind._tk_objref:
- case TCKind._tk_alias:
- case TCKind._tk_value_box:
- case TCKind._tk_native:
- case TCKind._tk_abstract_interface:
- setId(tc.id());
- _name = tc.name();
- break;
- }
- // set up stuff for unions
- switch (_kind) {
- case TCKind._tk_union:
- _discriminator = convertToNative(_orb, tc.discriminator_type());
- _defaultIndex = tc.default_index();
- _unionLabels = new AnyImpl[_memberCount];
- for (int i=0; i < _memberCount; i++)
- _unionLabels[i] = new AnyImpl(_orb, tc.member_label(i));
- break;
- }
- // set up length
- switch (_kind) {
- case TCKind._tk_string:
- case TCKind._tk_wstring:
- case TCKind._tk_sequence:
- case TCKind._tk_array:
- _length = tc.length();
- }
- // set up content type
- switch (_kind) {
- case TCKind._tk_sequence:
- case TCKind._tk_array:
- case TCKind._tk_alias:
- case TCKind._tk_value_box:
- _contentType = convertToNative(_orb, tc.content_type());
- }
- } catch (org.omg.CORBA.TypeCodePackage.Bounds e) {} catch (BadKind e) {}
- // dont have to worry about these since code ensures we dont step
- // out of bounds.
- }
- public TypeCodeImpl(int creationKind)
- // for primitive types
- {
- // the orb object
- _orb = null;
- // private API. dont bother checking that
- // (creationKind < 0 || creationKind > typeTable.length)
- _kind = creationKind;
- // do initialization for special cases
- switch (_kind) {
- case TCKind._tk_objref:
- {
- // this is being used to create typecode for CORBA::Object
- setId("IDL:omg.org/CORBA/Object:1.0");
- _name = "Object";
- break;
- }
- case TCKind._tk_string:
- case TCKind._tk_wstring:
- {
- _length =0;
- break;
- }
- case TCKind._tk_value:
- {
- _concrete_base = null;
- break;
- }
- }
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- int creationKind,
- String id,
- String name,
- StructMember[] members)
- // for structs and exceptions
- {
- // the orb object
- _orb = orb;
- if ((creationKind == TCKind._tk_struct) || (creationKind == TCKind._tk_except))
- {
- _kind = creationKind;
- setId(id);
- _name = name;
- _memberCount = members.length;
- _memberNames = new String[_memberCount];
- _memberTypes = new TypeCodeImpl[_memberCount];
- for (int i = 0 ; i < _memberCount ; i++) {
- _memberNames[i] = members[i].name;
- _memberTypes[i] = convertToNative(_orb, members[i].type);
- _memberTypes[i].setParent(this);
- }
- } // else initializes to null
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- int creationKind,
- String id,
- String name,
- TypeCode discriminator_type,
- UnionMember[] members)
- // for unions
- {
- // the orb object
- _orb = orb;
- if (creationKind == TCKind._tk_union) {
- _kind = creationKind;
- setId(id);
- _name = name;
- _memberCount = members.length;
- _discriminator = convertToNative(_orb, discriminator_type);
- _memberNames = new String[_memberCount];
- _memberTypes = new TypeCodeImpl[_memberCount];
- _unionLabels = new AnyImpl[_memberCount];
- for (int i = 0 ; i < _memberCount ; i++) {
- _memberNames[i] = members[i].name;
- _memberTypes[i] = convertToNative(_orb, members[i].type);
- _memberTypes[i].setParent(this);
- _unionLabels[i] = new AnyImpl(_orb, members[i].label);
- // check whether this is the default branch.
- if (_unionLabels[i].type().kind() == TCKind.tk_octet) {
- if (_unionLabels[i].extract_octet() == (byte)0) {
- _defaultIndex = i;
- }
- }
- }
- } // else initializes to null
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- int creationKind,
- String id,
- String name,
- short type_modifier,
- TypeCode concrete_base,
- ValueMember[] members)
- // for value types
- {
- // the orb object
- _orb = orb;
- if (creationKind == TCKind._tk_value) {
- _kind = creationKind;
- setId(id);
- _name = name;
- _type_modifier = type_modifier;
- if (_concrete_base != null) {
- _concrete_base = convertToNative(_orb, concrete_base);
- }
- _memberCount = members.length;
- _memberNames = new String[_memberCount];
- _memberTypes = new TypeCodeImpl[_memberCount];
- _memberAccess = new short[_memberCount];
- for (int i = 0 ; i < _memberCount ; i++) {
- _memberNames[i] = members[i].name;
- _memberTypes[i] = convertToNative(_orb, members[i].type);
- _memberTypes[i].setParent(this);
- _memberAccess[i] = members[i].access;
- }
- } // else initializes to null
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- int creationKind,
- String id,
- String name,
- String[] members)
- // for enums
- {
- // the orb object
- _orb = orb;
- if (creationKind == TCKind._tk_enum)
- {
- _kind = creationKind;
- setId(id);
- _name = name;
- _memberCount = members.length;
- _memberNames = new String[_memberCount];
- for (int i = 0 ; i < _memberCount ; i++)
- _memberNames[i] = members[i];
- } // else initializes to null
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- int creationKind,
- String id,
- String name,
- TypeCode original_type)
- // for aliases and value boxes
- {
- // the orb object
- _orb = orb;
- if ( creationKind == TCKind._tk_alias || creationKind == TCKind._tk_value_box )
- {
- _kind = creationKind;
- setId(id);
- _name = name;
- _contentType = convertToNative(_orb, original_type);
- }
- // else initializes to null
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- int creationKind,
- String id,
- String name)
- {
- // the orb object
- _orb = orb;
- if (creationKind == TCKind._tk_objref ||
- creationKind == TCKind._tk_native ||
- creationKind == TCKind._tk_abstract_interface)
- {
- _kind = creationKind;
- setId(id);
- _name = name;
- } // else initializes to null
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- int creationKind,
- int bound)
- // for strings
- {
- if (bound < 0)
- throw new BAD_PARAM("bound can not be negative!");
- // the orb object
- _orb = orb;
- if ((creationKind == TCKind._tk_string) || (creationKind == TCKind._tk_wstring))
- {
- _kind = creationKind;
- _length = bound;
- } // else initializes to null
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- int creationKind,
- int bound,
- TypeCode element_type)
- // for sequences and arrays
- {
- // the orb object
- _orb = orb;
- if ( creationKind == TCKind._tk_sequence || creationKind == TCKind._tk_array )
- {
- _kind = creationKind;
- _length = bound;
- _contentType = convertToNative(_orb, element_type);
- } // else initializes to null
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- int creationKind,
- int bound,
- int offset)
- // for recursive sequences
- {
- // the orb object
- _orb = orb;
- if (creationKind == TCKind._tk_sequence) {
- _kind = creationKind;
- _length = bound;
- _parentOffset = offset;
- } // else initializes to null
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- String id)
- // for recursive type codes
- {
- // the orb object
- _orb = orb;
- _kind = tk_indirect;
- // This is the type code of the type we stand in for, not our own.
- _id = id;
- // Try to resolve it now. May return null in which case
- // we try again later (see indirectType()).
- tryIndirectType();
- }
- public TypeCodeImpl(org.omg.CORBA.ORB orb,
- int creationKind,
- short digits,
- short scale)
- // for fixed
- {
- // the orb object
- _orb = orb;
- //if (digits < 1 || digits > 31)
- //throw new BAD_TYPECODE();
- if (creationKind == TCKind._tk_fixed) {
- _kind = creationKind;
- _digits = digits;
- _scale = scale;
- } // else initializes to null
- }
- ///////////////////////////////////////////////////////////////////////////
- // Other creation functions...
- public static TypeCodeImpl get_primitive_tc(TCKind tcKind)
- {
- try {
- return primitiveConstants[tcKind.value()];
- } catch (Throwable t) {
- throw new BAD_OPERATION("Invalid or unavailable typecode for kind = "+tcKind.value());
- }
- }
- public static TypeCodeImpl get_primitive_tc(int val)
- {
- try {
- return primitiveConstants[val];
- } catch (Throwable t) {
- throw new BAD_OPERATION("Invalid or unavailable typecode for kind = "+val);
- }
- }
- // Optimization:
- // If we checked for and returned constant primitive typecodes
- // here we could reduce object creation and also enable more
- // efficient typecode comparisons for primitive typecodes.
- //
- protected static TypeCodeImpl convertToNative(org.omg.CORBA.ORB orb,
- TypeCode tc)
- {
- if (tc instanceof TypeCodeImpl)
- return (TypeCodeImpl) tc;
- else
- return new TypeCodeImpl(orb, tc);
- }
- public static CDROutputStream newOutputStream(org.omg.CORBA.ORB orb) {
- TypeCodeOutputStream tcos = new TypeCodeOutputStream(orb);
- //if (debug) System.out.println("Created TypeCodeOutputStream " + tcos + " with no parent");
- return tcos;
- }
- // Support for indirect/recursive type codes
- private TypeCodeImpl indirectType() {
- _indirectType = tryIndirectType();
- if (_indirectType == null) {
- // Nothing we can do about that.
- throw new BAD_TYPECODE("Invoked operation on unresolved recursive type code!");
- }
- return _indirectType;
- }
- private TypeCodeImpl tryIndirectType() {
- // Assert that _kind == tk_indirect
- if (_indirectType != null)
- return _indirectType;
- if (_orb instanceof TypeCodeFactory) {
- setIndirectType(((TypeCodeFactory)_orb).getTypeCode(_id));
- } else {
- throw new BAD_TYPECODE("ORB not supporting recursive type codes!");
- }
- return _indirectType;
- }
- private void setIndirectType(TypeCodeImpl newType) {
- _indirectType = newType;
- if (_indirectType != null) {
- try {
- _id = _indirectType.id();
- } catch (BadKind e) {} // can't happen
- }
- }
- private void setId(String newID) {
- _id = newID;
- if (_orb instanceof TypeCodeFactory) {
- ((TypeCodeFactory)_orb).setTypeCode(_id, this);
- }
- // check whether return value != this which would indicate that the
- // repository id isn't unique.
- }
- private void setParent(TypeCodeImpl parent) {
- _parent = parent;
- }
- private TypeCodeImpl getParentAtLevel(int level) {
- if (level == 0)
- return this;
- if (_parent == null)
- throw new BAD_TYPECODE("Invoked operation on unresolved recursive type code!");
- return _parent.getParentAtLevel(level - 1);
- }
- private TypeCodeImpl lazy_content_type() {
- if (_contentType == null) {
- if (_kind == TCKind._tk_sequence && _parentOffset > 0 && _parent != null) {
- // This is an unresolved recursive sequence tc.
- // Try to resolve it now if the hierarchy is complete.
- TypeCodeImpl realParent = getParentAtLevel(_parentOffset);
- if (realParent != null && realParent._id != null) {
- // Create a recursive type code object as the content type.
- // This is when the recursive sequence typecode morphes
- // into a sequence typecode containing a recursive typecode.
- _contentType = new TypeCodeImpl(_orb, realParent._id);
- }
- }
- }
- return _contentType;
- }
- // Other private functions
- private TypeCode realType(TypeCode aType) {
- TypeCode realType = aType;
- try {
- // Note: Indirect types are handled in kind() method
- while (realType.kind().value() == TCKind._tk_alias) {
- realType = realType.content_type();
- }
- } catch (BadKind bad) { // impossible
- }
- return realType;
- }
- ///////////////////////////////////////////////////////////////////////////
- // TypeCode operations
- public final boolean equal(TypeCode tc)
- // _REVISIT_ for all optional names/ids, we might want to check that
- // they are equal in case both are non-nil.
- {
- if (tc == this)
- return true;
- try {
- if (_kind == tk_indirect) {
- //return indirectType().equal(tc);
- if (_id != null && tc.id() != null)
- return _id.equals(tc.id());
- return (_id == null && tc.id() == null);
- }
- // make sure kinds are identical.
- if (_kind != tc.kind().value()) {
- return false;
- }
- switch (typeTable[_kind]) {
- case EMPTY:
- // no parameters to check.
- return true;
- case SIMPLE:
- switch (_kind) {
- case TCKind._tk_string:
- case TCKind._tk_wstring:
- // check for bound.
- return (_length == tc.length());
- case TCKind._tk_fixed:
- return (_digits == tc.fixed_digits() && _scale == tc.fixed_scale());
- default:
- return false;
- }
- case COMPLEX:
- switch(_kind) {
- case TCKind._tk_objref:
- {
- // check for logical id.
- if (_id.compareTo(tc.id()) == 0) {
- return true;
- }
- if (_id.compareTo(get_primitive_tc(_kind).id()) == 0) {
- return true;
- }
- if (tc.id().compareTo(get_primitive_tc(_kind).id()) == 0) {
- return true;
- }
- return false;
- }
- case TCKind._tk_native:
- case TCKind._tk_abstract_interface:
- {
- // check for logical id.
- if (_id.compareTo(tc.id()) != 0) {
- return false;
- }
- // ignore name since its optional.
- return true;
- }
- case TCKind._tk_struct:
- case TCKind._tk_except:
- {
- // check for member count
- if (_memberCount != tc.member_count())
- return false;
- // check for repository id
- if (_id.compareTo(tc.id()) != 0)
- return false;
- // check for member types.
- for (int i = 0 ; i < _memberCount ; i++)
- if (! _memberTypes[i].equal(tc.member_type(i)))
- return false;
- // ignore id and names since those are optional.
- return true;
- }
- case TCKind._tk_union:
- {
- // check for member count
- if (_memberCount != tc.member_count())
- return false;
- // check for repository id
- if (_id.compareTo(tc.id()) != 0)
- return false;
- // check for default index
- if (_defaultIndex != tc.default_index())
- return false;
- // check for discriminator type
- if (!_discriminator.equal(tc.discriminator_type()))
- return false;
- // check for label types and values
- for (int i = 0 ; i < _memberCount ; i++)
- if (! _unionLabels[i].equal(tc.member_label(i)))
- return false;
- // check for branch types
- for (int i = 0 ; i < _memberCount ; i++)
- if (! _memberTypes[i].equal(tc.member_type(i)))
- return false;
- // ignore id and names since those are optional.
- return true;
- }
- case TCKind._tk_enum:
- {
- // check for repository id
- if (_id.compareTo(tc.id()) != 0)
- return false;
- // check member count