AnyImpl.java revision 672:2bb058ce572e
1139749Simp/* 2113584Ssimokawa * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3106813Ssimokawa * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4106813Ssimokawa * 5106813Ssimokawa * This code is free software; you can redistribute it and/or modify it 6106813Ssimokawa * under the terms of the GNU General Public License version 2 only, as 7106813Ssimokawa * published by the Free Software Foundation. Oracle designates this 8106813Ssimokawa * particular file as subject to the "Classpath" exception as provided 9106813Ssimokawa * by Oracle in the LICENSE file that accompanied this code. 10106813Ssimokawa * 11106813Ssimokawa * This code is distributed in the hope that it will be useful, but WITHOUT 12106813Ssimokawa * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13106813Ssimokawa * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14106813Ssimokawa * version 2 for more details (a copy is included in the LICENSE file that 15106813Ssimokawa * accompanied this code). 16106813Ssimokawa * 17106813Ssimokawa * You should have received a copy of the GNU General Public License version 18106813Ssimokawa * 2 along with this work; if not, write to the Free Software Foundation, 19106813Ssimokawa * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20106813Ssimokawa * 21106813Ssimokawa * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22106813Ssimokawa * or visit www.oracle.com if you need additional information or have any 23106813Ssimokawa * questions. 24106813Ssimokawa */ 25106813Ssimokawa/* 26106813Ssimokawa * Licensed Materials - Property of IBM 27106813Ssimokawa * RMI-IIOP v1.0 28106813Ssimokawa * Copyright IBM Corp. 1998 1999 All Rights Reserved 29106813Ssimokawa * 30106813Ssimokawa */ 31106813Ssimokawa 32106813Ssimokawapackage com.sun.corba.se.impl.corba; 33106813Ssimokawa 34106813Ssimokawaimport java.io.Serializable; 35106813Ssimokawaimport java.math.BigDecimal; 36106813Ssimokawaimport java.security.AccessController; 37106813Ssimokawaimport java.security.PrivilegedAction; 38106813Ssimokawaimport java.util.List ; 39106813Ssimokawaimport java.util.ArrayList ; 40106813Ssimokawa 41106813Ssimokawaimport org.omg.CORBA.Principal ; 42127468Ssimokawaimport org.omg.CORBA.TypeCode ; 43120660Ssimokawaimport org.omg.CORBA.Any ; 44120660Ssimokawaimport org.omg.CORBA.CompletionStatus ; 45120660Ssimokawaimport org.omg.CORBA.TCKind ; 46120660Ssimokawa 47106813Ssimokawaimport org.omg.CORBA.portable.Streamable; 48106813Ssimokawaimport org.omg.CORBA.portable.InputStream; 49106813Ssimokawaimport org.omg.CORBA.portable.OutputStream; 50106813Ssimokawaimport org.omg.CORBA.TypeCodePackage.BadKind; 51106813Ssimokawaimport org.omg.CORBA.TypeCodePackage.Bounds; 52106813Ssimokawa 53106813Ssimokawaimport com.sun.corba.se.spi.orb.ORB; 54118455Ssimokawaimport com.sun.corba.se.spi.orb.ORBVersionFactory; 55113584Ssimokawaimport com.sun.corba.se.spi.logging.CORBALogDomains; 56106813Ssimokawaimport com.sun.corba.se.spi.presentation.rmi.StubAdapter; 57106813Ssimokawa 58106813Ssimokawaimport com.sun.corba.se.impl.encoding.CDRInputStream; 59127468Ssimokawaimport com.sun.corba.se.impl.encoding.EncapsInputStream; 60127468Ssimokawaimport com.sun.corba.se.impl.encoding.EncapsOutputStream; 61127468Ssimokawaimport com.sun.corba.se.impl.io.ValueUtility; 62127468Ssimokawaimport com.sun.corba.se.impl.orbutil.RepositoryIdFactory; 63127468Ssimokawaimport com.sun.corba.se.impl.orbutil.RepositoryIdStrings; 64127468Ssimokawaimport com.sun.corba.se.impl.orbutil.ORBUtility; 65127468Ssimokawaimport com.sun.corba.se.impl.logging.ORBUtilSystemException; 66106813Ssimokawa 67106813Ssimokawa// subclasses must provide a matching helper class 68113584Ssimokawapublic class AnyImpl extends Any 69106813Ssimokawa{ 70109282Ssimokawa private static final class AnyInputStream extends EncapsInputStream 71127468Ssimokawa { 72106813Ssimokawa public AnyInputStream(EncapsInputStream theStream ) 73106813Ssimokawa { 74106813Ssimokawa super( theStream ); 75106813Ssimokawa } 76106813Ssimokawa } 77106813Ssimokawa 78106813Ssimokawa private static final class AnyOutputStream extends EncapsOutputStream 79106813Ssimokawa { 80106813Ssimokawa public AnyOutputStream(ORB orb) 81106813Ssimokawa { 82120660Ssimokawa super((ORB)orb); 83106813Ssimokawa } 84126080Sphk 85127468Ssimokawa public org.omg.CORBA.portable.InputStream create_input_stream() { 86127468Ssimokawa final org.omg.CORBA.portable.InputStream is = super 87127468Ssimokawa .create_input_stream(); 88127468Ssimokawa AnyInputStream aIS = AccessController 89127468Ssimokawa .doPrivileged(new PrivilegedAction<AnyInputStream>() { 90127468Ssimokawa @Override 91126080Sphk public AnyInputStream run() { 92111815Sphk return new AnyInputStream( 93111815Sphk (com.sun.corba.se.impl.encoding.EncapsInputStream) is); 94111815Sphk } 95111815Sphk }); 96111815Sphk return aIS; 97111815Sphk } 98111815Sphk } 99120660Ssimokawa 100111815Sphk // 101111942Ssimokawa // Always valid. 102127468Ssimokawa // 103111942Ssimokawa private TypeCodeImpl typeCode; 104120660Ssimokawa protected ORB orb; 105118455Ssimokawa private ORBUtilSystemException wrapper ; 106111942Ssimokawa 107106813Ssimokawa // 108106813Ssimokawa // Validity depends upon typecode. The 'value' and 'object' instance 109118293Ssimokawa // members are used to hold immutable types as defined by the 110169130Ssimokawa // isStreamed[] table below. Otherwise, 'stream' is non-null and 111118293Ssimokawa // holds the value in CDR marshaled format. As an optimization, the 112118293Ssimokawa // stream type is an Any extension of CDR stream that is used to 113118293Ssimokawa // detect an optimization in read_value(). 114169130Ssimokawa // 115169130Ssimokawa private CDRInputStream stream; 116118293Ssimokawa private long value; 117118293Ssimokawa private java.lang.Object object; 118106813Ssimokawa 119118293Ssimokawa // Setting the typecode via the type() accessor wipes out the value. 120118293Ssimokawa // An attempt to extract before the value is set will result 121118293Ssimokawa // in a BAD_OPERATION exception being raised. 122118293Ssimokawa private boolean isInitialized = false; 123118293Ssimokawa 124118293Ssimokawa private static final int DEFAULT_BUFFER_SIZE = 32; 125118293Ssimokawa 126118293Ssimokawa /* 127118293Ssimokawa * This boolean array tells us if a given typecode must be 128118293Ssimokawa * streamed. Objects that are immutable don't have to be streamed. 129118293Ssimokawa */ 130118293Ssimokawa static boolean isStreamed[] = { 131118293Ssimokawa false, // null 132118293Ssimokawa false, // void 133129585Sdfr false, // short 134129585Sdfr false, // long 135118293Ssimokawa false, // ushort 136118293Ssimokawa false, // ulong 137118293Ssimokawa false, // float 138118293Ssimokawa false, // double 139118293Ssimokawa false, // boolean 140118293Ssimokawa false, // char 141118293Ssimokawa false, // octet 142118293Ssimokawa false, // any 143118293Ssimokawa false, // TypeCode 144118293Ssimokawa true, // Principal 145118293Ssimokawa false, // objref 146118293Ssimokawa true, // struct 147118293Ssimokawa true, // union 148118293Ssimokawa false, // enum 149118293Ssimokawa false, // string 150118293Ssimokawa true, // sequence 151118293Ssimokawa true, // array 152118293Ssimokawa true, // alias 153118293Ssimokawa true, // except 154118293Ssimokawa false, // longlong 155118293Ssimokawa false, // ulonglong 156118293Ssimokawa false, // longdouble 157118293Ssimokawa false, // wchar 158118293Ssimokawa false, // wstring 159118293Ssimokawa false, // fixed 160118293Ssimokawa false, // value 161118293Ssimokawa false, // value_box (used to be true) 162118293Ssimokawa false, // native 163118293Ssimokawa false // abstract interface 164118293Ssimokawa }; 165118293Ssimokawa 166118293Ssimokawa static AnyImpl convertToNative(ORB orb, Any any) { 167118293Ssimokawa if (any instanceof AnyImpl) { 168118293Ssimokawa return (AnyImpl)any; 169118293Ssimokawa } else { 170118293Ssimokawa AnyImpl anyImpl = new AnyImpl(orb, any); 171118293Ssimokawa anyImpl.typeCode = TypeCodeImpl.convertToNative(orb, anyImpl.typeCode); 172118293Ssimokawa return anyImpl; 173118293Ssimokawa } 174118293Ssimokawa } 175118293Ssimokawa 176118293Ssimokawa /////////////////////////////////////////////////////////////////////////// 177118293Ssimokawa // Constructors 178118293Ssimokawa 179118293Ssimokawa /** 180118293Ssimokawa * A constructor that sets the Any to contain a null. It also marks 181118293Ssimokawa * the value as being invalid so that extractions throw an exception 182118293Ssimokawa * until an insertion has been performed. 183130585Sphk */ 184106813Ssimokawa public AnyImpl(ORB orb) 185106813Ssimokawa { 186169130Ssimokawa this.orb = orb; 187169130Ssimokawa wrapper = ORBUtilSystemException.get( (com.sun.corba.se.spi.orb.ORB)orb, 188169130Ssimokawa CORBALogDomains.RPC_PRESENTATION ) ; 189106813Ssimokawa 190122227Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_null); 191122227Ssimokawa stream = null; 192122227Ssimokawa object = null; 193170374Ssimokawa value = 0; 194170374Ssimokawa // null is a valid value 195170374Ssimokawa isInitialized = true; 196170374Ssimokawa } 197170374Ssimokawa 198170374Ssimokawa // 199170374Ssimokawa // Create a new AnyImpl which is a copy of obj. 200118293Ssimokawa // 201170374Ssimokawa public AnyImpl(ORB orb, Any obj) { 202170374Ssimokawa this(orb); 203170374Ssimokawa 204170374Ssimokawa if ((obj instanceof AnyImpl)) { 205118293Ssimokawa AnyImpl objImpl = (AnyImpl)obj; 206170374Ssimokawa typeCode = objImpl.typeCode; 207170374Ssimokawa value = objImpl.value; 208170374Ssimokawa object = objImpl.object; 209170374Ssimokawa isInitialized = objImpl.isInitialized; 210127468Ssimokawa 211118455Ssimokawa if (objImpl.stream != null) 212118455Ssimokawa stream = objImpl.stream.dup(); 213118455Ssimokawa 214118455Ssimokawa } else { 215183397Sed read_value(obj.create_input_stream(), obj.type()); 216118293Ssimokawa } 217118293Ssimokawa } 218118455Ssimokawa 219118455Ssimokawa /////////////////////////////////////////////////////////////////////////// 220169130Ssimokawa // basic accessors 221169130Ssimokawa 222169130Ssimokawa /** 223169130Ssimokawa * returns the type of the element contained in the Any. 224169130Ssimokawa * 225106813Ssimokawa * @return the TypeCode for the element in the Any 226106813Ssimokawa */ 227106813Ssimokawa public TypeCode type() { 228106813Ssimokawa return typeCode; 229130585Sphk } 230106813Ssimokawa 231118293Ssimokawa private TypeCode realType() { 232118293Ssimokawa return realType(typeCode); 233106813Ssimokawa } 234106813Ssimokawa 235106813Ssimokawa private TypeCode realType(TypeCode aType) { 236106813Ssimokawa TypeCode realType = aType; 237106813Ssimokawa try { 238106813Ssimokawa // Note: Indirect types are handled in kind() method 239106813Ssimokawa while (realType.kind().value() == TCKind._tk_alias) { 240118293Ssimokawa realType = realType.content_type(); 241169130Ssimokawa } 242118293Ssimokawa } catch (BadKind bad) { // impossible 243169130Ssimokawa throw wrapper.badkindCannotOccur( bad ) ; 244169130Ssimokawa } 245169130Ssimokawa return realType; 246169130Ssimokawa } 247169130Ssimokawa 248169130Ssimokawa /** 249169130Ssimokawa * sets the type of the element to be contained in the Any. 250169130Ssimokawa * 251118293Ssimokawa * @param tc the TypeCode for the element in the Any 252118293Ssimokawa */ 253118293Ssimokawa public void type(TypeCode tc) 254118293Ssimokawa { 255118293Ssimokawa //debug.log ("type2"); 256118293Ssimokawa // set the typecode 257118293Ssimokawa typeCode = TypeCodeImpl.convertToNative(orb, tc); 258118293Ssimokawa 259118293Ssimokawa stream = null; 260118293Ssimokawa value = 0; 261118293Ssimokawa object = null; 262118293Ssimokawa // null is the only legal value this Any can have after resetting the type code 263118293Ssimokawa isInitialized = (tc.kind().value() == TCKind._tk_null); 264118293Ssimokawa } 265118293Ssimokawa 266118293Ssimokawa /** 267118293Ssimokawa * checks for equality between Anys. 268118293Ssimokawa * 269118293Ssimokawa * @param otherAny the Any to be compared with. 270118293Ssimokawa * @return true if the Anys are equal, false otherwise. 271118293Ssimokawa */ 272118293Ssimokawa public boolean equal(Any otherAny) 273118293Ssimokawa { 274118293Ssimokawa //debug.log ("equal"); 275106813Ssimokawa 276118293Ssimokawa if (otherAny == this) 277118293Ssimokawa return true; 278106813Ssimokawa 279118293Ssimokawa // first check for typecode equality. 280118293Ssimokawa // note that this will take aliases into account 281118293Ssimokawa if (!typeCode.equal(otherAny.type())) 282118293Ssimokawa return false; 283118293Ssimokawa 284118293Ssimokawa // Resolve aliases here 285118293Ssimokawa TypeCode realType = realType(); 286118293Ssimokawa 287118293Ssimokawa // _REVISIT_ Possible optimization for the case where 288118293Ssimokawa // otherAny is a AnyImpl and the endianesses match. 289118293Ssimokawa // Need implementation of CDRInputStream.equals() 290106813Ssimokawa // For now we disable this to encourage testing the generic, 291118293Ssimokawa // unoptimized code below. 292118293Ssimokawa // Unfortunately this generic code needs to copy the whole stream 293106813Ssimokawa // at least once. 294106813Ssimokawa // if (AnyImpl.isStreamed[realType.kind().value()]) { 295106813Ssimokawa // if (otherAny instanceof AnyImpl) { 296106813Ssimokawa // return ((AnyImpl)otherAny).stream.equals(stream); 297169130Ssimokawa // } 298169130Ssimokawa // } 299169130Ssimokawa switch (realType.kind().value()) { 300169130Ssimokawa // handle primitive types 301169130Ssimokawa case TCKind._tk_null: 302169130Ssimokawa case TCKind._tk_void: 303169130Ssimokawa return true; 304169130Ssimokawa case TCKind._tk_short: 305169130Ssimokawa return (extract_short() == otherAny.extract_short()); 306170374Ssimokawa case TCKind._tk_long: 307169130Ssimokawa return (extract_long() == otherAny.extract_long()); 308170374Ssimokawa case TCKind._tk_ushort: 309169130Ssimokawa return (extract_ushort() == otherAny.extract_ushort()); 310170374Ssimokawa case TCKind._tk_ulong: 311170374Ssimokawa return (extract_ulong() == otherAny.extract_ulong()); 312169130Ssimokawa case TCKind._tk_float: 313170374Ssimokawa return (extract_float() == otherAny.extract_float()); 314169130Ssimokawa case TCKind._tk_double: 315169130Ssimokawa return (extract_double() == otherAny.extract_double()); 316169130Ssimokawa case TCKind._tk_boolean: 317170374Ssimokawa return (extract_boolean() == otherAny.extract_boolean()); 318169130Ssimokawa case TCKind._tk_char: 319169130Ssimokawa return (extract_char() == otherAny.extract_char()); 320169130Ssimokawa case TCKind._tk_wchar: 321169130Ssimokawa return (extract_wchar() == otherAny.extract_wchar()); 322169130Ssimokawa case TCKind._tk_octet: 323169130Ssimokawa return (extract_octet() == otherAny.extract_octet()); 324169130Ssimokawa case TCKind._tk_any: 325169130Ssimokawa return extract_any().equal(otherAny.extract_any()); 326169130Ssimokawa case TCKind._tk_TypeCode: 327169130Ssimokawa return extract_TypeCode().equal(otherAny.extract_TypeCode()); 328169130Ssimokawa case TCKind._tk_string: 329169130Ssimokawa return extract_string().equals(otherAny.extract_string()); 330169130Ssimokawa case TCKind._tk_wstring: 331169130Ssimokawa return (extract_wstring().equals(otherAny.extract_wstring())); 332169130Ssimokawa case TCKind._tk_longlong: 333169130Ssimokawa return (extract_longlong() == otherAny.extract_longlong()); 334169130Ssimokawa case TCKind._tk_ulonglong: 335170374Ssimokawa return (extract_ulonglong() == otherAny.extract_ulonglong()); 336169130Ssimokawa 337170374Ssimokawa case TCKind._tk_objref: 338169130Ssimokawa return (extract_Object().equals(otherAny.extract_Object())); 339169130Ssimokawa case TCKind._tk_Principal: 340169130Ssimokawa return (extract_Principal().equals(otherAny.extract_Principal())); 341106813Ssimokawa 342106813Ssimokawa case TCKind._tk_enum: 343106813Ssimokawa return (extract_long() == otherAny.extract_long()); 344106813Ssimokawa case TCKind._tk_fixed: 345130585Sphk return (extract_fixed().compareTo(otherAny.extract_fixed()) == 0); 346106813Ssimokawa case TCKind._tk_except: 347169130Ssimokawa case TCKind._tk_struct: 348106813Ssimokawa case TCKind._tk_union: 349169130Ssimokawa case TCKind._tk_sequence: 350106813Ssimokawa case TCKind._tk_array: 351106813Ssimokawa InputStream copyOfMyStream = this.create_input_stream(); 352106813Ssimokawa InputStream copyOfOtherStream = otherAny.create_input_stream(); 353106813Ssimokawa return equalMember(realType, copyOfMyStream, copyOfOtherStream); 354170374Ssimokawa 355106813Ssimokawa // Too complicated to handle value types the way we handle 356169130Ssimokawa // other complex types above. Don't try to decompose it here 357169130Ssimokawa // for faster comparison, just use Object.equals(). 358169130Ssimokawa case TCKind._tk_value: 359169130Ssimokawa case TCKind._tk_value_box: 360169130Ssimokawa return extract_Value().equals(otherAny.extract_Value()); 361169130Ssimokawa 362169130Ssimokawa case TCKind._tk_alias: 363169130Ssimokawa throw wrapper.errorResolvingAlias() ; 364118293Ssimokawa 365106813Ssimokawa case TCKind._tk_longdouble: 366170374Ssimokawa // Unspecified for Java 367106813Ssimokawa throw wrapper.tkLongDoubleNotSupported() ; 368113584Ssimokawa 369109988Ssimokawa default: 370106813Ssimokawa throw wrapper.typecodeNotSupported() ; 371109988Ssimokawa } 372106813Ssimokawa } 373106813Ssimokawa 374106813Ssimokawa // Needed for equal() in order to achieve linear performance for complex types. 375106813Ssimokawa // Uses up (recursively) copies of the InputStream in both Anys that got created in equal(). 376106813Ssimokawa private boolean equalMember(TypeCode memberType, InputStream myStream, InputStream otherStream) { 377106813Ssimokawa // Resolve aliases here 378169130Ssimokawa TypeCode realType = realType(memberType); 379109988Ssimokawa 380109988Ssimokawa try { 381106813Ssimokawa switch (realType.kind().value()) { 382106813Ssimokawa // handle primitive types 383170374Ssimokawa case TCKind._tk_null: 384109988Ssimokawa case TCKind._tk_void: 385109988Ssimokawa return true; 386109988Ssimokawa case TCKind._tk_short: 387109988Ssimokawa return (myStream.read_short() == otherStream.read_short()); 388106813Ssimokawa case TCKind._tk_long: 389170374Ssimokawa return (myStream.read_long() == otherStream.read_long()); 390109988Ssimokawa case TCKind._tk_ushort: 391109988Ssimokawa return (myStream.read_ushort() == otherStream.read_ushort()); 392109988Ssimokawa case TCKind._tk_ulong: 393170374Ssimokawa return (myStream.read_ulong() == otherStream.read_ulong()); 394113584Ssimokawa case TCKind._tk_float: 395113584Ssimokawa return (myStream.read_float() == otherStream.read_float()); 396169130Ssimokawa case TCKind._tk_double: 397169130Ssimokawa return (myStream.read_double() == otherStream.read_double()); 398113584Ssimokawa case TCKind._tk_boolean: 399106813Ssimokawa return (myStream.read_boolean() == otherStream.read_boolean()); 400106813Ssimokawa case TCKind._tk_char: 401106813Ssimokawa return (myStream.read_char() == otherStream.read_char()); 402109988Ssimokawa case TCKind._tk_wchar: 403129585Sdfr return (myStream.read_wchar() == otherStream.read_wchar()); 404106813Ssimokawa case TCKind._tk_octet: 405106813Ssimokawa return (myStream.read_octet() == otherStream.read_octet()); 406106813Ssimokawa case TCKind._tk_any: 407106813Ssimokawa return myStream.read_any().equal(otherStream.read_any()); 408106813Ssimokawa case TCKind._tk_TypeCode: 409169130Ssimokawa return myStream.read_TypeCode().equal(otherStream.read_TypeCode()); 410106813Ssimokawa case TCKind._tk_string: 411106813Ssimokawa return myStream.read_string().equals(otherStream.read_string()); 412109988Ssimokawa case TCKind._tk_wstring: 413109988Ssimokawa return (myStream.read_wstring().equals(otherStream.read_wstring())); 414170374Ssimokawa case TCKind._tk_longlong: 415109988Ssimokawa return (myStream.read_longlong() == otherStream.read_longlong()); 416109988Ssimokawa case TCKind._tk_ulonglong: 417106813Ssimokawa return (myStream.read_ulonglong() == otherStream.read_ulonglong()); 418106813Ssimokawa 419106813Ssimokawa case TCKind._tk_objref: 420106813Ssimokawa return (myStream.read_Object().equals(otherStream.read_Object())); 421106813Ssimokawa case TCKind._tk_Principal: 422169130Ssimokawa return (myStream.read_Principal().equals(otherStream.read_Principal())); 423169130Ssimokawa 424169130Ssimokawa case TCKind._tk_enum: 425169130Ssimokawa return (myStream.read_long() == otherStream.read_long()); 426169130Ssimokawa case TCKind._tk_fixed: 427169130Ssimokawa return (myStream.read_fixed().compareTo(otherStream.read_fixed()) == 0); 428169130Ssimokawa case TCKind._tk_except: 429169130Ssimokawa case TCKind._tk_struct: { 430169130Ssimokawa int length = realType.member_count(); 431169130Ssimokawa for (int i=0; i<length; i++) { 432169130Ssimokawa if ( ! equalMember(realType.member_type(i), myStream, otherStream)) { 433169130Ssimokawa return false; 434169130Ssimokawa } 435169130Ssimokawa } 436169130Ssimokawa return true; 437169130Ssimokawa } 438169130Ssimokawa case TCKind._tk_union: { 439169130Ssimokawa Any myDiscriminator = orb.create_any(); 440169130Ssimokawa Any otherDiscriminator = orb.create_any(); 441169130Ssimokawa myDiscriminator.read_value(myStream, realType.discriminator_type()); 442169130Ssimokawa otherDiscriminator.read_value(otherStream, realType.discriminator_type()); 443169130Ssimokawa 444169130Ssimokawa if ( ! myDiscriminator.equal(otherDiscriminator)) { 445194687Srdivacky return false; 446169130Ssimokawa } 447169130Ssimokawa TypeCodeImpl realTypeCodeImpl = TypeCodeImpl.convertToNative(orb, realType); 448169130Ssimokawa int memberIndex = realTypeCodeImpl.currentUnionMemberIndex(myDiscriminator); 449169130Ssimokawa if (memberIndex == -1) 450169130Ssimokawa throw wrapper.unionDiscriminatorError() ; 451170374Ssimokawa 452169130Ssimokawa if ( ! equalMember(realType.member_type(memberIndex), myStream, otherStream)) { 453169130Ssimokawa return false; 454169130Ssimokawa } 455169130Ssimokawa return true; 456169130Ssimokawa } 457170374Ssimokawa case TCKind._tk_sequence: { 458169130Ssimokawa int length = myStream.read_long(); 459169130Ssimokawa otherStream.read_long(); // just so that the two stream are in sync 460169130Ssimokawa for (int i=0; i<length; i++) { 461169130Ssimokawa if ( ! equalMember(realType.content_type(), myStream, otherStream)) { 462169130Ssimokawa return false; 463169130Ssimokawa } 464169130Ssimokawa } 465170374Ssimokawa return true; 466170374Ssimokawa } 467169130Ssimokawa case TCKind._tk_array: { 468170374Ssimokawa int length = realType.member_count(); 469169130Ssimokawa for (int i=0; i<length; i++) { 470169130Ssimokawa if ( ! equalMember(realType.content_type(), myStream, otherStream)) { 471169130Ssimokawa return false; 472169130Ssimokawa } 473169130Ssimokawa } 474169130Ssimokawa return true; 475169130Ssimokawa } 476169130Ssimokawa 477169130Ssimokawa // Too complicated to handle value types the way we handle 478130585Sphk // other complex types above. Don't try to decompose it here 479106813Ssimokawa // for faster comparison, just use Object.equals(). 480106813Ssimokawa case TCKind._tk_value: 481106813Ssimokawa case TCKind._tk_value_box: 482169130Ssimokawa org.omg.CORBA_2_3.portable.InputStream mine = 483106813Ssimokawa (org.omg.CORBA_2_3.portable.InputStream)myStream; 484106813Ssimokawa org.omg.CORBA_2_3.portable.InputStream other = 485106813Ssimokawa (org.omg.CORBA_2_3.portable.InputStream)otherStream; 486106813Ssimokawa return mine.read_value().equals(other.read_value()); 487106813Ssimokawa 488170374Ssimokawa case TCKind._tk_alias: 489106813Ssimokawa // error resolving alias above 490169130Ssimokawa throw wrapper.errorResolvingAlias() ; 491169130Ssimokawa 492169130Ssimokawa case TCKind._tk_longdouble: 493169130Ssimokawa throw wrapper.tkLongDoubleNotSupported() ; 494169130Ssimokawa 495169130Ssimokawa default: 496169130Ssimokawa throw wrapper.typecodeNotSupported() ; 497169130Ssimokawa } 498118293Ssimokawa } catch (BadKind badKind) { // impossible 499170374Ssimokawa throw wrapper.badkindCannotOccur() ; 500170374Ssimokawa } catch (Bounds bounds) { // impossible 501106813Ssimokawa throw wrapper.boundsCannotOccur() ; 502113802Ssimokawa } 503113802Ssimokawa } 504113802Ssimokawa 505106813Ssimokawa /////////////////////////////////////////////////////////////////////////// 506113802Ssimokawa // accessors for marshaling/unmarshaling 507106813Ssimokawa 508113802Ssimokawa /** 509113802Ssimokawa * returns an output stream that an Any value can be marshaled into. 510113802Ssimokawa * 511170374Ssimokawa * @return the OutputStream to marshal value of Any into 512169130Ssimokawa */ 513113802Ssimokawa public org.omg.CORBA.portable.OutputStream create_output_stream() 514170374Ssimokawa { 515170374Ssimokawa //debug.log ("create_output_stream"); 516170374Ssimokawa final ORB finalorb = this.orb; 517113802Ssimokawa return AccessController.doPrivileged(new PrivilegedAction<AnyOutputStream>() { 518170374Ssimokawa @Override 519109988Ssimokawa public AnyOutputStream run() { 520113802Ssimokawa return new AnyOutputStream(finalorb); 521113802Ssimokawa } 522170374Ssimokawa }); 523106813Ssimokawa } 524106813Ssimokawa 525170374Ssimokawa /** 526113802Ssimokawa * returns an input stream that an Any value can be marshaled out of. 527113802Ssimokawa * 528113802Ssimokawa * @return the InputStream to marshal value of Any out of. 529113802Ssimokawa */ 530113802Ssimokawa public org.omg.CORBA.portable.InputStream create_input_stream() 531113802Ssimokawa { 532113802Ssimokawa // 533113802Ssimokawa // We create a new InputStream so that multiple threads can call here 534113802Ssimokawa // and read the streams in parallel without thread safety problems. 535113802Ssimokawa // 536113802Ssimokawa //debug.log ("create_input_stream"); 537169130Ssimokawa if (AnyImpl.isStreamed[realType().kind().value()]) { 538113802Ssimokawa return stream.dup(); 539113802Ssimokawa } else { 540113802Ssimokawa OutputStream os = (OutputStream)orb.create_output_stream(); 541170374Ssimokawa TCUtility.marshalIn(os, realType(), value, object); 542113802Ssimokawa 543113802Ssimokawa return os.create_input_stream(); 544113802Ssimokawa } 545170374Ssimokawa } 546170374Ssimokawa 547170374Ssimokawa /////////////////////////////////////////////////////////////////////////// 548170374Ssimokawa // marshaling/unmarshaling routines 549106813Ssimokawa 550169130Ssimokawa // 551169130Ssimokawa // If the InputStream is a CDRInputStream then we can copy the bytes 552169130Ssimokawa // since it is in our format and does not have alignment issues. 553169130Ssimokawa // 554169130Ssimokawa public void read_value(org.omg.CORBA.portable.InputStream in, TypeCode tc) 555169130Ssimokawa { 556169130Ssimokawa //debug.log ("read_value"); 557169130Ssimokawa // 558169130Ssimokawa // Assume that someone isn't going to think they can keep reading 559170374Ssimokawa // from this stream after calling us. That would be likely for 560169130Ssimokawa // an IIOPInputStream but if it is an AnyInputStream then they 561170374Ssimokawa // presumably obtained it via our create_output_stream() so they could 562169130Ssimokawa // write the contents of an IDL data type to it and then call 563169130Ssimokawa // create_input_stream() for us to read it. This is how Helper classes 564169130Ssimokawa // typically implement the insert() method. 565106813Ssimokawa // We should probably document this behavior in the 1.1 revision 566106813Ssimokawa // task force. 567106813Ssimokawa // 568106813Ssimokawa 569130585Sphk typeCode = TypeCodeImpl.convertToNative(orb, tc); 570106813Ssimokawa int kind = realType().kind().value(); 571118293Ssimokawa if (kind >= isStreamed.length) { 572118293Ssimokawa throw wrapper.invalidIsstreamedTckind( CompletionStatus.COMPLETED_MAYBE, 573169130Ssimokawa new Integer(kind)) ; 574106813Ssimokawa } 575106813Ssimokawa 576106813Ssimokawa if (AnyImpl.isStreamed[kind]) { 577106813Ssimokawa if ( in instanceof AnyInputStream ) { 578106813Ssimokawa // could only have been created here 579109814Ssimokawa stream = (CDRInputStream)in; 580117473Ssimokawa } else { 581106813Ssimokawa org.omg.CORBA_2_3.portable.OutputStream out = 582106813Ssimokawa (org.omg.CORBA_2_3.portable.OutputStream)orb.create_output_stream(); 583106813Ssimokawa typeCode.copy((org.omg.CORBA_2_3.portable.InputStream)in, out); 584106813Ssimokawa stream = (CDRInputStream)out.create_input_stream(); 585106813Ssimokawa } 586106813Ssimokawa } else { 587106813Ssimokawa java.lang.Object[] objholder = new java.lang.Object[1]; 588106813Ssimokawa objholder[0] = object; 589106813Ssimokawa long[] longholder = new long[1]; 590106813Ssimokawa TCUtility.unmarshalIn(in, realType(), longholder, objholder); 591106813Ssimokawa value = longholder[0]; 592106813Ssimokawa object = objholder[0]; 593106813Ssimokawa stream = null; 594106813Ssimokawa } 595118293Ssimokawa isInitialized = true; 596169130Ssimokawa } 597118293Ssimokawa 598118293Ssimokawa 599118293Ssimokawa // 600106813Ssimokawa // We could optimize this by noticing whether the target stream 601106813Ssimokawa // has ever had anything marshaled on it that required an 602118293Ssimokawa // alignment of greater than 4 (was write_double() ever called on it). 603170374Ssimokawa // If not, then we can just do a byte array copy without having to 604170374Ssimokawa // drive the remarshaling through typecode interpretation. 605118293Ssimokawa // 606118293Ssimokawa public void write_value(OutputStream out) 607118293Ssimokawa { 608170374Ssimokawa //debug.log ("write_value"); 609118293Ssimokawa if (AnyImpl.isStreamed[realType().kind().value()]) { 610170374Ssimokawa typeCode.copy(stream.dup(), out); 611170374Ssimokawa } else { 612118293Ssimokawa // _REVISIT_ check isInitialized whether all we write is TypeCode! 613170374Ssimokawa TCUtility.marshalIn(out, realType(), value, object); 614118293Ssimokawa } 615118293Ssimokawa } 616118293Ssimokawa 617118293Ssimokawa /** 618118293Ssimokawa * takes a streamable and inserts its reference into the any 619106813Ssimokawa * 620106813Ssimokawa * @param s the streamable to insert 621118293Ssimokawa */ 622118293Ssimokawa public void insert_Streamable(Streamable s) 623118293Ssimokawa { 624118293Ssimokawa //debug.log ("insert_Streamable"); 625118293Ssimokawa typeCode = TypeCodeImpl.convertToNative(orb, s._type()); 626106813Ssimokawa object = s; 627106813Ssimokawa isInitialized = true; 628118293Ssimokawa } 629170374Ssimokawa 630170374Ssimokawa public Streamable extract_Streamable() 631118293Ssimokawa { 632118293Ssimokawa //debug.log( "extract_Streamable" ) ; 633118293Ssimokawa return (Streamable)object; 634170374Ssimokawa } 635118293Ssimokawa 636170374Ssimokawa /////////////////////////////////////////////////////////////////////////// 637170374Ssimokawa // insertion/extraction/replacement for all basic types 638118293Ssimokawa 639170374Ssimokawa /** 640118293Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 641118293Ssimokawa */ 642118293Ssimokawa public void insert_short(short s) 643118293Ssimokawa { 644118293Ssimokawa //debug.log ("insert_short"); 645118293Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_short); 646106813Ssimokawa value = s; 647106813Ssimokawa isInitialized = true; 648118293Ssimokawa } 649118293Ssimokawa 650118293Ssimokawa private String getTCKindName( int tc ) 651118293Ssimokawa { 652118293Ssimokawa if ((tc >= 0) && (tc < TypeCodeImpl.kindNames.length)) 653106813Ssimokawa return TypeCodeImpl.kindNames[tc] ; 654106813Ssimokawa else 655118293Ssimokawa return "UNKNOWN(" + tc + ")" ; 656106813Ssimokawa } 657106813Ssimokawa 658118293Ssimokawa private void checkExtractBadOperation( int expected ) 659118293Ssimokawa { 660118293Ssimokawa if (!isInitialized) 661118293Ssimokawa throw wrapper.extractNotInitialized() ; 662118293Ssimokawa 663118293Ssimokawa int tc = realType().kind().value() ; 664118293Ssimokawa if (tc != expected) { 665118293Ssimokawa String tcName = getTCKindName( tc ) ; 666118293Ssimokawa String expectedName = getTCKindName( expected ) ; 667118293Ssimokawa throw wrapper.extractWrongType( expectedName, tcName ) ; 668118293Ssimokawa } 669118293Ssimokawa } 670106813Ssimokawa 671106813Ssimokawa private void checkExtractBadOperationList( int[] expected ) 672120660Ssimokawa { 673120660Ssimokawa if (!isInitialized) 674121466Ssimokawa throw wrapper.extractNotInitialized() ; 675120660Ssimokawa 676106813Ssimokawa int tc = realType().kind().value() ; 677169130Ssimokawa for (int ctr=0; ctr<expected.length; ctr++) 678121466Ssimokawa if (tc == expected[ctr]) 679121466Ssimokawa return ; 680121466Ssimokawa 681121466Ssimokawa List list = new ArrayList() ; 682121466Ssimokawa for (int ctr=0; ctr<expected.length; ctr++) 683121466Ssimokawa list.add( getTCKindName( expected[ctr] ) ) ; 684121466Ssimokawa 685121466Ssimokawa String tcName = getTCKindName( tc ) ; 686106813Ssimokawa throw wrapper.extractWrongTypeList( list, tcName ) ; 687106813Ssimokawa } 688106813Ssimokawa 689106813Ssimokawa /** 690169130Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 691110582Ssimokawa */ 692106813Ssimokawa public short extract_short() 693169130Ssimokawa { 694108782Ssimokawa //debug.log ("extract_short"); 695106813Ssimokawa checkExtractBadOperation( TCKind._tk_short ) ; 696121466Ssimokawa return (short)value; 697106813Ssimokawa } 698120660Ssimokawa 699106813Ssimokawa /** 700106813Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 701106813Ssimokawa */ 702106813Ssimokawa public void insert_long(int l) 703106813Ssimokawa { 704106813Ssimokawa //debug.log ("insert_long"); 705106813Ssimokawa // A long value is applicable to enums as well, so don't erase the enum type code 706106813Ssimokawa // in case it was initialized that way before. 707121466Ssimokawa int kind = realType().kind().value(); 708120660Ssimokawa if (kind != TCKind._tk_long && kind != TCKind._tk_enum) { 709121466Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_long); 710120660Ssimokawa } 711127347Ssimokawa value = l; 712121466Ssimokawa isInitialized = true; 713170374Ssimokawa } 714121466Ssimokawa 715169130Ssimokawa /** 716121466Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 717170374Ssimokawa */ 718121466Ssimokawa public int extract_long() 719121466Ssimokawa { 720121466Ssimokawa //debug.log ("extract_long"); 721121466Ssimokawa checkExtractBadOperationList( new int[] { TCKind._tk_long, TCKind._tk_enum } ) ; 722106813Ssimokawa return (int)value; 723121466Ssimokawa } 724121466Ssimokawa 725121466Ssimokawa /** 726121466Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 727169130Ssimokawa */ 728129628Sdfr public void insert_ushort(short s) 729129628Sdfr { 730129628Sdfr //debug.log ("insert_ushort"); 731129628Sdfr typeCode = orb.get_primitive_tc(TCKind._tk_ushort); 732129628Sdfr value = s; 733129628Sdfr isInitialized = true; 734129628Sdfr } 735129628Sdfr 736129628Sdfr /** 737129628Sdfr * See the description of the <a href="#anyOps">general Any operations.</a> 738129628Sdfr */ 739129628Sdfr public short extract_ushort() 740129628Sdfr { 741121466Ssimokawa //debug.log ("extract_ushort"); 742129628Sdfr checkExtractBadOperation( TCKind._tk_ushort ) ; 743121466Ssimokawa return (short)value; 744120660Ssimokawa } 745106813Ssimokawa 746120660Ssimokawa /** 747106813Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 748169130Ssimokawa */ 749106813Ssimokawa public void insert_ulong(int l) 750106813Ssimokawa { 751169130Ssimokawa //debug.log ("insert_ulong"); 752106813Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_ulong); 753106813Ssimokawa value = l; 754106813Ssimokawa isInitialized = true; 755106813Ssimokawa } 756106813Ssimokawa 757169130Ssimokawa /** 758169130Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 759169130Ssimokawa */ 760110195Ssimokawa public int extract_ulong() 761106813Ssimokawa { 762106813Ssimokawa //debug.log ("extract_ulong"); 763106813Ssimokawa checkExtractBadOperation( TCKind._tk_ulong ) ; 764106813Ssimokawa return (int)value; 765106813Ssimokawa } 766106813Ssimokawa 767106813Ssimokawa /** 768106813Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 769106813Ssimokawa */ 770106813Ssimokawa public void insert_float(float f) 771170374Ssimokawa { 772106813Ssimokawa //debug.log ("insert_float"); 773106813Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_float); 774106813Ssimokawa value = Float.floatToIntBits(f); 775106813Ssimokawa isInitialized = true; 776120660Ssimokawa } 777120660Ssimokawa 778120660Ssimokawa /** 779169130Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 780169130Ssimokawa */ 781169130Ssimokawa public float extract_float() 782169130Ssimokawa { 783169130Ssimokawa //debug.log ("extract_float"); 784169130Ssimokawa checkExtractBadOperation( TCKind._tk_float ) ; 785169130Ssimokawa return Float.intBitsToFloat((int)value); 786169130Ssimokawa } 787169130Ssimokawa 788106813Ssimokawa /** 789106813Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 790106813Ssimokawa */ 791109814Ssimokawa public void insert_double(double d) 792109814Ssimokawa { 793109814Ssimokawa //debug.log ("insert_double"); 794169130Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_double); 795109814Ssimokawa value = Double.doubleToLongBits(d); 796169130Ssimokawa isInitialized = true; 797169130Ssimokawa } 798169130Ssimokawa 799109814Ssimokawa /** 800109814Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 801109814Ssimokawa */ 802109814Ssimokawa public double extract_double() 803109814Ssimokawa { 804109814Ssimokawa //debug.log ("extract_double"); 805109814Ssimokawa checkExtractBadOperation( TCKind._tk_double ) ; 806106813Ssimokawa return Double.longBitsToDouble(value); 807106813Ssimokawa } 808106813Ssimokawa 809106813Ssimokawa /** 810109814Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 811106813Ssimokawa */ 812106813Ssimokawa public void insert_longlong(long l) 813169130Ssimokawa { 814169130Ssimokawa //debug.log ("insert_longlong"); 815106813Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_longlong); 816106813Ssimokawa value = l; 817169130Ssimokawa isInitialized = true; 818110193Ssimokawa } 819106813Ssimokawa 820106813Ssimokawa /** 821169130Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 822117473Ssimokawa */ 823117473Ssimokawa public long extract_longlong() 824117473Ssimokawa { 825117473Ssimokawa //debug.log ("extract_longlong"); 826117473Ssimokawa checkExtractBadOperation( TCKind._tk_longlong ) ; 827117473Ssimokawa return value; 828117473Ssimokawa } 829129585Sdfr 830169130Ssimokawa /** 831117473Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 832117473Ssimokawa */ 833117473Ssimokawa public void insert_ulonglong(long l) 834117473Ssimokawa { 835117473Ssimokawa //debug.log ("insert_ulonglong"); 836117473Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_ulonglong); 837117473Ssimokawa value = l; 838106813Ssimokawa isInitialized = true; 839169019Ssimokawa } 840106813Ssimokawa 841106813Ssimokawa /** 842106813Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 843117473Ssimokawa */ 844117473Ssimokawa public long extract_ulonglong() 845117473Ssimokawa { 846117473Ssimokawa //debug.log ("extract_ulonglong"); 847106813Ssimokawa checkExtractBadOperation( TCKind._tk_ulonglong ) ; 848106813Ssimokawa return value; 849169130Ssimokawa } 850106813Ssimokawa 851106813Ssimokawa /** 852106813Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 853106813Ssimokawa */ 854106813Ssimokawa public void insert_boolean(boolean b) 855130585Sphk { 856106813Ssimokawa //debug.log ("insert_boolean"); 857118293Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_boolean); 858106813Ssimokawa value = (b)? 1:0; 859106813Ssimokawa isInitialized = true; 860106813Ssimokawa } 861106813Ssimokawa 862106813Ssimokawa /** 863106813Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 864118293Ssimokawa */ 865106813Ssimokawa public boolean extract_boolean() 866106813Ssimokawa { 867106813Ssimokawa //debug.log ("extract_boolean"); 868118293Ssimokawa checkExtractBadOperation( TCKind._tk_boolean ) ; 869106813Ssimokawa return (value == 0)? false: true; 870106813Ssimokawa } 871118293Ssimokawa 872106813Ssimokawa /** 873106813Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 874106813Ssimokawa */ 875106813Ssimokawa public void insert_char(char c) 876106813Ssimokawa { 877106813Ssimokawa //debug.log ("insert_char"); 878106813Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_char); 879106813Ssimokawa value = c; 880106813Ssimokawa isInitialized = true; 881106813Ssimokawa } 882106813Ssimokawa 883127468Ssimokawa /** 884130585Sphk * See the description of the <a href="#anyOps">general Any operations.</a> 885111615Ssimokawa */ 886201223Srnoland public char extract_char() 887201223Srnoland { 888111615Ssimokawa //debug.log ("extract_char"); 889106813Ssimokawa checkExtractBadOperation( TCKind._tk_char ) ; 890106813Ssimokawa return (char)value; 891106813Ssimokawa } 892127468Ssimokawa 893111615Ssimokawa /** 894111615Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 895201223Srnoland */ 896111615Ssimokawa public void insert_wchar(char c) 897106813Ssimokawa { 898106813Ssimokawa //debug.log ("insert_wchar"); 899106813Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_wchar); 900118455Ssimokawa value = c; 901120660Ssimokawa isInitialized = true; 902120660Ssimokawa } 903120660Ssimokawa 904130585Sphk /** 905120660Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 906120660Ssimokawa */ 907120660Ssimokawa public char extract_wchar() 908120660Ssimokawa { 909120660Ssimokawa //debug.log ("extract_wchar"); 910120660Ssimokawa checkExtractBadOperation( TCKind._tk_wchar ) ; 911120660Ssimokawa return (char)value; 912120660Ssimokawa } 913120660Ssimokawa 914120660Ssimokawa 915120660Ssimokawa /** 916120660Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 917120660Ssimokawa */ 918118455Ssimokawa public void insert_octet(byte b) 919118455Ssimokawa { 920118455Ssimokawa //debug.log ("insert_octet"); 921118455Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_octet); 922118455Ssimokawa value = b; 923127468Ssimokawa isInitialized = true; 924127468Ssimokawa } 925127468Ssimokawa 926130585Sphk /** 927118455Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 928118455Ssimokawa */ 929118455Ssimokawa public byte extract_octet() 930118455Ssimokawa { 931118455Ssimokawa //debug.log ("extract_octet"); 932118455Ssimokawa checkExtractBadOperation( TCKind._tk_octet ) ; 933118455Ssimokawa return (byte)value; 934118455Ssimokawa } 935118455Ssimokawa 936118455Ssimokawa /** 937118455Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 938118455Ssimokawa */ 939118455Ssimokawa public void insert_string(String s) 940118455Ssimokawa { 941118455Ssimokawa //debug.log ("insert_string"); 942118455Ssimokawa // Make sure type code information for bounded strings is not erased 943118455Ssimokawa if (typeCode.kind() == TCKind.tk_string) { 944118455Ssimokawa int length = 0; 945118455Ssimokawa try { 946118455Ssimokawa length = typeCode.length(); 947118455Ssimokawa } catch (BadKind bad) { 948118455Ssimokawa throw wrapper.badkindCannotOccur() ; 949118455Ssimokawa } 950127468Ssimokawa 951127468Ssimokawa // Check if bounded strings length is not exceeded 952127468Ssimokawa if (length != 0 && s != null && s.length() > length) { 953118455Ssimokawa throw wrapper.badStringBounds( new Integer(s.length()), 954118455Ssimokawa new Integer(length) ) ; 955118455Ssimokawa } 956118455Ssimokawa } else { 957118455Ssimokawa typeCode = orb.get_primitive_tc(TCKind._tk_string); 958127468Ssimokawa } 959118455Ssimokawa object = s; 960118455Ssimokawa isInitialized = true; 961148868Srwatson } 962148868Srwatson 963118455Ssimokawa /** 964118455Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 965118455Ssimokawa */ 966118455Ssimokawa public String extract_string() 967118455Ssimokawa { 968118455Ssimokawa //debug.log ("extract_string"); 969118455Ssimokawa checkExtractBadOperation( TCKind._tk_string ) ; 970130640Sphk return (String)object; 971118455Ssimokawa } 972118455Ssimokawa 973118455Ssimokawa /** 974120624Ssimokawa * See the description of the <a href="#anyOps">general Any operations.</a> 975118455Ssimokawa */ 976118455Ssimokawa public void insert_wstring(String s) 977118455Ssimokawa { 978118455Ssimokawa //debug.log ("insert_wstring"); 979118455Ssimokawa // Make sure type code information for bounded strings is not erased 980118455Ssimokawa if (typeCode.kind() == TCKind.tk_wstring) { 981118455Ssimokawa int length = 0; 982118455Ssimokawa try { 983118455Ssimokawa length = typeCode.length(); 984118455Ssimokawa } catch (BadKind bad) { 985118455Ssimokawa throw wrapper.badkindCannotOccur() ; 986118455Ssimokawa } 987118455Ssimokawa 988118455Ssimokawa // Check if bounded strings length is not exceeded 989118455Ssimokawa if (length != 0 && s != null && s.length() > length) { 990118455Ssimokawa throw wrapper.badStringBounds( new Integer(s.length()), 991118455Ssimokawa new Integer(length) ) ; 992118455Ssimokawa } 993118455Ssimokawa } else { 994255359Sdavide typeCode = orb.get_primitive_tc(TCKind._tk_wstring); 995255359Sdavide } 996255359Sdavide object = s; 997118455Ssimokawa isInitialized = true; 998118455Ssimokawa } 999118455Ssimokawa 1000118455Ssimokawa /** 1001 * See the description of the <a href="#anyOps">general Any operations.</a> 1002 */ 1003 public String extract_wstring() 1004 { 1005 //debug.log ("extract_wstring"); 1006 checkExtractBadOperation( TCKind._tk_wstring ) ; 1007 return (String)object; 1008 } 1009 1010 /** 1011 * See the description of the <a href="#anyOps">general Any operations.</a> 1012 */ 1013 public void insert_any(Any a) 1014 { 1015 //debug.log ("insert_any"); 1016 typeCode = orb.get_primitive_tc(TCKind._tk_any); 1017 object = a; 1018 stream = null; 1019 isInitialized = true; 1020 } 1021 1022 /** 1023 * See the description of the <a href="#anyOps">general Any operations.</a> 1024 */ 1025 public Any extract_any() 1026 { 1027 //debug.log ("extract_any"); 1028 checkExtractBadOperation( TCKind._tk_any ) ; 1029 return (Any)object; 1030 } 1031 1032 /** 1033 * See the description of the <a href="#anyOps">general Any operations.</a> 1034 */ 1035 public void insert_Object(org.omg.CORBA.Object o) 1036 { 1037 //debug.log ("insert_Object"); 1038 if ( o == null ) { 1039 typeCode = orb.get_primitive_tc(TCKind._tk_objref); 1040 } else { 1041 if (StubAdapter.isStub(o)) { 1042 String[] ids = StubAdapter.getTypeIds( o ) ; 1043 typeCode = new TypeCodeImpl(orb, TCKind._tk_objref, ids[0], ""); 1044 } else { 1045 throw wrapper.badInsertobjParam( 1046 CompletionStatus.COMPLETED_MAYBE, o.getClass().getName() ) ; 1047 } 1048 } 1049 1050 object = o; 1051 isInitialized = true; 1052 } 1053 1054 /** 1055 * A variant of the insertion operation that takes a typecode 1056 * argument as well. 1057 */ 1058 public void insert_Object(org.omg.CORBA.Object o, TypeCode tc) 1059 { 1060 //debug.log ("insert_Object2"); 1061 try { 1062 if ( tc.id().equals("IDL:omg.org/CORBA/Object:1.0") || o._is_a(tc.id()) ) 1063 { 1064 typeCode = TypeCodeImpl.convertToNative(orb, tc); 1065 object = o; 1066 } 1067 else { 1068 throw wrapper.insertObjectIncompatible() ; 1069 } 1070 } catch ( Exception ex ) { 1071 throw wrapper.insertObjectFailed(ex) ; 1072 } 1073 isInitialized = true; 1074 } 1075 1076 /** 1077 * See the description of the <a href="#anyOps">general Any operations.</a> 1078 */ 1079 public org.omg.CORBA.Object extract_Object() 1080 { 1081 //debug.log ("extract_Object"); 1082 if (!isInitialized) 1083 throw wrapper.extractNotInitialized() ; 1084 1085 // Check if the object contained here is of the type in typeCode 1086 org.omg.CORBA.Object obj = null; 1087 try { 1088 obj = (org.omg.CORBA.Object) object; 1089 if (typeCode.id().equals("IDL:omg.org/CORBA/Object:1.0") || obj._is_a(typeCode.id())) { 1090 return obj; 1091 } else { 1092 throw wrapper.extractObjectIncompatible() ; 1093 } 1094 } catch ( Exception ex ) { 1095 throw wrapper.extractObjectFailed(ex); 1096 } 1097 } 1098 1099 /** 1100 * See the description of the <a href="#anyOps">general Any operations.</a> 1101 */ 1102 public void insert_TypeCode(TypeCode tc) 1103 { 1104 //debug.log ("insert_TypeCode"); 1105 typeCode = orb.get_primitive_tc(TCKind._tk_TypeCode); 1106 object = tc; 1107 isInitialized = true; 1108 } 1109 1110 /** 1111 * See the description of the <a href="#anyOps">general Any operations.</a> 1112 */ 1113 public TypeCode extract_TypeCode() 1114 { 1115 //debug.log ("extract_TypeCode"); 1116 checkExtractBadOperation( TCKind._tk_TypeCode ) ; 1117 return (TypeCode)object; 1118 } 1119 1120 /** 1121 * @deprecated 1122 */ 1123 @Deprecated 1124 public void insert_Principal(Principal p) 1125 { 1126 typeCode = orb.get_primitive_tc(TCKind._tk_Principal); 1127 object = p; 1128 isInitialized = true; 1129 } 1130 1131 /** 1132 * @deprecated 1133 */ 1134 @Deprecated 1135 public Principal extract_Principal() 1136 { 1137 checkExtractBadOperation( TCKind._tk_Principal ) ; 1138 return (Principal)object; 1139 } 1140 1141 /** 1142 * Note that the Serializable really should be an IDLEntity of 1143 * some kind. It shouldn't just be an RMI-IIOP type. Currently, 1144 * we accept and will produce RMI repIds with the latest 1145 * calculations if given a non-IDLEntity Serializable. 1146 */ 1147 public Serializable extract_Value() 1148 { 1149 //debug.log ("extract_Value"); 1150 checkExtractBadOperationList( new int[] { TCKind._tk_value, 1151 TCKind._tk_value_box, TCKind._tk_abstract_interface } ) ; 1152 return (Serializable)object; 1153 } 1154 1155 public void insert_Value(Serializable v) 1156 { 1157 //debug.log ("insert_Value"); 1158 object = v; 1159 1160 TypeCode tc; 1161 1162 if ( v == null ) { 1163 tc = orb.get_primitive_tc (TCKind.tk_value); 1164 } else { 1165 // See note in getPrimitiveTypeCodeForClass. We 1166 // have to use the latest type code fixes in this 1167 // case since there is no way to know what ORB will 1168 // actually send this Any. In RMI-IIOP, when using 1169 // Util.writeAny, we can do the versioning correctly, 1170 // and use the insert_Value(Serializable, TypeCode) 1171 // method. 1172 // 1173 // The ORB singleton uses the latest version. 1174 tc = createTypeCodeForClass (v.getClass(), (ORB)ORB.init()); 1175 } 1176 1177 typeCode = TypeCodeImpl.convertToNative(orb, tc); 1178 isInitialized = true; 1179 } 1180 1181 public void insert_Value(Serializable v, org.omg.CORBA.TypeCode t) 1182 { 1183 //debug.log ("insert_Value2"); 1184 object = v; 1185 typeCode = TypeCodeImpl.convertToNative(orb, t); 1186 isInitialized = true; 1187 } 1188 1189 public void insert_fixed(java.math.BigDecimal value) { 1190 typeCode = TypeCodeImpl.convertToNative(orb, 1191 orb.create_fixed_tc(TypeCodeImpl.digits(value), TypeCodeImpl.scale(value))); 1192 object = value; 1193 isInitialized = true; 1194 } 1195 1196 public void insert_fixed(java.math.BigDecimal value, org.omg.CORBA.TypeCode type) 1197 { 1198 try { 1199 if (TypeCodeImpl.digits(value) > type.fixed_digits() || 1200 TypeCodeImpl.scale(value) > type.fixed_scale()) 1201 { 1202 throw wrapper.fixedNotMatch() ; 1203 } 1204 } catch (org.omg.CORBA.TypeCodePackage.BadKind bk) { 1205 // type isn't even of kind fixed 1206 throw wrapper.fixedBadTypecode( bk ) ; 1207 } 1208 typeCode = TypeCodeImpl.convertToNative(orb, type); 1209 object = value; 1210 isInitialized = true; 1211 } 1212 1213 public java.math.BigDecimal extract_fixed() { 1214 checkExtractBadOperation( TCKind._tk_fixed ) ; 1215 return (BigDecimal)object; 1216 } 1217 1218 /** 1219 * Utility method for insert_Value and Util.writeAny. 1220 * 1221 * The ORB passed in should have the desired ORBVersion. It 1222 * is used to generate the type codes. 1223 */ 1224 public TypeCode createTypeCodeForClass (java.lang.Class c, ORB tcORB) 1225 { 1226 // Look in the cache first 1227 TypeCodeImpl classTC = tcORB.getTypeCodeForClass(c); 1228 if (classTC != null) 1229 return classTC; 1230 1231 // All cases need to be able to create repository IDs. 1232 // 1233 // See bug 4391648 for more info about the tcORB in this 1234 // case. 1235 RepositoryIdStrings repStrs 1236 = RepositoryIdFactory.getRepIdStringsFactory(); 1237 1238 1239 // Assertion: c instanceof Serializable? 1240 1241 if ( c.isArray() ) { 1242 // Arrays - may recurse for multi-dimensional arrays 1243 Class componentClass = c.getComponentType(); 1244 TypeCode embeddedType; 1245 if ( componentClass.isPrimitive() ) { 1246 embeddedType = getPrimitiveTypeCodeForClass(componentClass, 1247 tcORB); 1248 } else { 1249 embeddedType = createTypeCodeForClass (componentClass, 1250 tcORB); 1251 } 1252 TypeCode t = tcORB.create_sequence_tc (0, embeddedType); 1253 1254 String id = repStrs.createForJavaType(c); 1255 1256 return tcORB.create_value_box_tc (id, "Sequence", t); 1257 } else if ( c == java.lang.String.class ) { 1258 // Strings 1259 TypeCode t = tcORB.create_string_tc (0); 1260 1261 String id = repStrs.createForJavaType(c); 1262 1263 return tcORB.create_value_box_tc (id, "StringValue", t); 1264 } 1265 1266 // Anything else 1267 // We know that this is a TypeCodeImpl since it is our ORB 1268 classTC = (TypeCodeImpl)ValueUtility.createTypeCodeForClass( 1269 tcORB, c, ORBUtility.createValueHandler()); 1270 // Intruct classTC to store its buffer 1271 classTC.setCaching(true); 1272 // Update the cache 1273 tcORB.setTypeCodeForClass(c, classTC); 1274 return classTC; 1275 } 1276 1277 /** 1278 * It looks like this was copied from io.ValueUtility at some 1279 * point. 1280 * 1281 * It's used by createTypeCodeForClass. The tcORB passed in 1282 * should have the desired ORB version, and is used to 1283 * create the type codes. 1284 */ 1285 private TypeCode getPrimitiveTypeCodeForClass (Class c, ORB tcORB) 1286 { 1287 //debug.log ("getPrimitiveTypeCodeForClass"); 1288 1289 if (c == Integer.TYPE) { 1290 return tcORB.get_primitive_tc (TCKind.tk_long); 1291 } else if (c == Byte.TYPE) { 1292 return tcORB.get_primitive_tc (TCKind.tk_octet); 1293 } else if (c == Long.TYPE) { 1294 return tcORB.get_primitive_tc (TCKind.tk_longlong); 1295 } else if (c == Float.TYPE) { 1296 return tcORB.get_primitive_tc (TCKind.tk_float); 1297 } else if (c == Double.TYPE) { 1298 return tcORB.get_primitive_tc (TCKind.tk_double); 1299 } else if (c == Short.TYPE) { 1300 return tcORB.get_primitive_tc (TCKind.tk_short); 1301 } else if (c == Character.TYPE) { 1302 // For Merlin or later JDKs, or for foreign ORBs, 1303 // we correctly say that a Java char maps to a 1304 // CORBA wchar. For backwards compatibility 1305 // with our older ORBs, we say it maps to a 1306 // CORBA char. This is only used in RMI-IIOP 1307 // in our javax.rmi.CORBA.Util delegate's 1308 // writeAny method. In Java IDL, there's no way 1309 // to know the ORB version that the Any will be 1310 // sent out with -- it could be different than 1311 // the one used to create the Any -- so we use the 1312 // most recent version (see insert_Value). 1313 if (ORBVersionFactory.getFOREIGN().compareTo(tcORB.getORBVersion()) == 0 || 1314 ORBVersionFactory.getNEWER().compareTo(tcORB.getORBVersion()) <= 0) 1315 return tcORB.get_primitive_tc(TCKind.tk_wchar); 1316 else 1317 return tcORB.get_primitive_tc(TCKind.tk_char); 1318 } else if (c == Boolean.TYPE) { 1319 return tcORB.get_primitive_tc (TCKind.tk_boolean); 1320 } else { 1321 // _REVISIT_ Not sure if this is right. 1322 return tcORB.get_primitive_tc (TCKind.tk_any); 1323 } 1324 } 1325 1326 // Extracts a member value according to the given TypeCode from the given complex Any 1327 // (at the Anys current internal stream position, consuming the anys stream on the way) 1328 // and returns it wrapped into a new Any 1329 public Any extractAny(TypeCode memberType, ORB orb) { 1330 Any returnValue = orb.create_any(); 1331 OutputStream out = returnValue.create_output_stream(); 1332 TypeCodeImpl.convertToNative(orb, memberType).copy((InputStream)stream, out); 1333 returnValue.read_value(out.create_input_stream(), memberType); 1334 return returnValue; 1335 } 1336 1337 // This method could very well be moved into TypeCodeImpl or a common utility class, 1338 // but is has to be in this package. 1339 static public Any extractAnyFromStream(TypeCode memberType, InputStream input, ORB orb) { 1340 Any returnValue = orb.create_any(); 1341 OutputStream out = returnValue.create_output_stream(); 1342 TypeCodeImpl.convertToNative(orb, memberType).copy(input, out); 1343 returnValue.read_value(out.create_input_stream(), memberType); 1344 return returnValue; 1345 } 1346 1347 // There is no other way for DynAnys to find out whether the Any is initialized. 1348 public boolean isInitialized() { 1349 return isInitialized; 1350 } 1351} 1352