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