📄 anyimpl.java
字号:
/* * @(#)AnyImpl.java 1.66 06/10/09 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. *//* * Licensed Materials - Property of IBM * RMI-IIOP v1.0 * Copyright IBM Corp. 1998 1999 All Rights Reserved * * US Government Users Restricted Rights - Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */package com.sun.corba.se.impl.corba;import java.io.Serializable;import java.math.BigDecimal;import java.util.List ;import java.util.ArrayList ;import org.omg.CORBA.Principal ;import org.omg.CORBA.TypeCode ;import org.omg.CORBA.Any ;import org.omg.CORBA.CompletionStatus ;import org.omg.CORBA.TCKind ;import org.omg.CORBA.portable.Streamable;import org.omg.CORBA.portable.InputStream;import org.omg.CORBA.portable.OutputStream;import org.omg.CORBA.TypeCodePackage.BadKind;import org.omg.CORBA.TypeCodePackage.Bounds;import com.sun.corba.se.spi.orb.ORB;import com.sun.corba.se.spi.orb.ORBVersionFactory;import com.sun.corba.se.spi.logging.CORBALogDomains;import com.sun.corba.se.spi.presentation.rmi.StubAdapter;import com.sun.corba.se.impl.encoding.CDRInputStream;import com.sun.corba.se.impl.encoding.EncapsInputStream;import com.sun.corba.se.impl.encoding.EncapsOutputStream;import com.sun.corba.se.impl.io.ValueUtility;import com.sun.corba.se.impl.orbutil.RepositoryIdFactory;import com.sun.corba.se.impl.orbutil.RepositoryIdStrings;import com.sun.corba.se.impl.orbutil.ORBUtility;import com.sun.corba.se.impl.logging.ORBUtilSystemException;// subclasses must provide a matching helper classpublic class AnyImpl extends Any{ private static final class AnyInputStream extends EncapsInputStream { public AnyInputStream(EncapsInputStream theStream ) { super( theStream ); } } private static final class AnyOutputStream extends EncapsOutputStream { public AnyOutputStream(ORB orb) { super((ORB)orb); } public org.omg.CORBA.portable.InputStream create_input_stream() { return new AnyInputStream( (com.sun.corba.se.impl.encoding.EncapsInputStream) super.create_input_stream()); } } // // Always valid. // private TypeCodeImpl typeCode; protected ORB orb; private ORBUtilSystemException wrapper ; // // Validity depends upon typecode. The 'value' and 'object' instance // members are used to hold immutable types as defined by the // isStreamed[] table below. Otherwise, 'stream' is non-null and // holds the value in CDR marshaled format. As an optimization, the // stream type is an Any extension of CDR stream that is used to // detect an optimization in read_value(). // private CDRInputStream stream; private long value; private java.lang.Object object; // Setting the typecode via the type() accessor wipes out the value. // An attempt to extract before the value is set will result // in a BAD_OPERATION exception being raised. private boolean isInitialized = false; private static final int DEFAULT_BUFFER_SIZE = 32; /* * This boolean array tells us if a given typecode must be * streamed. Objects that are immutable don't have to be streamed. */ static boolean isStreamed[] = { false, // null false, // void false, // short false, // long false, // ushort false, // ulong false, // float false, // double false, // boolean false, // char false, // octet false, // any false, // TypeCode true, // Principal false, // objref true, // struct true, // union false, // enum false, // string true, // sequence true, // array true, // alias true, // except false, // longlong false, // ulonglong false, // longdouble false, // wchar false, // wstring false, // fixed false, // value false, // value_box (used to be true) false, // native false // abstract interface }; static AnyImpl convertToNative(ORB orb, Any any) { if (any instanceof AnyImpl) { return (AnyImpl)any; } else { AnyImpl anyImpl = new AnyImpl(orb, any); anyImpl.typeCode = TypeCodeImpl.convertToNative(orb, anyImpl.typeCode); return anyImpl; } } /////////////////////////////////////////////////////////////////////////// // Constructors /** * A constructor that sets the Any to contain a null. It also marks * the value as being invalid so that extractions throw an exception * until an insertion has been performed. */ public AnyImpl(ORB orb) { this.orb = orb; wrapper = ORBUtilSystemException.get( (com.sun.corba.se.spi.orb.ORB)orb, CORBALogDomains.RPC_PRESENTATION ) ; typeCode = orb.get_primitive_tc(TCKind._tk_null); stream = null; object = null; value = 0; // null is a valid value isInitialized = true; } // // Create a new AnyImpl which is a copy of obj. // public AnyImpl(ORB orb, Any obj) { this(orb); if ((obj instanceof AnyImpl)) { AnyImpl objImpl = (AnyImpl)obj; typeCode = objImpl.typeCode; value = objImpl.value; object = objImpl.object; isInitialized = objImpl.isInitialized; if (objImpl.stream != null) stream = objImpl.stream.dup(); } else { read_value(obj.create_input_stream(), obj.type()); } } /////////////////////////////////////////////////////////////////////////// // basic accessors /** * returns the type of the element contained in the Any. * * @result the TypeCode for the element in the Any */ public TypeCode type() { return typeCode; } private TypeCode realType() { return realType(typeCode); } 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( bad ) ; } return realType; } /** * sets the type of the element to be contained in the Any. * * @param tc the TypeCode for the element in the Any */ public void type(TypeCode tc) { //debug.log ("type2"); // set the typecode typeCode = TypeCodeImpl.convertToNative(orb, tc); stream = null; value = 0; object = null; // null is the only legal value this Any can have after resetting the type code isInitialized = (tc.kind().value() == TCKind._tk_null); } /** * checks for equality between Anys. * * @param otherAny the Any to be compared with. * @result true if the Anys are equal, false otherwise. */ public boolean equal(Any otherAny) { //debug.log ("equal"); if (otherAny == this) return true; // first check for typecode equality. // note that this will take aliases into account if (!typeCode.equal(otherAny.type())) return false; // Resolve aliases here TypeCode realType = realType(); // _REVISIT_ Possible optimization for the case where // otherAny is a AnyImpl and the endianesses match. // Need implementation of CDRInputStream.equals() // For now we disable this to encourage testing the generic, // unoptimized code below. // Unfortunately this generic code needs to copy the whole stream // at least once. // if (AnyImpl.isStreamed[realType.kind().value()]) { // if (otherAny instanceof AnyImpl) { // return ((AnyImpl)otherAny).stream.equals(stream); // } // } switch (realType.kind().value()) { // handle primitive types case TCKind._tk_null: case TCKind._tk_void: return true; case TCKind._tk_short: return (extract_short() == otherAny.extract_short()); case TCKind._tk_long: return (extract_long() == otherAny.extract_long()); case TCKind._tk_ushort: return (extract_ushort() == otherAny.extract_ushort()); case TCKind._tk_ulong: return (extract_ulong() == otherAny.extract_ulong()); case TCKind._tk_float: return (extract_float() == otherAny.extract_float()); case TCKind._tk_double: return (extract_double() == otherAny.extract_double()); case TCKind._tk_boolean: return (extract_boolean() == otherAny.extract_boolean()); case TCKind._tk_char: return (extract_char() == otherAny.extract_char()); case TCKind._tk_wchar: return (extract_wchar() == otherAny.extract_wchar()); case TCKind._tk_octet: return (extract_octet() == otherAny.extract_octet()); case TCKind._tk_any: return extract_any().equal(otherAny.extract_any()); case TCKind._tk_TypeCode: return extract_TypeCode().equal(otherAny.extract_TypeCode()); case TCKind._tk_string: return extract_string().equals(otherAny.extract_string()); case TCKind._tk_wstring: return (extract_wstring().equals(otherAny.extract_wstring())); case TCKind._tk_longlong: return (extract_longlong() == otherAny.extract_longlong()); case TCKind._tk_ulonglong: return (extract_ulonglong() == otherAny.extract_ulonglong()); case TCKind._tk_objref: return (extract_Object().equals(otherAny.extract_Object())); case TCKind._tk_Principal: return (extract_Principal().equals(otherAny.extract_Principal())); case TCKind._tk_enum: return (extract_long() == otherAny.extract_long()); case TCKind._tk_fixed: return (extract_fixed().compareTo(otherAny.extract_fixed()) == 0); case TCKind._tk_except: case TCKind._tk_struct: case TCKind._tk_union: case TCKind._tk_sequence: case TCKind._tk_array: InputStream copyOfMyStream = this.create_input_stream(); InputStream copyOfOtherStream = otherAny.create_input_stream(); return equalMember(realType, copyOfMyStream, copyOfOtherStream); // Too complicated to handle value types the way we handle // other complex types above. Don't try to decompose it here // for faster comparison, just use Object.equals(). case TCKind._tk_value: case TCKind._tk_value_box: return extract_Value().equals(otherAny.extract_Value()); case TCKind._tk_alias: throw wrapper.errorResolvingAlias() ; case TCKind._tk_longdouble: // Unspecified for Java throw wrapper.tkLongDoubleNotSupported() ; default: throw wrapper.typecodeNotSupported() ; } } // Needed for equal() in order to achieve linear performance for complex types. // Uses up (recursively) copies of the InputStream in both Anys that got created in equal(). private boolean equalMember(TypeCode memberType, InputStream myStream, InputStream otherStream) { // Resolve aliases here TypeCode realType = realType(memberType); try { switch (realType.kind().value()) { // handle primitive types case TCKind._tk_null: case TCKind._tk_void: return true; case TCKind._tk_short: return (myStream.read_short() == otherStream.read_short()); case TCKind._tk_long: return (myStream.read_long() == otherStream.read_long()); case TCKind._tk_ushort: return (myStream.read_ushort() == otherStream.read_ushort()); case TCKind._tk_ulong: return (myStream.read_ulong() == otherStream.read_ulong()); case TCKind._tk_float: return (myStream.read_float() == otherStream.read_float()); case TCKind._tk_double: return (myStream.read_double() == otherStream.read_double()); case TCKind._tk_boolean: return (myStream.read_boolean() == otherStream.read_boolean()); case TCKind._tk_char: return (myStream.read_char() == otherStream.read_char()); case TCKind._tk_wchar: return (myStream.read_wchar() == otherStream.read_wchar()); case TCKind._tk_octet: return (myStream.read_octet() == otherStream.read_octet()); case TCKind._tk_any: return myStream.read_any().equal(otherStream.read_any()); case TCKind._tk_TypeCode: return myStream.read_TypeCode().equal(otherStream.read_TypeCode()); case TCKind._tk_string: return myStream.read_string().equals(otherStream.read_string()); case TCKind._tk_wstring: return (myStream.read_wstring().equals(otherStream.read_wstring())); case TCKind._tk_longlong: return (myStream.read_longlong() == otherStream.read_longlong()); case TCKind._tk_ulonglong: return (myStream.read_ulonglong() == otherStream.read_ulonglong()); case TCKind._tk_objref: return (myStream.read_Object().equals(otherStream.read_Object())); case TCKind._tk_Principal: return (myStream.read_Principal().equals(otherStream.read_Principal())); case TCKind._tk_enum: return (myStream.read_long() == otherStream.read_long()); case TCKind._tk_fixed: return (myStream.read_fixed().compareTo(otherStream.read_fixed()) == 0); case TCKind._tk_except: case TCKind._tk_struct: { int length = realType.member_count(); for (int i=0; i<length; i++) { if ( ! equalMember(realType.member_type(i), myStream, otherStream)) { return false; } } return true; } case TCKind._tk_union: { Any myDiscriminator = orb.create_any(); Any otherDiscriminator = orb.create_any(); myDiscriminator.read_value(myStream, realType.discriminator_type()); otherDiscriminator.read_value(otherStream, realType.discriminator_type()); if ( ! myDiscriminator.equal(otherDiscriminator)) { return false; } TypeCodeImpl realTypeCodeImpl = TypeCodeImpl.convertToNative(orb, realType); int memberIndex = realTypeCodeImpl.currentUnionMemberIndex(myDiscriminator); if (memberIndex == -1) throw wrapper.unionDiscriminatorError() ; if ( ! equalMember(realType.member_type(memberIndex), myStream, otherStream)) { return false; } return true; } case TCKind._tk_sequence: { int length = myStream.read_long(); otherStream.read_long(); // just so that the two stream are in sync for (int i=0; i<length; i++) { if ( ! equalMember(realType.content_type(), myStream, otherStream)) { return false; } } return true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -