- /*
- * @(#)TypeCodeImpl.java 1.94 04/06/21
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
- package com.sun.corba.se.impl.corba;
- 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;
- import org.omg.CORBA.TypeCode ;
- import org.omg.CORBA.StructMember ;
- import org.omg.CORBA.UnionMember ;
- import org.omg.CORBA.ValueMember ;
- import org.omg.CORBA.TCKind ;
- import org.omg.CORBA.Any ;
- import org.omg.CORBA.Principal ;
- import org.omg.CORBA.BAD_TYPECODE ;
- import org.omg.CORBA.BAD_PARAM ;
- import org.omg.CORBA.BAD_OPERATION ;
- import org.omg.CORBA.INTERNAL ;
- import org.omg.CORBA.MARSHAL ;
- import org.omg.CORBA.TypeCodePackage.BadKind ;
- import org.omg.CORBA_2_3.portable.InputStream;
- import org.omg.CORBA_2_3.portable.OutputStream;
- import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
- import com.sun.corba.se.spi.orb.ORB;
- import com.sun.corba.se.spi.logging.CORBALogDomains;
- import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
- import com.sun.corba.se.impl.encoding.MarshalInputStream;
- import com.sun.corba.se.impl.encoding.CodeSetConversion;
- import com.sun.corba.se.impl.encoding.CDRInputStream;
- import com.sun.corba.se.impl.encoding.CDROutputStream;
- import com.sun.corba.se.impl.encoding.TypeCodeInputStream;
- import com.sun.corba.se.impl.encoding.TypeCodeOutputStream;
- import com.sun.corba.se.impl.encoding.TypeCodeReader;
- import com.sun.corba.se.impl.encoding.WrapperInputStream;
- import com.sun.corba.se.impl.logging.ORBUtilSystemException;
- // no chance of subclasses, so no problems with runtime helper lookup
- public final class TypeCodeImpl extends TypeCode
- {
- //static final boolean debug = false;
- // 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
- // This is also used in AnyImpl.
- 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 ORB _orb;
- private ORBUtilSystemException wrapper ;
- ///////////////////////////////////////////////////////////////////////////
- // Constructors...
- public TypeCodeImpl(ORB orb)
- {
- // initialized to tk_null
- _orb = orb;
- wrapper = ORBUtilSystemException.get(
- (com.sun.corba.se.spi.orb.ORB)orb, CORBALogDomains.RPC_PRESENTATION ) ;
- }
- public TypeCodeImpl(ORB orb, TypeCode tc)
- // to handle conversion of "remote" typecodes into "native" style.
- // also see the 'convertToNative(ORB orb, TypeCode tc)' function
- {
- this(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 wrapper.badRemoteTypecode() ;
- if (tci._kind == TCKind._tk_sequence && tci._contentType == null)
- throw wrapper.badRemoteTypecode() ;
- }
- // 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(ORB orb, int creationKind)
- // for primitive types
- {
- this(orb);
- // 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(ORB orb,
- int creationKind,
- String id,
- String name,
- StructMember[] members)
- // for structs and exceptions
- {
- this(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(ORB orb,
- int creationKind,
- String id,
- String name,
- TypeCode discriminator_type,
- UnionMember[] members)
- // for unions
- {
- this(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(ORB orb,
- int creationKind,
- String id,
- String name,
- short type_modifier,
- TypeCode concrete_base,
- ValueMember[] members)
- // for value types
- {
- this(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(ORB orb,
- int creationKind,
- String id,
- String name,
- String[] members)
- // for enums
- {
- this(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(ORB orb,
- int creationKind,
- String id,
- String name,
- TypeCode original_type)
- // for aliases and value boxes
- {
- this(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(ORB orb,
- int creationKind,
- String id,
- String name)
- {
- this(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(ORB orb,
- int creationKind,
- int bound)
- // for strings
- {
- this(orb) ;
- if (bound < 0)
- throw wrapper.negativeBounds() ;
- if ((creationKind == TCKind._tk_string) || (creationKind == TCKind._tk_wstring)) {
- _kind = creationKind;
- _length = bound;
- } // else initializes to null
- }
- public TypeCodeImpl(ORB orb,
- int creationKind,
- int bound,
- TypeCode element_type)
- // for sequences and arrays
- {
- this(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(ORB orb,
- int creationKind,
- int bound,
- int offset)
- // for recursive sequences
- {
- this(orb) ;
- if (creationKind == TCKind._tk_sequence) {
- _kind = creationKind;
- _length = bound;
- _parentOffset = offset;
- } // else initializes to null
- }
- public TypeCodeImpl(ORB orb,
- String id)
- // for recursive type codes
- {
- this(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(ORB orb,
- int creationKind,
- short digits,
- short scale)
- // for fixed
- {
- this(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...
- // 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(ORB orb,
- TypeCode tc)
- {
- if (tc instanceof TypeCodeImpl)
- return (TypeCodeImpl) tc;
- else
- return new TypeCodeImpl(orb, tc);
- }
- public static CDROutputStream newOutputStream(ORB orb) {
- TypeCodeOutputStream tcos = new TypeCodeOutputStream((ORB)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 wrapper.unresolvedRecursiveTypecode() ;
- }
- return _indirectType;
- }
- private TypeCodeImpl tryIndirectType() {
- // Assert that _kind == tk_indirect
- if (_indirectType != null)
- return _indirectType;
- setIndirectType(_orb.getTypeCode(_id));
- return _indirectType;
- }
- private void setIndirectType(TypeCodeImpl newType) {
- _indirectType = newType;
- if (_indirectType != null) {
- try {
- _id = _indirectType.id();
- } catch (BadKind e) {
- // can't happen
- throw wrapper.badkindCannotOccur() ;
- }
- }
- }
- 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 wrapper.unresolvedRecursiveTypecode() ;
- 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)_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
- throw wrapper.badkindCannotOccur() ;
- }
- 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(
- (_orb.get_primitive_tc(_kind)).id()) == 0)
- {
- return true;
- }
- if (tc.id().compareTo(
- (_orb.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
- if (_memberCount != tc.member_count())
- return false;
- // ignore names since those are optional.
- return true;
- }
- case TCKind._tk_sequence:
- case TCKind._tk_array:
- {
- // check bound/length
- if (_length != tc.length()) {
- return false;
- }
- // check content type
- if (! lazy_content_type().equal(tc.content_type())) {
- return false;
- }
- // ignore id and name since those are optional.
- return true;
- }
- case TCKind._tk_value:
- {
- // 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 (_memberAccess[i] != tc.member_visibility(i) ||
- ! _memberTypes[i].equal(tc.member_type(i)))
- return false;
- if (_type_modifier == tc.type_modifier())
- return false;
- // concrete_base may be null
- TypeCode tccb = tc.concrete_base_type();
- if ((_concrete_base == null && tccb != null) ||
- (_concrete_base != null && tccb == null) ||
- ! _concrete_base.equal(tccb))
- {
- return false;
- }
- // ignore id and names since those are optional.
- return true;
- }
- case TCKind._tk_alias:
- case TCKind._tk_value_box:
- {
- // check for repository id
- if (_id.compareTo(tc.id()) != 0) {
- return false;
- }
- // check for equality with the true type
- return _contentType.equal(tc.content_type());
- }
- }
- }
- } catch (org.omg.CORBA.TypeCodePackage.Bounds e) {} catch (BadKind e) {}
- // dont have to worry about these since the code ensures these dont
- // arise.
- return false;
- }
- /**
- * The equivalent operation is used by the ORB when determining type equivalence
- * for values stored in an IDL any.
- */
- public boolean equivalent(TypeCode tc) {
- if (tc == this) {
- return true;
- }
- // If the result of the kind operation on either TypeCode is tk_alias, recursively
- // replace the TypeCode with the result of calling content_type, until the kind
- // is no longer tk_alias.
- // Note: Always resolve indirect types first!
- TypeCode myRealType = (_kind == tk_indirect ? indirectType() : this);
- myRealType = realType(myRealType);
- TypeCode otherRealType = realType(tc);
- // If results of the kind operation on each typecode differ,
- // equivalent returns false.
- if (myRealType.kind().value() != otherRealType.kind().value()) {
- return false;
- }
- String myID = null;
- String otherID = null;
- try {
- myID = this.id();
- otherID = tc.id();
- // At this point the id operation is valid for both TypeCodes.
- // Return true if the results of id for both TypeCodes are non-empty strings
- // and both strings are equal.
- // If both ids are non-empty but are not equal, then equivalent returns FALSE.
- if (myID != null && otherID != null) {
- return (myID.equals(otherID));
- }
- } catch (BadKind e) {
- // id operation is not valid for either or both TypeCodes
- }
- // If either or both id is an empty string, or the TypeCode kind does not support
- // the id operation, perform a structural comparison of the TypeCodes.
- int myKind = myRealType.kind().value();
- try {
- if (myKind == TCKind._tk_struct ||
- myKind == TCKind._tk_union ||
- myKind == TCKind._tk_enum ||
- myKind == TCKind._tk_except ||
- myKind == TCKind._tk_value)
- {
- if (myRealType.member_count() != otherRealType.member_count())
- return false;
- }
- if (myKind == TCKind._tk_union)
- {
- if (myRealType.default_index() != otherRealType.default_index())
- return false;
- }
- if (myKind == TCKind._tk_string ||
- myKind == TCKind._tk_wstring ||
- myKind == TCKind._tk_sequence ||
- myKind == TCKind._tk_array)
- {
- if (myRealType.length() != otherRealType.length())
- return false;
- }
- if (myKind == TCKind._tk_fixed)
- {
- if (myRealType.fixed_digits() != otherRealType.fixed_digits() ||
- myRealType.fixed_scale() != otherRealType.fixed_scale())
- return false;
- }
- if (myKind == TCKind._tk_union)
- {
- for (int i=0; i<myRealType.member_count(); i++) {
- if (myRealType.member_label(i) != otherRealType.member_label(i))
- return false;
- }
- if ( ! myRealType.discriminator_type().equivalent(
- otherRealType.discriminator_type()))
- return false;
- }
- if (myKind == TCKind._tk_alias ||
- myKind == TCKind._tk_value_box ||
- myKind == TCKind._tk_sequence ||
- myKind == TCKind._tk_array)
- {
- if ( ! myRealType.content_type().equivalent(otherRealType.content_type()))
- return false;
- }
- if (myKind == TCKind._tk_struct ||
- myKind == TCKind._tk_union ||
- myKind == TCKind._tk_except ||
- myKind == TCKind._tk_value)
- {
- for (int i=0; i<myRealType.member_count(); i++) {
- if ( ! myRealType.member_type(i).equivalent(
- otherRealType.member_type(i)))
- return false;
- }
- }
- } catch (BadKind e) {
- // impossible if we checked correctly above
- throw wrapper.badkindCannotOccur() ;
- } catch (org.omg.CORBA.TypeCodePackage.Bounds e) {
- // impossible if we checked correctly above
- throw wrapper.boundsCannotOccur() ;
- }
- // Structural comparison succeeded!
- return true;
- }
- public TypeCode get_compact_typecode() {
- // _REVISIT_ It isn't clear whether this method should operate on this or a copy.
- // For now just return this unmodified because the name and member_name fields
- // aren't used for comparison anyways.
- return this;
- }
- public TCKind kind()
- {
- if (_kind == tk_indirect)
- return indirectType().kind();
- return TCKind.from_int(_kind);
- }
- public boolean is_recursive()
- {
- // Recursive is the only form of indirect type codes right now.
- // Indirection can also be used for repeated type codes.
- return (_kind == tk_indirect);
- }
- public String id()
- throws BadKind
- {
- switch (_kind) {
- case tk_indirect:
- //return indirectType().id(); // same as _id
- case TCKind._tk_except:
- case TCKind._tk_objref:
- case TCKind._tk_struct:
- case TCKind._tk_union:
- case TCKind._tk_enum:
- case TCKind._tk_alias:
- case TCKind._tk_value:
- case TCKind._tk_value_box:
- case TCKind._tk_native:
- case TCKind._tk_abstract_interface:
- // exception and objref typecodes must have a repository id.
- // structs, unions, enums, and aliases may or may not.
- return _id;
- default:
- // all other typecodes throw the BadKind exception.
- throw new BadKind();
- }
- }
- public String name()
- throws BadKind
- {
- switch (_kind) {
- case tk_indirect:
- return indirectType().name();
- case TCKind._tk_except:
- case TCKind._tk_objref:
- case TCKind._tk_struct:
- case TCKind._tk_union:
- case TCKind._tk_enum:
- case TCKind._tk_alias:
- case TCKind._tk_value:
- case TCKind._tk_value_box:
- case TCKind._tk_native:
- case TCKind._tk_abstract_interface:
- return _name;
- default:
- throw new BadKind();
- }
- }
- public int member_count()
- throws BadKind
- {
- switch (_kind) {
- case tk_indirect:
- return indirectType().member_count();
- case TCKind._tk_except:
- case TCKind._tk_struct:
- case TCKind._tk_union:
- case TCKind._tk_enum:
- case TCKind._tk_value:
- return _memberCount;
- default:
- throw new BadKind();
- }
- }
- public String member_name(int index)
- throws BadKind, org.omg.CORBA.TypeCodePackage.Bounds
- {
- switch (_kind) {
- case tk_indirect:
- return indirectType().member_name(index);
- case TCKind._tk_except:
- case TCKind._tk_struct:
- case TCKind._tk_union:
- case TCKind._tk_enum:
- case TCKind._tk_value:
- try {
- return _memberNames[index];
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new org.omg.CORBA.TypeCodePackage.Bounds();
- }
- default:
- throw new BadKind();
- }
- }
- public TypeCode member_type(int index)
- throws BadKind, org.omg.CORBA.TypeCodePackage.Bounds
- {
- switch (_kind) {
- case tk_indirect:
- return indirectType().member_type(index);
- case TCKind._tk_except:
- case TCKind._tk_struct:
- case TCKind._tk_union:
- case TCKind._tk_value:
- try {
- return _memberTypes[index];
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new org.omg.CORBA.TypeCodePackage.Bounds();
- }
- default:
- throw new BadKind();
- }
- }
- public Any member_label(int index)
- throws BadKind, org.omg.CORBA.TypeCodePackage.Bounds
- {
- switch (_kind) {
- case tk_indirect:
- return indirectType().member_label(index);
- case TCKind._tk_union:
- try {
- // _REVISIT_ Why create a new Any for this?
- return new AnyImpl(_orb, _unionLabels[index]);
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new org.omg.CORBA.TypeCodePackage.Bounds();
- }
- default:
- throw new BadKind();
- }
- }
- public TypeCode discriminator_type()
- throws BadKind
- {
- switch (_kind) {
- case tk_indirect:
- return indirectType().discriminator_type();
- case TCKind._tk_union:
- return _discriminator;
- default:
- throw new BadKind();
- }
- }
- public int default_index()
- throws BadKind
- {
- switch (_kind) {
- case tk_indirect:
- return indirectType().default_index();
- case TCKind._tk_union:
- return _defaultIndex;
- default:
- throw new BadKind();
- }
- }
- public int length()
- throws BadKind
- {
- switch (_kind) {
- case tk_indirect:
- return indirectType().length();
- case TCKind._tk_string:
- case TCKind._tk_wstring:
- case TCKind._tk_sequence:
- case TCKind._tk_array:
- return _length;
- default:
- throw new BadKind();
- }
- }
- public TypeCode content_type()
- throws BadKind
- {
- switch (_kind) {
- case tk_indirect:
- return indirectType().content_type();
- case TCKind._tk_sequence:
- return lazy_content_type();
- case TCKind._tk_array:
- case TCKind._tk_alias:
- case TCKind._tk_value_box:
- return _contentType;
- default:
- throw new BadKind();
- }
- }
- public short fixed_digits() throws BadKind {
- switch (_kind) {
- case TCKind._tk_fixed:
- return _digits;
- default:
- throw new BadKind();
- }
- }
- public short fixed_scale() throws BadKind {
- switch (_kind) {
- case TCKind._tk_fixed:
- return _scale;
- default:
- throw new BadKind();
- }
- }
- public short member_visibility(int index) throws BadKind,
- org.omg.CORBA.TypeCodePackage.Bounds {
- switch (_kind) {
- case tk_indirect:
- return indirectType().member_visibility(index);
- case TCKind._tk_value:
- try {
- return _memberAccess[index];
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new org.omg.CORBA.TypeCodePackage.Bounds();
- }
- default:
- throw new BadKind();
- }
- }
- public short type_modifier() throws BadKind {
- switch (_kind) {
- case tk_indirect:
- return indirectType().type_modifier();
- case TCKind._tk_value:
- return _type_modifier;
- default:
- throw new BadKind();
- }
- }
- public TypeCode concrete_base_type() throws BadKind {
- switch (_kind) {
- case tk_indirect:
- return indirectType().concrete_base_type();
- case TCKind._tk_value:
- return _concrete_base;
- default:
- throw new BadKind();
- }
- }
- public void read_value(InputStream is) {
- if (is instanceof TypeCodeReader) {
- // hardly possible unless caller knows our "private" stream classes.
- if (read_value_kind((TypeCodeReader)is))
- read_value_body(is);
- } else if (is instanceof CDRInputStream) {
- WrapperInputStream wrapper = new WrapperInputStream((CDRInputStream)is);
- //if (debug) System.out.println("Created WrapperInputStream " + wrapper +
- // " with no parent");
- if (read_value_kind((TypeCodeReader)wrapper))
- read_value_body(wrapper);
- } else {
- read_value_kind(is);
- read_value_body(is);
- }
- }
- private void read_value_recursive(TypeCodeInputStream is) {
- // don't wrap a CDRInputStream reading "inner" TypeCodes.
- if (is instanceof TypeCodeReader) {
- if (read_value_kind((TypeCodeReader)is))
- read_value_body(is);
- } else {
- read_value_kind((InputStream)is);
- read_value_body(is);
- }
- }
- boolean read_value_kind(TypeCodeReader tcis)
- {
- _kind = tcis.read_long();
- // Bug fix 5034649: allow for padding that precedes the typecode kind.
- int myPosition = tcis.getTopLevelPosition()-4;
- // check validity of kind
- if ((_kind < 0 || _kind > typeTable.length) && _kind != tk_indirect) {
- throw wrapper.cannotMarshalBadTckind() ;
- }
- // Don't do any work if this is native
- if (_kind == TCKind._tk_native)
- throw wrapper.cannotMarshalNative() ;
- // We have to remember the stream and position for EVERY type code
- // in case some recursive or indirect type code references it.
- TypeCodeReader topStream = tcis.getTopLevelStream();
- if (_kind == tk_indirect) {
- int streamOffset = tcis.read_long();
- if (streamOffset > -4)
- throw wrapper.invalidIndirection( new Integer(streamOffset) ) ;
- // The encoding used for indirection is the same as that used for recursive ,
- // TypeCodes i.e., a 0xffffffff indirection marker followed by a long offset
- // (in units of octets) from the beginning of the long offset.
- int topPos = tcis.getTopLevelPosition();
- // substract 4 to get back to the beginning of the long offset.
- int indirectTypePosition = topPos - 4 + streamOffset;
- // Now we have to find the referenced type
- // by its indirectTypePosition within topStream.
- //if (debug) System.out.println(
- // "TypeCodeImpl looking up indirection at position topPos " +
- //topPos + " - 4 + offset " + streamOffset + " = " + indirectTypePosition);
- TypeCodeImpl type = topStream.getTypeCodeAtPosition(indirectTypePosition);
- if (type == null)
- throw wrapper.indirectionNotFound( new Integer(indirectTypePosition) ) ;
- setIndirectType(type);
- return false;
- }
- topStream.addTypeCodeAtPosition(this, myPosition);
- return true;
- }
- void read_value_kind(InputStream is) {
- // unmarshal the kind
- _kind = is.read_long();
- // check validity of kind
- if ((_kind < 0 || _kind > typeTable.length) && _kind != tk_indirect) {
- throw wrapper.cannotMarshalBadTckind() ;
- }
- // Don't do any work if this is native
- if (_kind == TCKind._tk_native)
- throw wrapper.cannotMarshalNative() ;
- if (_kind == tk_indirect) {
- throw wrapper.recursiveTypecodeError() ;
- }
- }
- void read_value_body(InputStream is) {
- // start unmarshaling the rest of the typecode, based on the
- // encoding (empty, simple or complex).
- switch (typeTable[_kind]) {
- case EMPTY:
- // nothing to unmarshal
- break;
- case SIMPLE:
- switch (_kind) {
- case TCKind._tk_string:
- case TCKind._tk_wstring:
- _length = is.read_long();
- break;
- case TCKind._tk_fixed:
- _digits = is.read_ushort();
- _scale = is.read_short();
- break;
- default:
- throw wrapper.invalidSimpleTypecode() ;
- }
- break;
- case COMPLEX:
- {
- TypeCodeInputStream _encap = TypeCodeInputStream.readEncapsulation(is,
- is.orb());
- switch(_kind) {
- case TCKind._tk_objref:
- case TCKind._tk_abstract_interface:
- {
- // get the repository id
- setId(_encap.read_string());
- // get the name
- _name = _encap.read_string();
- }
- break;
- case TCKind._tk_union:
- {
- // get the repository id
- setId(_encap.read_string());
- // get the name
- _name = _encap.read_string();
- // discriminant typecode
- _discriminator = new TypeCodeImpl((ORB)is.orb());
- _discriminator.read_value_recursive(_encap);
- // default index
- _defaultIndex = _encap.read_long();
- // get the number of members
- _memberCount = _encap.read_long();
- // create arrays for the label values, names and types of members
- _unionLabels = new AnyImpl[_memberCount];
- _memberNames = new String[_memberCount];
- _memberTypes = new TypeCodeImpl[_memberCount];
- // read off label values, names and types
- for (int i=0; i < _memberCount; i++) {
- _unionLabels[i] = new AnyImpl((ORB)is.orb());
- if (i == _defaultIndex)
- // for the default case, read off the zero octet
- _unionLabels[i].insert_octet(_encap.read_octet());
- else {
- switch (realType(_discriminator).kind().value()) {
- case TCKind._tk_short:
- _unionLabels[i].insert_short(_encap.read_short());
- break;
- case TCKind._tk_long:
- _unionLabels[i].insert_long(_encap.read_long());
- break;
- case TCKind._tk_ushort:
- _unionLabels[i].insert_ushort(_encap.read_short());
- break;
- case TCKind._tk_ulong:
- _unionLabels[i].insert_ulong(_encap.read_long());
- break;
- case TCKind._tk_float:
- _unionLabels[i].insert_float(_encap.read_float());
- break;
- case TCKind._tk_double:
- _unionLabels[i].insert_double(_encap.read_double());
- break;
- case TCKind._tk_boolean:
- _unionLabels[i].insert_boolean(_encap.read_boolean());
- break;
- case