/*
* Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.jboss.com.sun.corba.se.impl.corba;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.omg.CORBA.Any;
import org.omg.CORBA.StructMember;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.UnionMember;
import org.omg.CORBA.ValueMember;
import org.omg.CORBA.TypeCodePackage.BadKind;
import org.omg.CORBA_2_3.portable.InputStream;
import org.omg.CORBA_2_3.portable.OutputStream;
import org.jboss.com.sun.corba.se.impl.corba.AnyImpl;
import org.jboss.com.sun.corba.se.impl.encoding.CDRInputStream;
import org.jboss.com.sun.corba.se.impl.encoding.CDROutputStream;
import org.jboss.com.sun.corba.se.impl.encoding.TypeCodeInputStream;
import org.jboss.com.sun.corba.se.impl.encoding.TypeCodeOutputStream;
import org.jboss.com.sun.corba.se.impl.encoding.TypeCodeReader;
import org.jboss.com.sun.corba.se.impl.encoding.WrapperInputStream;
import org.jboss.com.sun.corba.se.impl.logging.ORBUtilSystemException;
import org.jboss.com.sun.corba.se.spi.logging.CORBALogDomains;
import org.jboss.com.sun.corba.se.spi.orb.ORB;
// no chance of subclasses, so no problems with runtime helper lookup
public final class TypeCodeImpl extends TypeCode
{
private static final long serialVersionUID = 1731926541593542883L;
// 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
// 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;
public TypeCodeImpl(ORB orb)
{
// initialized to tk_null
_orb = orb;
wrapper = ORBUtilSystemException.get(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);
// 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;
((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, 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)
{
if (read_value_kind((TypeCodeReader) 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 TCKind._tk_char :
_unionLabels[i].insert_char(_encap.read_char());
break;
case TCKind._tk_enum :
_unionLabels[i].type(_discriminator);
_unionLabels[i].insert_long(_encap.read_long());
break;
case TCKind._tk_longlong :
_unionLabels[i].insert_longlong(_encap.read_longlong());
break;
case TCKind._tk_ulonglong :
_unionLabels[i].insert_ulonglong(_encap.read_longlong());
break;
// _REVISIT_ figure out long double mapping
// case TCKind.tk_longdouble:
// _unionLabels[i].insert_longdouble(_encap.getDouble());
// break;
case TCKind._tk_wchar :
_unionLabels[i].insert_wchar(_encap.read_wchar());
break;
default :
throw wrapper.invalidComplexTypecode();
}
}
_memberNames[i] = _encap.read_string();
_memberTypes[i] = new TypeCodeImpl((ORB) is.orb());
_memberTypes[i].read_value_recursive(_encap);
_memberTypes[i].setParent(this);
}
}
break;
case TCKind._tk_enum : {
// get the repository id
setId(_encap.read_string());
// get the name
_name = _encap.read_string();
// get the number of members
_memberCount = _encap.read_long();
// create arrays for the identifier names
_memberNames = new String[_memberCount];
// read off identifier names
for (int i = 0; i < _memberCount; i++)
_memberNames[i] = _encap.read_string();
}
break;
case TCKind._tk_sequence : {
// get the type of the sequence
_contentType = new TypeCodeImpl((ORB) is.orb());
_contentType.read_value_recursive(_encap);
// get the bound on the length of the sequence
_length = _encap.read_long();
}
break;
case TCKind._tk_array : {
// get the type of the array
_contentType = new TypeCodeImpl((ORB) is.orb());
_contentType.read_value_recursive(_encap);
// get the length of the array
_length = _encap.read_long();
}
break;
case TCKind._tk_alias :
case TCKind._tk_value_box : {
// get the repository id
setId(_encap.read_string());
// get the name
_name = _encap.read_string();
// get the type aliased
_contentType = new TypeCodeImpl((ORB) is.orb());
_contentType.read_value_recursive(_encap);
}
break;
case TCKind._tk_except :
case TCKind._tk_struct : {
// get the repository id
setId(_encap.read_string());
// get the name
_name = _encap.read_string();
// get the number of members
_memberCount = _encap.read_long();
// create arrays for the names and types of members
_memberNames = new String[_memberCount];
_memberTypes = new TypeCodeImpl[_memberCount];
// read off member names and types
for (int i = 0; i < _memberCount; i++)
{
_memberNames[i] = _encap.read_string();
_memberTypes[i] = new TypeCodeImpl((ORB) is.orb());
// if (debug) System.out.println("TypeCode " + _name +
// " reading member " + _memberNames[i]);
_memberTypes[i].read_value_recursive(_encap);
_memberTypes[i].setParent(this);
}
}
break;
case TCKind._tk_value : {
// get the repository id
setId(_encap.read_string());
// get the name
_name = _encap.read_string();
// get the type modifier
_type_modifier = _encap.read_short();
// get the type aliased
_concrete_base = new TypeCodeImpl((ORB) is.orb());
_concrete_base.read_value_recursive(_encap);
if (_concrete_base.kind().value() == TCKind._tk_null)
{
_concrete_base = null;
}
// get the number of members
_memberCount = _encap.read_long();
// create arrays for the names, types and visibility of members
_memberNames = new String[_memberCount];
_memberTypes = new TypeCodeImpl[_memberCount];
_memberAccess = new short[_memberCount];
// read off value member visibilities
for (int i = 0; i < _memberCount; i++)
{
_memberNames[i] = _encap.read_string();
_memberTypes[i] = new TypeCodeImpl((ORB) is.orb());
// if (debug) System.out.println("TypeCode " + _name +
// " reading member " + _memberNames[i]);
_memberTypes[i].read_value_recursive(_encap);
_memberTypes[i].setParent(this);
_memberAccess[i] = _encap.read_short();
}
}
break;
default :
throw wrapper.invalidTypecodeKindMarshal();
}
break;
}
}
}
public void write_value(OutputStream os)
{
// Wrap OutputStream into TypeCodeOutputStream.
// This test shouldn't be necessary according to the Java language spec.
if (os instanceof TypeCodeOutputStream)
{
this.write_value((TypeCodeOutputStream) os);
}
else
{
TypeCodeOutputStream wrapperOutStream = null;
if (outBuffer == null)
{
wrapperOutStream = TypeCodeOutputStream.wrapOutputStream(os);
this.write_value(wrapperOutStream);
if (cachingEnabled)
{
// Cache the buffer for repeated writes
outBuffer = wrapperOutStream.getTypeCodeBuffer();
// if (outBuffer != null)
// System.out.println("Caching outBuffer with length = " +
// outBuffer.length + " for id = " + _id);
}
}
else
{
// System.out.println("Using cached outBuffer: length = " + outBuffer.length +
// ", id = " + _id);
}
// Write the first 4 bytes first to trigger alignment.
// We know that it is the kind.
if (cachingEnabled && outBuffer != null)
{
os.write_long(_kind);
os.write_octet_array(outBuffer, 0, outBuffer.length);
}
else
{
// System.out.println("Buffer is empty for " + _id);
wrapperOutStream.writeRawBuffer(os, _kind);
}
}
}
public void write_value(TypeCodeOutputStream tcos)
{
// Don't do any work if this is native
if (_kind == TCKind._tk_native)
throw wrapper.cannotMarshalNative();
TypeCodeOutputStream topStream = tcos.getTopLevelStream();
// if (debug) tcos.printBuffer();
if (_kind == tk_indirect)
{
// if (debug) System.out.println("Writing indirection " + _name + "to " + _id);
// 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 pos = topStream.getPositionForID(_id);
// if (debug) System.out.println("TypeCodeImpl " + tcos +
// " writing indirection " + _id +
// " to position " + pos + " at position " + topPos);
tcos.writeIndirection(tk_indirect, pos);
// All that gets written is _kind and offset.
return;
}
// The original approach changed for 5034649
// topStream.addIDAtPosition(_id, tcos.getTopLevelPosition());
// marshal the kind
tcos.write_long(_kind);
// if (debug) System.out.println("Writing " + _name + " with id " + _id);
// We have to remember the stream and position for EVERY type code
// in case some recursive or indirect type code references it.
//
// Bug fix 5034649:
// Do this AFTER the write of the _kind in case the alignment
// for the long changes the position.
topStream.addIDAtPosition(_id, tcos.getTopLevelPosition() - 4);
switch (typeTable[_kind])
{
case EMPTY :
// nothing more to marshal
break;
case SIMPLE :
switch (_kind)
{
case TCKind._tk_string :
case TCKind._tk_wstring :
// marshal the bound on string length
tcos.write_long(_length);
break;
case TCKind._tk_fixed :
tcos.write_ushort(_digits);
tcos.write_short(_scale);
break;
default :
// unknown typecode kind
throw wrapper.invalidSimpleTypecode();
}
break;
case COMPLEX : {
// create an encapsulation
TypeCodeOutputStream _encap = tcos.createEncapsulation(tcos.orb());
switch (_kind)
{
case TCKind._tk_objref :
case TCKind._tk_abstract_interface : {
// put the repository id
_encap.write_string(_id);
// put the name
_encap.write_string(_name);
}
break;
case TCKind._tk_union : {
// put the repository id
_encap.write_string(_id);
// put the name
_encap.write_string(_name);
// discriminant typecode
_discriminator.write_value(_encap);
// default index
_encap.write_long(_defaultIndex);
// put the number of members
_encap.write_long(_memberCount);
// marshal label values, names and types
for (int i = 0; i < _memberCount; i++)
{
// for the default case, marshal the zero octet
if (i == _defaultIndex)
_encap.write_octet(_unionLabels[i].extract_octet());
else
{
switch (realType(_discriminator).kind().value())
{
case TCKind._tk_short :
_encap.write_short(_unionLabels[i].extract_short());
break;
case TCKind._tk_long :
_encap.write_long(_unionLabels[i].extract_long());
break;
case TCKind._tk_ushort :
_encap.write_short(_unionLabels[i].extract_ushort());
break;
case TCKind._tk_ulong :
_encap.write_long(_unionLabels[i].extract_ulong());
break;
case TCKind._tk_float :
_encap.write_float(_unionLabels[i].extract_float());
break;
case TCKind._tk_double :
_encap.write_double(_unionLabels[i].extract_double());
break;
case TCKind._tk_boolean :
_encap.write_boolean(_unionLabels[i].extract_boolean());
break;
case TCKind._tk_char :
_encap.write_char(_unionLabels[i].extract_char());
break;
case TCKind._tk_enum :
_encap.write_long(_unionLabels[i].extract_long());
break;
case TCKind._tk_longlong :
_encap.write_longlong(_unionLabels[i].extract_longlong());
break;
case TCKind._tk_ulonglong :
_encap.write_longlong(_unionLabels[i].extract_ulonglong());
break;
// _REVISIT_ figure out long double mapping
// case TCKind.tk_longdouble:
// _encap.putDouble(_unionLabels[i].extract_longdouble());
// break;
case TCKind._tk_wchar :
_encap.write_wchar(_unionLabels[i].extract_wchar());
break;
default :
throw wrapper.invalidComplexTypecode();
}
}
_encap.write_string(_memberNames[i]);
_memberTypes[i].write_value(_encap);
}
}
break;
case TCKind._tk_enum : {
// put the repository id
_encap.write_string(_id);
// put the name
_encap.write_string(_name);
// put the number of members
_encap.write_long(_memberCount);
// marshal identifier names
for (int i = 0; i < _memberCount; i++)
_encap.write_string(_memberNames[i]);
}
break;
case TCKind._tk_sequence : {
// put the type of the sequence
lazy_content_type().write_value(_encap);
// put the bound on the length of the sequence
_encap.write_long(_length);
}
break;
case TCKind._tk_array : {
// put the type of the array
_contentType.write_value(_encap);
// put the length of the array
_encap.write_long(_length);
}
break;
case TCKind._tk_alias :
case TCKind._tk_value_box : {
// put the repository id
_encap.write_string(_id);
// put the name
_encap.write_string(_name);
// put the type aliased
_contentType.write_value(_encap);
}
break;
case TCKind._tk_struct :
case TCKind._tk_except : {
// put the repository id
_encap.write_string(_id);
// put the name
_encap.write_string(_name);
// put the number of members
_encap.write_long(_memberCount);
// marshal member names and types
for (int i = 0; i < _memberCount; i++)
{
_encap.write_string(_memberNames[i]);
// if (debug) System.out.println("TypeCode " + _name +
// " writing member " + _memberNames[i]);
_memberTypes[i].write_value(_encap);
}
}
break;
case TCKind._tk_value : {
// put the repository id
_encap.write_string(_id);
// put the name
_encap.write_string(_name);
// put the type modifier
_encap.write_short(_type_modifier);
// put the type aliased
if (_concrete_base == null)
{
_orb.get_primitive_tc(TCKind._tk_null).write_value(_encap);
}
else
{
_concrete_base.write_value(_encap);
}
// put the number of members
_encap.write_long(_memberCount);
// marshal member names and types
for (int i = 0; i < _memberCount; i++)
{
_encap.write_string(_memberNames[i]);
// if (debug) System.out.println("TypeCode " + _name +
// " writing member " + _memberNames[i]);
_memberTypes[i].write_value(_encap);
_encap.write_short(_memberAccess[i]);
}
}
break;
default :
throw wrapper.invalidTypecodeKindMarshal();
}
// marshal the encapsulation
_encap.writeOctetSequenceTo(tcos);
break;
}
}
}
/**
* This is not a copy of the TypeCodeImpl objects, but instead it copies the value this type code is representing.
* See AnyImpl read_value and write_value for usage. The state of this TypeCodeImpl instance isn't changed, only
* used by the Any to do the correct copy.
*/
@SuppressWarnings("deprecation")
protected void copy(org.omg.CORBA.portable.InputStream src, org.omg.CORBA.portable.OutputStream dst)
{
switch (_kind)
{
case TCKind._tk_null :
case TCKind._tk_void :
case TCKind._tk_native :
case TCKind._tk_abstract_interface :
break;
case TCKind._tk_short :
case TCKind._tk_ushort :
dst.write_short(src.read_short());
break;
case TCKind._tk_long :
case TCKind._tk_ulong :
dst.write_long(src.read_long());
break;
case TCKind._tk_float :
dst.write_float(src.read_float());
break;
case TCKind._tk_double :
dst.write_double(src.read_double());
break;
case TCKind._tk_longlong :
case TCKind._tk_ulonglong :
dst.write_longlong(src.read_longlong());
break;
case TCKind._tk_longdouble :
throw wrapper.tkLongDoubleNotSupported();
case TCKind._tk_boolean :
dst.write_boolean(src.read_boolean());
break;
case TCKind._tk_char :
dst.write_char(src.read_char());
break;
case TCKind._tk_wchar :
dst.write_wchar(src.read_wchar());
break;
case TCKind._tk_octet :
dst.write_octet(src.read_octet());
break;
case TCKind._tk_string : {
String s;
s = src.read_string();
// make sure length bound in typecode is not violated
if ((_length != 0) && (s.length() > _length))
throw wrapper.badStringBounds(new Integer(s.length()), new Integer(_length));
dst.write_string(s);
}
break;
case TCKind._tk_wstring : {
String s;
s = src.read_wstring();
// make sure length bound in typecode is not violated
if ((_length != 0) && (s.length() > _length))
throw wrapper.badStringBounds(new Integer(s.length()), new Integer(_length));
dst.write_wstring(s);
}
break;
case TCKind._tk_fixed : {
dst.write_ushort(src.read_ushort());
dst.write_short(src.read_short());
}
break;
case TCKind._tk_any : {
// Any tmp = new AnyImpl(_orb);
Any tmp = ((CDRInputStream) src).orb().create_any();
TypeCodeImpl t = new TypeCodeImpl((ORB) dst.orb());
t.read_value((org.omg.CORBA_2_3.portable.InputStream) src);
t.write_value((org.omg.CORBA_2_3.portable.OutputStream) dst);
tmp.read_value(src, t);
tmp.write_value(dst);
break;
}
case TCKind._tk_TypeCode : {
dst.write_TypeCode(src.read_TypeCode());
break;
}
case TCKind._tk_Principal : {
dst.write_Principal(src.read_Principal());
break;
}
case TCKind._tk_objref : {
dst.write_Object(src.read_Object());
break;
}
case TCKind._tk_except :
// Copy repositoryId
dst.write_string(src.read_string());
// Fall into ...
// _REVISIT_ what about the inherited members of this values concrete base type?
case TCKind._tk_value :
case TCKind._tk_struct : {
// copy each element, using the corresponding member type
for (int i = 0; i < _memberTypes.length; i++)
{
_memberTypes[i].copy(src, dst);
}
break;
}
case TCKind._tk_union :
/*
* _REVISIT_ More generic code? { Any discriminator = new AnyImpl(_orb); discriminator.read_value(src,
* _discriminator); discriminator.write_value(dst); int labelIndex =
* currentUnionMemberIndex(discriminator); if (labelIndex == -1) { // check if label has not been found
* if (_defaultIndex == -1) // throw exception if default was not expected throw new MARSHAL(); else //
* must be of the default branch type _memberTypes[_defaultIndex].copy(src, dst); } else {
* _memberTypes[labelIndex].copy(src, dst); } }
*/
{
Any tagValue = new AnyImpl((ORB) src.orb());
switch (realType(_discriminator).kind().value())
{
case TCKind._tk_short : {
short value = src.read_short();
tagValue.insert_short(value);
dst.write_short(value);
break;
}
case TCKind._tk_long : {
int value = src.read_long();
tagValue.insert_long(value);
dst.write_long(value);
break;
}
case TCKind._tk_ushort : {
short value = src.read_short();
tagValue.insert_ushort(value);
dst.write_short(value);
break;
}
case TCKind._tk_ulong : {
int value = src.read_long();
tagValue.insert_ulong(value);
dst.write_long(value);
break;
}
case TCKind._tk_float : {
float value = src.read_float();
tagValue.insert_float(value);
dst.write_float(value);
break;
}
case TCKind._tk_double : {
double value = src.read_double();
tagValue.insert_double(value);
dst.write_double(value);
break;
}
case TCKind._tk_boolean : {
boolean value = src.read_boolean();
tagValue.insert_boolean(value);
dst.write_boolean(value);
break;
}
case TCKind._tk_char : {
char value = src.read_char();
tagValue.insert_char(value);
dst.write_char(value);
break;
}
case TCKind._tk_enum : {
int value = src.read_long();
tagValue.type(_discriminator);
tagValue.insert_long(value);
dst.write_long(value);
break;
}
case TCKind._tk_longlong : {
long value = src.read_longlong();
tagValue.insert_longlong(value);
dst.write_longlong(value);
break;
}
case TCKind._tk_ulonglong : {
long value = src.read_longlong();
tagValue.insert_ulonglong(value);
dst.write_longlong(value);
break;
}
// _REVISIT_ figure out long double mapping
// case TCKind.tk_longdouble:
// {
// double value = src.read_double();
// tagValue.insert_longdouble(value);
// dst.putDouble(value);
// break;
// }
case TCKind._tk_wchar : {
char value = src.read_wchar();
tagValue.insert_wchar(value);
dst.write_wchar(value);
break;
}
default :
throw wrapper.illegalUnionDiscriminatorType();
}
// using the value of the tag, find out the type of the value
// following.
int labelIndex;
for (labelIndex = 0; labelIndex < _unionLabels.length; labelIndex++)
{
// use equality over anys
if (tagValue.equal(_unionLabels[labelIndex]))
{
_memberTypes[labelIndex].copy(src, dst);
break;
}
}
if (labelIndex == _unionLabels.length)
{
// check if label has not been found
if (_defaultIndex == -1)
// throw exception if default was not expected
throw wrapper.unexpectedUnionDefault();
else
// must be of the default branch type
_memberTypes[_defaultIndex].copy(src, dst);
}
break;
}
case TCKind._tk_enum :
dst.write_long(src.read_long());
break;
case TCKind._tk_sequence :
// get the length of the sequence
int seqLength = src.read_long();
// check for sequence bound violated
if ((_length != 0) && (seqLength > _length))
throw wrapper.badSequenceBounds(new Integer(seqLength), new Integer(_length));
// write the length of the sequence
dst.write_long(seqLength);
// copy each element of the seq using content type
lazy_content_type(); // make sure it's resolved
for (int i = 0; i < seqLength; i++)
_contentType.copy(src, dst);
break;
case TCKind._tk_array :
// copy each element of the array using content type
for (int i = 0; i < _length; i++)
_contentType.copy(src, dst);
break;
case TCKind._tk_alias :
case TCKind._tk_value_box :
// follow the alias
_contentType.copy(src, dst);
break;
case tk_indirect :
// need to follow offset, get unmarshal typecode from that
// offset, and use that to do the copy
// Don't need to read type code before using it to do the copy.
// It should be fully usable.
indirectType().copy(src, dst);
break;
default :
throw wrapper.invalidTypecodeKindMarshal();
}
}
static protected short digits(java.math.BigDecimal value)
{
if (value == null)
return 0;
short length = (short) value.unscaledValue().toString().length();
if (value.signum() == -1)
length--;
return length;
}
static protected short scale(java.math.BigDecimal value)
{
if (value == null)
return 0;
return (short) value.scale();
}
// Utility methods
// Only for union type. Returns the index of the union member
// corresponding to the discriminator. If not found returns the
// default index or -1 if there is no default index.
int currentUnionMemberIndex(Any discriminatorValue) throws BadKind
{
if (_kind != TCKind._tk_union)
throw new BadKind();
try
{
for (int i = 0; i < member_count(); i++)
{
if (member_label(i).equal(discriminatorValue))
{
return i;
}
}
if (_defaultIndex != -1)
{
return _defaultIndex;
}
}
catch (BadKind bad)
{
}
catch (org.omg.CORBA.TypeCodePackage.Bounds bounds)
{
}
return -1;
}
public String description()
{
return "TypeCodeImpl with kind " + _kind + " and id " + _id;
}
public String toString()
{
ByteArrayOutputStream byteOut = new ByteArrayOutputStream(1024);
PrintStream printOut = new PrintStream(byteOut, true);
printStream(printOut);
return super.toString() + " =\n" + byteOut.toString();
}
public void printStream(PrintStream s)
{
printStream(s, 0);
}
private void printStream(PrintStream s, int level)
{
if (_kind == tk_indirect)
{
s.print("indirect " + _id);
return;
}
switch (_kind)
{
case TCKind._tk_null :
case TCKind._tk_void :
case TCKind._tk_short :
case TCKind._tk_long :
case TCKind._tk_ushort :
case TCKind._tk_ulong :
case TCKind._tk_float :
case TCKind._tk_double :
case TCKind._tk_boolean :
case TCKind._tk_char :
case TCKind._tk_octet :
case TCKind._tk_any :
case TCKind._tk_TypeCode :
case TCKind._tk_Principal :
case TCKind._tk_objref :
case TCKind._tk_longlong :
case TCKind._tk_ulonglong :
case TCKind._tk_longdouble :
case TCKind._tk_wchar :
case TCKind._tk_native :
s.print(kindNames[_kind] + " " + _name);
break;
case TCKind._tk_struct :
case TCKind._tk_except :
case TCKind._tk_value :
s.println(kindNames[_kind] + " " + _name + " = {");
for (int i = 0; i < _memberCount; i++)
{
// memberName might differ from the name of the member.
s.print(indent(level + 1));
if (_memberTypes[i] != null)
_memberTypes[i].printStream(s, level + 1);
else
s.print("<unknown type>");
s.println(" " + _memberNames[i] + ";");
}
s.print(indent(level) + "}");
break;
case TCKind._tk_union :
s.print("union " + _name + "...");
break;
case TCKind._tk_enum :
s.print("enum " + _name + "...");
break;
case TCKind._tk_string :
if (_length == 0)
s.print("unbounded string " + _name);
else
s.print("bounded string(" + _length + ") " + _name);
break;
case TCKind._tk_sequence :
case TCKind._tk_array :
s.println(kindNames[_kind] + "[" + _length + "] " + _name + " = {");
s.print(indent(level + 1));
if (lazy_content_type() != null)
{
lazy_content_type().printStream(s, level + 1);
}
s.println(indent(level) + "}");
break;
case TCKind._tk_alias :
s.print("alias " + _name + " = " + (_contentType != null ? _contentType._name : "<unresolved>"));
break;
case TCKind._tk_wstring :
s.print("wstring[" + _length + "] " + _name);
break;
case TCKind._tk_fixed :
s.print("fixed(" + _digits + ", " + _scale + ") " + _name);
break;
case TCKind._tk_value_box :
s.print("valueBox " + _name + "...");
break;
case TCKind._tk_abstract_interface :
s.print("abstractInterface " + _name + "...");
break;
default :
s.print("<unknown type>");
break;
}
}
private String indent(int level)
{
String indent = "";
for (int i = 0; i < level; i++)
{
indent += " ";
}
return indent;
}
protected void setCaching(boolean enableCaching)
{
cachingEnabled = enableCaching;
if (enableCaching == false)
outBuffer = null;
}
}