src/share/classes/com/sun/corba/se/impl/corba/TypeCodeImpl.java

Thu, 31 Aug 2017 18:10:36 +0800

author
aoqi
date
Thu, 31 Aug 2017 18:10:36 +0800
changeset 748
6845b95cba6b
parent 478
80161c61aa68
parent 0
7ef37b2cdcad
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.corba.se.impl.corba;
aoqi@0 27
aoqi@0 28 import java.util.HashMap;
aoqi@0 29 import java.util.Map;
aoqi@0 30 import java.util.Iterator;
aoqi@0 31 import java.util.List;
aoqi@0 32 import java.util.Collections;
aoqi@0 33 import java.util.ArrayList;
aoqi@0 34 import java.io.IOException;
aoqi@0 35 import java.io.PrintStream;
aoqi@0 36 import java.io.ByteArrayOutputStream;
aoqi@0 37 import java.math.BigDecimal;
aoqi@0 38 import java.math.BigInteger;
aoqi@0 39
aoqi@0 40 import org.omg.CORBA.TypeCode ;
aoqi@0 41 import org.omg.CORBA.StructMember ;
aoqi@0 42 import org.omg.CORBA.UnionMember ;
aoqi@0 43 import org.omg.CORBA.ValueMember ;
aoqi@0 44 import org.omg.CORBA.TCKind ;
aoqi@0 45 import org.omg.CORBA.Any ;
aoqi@0 46 import org.omg.CORBA.Principal ;
aoqi@0 47 import org.omg.CORBA.BAD_TYPECODE ;
aoqi@0 48 import org.omg.CORBA.BAD_PARAM ;
aoqi@0 49 import org.omg.CORBA.BAD_OPERATION ;
aoqi@0 50 import org.omg.CORBA.INTERNAL ;
aoqi@0 51 import org.omg.CORBA.MARSHAL ;
aoqi@0 52 import org.omg.CORBA.TypeCodePackage.BadKind ;
aoqi@0 53 import org.omg.CORBA_2_3.portable.InputStream;
aoqi@0 54 import org.omg.CORBA_2_3.portable.OutputStream;
aoqi@0 55
aoqi@0 56 import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
aoqi@0 57 import com.sun.corba.se.spi.orb.ORB;
aoqi@0 58 import com.sun.corba.se.spi.logging.CORBALogDomains;
aoqi@0 59
aoqi@0 60 import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
aoqi@0 61 import com.sun.corba.se.impl.encoding.MarshalInputStream;
aoqi@0 62 import com.sun.corba.se.impl.encoding.CodeSetConversion;
aoqi@0 63 import com.sun.corba.se.impl.encoding.CDRInputStream;
aoqi@0 64 import com.sun.corba.se.impl.encoding.CDROutputStream;
aoqi@0 65 import com.sun.corba.se.impl.encoding.TypeCodeInputStream;
aoqi@0 66 import com.sun.corba.se.impl.encoding.TypeCodeOutputStream;
aoqi@0 67 import com.sun.corba.se.impl.encoding.TypeCodeReader;
aoqi@0 68 import com.sun.corba.se.impl.encoding.WrapperInputStream;
aoqi@0 69
aoqi@0 70 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
aoqi@0 71
aoqi@0 72 // no chance of subclasses, so no problems with runtime helper lookup
aoqi@0 73 public final class TypeCodeImpl extends TypeCode
aoqi@0 74 {
aoqi@0 75 //static final boolean debug = false;
aoqi@0 76
aoqi@0 77 // the indirection TCKind, needed for recursive typecodes.
aoqi@0 78 protected static final int tk_indirect = 0xFFFFFFFF;
aoqi@0 79
aoqi@0 80 // typecode encodings have three different categories that determine
aoqi@0 81 // how the encoding should be done.
aoqi@0 82
aoqi@0 83 private static final int EMPTY = 0; // no parameters
aoqi@0 84 private static final int SIMPLE = 1; // simple parameters.
aoqi@0 85 private static final int COMPLEX = 2; // complex parameters. need to
aoqi@0 86 // use CDR encapsulation for
aoqi@0 87 // parameters
aoqi@0 88
aoqi@0 89 // a table storing the encoding category for the various typecodes.
aoqi@0 90
aoqi@0 91 private static final int typeTable[] = {
aoqi@0 92 EMPTY, // tk_null
aoqi@0 93 EMPTY, // tk_void
aoqi@0 94 EMPTY, // tk_short
aoqi@0 95 EMPTY, // tk_long
aoqi@0 96 EMPTY, // tk_ushort
aoqi@0 97 EMPTY, // tk_ulong
aoqi@0 98 EMPTY, // tk_float
aoqi@0 99 EMPTY, // tk_double
aoqi@0 100 EMPTY, // tk_boolean
aoqi@0 101 EMPTY, // tk_char
aoqi@0 102 EMPTY, // tk_octet
aoqi@0 103 EMPTY, // tk_any
aoqi@0 104 EMPTY, // tk_typecode
aoqi@0 105 EMPTY, // tk_principal
aoqi@0 106 COMPLEX, // tk_objref
aoqi@0 107 COMPLEX, // tk_struct
aoqi@0 108 COMPLEX, // tk_union
aoqi@0 109 COMPLEX, // tk_enum
aoqi@0 110 SIMPLE, // tk_string
aoqi@0 111 COMPLEX, // tk_sequence
aoqi@0 112 COMPLEX, // tk_array
aoqi@0 113 COMPLEX, // tk_alias
aoqi@0 114 COMPLEX, // tk_except
aoqi@0 115 EMPTY, // tk_longlong
aoqi@0 116 EMPTY, // tk_ulonglong
aoqi@0 117 EMPTY, // tk_longdouble
aoqi@0 118 EMPTY, // tk_wchar
aoqi@0 119 SIMPLE, // tk_wstring
aoqi@0 120 SIMPLE, // tk_fixed
aoqi@0 121 COMPLEX, // tk_value
aoqi@0 122 COMPLEX, // tk_value_box
aoqi@0 123 COMPLEX, // tk_native
aoqi@0 124 COMPLEX // tk_abstract_interface
aoqi@0 125 };
aoqi@0 126
aoqi@0 127 // Maps TCKind values to names
aoqi@0 128 // This is also used in AnyImpl.
aoqi@0 129 static final String[] kindNames = {
aoqi@0 130 "null",
aoqi@0 131 "void",
aoqi@0 132 "short",
aoqi@0 133 "long",
aoqi@0 134 "ushort",
aoqi@0 135 "ulong",
aoqi@0 136 "float",
aoqi@0 137 "double",
aoqi@0 138 "boolean",
aoqi@0 139 "char",
aoqi@0 140 "octet",
aoqi@0 141 "any",
aoqi@0 142 "typecode",
aoqi@0 143 "principal",
aoqi@0 144 "objref",
aoqi@0 145 "struct",
aoqi@0 146 "union",
aoqi@0 147 "enum",
aoqi@0 148 "string",
aoqi@0 149 "sequence",
aoqi@0 150 "array",
aoqi@0 151 "alias",
aoqi@0 152 "exception",
aoqi@0 153 "longlong",
aoqi@0 154 "ulonglong",
aoqi@0 155 "longdouble",
aoqi@0 156 "wchar",
aoqi@0 157 "wstring",
aoqi@0 158 "fixed",
aoqi@0 159 "value",
aoqi@0 160 "valueBox",
aoqi@0 161 "native",
aoqi@0 162 "abstractInterface"
aoqi@0 163 };
aoqi@0 164
aoqi@0 165 private int _kind = 0; // the typecode kind
aoqi@0 166
aoqi@0 167 // data members for representing the various kinds of typecodes.
aoqi@0 168 private String _id = ""; // the typecode repository id
aoqi@0 169 private String _name = ""; // the typecode name
aoqi@0 170 private int _memberCount = 0; // member count
aoqi@0 171 private String _memberNames[] = null; // names of members
aoqi@0 172 private TypeCodeImpl _memberTypes[] = null; // types of members
aoqi@0 173 private AnyImpl _unionLabels[] = null; // values of union labels
aoqi@0 174 private TypeCodeImpl _discriminator = null; // union discriminator type
aoqi@0 175 private int _defaultIndex = -1; // union default index
aoqi@0 176 private int _length = 0; // string/seq/array length
aoqi@0 177 private TypeCodeImpl _contentType = null; // seq/array/alias type
aoqi@0 178 // fixed
aoqi@0 179 private short _digits = 0;
aoqi@0 180 private short _scale = 0;
aoqi@0 181 // value type
aoqi@0 182 // _REVISIT_ We might want to keep references to the ValueMember classes
aoqi@0 183 // passed in at initialization instead of copying the relevant data.
aoqi@0 184 // Is the data immutable? What about StructMember, UnionMember etc.?
aoqi@0 185 private short _type_modifier = -1; // VM_NONE, VM_CUSTOM,
aoqi@0 186 // VM_ABSTRACT, VM_TRUNCATABLE
aoqi@0 187 private TypeCodeImpl _concrete_base = null; // concrete base type
aoqi@0 188 private short _memberAccess[] = null; // visibility of ValueMember
aoqi@0 189 // recursive sequence support
aoqi@0 190 private TypeCodeImpl _parent = null; // the enclosing type code
aoqi@0 191 private int _parentOffset = 0; // the level of enclosure
aoqi@0 192 // recursive type code support
aoqi@0 193 private TypeCodeImpl _indirectType = null;
aoqi@0 194
aoqi@0 195 // caches the byte buffer written in write_value for quick remarshaling...
aoqi@0 196 private byte[] outBuffer = null;
aoqi@0 197 // ... but only if caching is enabled
aoqi@0 198 private boolean cachingEnabled = false;
aoqi@0 199
aoqi@0 200 // the ORB instance: may be instanceof ORBSingleton or ORB
aoqi@0 201 private ORB _orb;
aoqi@0 202 private ORBUtilSystemException wrapper ;
aoqi@0 203
aoqi@0 204 ///////////////////////////////////////////////////////////////////////////
aoqi@0 205 // Constructors...
aoqi@0 206
aoqi@0 207 public TypeCodeImpl(ORB orb)
aoqi@0 208 {
aoqi@0 209 // initialized to tk_null
aoqi@0 210 _orb = orb;
aoqi@0 211 wrapper = ORBUtilSystemException.get(
aoqi@0 212 (com.sun.corba.se.spi.orb.ORB)orb, CORBALogDomains.RPC_PRESENTATION ) ;
aoqi@0 213 }
aoqi@0 214
aoqi@0 215 public TypeCodeImpl(ORB orb, TypeCode tc)
aoqi@0 216 // to handle conversion of "remote" typecodes into "native" style.
aoqi@0 217 // also see the 'convertToNative(ORB orb, TypeCode tc)' function
aoqi@0 218 {
aoqi@0 219 this(orb) ;
aoqi@0 220
aoqi@0 221 // This is a protection against misuse of this constructor.
aoqi@0 222 // Should only be used if tc is not an instance of this class!
aoqi@0 223 // Otherwise we run into problems with recursive/indirect type codes.
aoqi@0 224 // _REVISIT_ We should make this constructor private
aoqi@0 225 if (tc instanceof TypeCodeImpl) {
aoqi@0 226 TypeCodeImpl tci = (TypeCodeImpl)tc;
aoqi@0 227 if (tci._kind == tk_indirect)
aoqi@0 228 throw wrapper.badRemoteTypecode() ;
aoqi@0 229 if (tci._kind == TCKind._tk_sequence && tci._contentType == null)
aoqi@0 230 throw wrapper.badRemoteTypecode() ;
aoqi@0 231 }
aoqi@0 232
aoqi@0 233 // set up kind
aoqi@0 234 _kind = tc.kind().value();
aoqi@0 235
aoqi@0 236 try {
aoqi@0 237 // set up parameters
aoqi@0 238 switch (_kind) {
aoqi@0 239 case TCKind._tk_value:
aoqi@0 240 _type_modifier = tc.type_modifier();
aoqi@0 241 // concrete base may be null
aoqi@0 242 TypeCode tccb = tc.concrete_base_type();
aoqi@0 243 if (tccb != null) {
aoqi@0 244 _concrete_base = convertToNative(_orb, tccb);
aoqi@0 245 } else {
aoqi@0 246 _concrete_base = null;
aoqi@0 247 }
aoqi@0 248 //_memberAccess = tc._memberAccess;
aoqi@0 249 // Need to reconstruct _memberAccess using member_count() and member_visibility()
aoqi@0 250 _memberAccess = new short[tc.member_count()];
aoqi@0 251 for (int i=0; i < tc.member_count(); i++) {
aoqi@0 252 _memberAccess[i] = tc.member_visibility(i);
aoqi@0 253 }
aoqi@0 254 case TCKind._tk_except:
aoqi@0 255 case TCKind._tk_struct:
aoqi@0 256 case TCKind._tk_union:
aoqi@0 257 // set up member types
aoqi@0 258 _memberTypes = new TypeCodeImpl[tc.member_count()];
aoqi@0 259 for (int i=0; i < tc.member_count(); i++) {
aoqi@0 260 _memberTypes[i] = convertToNative(_orb, tc.member_type(i));
aoqi@0 261 _memberTypes[i].setParent(this);
aoqi@0 262 }
aoqi@0 263 case TCKind._tk_enum:
aoqi@0 264 // set up member names
aoqi@0 265 _memberNames = new String[tc.member_count()];
aoqi@0 266 for (int i=0; i < tc.member_count(); i++) {
aoqi@0 267 _memberNames[i] = tc.member_name(i);
aoqi@0 268 }
aoqi@0 269 // set up member count
aoqi@0 270 _memberCount = tc.member_count();
aoqi@0 271 case TCKind._tk_objref:
aoqi@0 272 case TCKind._tk_alias:
aoqi@0 273 case TCKind._tk_value_box:
aoqi@0 274 case TCKind._tk_native:
aoqi@0 275 case TCKind._tk_abstract_interface:
aoqi@0 276 setId(tc.id());
aoqi@0 277 _name = tc.name();
aoqi@0 278 break;
aoqi@0 279 }
aoqi@0 280
aoqi@0 281 // set up stuff for unions
aoqi@0 282 switch (_kind) {
aoqi@0 283 case TCKind._tk_union:
aoqi@0 284 _discriminator = convertToNative(_orb, tc.discriminator_type());
aoqi@0 285 _defaultIndex = tc.default_index();
aoqi@0 286 _unionLabels = new AnyImpl[_memberCount];
aoqi@0 287 for (int i=0; i < _memberCount; i++)
aoqi@0 288 _unionLabels[i] = new AnyImpl(_orb, tc.member_label(i));
aoqi@0 289 break;
aoqi@0 290 }
aoqi@0 291
aoqi@0 292 // set up length
aoqi@0 293 switch (_kind) {
aoqi@0 294 case TCKind._tk_string:
aoqi@0 295 case TCKind._tk_wstring:
aoqi@0 296 case TCKind._tk_sequence:
aoqi@0 297 case TCKind._tk_array:
aoqi@0 298 _length = tc.length();
aoqi@0 299 }
aoqi@0 300
aoqi@0 301 // set up content type
aoqi@0 302 switch (_kind) {
aoqi@0 303 case TCKind._tk_sequence:
aoqi@0 304 case TCKind._tk_array:
aoqi@0 305 case TCKind._tk_alias:
aoqi@0 306 case TCKind._tk_value_box:
aoqi@0 307 _contentType = convertToNative(_orb, tc.content_type());
aoqi@0 308 }
aoqi@0 309 } catch (org.omg.CORBA.TypeCodePackage.Bounds e) {} catch (BadKind e) {}
aoqi@0 310 // dont have to worry about these since code ensures we dont step
aoqi@0 311 // out of bounds.
aoqi@0 312 }
aoqi@0 313
aoqi@0 314 public TypeCodeImpl(ORB orb, int creationKind)
aoqi@0 315 // for primitive types
aoqi@0 316 {
aoqi@0 317 this(orb);
aoqi@0 318
aoqi@0 319 // private API. dont bother checking that
aoqi@0 320 // (creationKind < 0 || creationKind > typeTable.length)
aoqi@0 321
aoqi@0 322 _kind = creationKind;
aoqi@0 323
aoqi@0 324 // do initialization for special cases
aoqi@0 325 switch (_kind) {
aoqi@0 326 case TCKind._tk_objref:
aoqi@0 327 {
aoqi@0 328 // this is being used to create typecode for CORBA::Object
aoqi@0 329 setId("IDL:omg.org/CORBA/Object:1.0");
aoqi@0 330 _name = "Object";
aoqi@0 331 break;
aoqi@0 332 }
aoqi@0 333
aoqi@0 334 case TCKind._tk_string:
aoqi@0 335 case TCKind._tk_wstring:
aoqi@0 336 {
aoqi@0 337 _length =0;
aoqi@0 338 break;
aoqi@0 339 }
aoqi@0 340
aoqi@0 341 case TCKind._tk_value:
aoqi@0 342 {
aoqi@0 343 _concrete_base = null;
aoqi@0 344 break;
aoqi@0 345 }
aoqi@0 346 }
aoqi@0 347 }
aoqi@0 348
aoqi@0 349 public TypeCodeImpl(ORB orb,
aoqi@0 350 int creationKind,
aoqi@0 351 String id,
aoqi@0 352 String name,
aoqi@0 353 StructMember[] members)
aoqi@0 354 // for structs and exceptions
aoqi@0 355 {
aoqi@0 356 this(orb);
aoqi@0 357
aoqi@0 358 if ((creationKind == TCKind._tk_struct) || (creationKind == TCKind._tk_except)) {
aoqi@0 359 _kind = creationKind;
aoqi@0 360 setId(id);
aoqi@0 361 _name = name;
aoqi@0 362 _memberCount = members.length;
aoqi@0 363
aoqi@0 364 _memberNames = new String[_memberCount];
aoqi@0 365 _memberTypes = new TypeCodeImpl[_memberCount];
aoqi@0 366
aoqi@0 367 for (int i = 0 ; i < _memberCount ; i++) {
aoqi@0 368 _memberNames[i] = members[i].name;
aoqi@0 369 _memberTypes[i] = convertToNative(_orb, members[i].type);
aoqi@0 370 _memberTypes[i].setParent(this);
aoqi@0 371 }
aoqi@0 372 } // else initializes to null
aoqi@0 373 }
aoqi@0 374
aoqi@0 375 public TypeCodeImpl(ORB orb,
aoqi@0 376 int creationKind,
aoqi@0 377 String id,
aoqi@0 378 String name,
aoqi@0 379 TypeCode discriminator_type,
aoqi@0 380 UnionMember[] members)
aoqi@0 381 // for unions
aoqi@0 382 {
aoqi@0 383 this(orb) ;
aoqi@0 384
aoqi@0 385 if (creationKind == TCKind._tk_union) {
aoqi@0 386 _kind = creationKind;
aoqi@0 387 setId(id);
aoqi@0 388 _name = name;
aoqi@0 389 _memberCount = members.length;
aoqi@0 390 _discriminator = convertToNative(_orb, discriminator_type);
aoqi@0 391
aoqi@0 392 _memberNames = new String[_memberCount];
aoqi@0 393 _memberTypes = new TypeCodeImpl[_memberCount];
aoqi@0 394 _unionLabels = new AnyImpl[_memberCount];
aoqi@0 395
aoqi@0 396 for (int i = 0 ; i < _memberCount ; i++) {
aoqi@0 397 _memberNames[i] = members[i].name;
aoqi@0 398 _memberTypes[i] = convertToNative(_orb, members[i].type);
aoqi@0 399 _memberTypes[i].setParent(this);
aoqi@0 400 _unionLabels[i] = new AnyImpl(_orb, members[i].label);
aoqi@0 401 // check whether this is the default branch.
aoqi@0 402 if (_unionLabels[i].type().kind() == TCKind.tk_octet) {
aoqi@0 403 if (_unionLabels[i].extract_octet() == (byte)0) {
aoqi@0 404 _defaultIndex = i;
aoqi@0 405 }
aoqi@0 406 }
aoqi@0 407 }
aoqi@0 408 } // else initializes to null
aoqi@0 409 }
aoqi@0 410
aoqi@0 411 public TypeCodeImpl(ORB orb,
aoqi@0 412 int creationKind,
aoqi@0 413 String id,
aoqi@0 414 String name,
aoqi@0 415 short type_modifier,
aoqi@0 416 TypeCode concrete_base,
aoqi@0 417 ValueMember[] members)
aoqi@0 418 // for value types
aoqi@0 419 {
aoqi@0 420 this(orb) ;
aoqi@0 421
aoqi@0 422 if (creationKind == TCKind._tk_value) {
aoqi@0 423 _kind = creationKind;
aoqi@0 424 setId(id);
aoqi@0 425 _name = name;
aoqi@0 426 _type_modifier = type_modifier;
aoqi@0 427 if (concrete_base != null) {
aoqi@0 428 _concrete_base = convertToNative(_orb, concrete_base);
aoqi@0 429 }
aoqi@0 430 _memberCount = members.length;
aoqi@0 431
aoqi@0 432 _memberNames = new String[_memberCount];
aoqi@0 433 _memberTypes = new TypeCodeImpl[_memberCount];
aoqi@0 434 _memberAccess = new short[_memberCount];
aoqi@0 435
aoqi@0 436 for (int i = 0 ; i < _memberCount ; i++) {
aoqi@0 437 _memberNames[i] = members[i].name;
aoqi@0 438 _memberTypes[i] = convertToNative(_orb, members[i].type);
aoqi@0 439 _memberTypes[i].setParent(this);
aoqi@0 440 _memberAccess[i] = members[i].access;
aoqi@0 441 }
aoqi@0 442 } // else initializes to null
aoqi@0 443 }
aoqi@0 444
aoqi@0 445
aoqi@0 446 public TypeCodeImpl(ORB orb,
aoqi@0 447 int creationKind,
aoqi@0 448 String id,
aoqi@0 449 String name,
aoqi@0 450 String[] members)
aoqi@0 451 // for enums
aoqi@0 452 {
aoqi@0 453 this(orb) ;
aoqi@0 454
aoqi@0 455 if (creationKind == TCKind._tk_enum)
aoqi@0 456 {
aoqi@0 457 _kind = creationKind;
aoqi@0 458 setId(id);
aoqi@0 459 _name = name;
aoqi@0 460 _memberCount = members.length;
aoqi@0 461
aoqi@0 462 _memberNames = new String[_memberCount];
aoqi@0 463
aoqi@0 464 for (int i = 0 ; i < _memberCount ; i++)
aoqi@0 465 _memberNames[i] = members[i];
aoqi@0 466 } // else initializes to null
aoqi@0 467 }
aoqi@0 468
aoqi@0 469 public TypeCodeImpl(ORB orb,
aoqi@0 470 int creationKind,
aoqi@0 471 String id,
aoqi@0 472 String name,
aoqi@0 473 TypeCode original_type)
aoqi@0 474 // for aliases and value boxes
aoqi@0 475 {
aoqi@0 476 this(orb) ;
aoqi@0 477
aoqi@0 478 if ( creationKind == TCKind._tk_alias || creationKind == TCKind._tk_value_box )
aoqi@0 479 {
aoqi@0 480 _kind = creationKind;
aoqi@0 481 setId(id);
aoqi@0 482 _name = name;
aoqi@0 483 _contentType = convertToNative(_orb, original_type);
aoqi@0 484 }
aoqi@0 485 // else initializes to null
aoqi@0 486
aoqi@0 487 }
aoqi@0 488
aoqi@0 489 public TypeCodeImpl(ORB orb,
aoqi@0 490 int creationKind,
aoqi@0 491 String id,
aoqi@0 492 String name)
aoqi@0 493 {
aoqi@0 494 this(orb) ;
aoqi@0 495
aoqi@0 496 if (creationKind == TCKind._tk_objref ||
aoqi@0 497 creationKind == TCKind._tk_native ||
aoqi@0 498 creationKind == TCKind._tk_abstract_interface)
aoqi@0 499 {
aoqi@0 500 _kind = creationKind;
aoqi@0 501 setId(id);
aoqi@0 502 _name = name;
aoqi@0 503 } // else initializes to null
aoqi@0 504 }
aoqi@0 505
aoqi@0 506
aoqi@0 507 public TypeCodeImpl(ORB orb,
aoqi@0 508 int creationKind,
aoqi@0 509 int bound)
aoqi@0 510 // for strings
aoqi@0 511 {
aoqi@0 512 this(orb) ;
aoqi@0 513
aoqi@0 514 if (bound < 0)
aoqi@0 515 throw wrapper.negativeBounds() ;
aoqi@0 516
aoqi@0 517 if ((creationKind == TCKind._tk_string) || (creationKind == TCKind._tk_wstring)) {
aoqi@0 518 _kind = creationKind;
aoqi@0 519 _length = bound;
aoqi@0 520 } // else initializes to null
aoqi@0 521 }
aoqi@0 522
aoqi@0 523 public TypeCodeImpl(ORB orb,
aoqi@0 524 int creationKind,
aoqi@0 525 int bound,
aoqi@0 526 TypeCode element_type)
aoqi@0 527 // for sequences and arrays
aoqi@0 528 {
aoqi@0 529 this(orb) ;
aoqi@0 530
aoqi@0 531 if ( creationKind == TCKind._tk_sequence || creationKind == TCKind._tk_array ) {
aoqi@0 532 _kind = creationKind;
aoqi@0 533 _length = bound;
aoqi@0 534 _contentType = convertToNative(_orb, element_type);
aoqi@0 535 } // else initializes to null
aoqi@0 536 }
aoqi@0 537
aoqi@0 538 public TypeCodeImpl(ORB orb,
aoqi@0 539 int creationKind,
aoqi@0 540 int bound,
aoqi@0 541 int offset)
aoqi@0 542 // for recursive sequences
aoqi@0 543 {
aoqi@0 544 this(orb) ;
aoqi@0 545
aoqi@0 546 if (creationKind == TCKind._tk_sequence) {
aoqi@0 547 _kind = creationKind;
aoqi@0 548 _length = bound;
aoqi@0 549 _parentOffset = offset;
aoqi@0 550 } // else initializes to null
aoqi@0 551 }
aoqi@0 552
aoqi@0 553 public TypeCodeImpl(ORB orb,
aoqi@0 554 String id)
aoqi@0 555 // for recursive type codes
aoqi@0 556 {
aoqi@0 557 this(orb) ;
aoqi@0 558
aoqi@0 559 _kind = tk_indirect;
aoqi@0 560 // This is the type code of the type we stand in for, not our own.
aoqi@0 561 _id = id;
aoqi@0 562 // Try to resolve it now. May return null in which case
aoqi@0 563 // we try again later (see indirectType()).
aoqi@0 564 tryIndirectType();
aoqi@0 565 }
aoqi@0 566
aoqi@0 567 public TypeCodeImpl(ORB orb,
aoqi@0 568 int creationKind,
aoqi@0 569 short digits,
aoqi@0 570 short scale)
aoqi@0 571 // for fixed
aoqi@0 572 {
aoqi@0 573 this(orb) ;
aoqi@0 574
aoqi@0 575 //if (digits < 1 || digits > 31)
aoqi@0 576 //throw new BAD_TYPECODE();
aoqi@0 577
aoqi@0 578 if (creationKind == TCKind._tk_fixed) {
aoqi@0 579 _kind = creationKind;
aoqi@0 580 _digits = digits;
aoqi@0 581 _scale = scale;
aoqi@0 582 } // else initializes to null
aoqi@0 583 }
aoqi@0 584
aoqi@0 585 ///////////////////////////////////////////////////////////////////////////
aoqi@0 586 // Other creation functions...
aoqi@0 587
aoqi@0 588 // Optimization:
aoqi@0 589 // If we checked for and returned constant primitive typecodes
aoqi@0 590 // here we could reduce object creation and also enable more
aoqi@0 591 // efficient typecode comparisons for primitive typecodes.
aoqi@0 592 //
aoqi@0 593 protected static TypeCodeImpl convertToNative(ORB orb,
aoqi@0 594 TypeCode tc)
aoqi@0 595 {
aoqi@0 596 if (tc instanceof TypeCodeImpl)
aoqi@0 597 return (TypeCodeImpl) tc;
aoqi@0 598 else
aoqi@0 599 return new TypeCodeImpl(orb, tc);
aoqi@0 600 }
aoqi@0 601
aoqi@0 602 public static CDROutputStream newOutputStream(ORB orb) {
aoqi@0 603 TypeCodeOutputStream tcos =
aoqi@0 604 sun.corba.OutputStreamFactory.newTypeCodeOutputStream(orb);
aoqi@0 605 //if (debug) System.out.println("Created TypeCodeOutputStream " + tcos +
aoqi@0 606 // " with no parent");
aoqi@0 607 return tcos;
aoqi@0 608 }
aoqi@0 609
aoqi@0 610 // Support for indirect/recursive type codes
aoqi@0 611
aoqi@0 612 private TypeCodeImpl indirectType() {
aoqi@0 613 _indirectType = tryIndirectType();
aoqi@0 614 if (_indirectType == null) {
aoqi@0 615 // Nothing we can do about that.
aoqi@0 616 throw wrapper.unresolvedRecursiveTypecode() ;
aoqi@0 617 }
aoqi@0 618 return _indirectType;
aoqi@0 619 }
aoqi@0 620
aoqi@0 621 private TypeCodeImpl tryIndirectType() {
aoqi@0 622 // Assert that _kind == tk_indirect
aoqi@0 623 if (_indirectType != null)
aoqi@0 624 return _indirectType;
aoqi@0 625
aoqi@0 626 setIndirectType(_orb.getTypeCode(_id));
aoqi@0 627
aoqi@0 628 return _indirectType;
aoqi@0 629 }
aoqi@0 630
aoqi@0 631 private void setIndirectType(TypeCodeImpl newType) {
aoqi@0 632 _indirectType = newType;
aoqi@0 633 if (_indirectType != null) {
aoqi@0 634 try {
aoqi@0 635 _id = _indirectType.id();
aoqi@0 636 } catch (BadKind e) {
aoqi@0 637 // can't happen
aoqi@0 638 throw wrapper.badkindCannotOccur() ;
aoqi@0 639 }
aoqi@0 640 }
aoqi@0 641 }
aoqi@0 642
aoqi@0 643 private void setId(String newID) {
aoqi@0 644 _id = newID;
aoqi@0 645 if (_orb instanceof TypeCodeFactory) {
aoqi@0 646 ((TypeCodeFactory)_orb).setTypeCode(_id, this);
aoqi@0 647 }
aoqi@0 648 // check whether return value != this which would indicate that the
aoqi@0 649 // repository id isn't unique.
aoqi@0 650 }
aoqi@0 651
aoqi@0 652 private void setParent(TypeCodeImpl parent) {
aoqi@0 653 _parent = parent;
aoqi@0 654 }
aoqi@0 655
aoqi@0 656 private TypeCodeImpl getParentAtLevel(int level) {
aoqi@0 657 if (level == 0)
aoqi@0 658 return this;
aoqi@0 659
aoqi@0 660 if (_parent == null)
aoqi@0 661 throw wrapper.unresolvedRecursiveTypecode() ;
aoqi@0 662
aoqi@0 663 return _parent.getParentAtLevel(level - 1);
aoqi@0 664 }
aoqi@0 665
aoqi@0 666 private TypeCodeImpl lazy_content_type() {
aoqi@0 667 if (_contentType == null) {
aoqi@0 668 if (_kind == TCKind._tk_sequence && _parentOffset > 0 && _parent != null) {
aoqi@0 669 // This is an unresolved recursive sequence tc.
aoqi@0 670 // Try to resolve it now if the hierarchy is complete.
aoqi@0 671 TypeCodeImpl realParent = getParentAtLevel(_parentOffset);
aoqi@0 672 if (realParent != null && realParent._id != null) {
aoqi@0 673 // Create a recursive type code object as the content type.
aoqi@0 674 // This is when the recursive sequence typecode morphes
aoqi@0 675 // into a sequence typecode containing a recursive typecode.
aoqi@0 676 _contentType = new TypeCodeImpl((ORB)_orb, realParent._id);
aoqi@0 677 }
aoqi@0 678 }
aoqi@0 679 }
aoqi@0 680 return _contentType;
aoqi@0 681 }
aoqi@0 682
aoqi@0 683 // Other private functions
aoqi@0 684
aoqi@0 685 private TypeCode realType(TypeCode aType) {
aoqi@0 686 TypeCode realType = aType;
aoqi@0 687 try {
aoqi@0 688 // Note: Indirect types are handled in kind() method
aoqi@0 689 while (realType.kind().value() == TCKind._tk_alias) {
aoqi@0 690 realType = realType.content_type();
aoqi@0 691 }
aoqi@0 692 } catch (BadKind bad) {
aoqi@0 693 // impossible
aoqi@0 694 throw wrapper.badkindCannotOccur() ;
aoqi@0 695 }
aoqi@0 696 return realType;
aoqi@0 697 }
aoqi@0 698
aoqi@0 699 ///////////////////////////////////////////////////////////////////////////
aoqi@0 700 // TypeCode operations
aoqi@0 701
aoqi@0 702 public final boolean equal(TypeCode tc)
aoqi@0 703 // _REVISIT_ for all optional names/ids, we might want to check that
aoqi@0 704 // they are equal in case both are non-nil.
aoqi@0 705 {
aoqi@0 706 if (tc == this)
aoqi@0 707 return true;
aoqi@0 708
aoqi@0 709 try {
aoqi@0 710
aoqi@0 711 if (_kind == tk_indirect) {
aoqi@0 712 //return indirectType().equal(tc);
aoqi@0 713 if (_id != null && tc.id() != null)
aoqi@0 714 return _id.equals(tc.id());
aoqi@0 715 return (_id == null && tc.id() == null);
aoqi@0 716 }
aoqi@0 717
aoqi@0 718 // make sure kinds are identical.
aoqi@0 719 if (_kind != tc.kind().value()) {
aoqi@0 720 return false;
aoqi@0 721 }
aoqi@0 722
aoqi@0 723 switch (typeTable[_kind]) {
aoqi@0 724 case EMPTY:
aoqi@0 725 // no parameters to check.
aoqi@0 726 return true;
aoqi@0 727
aoqi@0 728 case SIMPLE:
aoqi@0 729 switch (_kind) {
aoqi@0 730 case TCKind._tk_string:
aoqi@0 731 case TCKind._tk_wstring:
aoqi@0 732 // check for bound.
aoqi@0 733 return (_length == tc.length());
aoqi@0 734
aoqi@0 735 case TCKind._tk_fixed:
aoqi@0 736 return (_digits == tc.fixed_digits() && _scale == tc.fixed_scale());
aoqi@0 737 default:
aoqi@0 738 return false;
aoqi@0 739 }
aoqi@0 740
aoqi@0 741 case COMPLEX:
aoqi@0 742
aoqi@0 743 switch(_kind) {
aoqi@0 744
aoqi@0 745 case TCKind._tk_objref:
aoqi@0 746 {
aoqi@0 747 // check for logical id.
aoqi@0 748 if (_id.compareTo(tc.id()) == 0) {
aoqi@0 749 return true;
aoqi@0 750 }
aoqi@0 751
aoqi@0 752 if (_id.compareTo(
aoqi@0 753 (_orb.get_primitive_tc(_kind)).id()) == 0)
aoqi@0 754 {
aoqi@0 755 return true;
aoqi@0 756 }
aoqi@0 757
aoqi@0 758 if (tc.id().compareTo(
aoqi@0 759 (_orb.get_primitive_tc(_kind)).id()) == 0)
aoqi@0 760 {
aoqi@0 761 return true;
aoqi@0 762 }
aoqi@0 763
aoqi@0 764 return false;
aoqi@0 765 }
aoqi@0 766
aoqi@0 767 case TCKind._tk_native:
aoqi@0 768 case TCKind._tk_abstract_interface:
aoqi@0 769 {
aoqi@0 770 // check for logical id.
aoqi@0 771 if (_id.compareTo(tc.id()) != 0) {
aoqi@0 772 return false;
aoqi@0 773
aoqi@0 774 }
aoqi@0 775 // ignore name since its optional.
aoqi@0 776 return true;
aoqi@0 777 }
aoqi@0 778
aoqi@0 779 case TCKind._tk_struct:
aoqi@0 780 case TCKind._tk_except:
aoqi@0 781 {
aoqi@0 782 // check for member count
aoqi@0 783 if (_memberCount != tc.member_count())
aoqi@0 784 return false;
aoqi@0 785 // check for repository id
aoqi@0 786 if (_id.compareTo(tc.id()) != 0)
aoqi@0 787 return false;
aoqi@0 788 // check for member types.
aoqi@0 789 for (int i = 0 ; i < _memberCount ; i++)
aoqi@0 790 if (! _memberTypes[i].equal(tc.member_type(i)))
aoqi@0 791 return false;
aoqi@0 792 // ignore id and names since those are optional.
aoqi@0 793 return true;
aoqi@0 794 }
aoqi@0 795
aoqi@0 796 case TCKind._tk_union:
aoqi@0 797 {
aoqi@0 798 // check for member count
aoqi@0 799 if (_memberCount != tc.member_count())
aoqi@0 800 return false;
aoqi@0 801 // check for repository id
aoqi@0 802 if (_id.compareTo(tc.id()) != 0)
aoqi@0 803 return false;
aoqi@0 804 // check for default index
aoqi@0 805 if (_defaultIndex != tc.default_index())
aoqi@0 806 return false;
aoqi@0 807 // check for discriminator type
aoqi@0 808 if (!_discriminator.equal(tc.discriminator_type()))
aoqi@0 809 return false;
aoqi@0 810 // check for label types and values
aoqi@0 811 for (int i = 0 ; i < _memberCount ; i++)
aoqi@0 812 if (! _unionLabels[i].equal(tc.member_label(i)))
aoqi@0 813 return false;
aoqi@0 814 // check for branch types
aoqi@0 815 for (int i = 0 ; i < _memberCount ; i++)
aoqi@0 816 if (! _memberTypes[i].equal(tc.member_type(i)))
aoqi@0 817 return false;
aoqi@0 818 // ignore id and names since those are optional.
aoqi@0 819 return true;
aoqi@0 820 }
aoqi@0 821
aoqi@0 822 case TCKind._tk_enum:
aoqi@0 823 {
aoqi@0 824 // check for repository id
aoqi@0 825 if (_id.compareTo(tc.id()) != 0)
aoqi@0 826 return false;
aoqi@0 827 // check member count
aoqi@0 828 if (_memberCount != tc.member_count())
aoqi@0 829 return false;
aoqi@0 830 // ignore names since those are optional.
aoqi@0 831 return true;
aoqi@0 832 }
aoqi@0 833
aoqi@0 834 case TCKind._tk_sequence:
aoqi@0 835 case TCKind._tk_array:
aoqi@0 836 {
aoqi@0 837 // check bound/length
aoqi@0 838 if (_length != tc.length()) {
aoqi@0 839 return false;
aoqi@0 840 }
aoqi@0 841 // check content type
aoqi@0 842 if (! lazy_content_type().equal(tc.content_type())) {
aoqi@0 843 return false;
aoqi@0 844 }
aoqi@0 845 // ignore id and name since those are optional.
aoqi@0 846 return true;
aoqi@0 847 }
aoqi@0 848
aoqi@0 849 case TCKind._tk_value:
aoqi@0 850 {
aoqi@0 851 // check for member count
aoqi@0 852 if (_memberCount != tc.member_count())
aoqi@0 853 return false;
aoqi@0 854 // check for repository id
aoqi@0 855 if (_id.compareTo(tc.id()) != 0)
aoqi@0 856 return false;
aoqi@0 857 // check for member types.
aoqi@0 858 for (int i = 0 ; i < _memberCount ; i++)
aoqi@0 859 if (_memberAccess[i] != tc.member_visibility(i) ||
aoqi@0 860 ! _memberTypes[i].equal(tc.member_type(i)))
aoqi@0 861 return false;
aoqi@0 862 if (_type_modifier == tc.type_modifier())
aoqi@0 863 return false;
aoqi@0 864 // concrete_base may be null
aoqi@0 865 TypeCode tccb = tc.concrete_base_type();
aoqi@0 866 if ((_concrete_base == null && tccb != null) ||
aoqi@0 867 (_concrete_base != null && tccb == null) ||
aoqi@0 868 ! _concrete_base.equal(tccb))
aoqi@0 869 {
aoqi@0 870 return false;
aoqi@0 871 }
aoqi@0 872 // ignore id and names since those are optional.
aoqi@0 873 return true;
aoqi@0 874 }
aoqi@0 875
aoqi@0 876 case TCKind._tk_alias:
aoqi@0 877 case TCKind._tk_value_box:
aoqi@0 878 {
aoqi@0 879 // check for repository id
aoqi@0 880 if (_id.compareTo(tc.id()) != 0) {
aoqi@0 881 return false;
aoqi@0 882 }
aoqi@0 883 // check for equality with the true type
aoqi@0 884 return _contentType.equal(tc.content_type());
aoqi@0 885 }
aoqi@0 886 }
aoqi@0 887 }
aoqi@0 888 } catch (org.omg.CORBA.TypeCodePackage.Bounds e) {} catch (BadKind e) {}
aoqi@0 889 // dont have to worry about these since the code ensures these dont
aoqi@0 890 // arise.
aoqi@0 891 return false;
aoqi@0 892 }
aoqi@0 893
aoqi@0 894 /**
aoqi@0 895 * The equivalent operation is used by the ORB when determining type equivalence
aoqi@0 896 * for values stored in an IDL any.
aoqi@0 897 */
aoqi@0 898 public boolean equivalent(TypeCode tc) {
aoqi@0 899 if (tc == this) {
aoqi@0 900 return true;
aoqi@0 901 }
aoqi@0 902
aoqi@0 903 // If the result of the kind operation on either TypeCode is tk_alias, recursively
aoqi@0 904 // replace the TypeCode with the result of calling content_type, until the kind
aoqi@0 905 // is no longer tk_alias.
aoqi@0 906 // Note: Always resolve indirect types first!
aoqi@0 907 TypeCode myRealType = (_kind == tk_indirect ? indirectType() : this);
aoqi@0 908 myRealType = realType(myRealType);
aoqi@0 909 TypeCode otherRealType = realType(tc);
aoqi@0 910
aoqi@0 911 // If results of the kind operation on each typecode differ,
aoqi@0 912 // equivalent returns false.
aoqi@0 913 if (myRealType.kind().value() != otherRealType.kind().value()) {
aoqi@0 914 return false;
aoqi@0 915 }
aoqi@0 916
aoqi@0 917 String myID = null;
aoqi@0 918 String otherID = null;
aoqi@0 919 try {
aoqi@0 920 myID = this.id();
aoqi@0 921 otherID = tc.id();
aoqi@0 922 // At this point the id operation is valid for both TypeCodes.
aoqi@0 923
aoqi@0 924 // Return true if the results of id for both TypeCodes are non-empty strings
aoqi@0 925 // and both strings are equal.
aoqi@0 926 // If both ids are non-empty but are not equal, then equivalent returns FALSE.
aoqi@0 927 if (myID != null && otherID != null) {
aoqi@0 928 return (myID.equals(otherID));
aoqi@0 929 }
aoqi@0 930 } catch (BadKind e) {
aoqi@0 931 // id operation is not valid for either or both TypeCodes
aoqi@0 932 }
aoqi@0 933
aoqi@0 934 // If either or both id is an empty string, or the TypeCode kind does not support
aoqi@0 935 // the id operation, perform a structural comparison of the TypeCodes.
aoqi@0 936
aoqi@0 937 int myKind = myRealType.kind().value();
aoqi@0 938 try {
aoqi@0 939 if (myKind == TCKind._tk_struct ||
aoqi@0 940 myKind == TCKind._tk_union ||
aoqi@0 941 myKind == TCKind._tk_enum ||
aoqi@0 942 myKind == TCKind._tk_except ||
aoqi@0 943 myKind == TCKind._tk_value)
aoqi@0 944 {
aoqi@0 945 if (myRealType.member_count() != otherRealType.member_count())
aoqi@0 946 return false;
aoqi@0 947 }
aoqi@0 948 if (myKind == TCKind._tk_union)
aoqi@0 949 {
aoqi@0 950 if (myRealType.default_index() != otherRealType.default_index())
aoqi@0 951 return false;
aoqi@0 952 }
aoqi@0 953 if (myKind == TCKind._tk_string ||
aoqi@0 954 myKind == TCKind._tk_wstring ||
aoqi@0 955 myKind == TCKind._tk_sequence ||
aoqi@0 956 myKind == TCKind._tk_array)
aoqi@0 957 {
aoqi@0 958 if (myRealType.length() != otherRealType.length())
aoqi@0 959 return false;
aoqi@0 960 }
aoqi@0 961 if (myKind == TCKind._tk_fixed)
aoqi@0 962 {
aoqi@0 963 if (myRealType.fixed_digits() != otherRealType.fixed_digits() ||
aoqi@0 964 myRealType.fixed_scale() != otherRealType.fixed_scale())
aoqi@0 965 return false;
aoqi@0 966 }
aoqi@0 967 if (myKind == TCKind._tk_union)
aoqi@0 968 {
aoqi@0 969 for (int i=0; i<myRealType.member_count(); i++) {
aoqi@0 970 if (myRealType.member_label(i) != otherRealType.member_label(i))
aoqi@0 971 return false;
aoqi@0 972 }
aoqi@0 973 if ( ! myRealType.discriminator_type().equivalent(
aoqi@0 974 otherRealType.discriminator_type()))
aoqi@0 975 return false;
aoqi@0 976 }
aoqi@0 977 if (myKind == TCKind._tk_alias ||
aoqi@0 978 myKind == TCKind._tk_value_box ||
aoqi@0 979 myKind == TCKind._tk_sequence ||
aoqi@0 980 myKind == TCKind._tk_array)
aoqi@0 981 {
aoqi@0 982 if ( ! myRealType.content_type().equivalent(otherRealType.content_type()))
aoqi@0 983 return false;
aoqi@0 984 }
aoqi@0 985 if (myKind == TCKind._tk_struct ||
aoqi@0 986 myKind == TCKind._tk_union ||
aoqi@0 987 myKind == TCKind._tk_except ||
aoqi@0 988 myKind == TCKind._tk_value)
aoqi@0 989 {
aoqi@0 990 for (int i=0; i<myRealType.member_count(); i++) {
aoqi@0 991 if ( ! myRealType.member_type(i).equivalent(
aoqi@0 992 otherRealType.member_type(i)))
aoqi@0 993 return false;
aoqi@0 994 }
aoqi@0 995 }
aoqi@0 996 } catch (BadKind e) {
aoqi@0 997 // impossible if we checked correctly above
aoqi@0 998 throw wrapper.badkindCannotOccur() ;
aoqi@0 999 } catch (org.omg.CORBA.TypeCodePackage.Bounds e) {
aoqi@0 1000 // impossible if we checked correctly above
aoqi@0 1001 throw wrapper.boundsCannotOccur() ;
aoqi@0 1002 }
aoqi@0 1003
aoqi@0 1004 // Structural comparison succeeded!
aoqi@0 1005 return true;
aoqi@0 1006 }
aoqi@0 1007
aoqi@0 1008 public TypeCode get_compact_typecode() {
aoqi@0 1009 // _REVISIT_ It isn't clear whether this method should operate on this or a copy.
aoqi@0 1010 // For now just return this unmodified because the name and member_name fields
aoqi@0 1011 // aren't used for comparison anyways.
aoqi@0 1012 return this;
aoqi@0 1013 }
aoqi@0 1014
aoqi@0 1015 public TCKind kind()
aoqi@0 1016 {
aoqi@0 1017 if (_kind == tk_indirect)
aoqi@0 1018 return indirectType().kind();
aoqi@0 1019 return TCKind.from_int(_kind);
aoqi@0 1020 }
aoqi@0 1021
aoqi@0 1022 public boolean is_recursive()
aoqi@0 1023 {
aoqi@0 1024 // Recursive is the only form of indirect type codes right now.
aoqi@0 1025 // Indirection can also be used for repeated type codes.
aoqi@0 1026 return (_kind == tk_indirect);
aoqi@0 1027 }
aoqi@0 1028
aoqi@0 1029 public String id()
aoqi@0 1030 throws BadKind
aoqi@0 1031 {
aoqi@0 1032 switch (_kind) {
aoqi@0 1033 case tk_indirect:
aoqi@0 1034 //return indirectType().id(); // same as _id
aoqi@0 1035 case TCKind._tk_except:
aoqi@0 1036 case TCKind._tk_objref:
aoqi@0 1037 case TCKind._tk_struct:
aoqi@0 1038 case TCKind._tk_union:
aoqi@0 1039 case TCKind._tk_enum:
aoqi@0 1040 case TCKind._tk_alias:
aoqi@0 1041 case TCKind._tk_value:
aoqi@0 1042 case TCKind._tk_value_box:
aoqi@0 1043 case TCKind._tk_native:
aoqi@0 1044 case TCKind._tk_abstract_interface:
aoqi@0 1045 // exception and objref typecodes must have a repository id.
aoqi@0 1046 // structs, unions, enums, and aliases may or may not.
aoqi@0 1047 return _id;
aoqi@0 1048 default:
aoqi@0 1049 // all other typecodes throw the BadKind exception.
aoqi@0 1050 throw new BadKind();
aoqi@0 1051 }
aoqi@0 1052 }
aoqi@0 1053
aoqi@0 1054 public String name()
aoqi@0 1055 throws BadKind
aoqi@0 1056 {
aoqi@0 1057 switch (_kind) {
aoqi@0 1058 case tk_indirect:
aoqi@0 1059 return indirectType().name();
aoqi@0 1060 case TCKind._tk_except:
aoqi@0 1061 case TCKind._tk_objref:
aoqi@0 1062 case TCKind._tk_struct:
aoqi@0 1063 case TCKind._tk_union:
aoqi@0 1064 case TCKind._tk_enum:
aoqi@0 1065 case TCKind._tk_alias:
aoqi@0 1066 case TCKind._tk_value:
aoqi@0 1067 case TCKind._tk_value_box:
aoqi@0 1068 case TCKind._tk_native:
aoqi@0 1069 case TCKind._tk_abstract_interface:
aoqi@0 1070 return _name;
aoqi@0 1071 default:
aoqi@0 1072 throw new BadKind();
aoqi@0 1073 }
aoqi@0 1074 }
aoqi@0 1075
aoqi@0 1076 public int member_count()
aoqi@0 1077 throws BadKind
aoqi@0 1078 {
aoqi@0 1079 switch (_kind) {
aoqi@0 1080 case tk_indirect:
aoqi@0 1081 return indirectType().member_count();
aoqi@0 1082 case TCKind._tk_except:
aoqi@0 1083 case TCKind._tk_struct:
aoqi@0 1084 case TCKind._tk_union:
aoqi@0 1085 case TCKind._tk_enum:
aoqi@0 1086 case TCKind._tk_value:
aoqi@0 1087 return _memberCount;
aoqi@0 1088 default:
aoqi@0 1089 throw new BadKind();
aoqi@0 1090 }
aoqi@0 1091 }
aoqi@0 1092
aoqi@0 1093 public String member_name(int index)
aoqi@0 1094 throws BadKind, org.omg.CORBA.TypeCodePackage.Bounds
aoqi@0 1095 {
aoqi@0 1096 switch (_kind) {
aoqi@0 1097 case tk_indirect:
aoqi@0 1098 return indirectType().member_name(index);
aoqi@0 1099 case TCKind._tk_except:
aoqi@0 1100 case TCKind._tk_struct:
aoqi@0 1101 case TCKind._tk_union:
aoqi@0 1102 case TCKind._tk_enum:
aoqi@0 1103 case TCKind._tk_value:
aoqi@0 1104 try {
aoqi@0 1105 return _memberNames[index];
aoqi@0 1106 } catch (ArrayIndexOutOfBoundsException e) {
aoqi@0 1107 throw new org.omg.CORBA.TypeCodePackage.Bounds();
aoqi@0 1108 }
aoqi@0 1109 default:
aoqi@0 1110 throw new BadKind();
aoqi@0 1111 }
aoqi@0 1112 }
aoqi@0 1113
aoqi@0 1114 public TypeCode member_type(int index)
aoqi@0 1115 throws BadKind, org.omg.CORBA.TypeCodePackage.Bounds
aoqi@0 1116 {
aoqi@0 1117 switch (_kind) {
aoqi@0 1118 case tk_indirect:
aoqi@0 1119 return indirectType().member_type(index);
aoqi@0 1120 case TCKind._tk_except:
aoqi@0 1121 case TCKind._tk_struct:
aoqi@0 1122 case TCKind._tk_union:
aoqi@0 1123 case TCKind._tk_value:
aoqi@0 1124 try {
aoqi@0 1125 return _memberTypes[index];
aoqi@0 1126 } catch (ArrayIndexOutOfBoundsException e) {
aoqi@0 1127 throw new org.omg.CORBA.TypeCodePackage.Bounds();
aoqi@0 1128 }
aoqi@0 1129 default:
aoqi@0 1130 throw new BadKind();
aoqi@0 1131 }
aoqi@0 1132 }
aoqi@0 1133
aoqi@0 1134 public Any member_label(int index)
aoqi@0 1135 throws BadKind, org.omg.CORBA.TypeCodePackage.Bounds
aoqi@0 1136 {
aoqi@0 1137 switch (_kind) {
aoqi@0 1138 case tk_indirect:
aoqi@0 1139 return indirectType().member_label(index);
aoqi@0 1140 case TCKind._tk_union:
aoqi@0 1141 try {
aoqi@0 1142 // _REVISIT_ Why create a new Any for this?
aoqi@0 1143 return new AnyImpl(_orb, _unionLabels[index]);
aoqi@0 1144 } catch (ArrayIndexOutOfBoundsException e) {
aoqi@0 1145 throw new org.omg.CORBA.TypeCodePackage.Bounds();
aoqi@0 1146 }
aoqi@0 1147 default:
aoqi@0 1148 throw new BadKind();
aoqi@0 1149 }
aoqi@0 1150 }
aoqi@0 1151
aoqi@0 1152 public TypeCode discriminator_type()
aoqi@0 1153 throws BadKind
aoqi@0 1154 {
aoqi@0 1155 switch (_kind) {
aoqi@0 1156 case tk_indirect:
aoqi@0 1157 return indirectType().discriminator_type();
aoqi@0 1158 case TCKind._tk_union:
aoqi@0 1159 return _discriminator;
aoqi@0 1160 default:
aoqi@0 1161 throw new BadKind();
aoqi@0 1162 }
aoqi@0 1163 }
aoqi@0 1164
aoqi@0 1165 public int default_index()
aoqi@0 1166 throws BadKind
aoqi@0 1167 {
aoqi@0 1168 switch (_kind) {
aoqi@0 1169 case tk_indirect:
aoqi@0 1170 return indirectType().default_index();
aoqi@0 1171 case TCKind._tk_union:
aoqi@0 1172 return _defaultIndex;
aoqi@0 1173 default:
aoqi@0 1174 throw new BadKind();
aoqi@0 1175 }
aoqi@0 1176 }
aoqi@0 1177
aoqi@0 1178 public int length()
aoqi@0 1179 throws BadKind
aoqi@0 1180 {
aoqi@0 1181 switch (_kind) {
aoqi@0 1182 case tk_indirect:
aoqi@0 1183 return indirectType().length();
aoqi@0 1184 case TCKind._tk_string:
aoqi@0 1185 case TCKind._tk_wstring:
aoqi@0 1186 case TCKind._tk_sequence:
aoqi@0 1187 case TCKind._tk_array:
aoqi@0 1188 return _length;
aoqi@0 1189 default:
aoqi@0 1190 throw new BadKind();
aoqi@0 1191 }
aoqi@0 1192 }
aoqi@0 1193
aoqi@0 1194 public TypeCode content_type()
aoqi@0 1195 throws BadKind
aoqi@0 1196 {
aoqi@0 1197 switch (_kind) {
aoqi@0 1198 case tk_indirect:
aoqi@0 1199 return indirectType().content_type();
aoqi@0 1200 case TCKind._tk_sequence:
aoqi@0 1201 return lazy_content_type();
aoqi@0 1202 case TCKind._tk_array:
aoqi@0 1203 case TCKind._tk_alias:
aoqi@0 1204 case TCKind._tk_value_box:
aoqi@0 1205 return _contentType;
aoqi@0 1206 default:
aoqi@0 1207 throw new BadKind();
aoqi@0 1208 }
aoqi@0 1209 }
aoqi@0 1210
aoqi@0 1211 public short fixed_digits() throws BadKind {
aoqi@0 1212 switch (_kind) {
aoqi@0 1213 case TCKind._tk_fixed:
aoqi@0 1214 return _digits;
aoqi@0 1215 default:
aoqi@0 1216 throw new BadKind();
aoqi@0 1217 }
aoqi@0 1218 }
aoqi@0 1219
aoqi@0 1220 public short fixed_scale() throws BadKind {
aoqi@0 1221 switch (_kind) {
aoqi@0 1222 case TCKind._tk_fixed:
aoqi@0 1223 return _scale;
aoqi@0 1224 default:
aoqi@0 1225 throw new BadKind();
aoqi@0 1226 }
aoqi@0 1227 }
aoqi@0 1228
aoqi@0 1229 public short member_visibility(int index) throws BadKind,
aoqi@0 1230 org.omg.CORBA.TypeCodePackage.Bounds {
aoqi@0 1231 switch (_kind) {
aoqi@0 1232 case tk_indirect:
aoqi@0 1233 return indirectType().member_visibility(index);
aoqi@0 1234 case TCKind._tk_value:
aoqi@0 1235 try {
aoqi@0 1236 return _memberAccess[index];
aoqi@0 1237 } catch (ArrayIndexOutOfBoundsException e) {
aoqi@0 1238 throw new org.omg.CORBA.TypeCodePackage.Bounds();
aoqi@0 1239 }
aoqi@0 1240 default:
aoqi@0 1241 throw new BadKind();
aoqi@0 1242 }
aoqi@0 1243 }
aoqi@0 1244
aoqi@0 1245 public short type_modifier() throws BadKind {
aoqi@0 1246 switch (_kind) {
aoqi@0 1247 case tk_indirect:
aoqi@0 1248 return indirectType().type_modifier();
aoqi@0 1249 case TCKind._tk_value:
aoqi@0 1250 return _type_modifier;
aoqi@0 1251 default:
aoqi@0 1252 throw new BadKind();
aoqi@0 1253 }
aoqi@0 1254 }
aoqi@0 1255
aoqi@0 1256 public TypeCode concrete_base_type() throws BadKind {
aoqi@0 1257 switch (_kind) {
aoqi@0 1258 case tk_indirect:
aoqi@0 1259 return indirectType().concrete_base_type();
aoqi@0 1260 case TCKind._tk_value:
aoqi@0 1261 return _concrete_base;
aoqi@0 1262 default:
aoqi@0 1263 throw new BadKind();
aoqi@0 1264 }
aoqi@0 1265 }
aoqi@0 1266
aoqi@0 1267 public void read_value(InputStream is) {
aoqi@0 1268 if (is instanceof TypeCodeReader) {
aoqi@0 1269 // hardly possible unless caller knows our "private" stream classes.
aoqi@0 1270 if (read_value_kind((TypeCodeReader)is))
aoqi@0 1271 read_value_body(is);
aoqi@0 1272 } else if (is instanceof CDRInputStream) {
aoqi@0 1273 WrapperInputStream wrapper = new WrapperInputStream((CDRInputStream)is);
aoqi@0 1274 //if (debug) System.out.println("Created WrapperInputStream " + wrapper +
aoqi@0 1275 // " with no parent");
aoqi@0 1276 if (read_value_kind((TypeCodeReader)wrapper))
aoqi@0 1277 read_value_body(wrapper);
aoqi@0 1278 } else {
aoqi@0 1279 read_value_kind(is);
aoqi@0 1280 read_value_body(is);
aoqi@0 1281 }
aoqi@0 1282 }
aoqi@0 1283
aoqi@0 1284 private void read_value_recursive(TypeCodeInputStream is) {
aoqi@0 1285 // don't wrap a CDRInputStream reading "inner" TypeCodes.
aoqi@0 1286 if (is instanceof TypeCodeReader) {
aoqi@0 1287 if (read_value_kind((TypeCodeReader)is))
aoqi@0 1288 read_value_body(is);
aoqi@0 1289 } else {
aoqi@0 1290 read_value_kind((InputStream)is);
aoqi@0 1291 read_value_body(is);
aoqi@0 1292 }
aoqi@0 1293 }
aoqi@0 1294
aoqi@0 1295 boolean read_value_kind(TypeCodeReader tcis)
aoqi@0 1296 {
aoqi@0 1297 _kind = tcis.read_long();
aoqi@0 1298
aoqi@0 1299 // Bug fix 5034649: allow for padding that precedes the typecode kind.
aoqi@0 1300 int myPosition = tcis.getTopLevelPosition()-4;
aoqi@0 1301
aoqi@0 1302 // check validity of kind
aoqi@0 1303 if ((_kind < 0 || _kind > typeTable.length) && _kind != tk_indirect) {
aoqi@0 1304 throw wrapper.cannotMarshalBadTckind() ;
aoqi@0 1305 }
aoqi@0 1306
aoqi@0 1307 // Don't do any work if this is native
aoqi@0 1308 if (_kind == TCKind._tk_native)
aoqi@0 1309 throw wrapper.cannotMarshalNative() ;
aoqi@0 1310
aoqi@0 1311 // We have to remember the stream and position for EVERY type code
aoqi@0 1312 // in case some recursive or indirect type code references it.
aoqi@0 1313 TypeCodeReader topStream = tcis.getTopLevelStream();
aoqi@0 1314
aoqi@0 1315 if (_kind == tk_indirect) {
aoqi@0 1316 int streamOffset = tcis.read_long();
aoqi@0 1317 if (streamOffset > -4)
aoqi@0 1318 throw wrapper.invalidIndirection( new Integer(streamOffset) ) ;
aoqi@0 1319
aoqi@0 1320 // The encoding used for indirection is the same as that used for recursive ,
aoqi@0 1321 // TypeCodes i.e., a 0xffffffff indirection marker followed by a long offset
aoqi@0 1322 // (in units of octets) from the beginning of the long offset.
aoqi@0 1323 int topPos = tcis.getTopLevelPosition();
aoqi@0 1324 // substract 4 to get back to the beginning of the long offset.
aoqi@0 1325 int indirectTypePosition = topPos - 4 + streamOffset;
aoqi@0 1326
aoqi@0 1327 // Now we have to find the referenced type
aoqi@0 1328 // by its indirectTypePosition within topStream.
aoqi@0 1329 //if (debug) System.out.println(
aoqi@0 1330 // "TypeCodeImpl looking up indirection at position topPos " +
aoqi@0 1331 //topPos + " - 4 + offset " + streamOffset + " = " + indirectTypePosition);
aoqi@0 1332 TypeCodeImpl type = topStream.getTypeCodeAtPosition(indirectTypePosition);
aoqi@0 1333 if (type == null)
aoqi@0 1334 throw wrapper.indirectionNotFound( new Integer(indirectTypePosition) ) ;
aoqi@0 1335 setIndirectType(type);
aoqi@0 1336 return false;
aoqi@0 1337 }
aoqi@0 1338
aoqi@0 1339 topStream.addTypeCodeAtPosition(this, myPosition);
aoqi@0 1340 return true;
aoqi@0 1341 }
aoqi@0 1342
aoqi@0 1343 void read_value_kind(InputStream is) {
aoqi@0 1344 // unmarshal the kind
aoqi@0 1345 _kind = is.read_long();
aoqi@0 1346
aoqi@0 1347 // check validity of kind
aoqi@0 1348 if ((_kind < 0 || _kind > typeTable.length) && _kind != tk_indirect) {
aoqi@0 1349 throw wrapper.cannotMarshalBadTckind() ;
aoqi@0 1350 }
aoqi@0 1351 // Don't do any work if this is native
aoqi@0 1352 if (_kind == TCKind._tk_native)
aoqi@0 1353 throw wrapper.cannotMarshalNative() ;
aoqi@0 1354
aoqi@0 1355 if (_kind == tk_indirect) {
aoqi@0 1356 throw wrapper.recursiveTypecodeError() ;
aoqi@0 1357 }
aoqi@0 1358 }
aoqi@0 1359
aoqi@0 1360 void read_value_body(InputStream is) {
aoqi@0 1361 // start unmarshaling the rest of the typecode, based on the
aoqi@0 1362 // encoding (empty, simple or complex).
aoqi@0 1363
aoqi@0 1364 switch (typeTable[_kind]) {
aoqi@0 1365 case EMPTY:
aoqi@0 1366 // nothing to unmarshal
aoqi@0 1367 break;
aoqi@0 1368
aoqi@0 1369 case SIMPLE:
aoqi@0 1370 switch (_kind) {
aoqi@0 1371 case TCKind._tk_string:
aoqi@0 1372 case TCKind._tk_wstring:
aoqi@0 1373 _length = is.read_long();
aoqi@0 1374 break;
aoqi@0 1375 case TCKind._tk_fixed:
aoqi@0 1376 _digits = is.read_ushort();
aoqi@0 1377 _scale = is.read_short();
aoqi@0 1378 break;
aoqi@0 1379 default:
aoqi@0 1380 throw wrapper.invalidSimpleTypecode() ;
aoqi@0 1381 }
aoqi@0 1382 break;
aoqi@0 1383
aoqi@0 1384 case COMPLEX:
aoqi@0 1385 {
aoqi@0 1386 TypeCodeInputStream _encap = TypeCodeInputStream.readEncapsulation(is,
aoqi@0 1387 is.orb());
aoqi@0 1388
aoqi@0 1389 switch(_kind) {
aoqi@0 1390
aoqi@0 1391 case TCKind._tk_objref:
aoqi@0 1392 case TCKind._tk_abstract_interface:
aoqi@0 1393 {
aoqi@0 1394 // get the repository id
aoqi@0 1395 setId(_encap.read_string());
aoqi@0 1396 // get the name
aoqi@0 1397 _name = _encap.read_string();
aoqi@0 1398 }
aoqi@0 1399 break;
aoqi@0 1400
aoqi@0 1401 case TCKind._tk_union:
aoqi@0 1402 {
aoqi@0 1403 // get the repository id
aoqi@0 1404 setId(_encap.read_string());
aoqi@0 1405
aoqi@0 1406 // get the name
aoqi@0 1407 _name = _encap.read_string();
aoqi@0 1408
aoqi@0 1409 // discriminant typecode
aoqi@0 1410 _discriminator = new TypeCodeImpl((ORB)is.orb());
aoqi@0 1411 _discriminator.read_value_recursive(_encap);
aoqi@0 1412
aoqi@0 1413 // default index
aoqi@0 1414 _defaultIndex = _encap.read_long();
aoqi@0 1415
aoqi@0 1416 // get the number of members
aoqi@0 1417 _memberCount = _encap.read_long();
aoqi@0 1418
aoqi@0 1419 // create arrays for the label values, names and types of members
aoqi@0 1420 _unionLabels = new AnyImpl[_memberCount];
aoqi@0 1421 _memberNames = new String[_memberCount];
aoqi@0 1422 _memberTypes = new TypeCodeImpl[_memberCount];
aoqi@0 1423
aoqi@0 1424 // read off label values, names and types
aoqi@0 1425 for (int i=0; i < _memberCount; i++) {
aoqi@0 1426 _unionLabels[i] = new AnyImpl((ORB)is.orb());
aoqi@0 1427 if (i == _defaultIndex)
aoqi@0 1428 // for the default case, read off the zero octet
aoqi@0 1429 _unionLabels[i].insert_octet(_encap.read_octet());
aoqi@0 1430 else {
aoqi@0 1431 switch (realType(_discriminator).kind().value()) {
aoqi@0 1432 case TCKind._tk_short:
aoqi@0 1433 _unionLabels[i].insert_short(_encap.read_short());
aoqi@0 1434 break;
aoqi@0 1435 case TCKind._tk_long:
aoqi@0 1436 _unionLabels[i].insert_long(_encap.read_long());
aoqi@0 1437 break;
aoqi@0 1438 case TCKind._tk_ushort:
aoqi@0 1439 _unionLabels[i].insert_ushort(_encap.read_short());
aoqi@0 1440 break;
aoqi@0 1441 case TCKind._tk_ulong:
aoqi@0 1442 _unionLabels[i].insert_ulong(_encap.read_long());
aoqi@0 1443 break;
aoqi@0 1444 case TCKind._tk_float:
aoqi@0 1445 _unionLabels[i].insert_float(_encap.read_float());
aoqi@0 1446 break;
aoqi@0 1447 case TCKind._tk_double:
aoqi@0 1448 _unionLabels[i].insert_double(_encap.read_double());
aoqi@0 1449 break;
aoqi@0 1450 case TCKind._tk_boolean:
aoqi@0 1451 _unionLabels[i].insert_boolean(_encap.read_boolean());
aoqi@0 1452 break;
aoqi@0 1453 case TCKind._tk_char:
aoqi@0 1454 _unionLabels[i].insert_char(_encap.read_char());
aoqi@0 1455 break;
aoqi@0 1456 case TCKind._tk_enum:
aoqi@0 1457 _unionLabels[i].type(_discriminator);
aoqi@0 1458 _unionLabels[i].insert_long(_encap.read_long());
aoqi@0 1459 break;
aoqi@0 1460 case TCKind._tk_longlong:
aoqi@0 1461 _unionLabels[i].insert_longlong(_encap.read_longlong());
aoqi@0 1462 break;
aoqi@0 1463 case TCKind._tk_ulonglong:
aoqi@0 1464 _unionLabels[i].insert_ulonglong(_encap.read_longlong());
aoqi@0 1465 break;
aoqi@0 1466 // _REVISIT_ figure out long double mapping
aoqi@0 1467 // case TCKind.tk_longdouble:
aoqi@0 1468 // _unionLabels[i].insert_longdouble(_encap.getDouble());
aoqi@0 1469 // break;
aoqi@0 1470 case TCKind._tk_wchar:
aoqi@0 1471 _unionLabels[i].insert_wchar(_encap.read_wchar());
aoqi@0 1472 break;
aoqi@0 1473 default:
aoqi@0 1474 throw wrapper.invalidComplexTypecode() ;
aoqi@0 1475 }
aoqi@0 1476 }
aoqi@0 1477 _memberNames[i] = _encap.read_string();
aoqi@0 1478 _memberTypes[i] = new TypeCodeImpl((ORB)is.orb());
aoqi@0 1479 _memberTypes[i].read_value_recursive(_encap);
aoqi@0 1480 _memberTypes[i].setParent(this);
aoqi@0 1481 }
aoqi@0 1482 }
aoqi@0 1483 break;
aoqi@0 1484
aoqi@0 1485 case TCKind._tk_enum:
aoqi@0 1486 {
aoqi@0 1487 // get the repository id
aoqi@0 1488 setId(_encap.read_string());
aoqi@0 1489
aoqi@0 1490 // get the name
aoqi@0 1491 _name = _encap.read_string();
aoqi@0 1492
aoqi@0 1493 // get the number of members
aoqi@0 1494 _memberCount = _encap.read_long();
aoqi@0 1495
aoqi@0 1496 // create arrays for the identifier names
aoqi@0 1497 _memberNames = new String[_memberCount];
aoqi@0 1498
aoqi@0 1499 // read off identifier names
aoqi@0 1500 for (int i=0; i < _memberCount; i++)
aoqi@0 1501 _memberNames[i] = _encap.read_string();
aoqi@0 1502 }
aoqi@0 1503 break;
aoqi@0 1504
aoqi@0 1505 case TCKind._tk_sequence:
aoqi@0 1506 {
aoqi@0 1507 // get the type of the sequence
aoqi@0 1508 _contentType = new TypeCodeImpl((ORB)is.orb());
aoqi@0 1509 _contentType.read_value_recursive(_encap);
aoqi@0 1510
aoqi@0 1511 // get the bound on the length of the sequence
aoqi@0 1512 _length = _encap.read_long();
aoqi@0 1513 }
aoqi@0 1514 break;
aoqi@0 1515
aoqi@0 1516 case TCKind._tk_array:
aoqi@0 1517 {
aoqi@0 1518 // get the type of the array
aoqi@0 1519 _contentType = new TypeCodeImpl((ORB)is.orb());
aoqi@0 1520 _contentType.read_value_recursive(_encap);
aoqi@0 1521
aoqi@0 1522 // get the length of the array
aoqi@0 1523 _length = _encap.read_long();
aoqi@0 1524 }
aoqi@0 1525 break;
aoqi@0 1526
aoqi@0 1527 case TCKind._tk_alias:
aoqi@0 1528 case TCKind._tk_value_box:
aoqi@0 1529 {
aoqi@0 1530 // get the repository id
aoqi@0 1531 setId(_encap.read_string());
aoqi@0 1532
aoqi@0 1533 // get the name
aoqi@0 1534 _name = _encap.read_string();
aoqi@0 1535
aoqi@0 1536 // get the type aliased
aoqi@0 1537 _contentType = new TypeCodeImpl((ORB)is.orb());
aoqi@0 1538 _contentType.read_value_recursive(_encap);
aoqi@0 1539 }
aoqi@0 1540 break;
aoqi@0 1541
aoqi@0 1542 case TCKind._tk_except:
aoqi@0 1543 case TCKind._tk_struct:
aoqi@0 1544 {
aoqi@0 1545 // get the repository id
aoqi@0 1546 setId(_encap.read_string());
aoqi@0 1547
aoqi@0 1548 // get the name
aoqi@0 1549 _name = _encap.read_string();
aoqi@0 1550
aoqi@0 1551 // get the number of members
aoqi@0 1552 _memberCount = _encap.read_long();
aoqi@0 1553
aoqi@0 1554 // create arrays for the names and types of members
aoqi@0 1555 _memberNames = new String[_memberCount];
aoqi@0 1556 _memberTypes = new TypeCodeImpl[_memberCount];
aoqi@0 1557
aoqi@0 1558 // read off member names and types
aoqi@0 1559 for (int i=0; i < _memberCount; i++) {
aoqi@0 1560 _memberNames[i] = _encap.read_string();
aoqi@0 1561 _memberTypes[i] = new TypeCodeImpl((ORB)is.orb());
aoqi@0 1562 //if (debug) System.out.println("TypeCode " + _name +
aoqi@0 1563 // " reading member " + _memberNames[i]);
aoqi@0 1564 _memberTypes[i].read_value_recursive(_encap);
aoqi@0 1565 _memberTypes[i].setParent(this);
aoqi@0 1566 }
aoqi@0 1567 }
aoqi@0 1568 break;
aoqi@0 1569
aoqi@0 1570 case TCKind._tk_value:
aoqi@0 1571 {
aoqi@0 1572 // get the repository id
aoqi@0 1573 setId(_encap.read_string());
aoqi@0 1574
aoqi@0 1575 // get the name
aoqi@0 1576 _name = _encap.read_string();
aoqi@0 1577
aoqi@0 1578 // get the type modifier
aoqi@0 1579 _type_modifier = _encap.read_short();
aoqi@0 1580
aoqi@0 1581 // get the type aliased
aoqi@0 1582 _concrete_base = new TypeCodeImpl((ORB)is.orb());
aoqi@0 1583 _concrete_base.read_value_recursive(_encap);
aoqi@0 1584 if (_concrete_base.kind().value() == TCKind._tk_null) {
aoqi@0 1585 _concrete_base = null;
aoqi@0 1586 }
aoqi@0 1587
aoqi@0 1588 // get the number of members
aoqi@0 1589 _memberCount = _encap.read_long();
aoqi@0 1590
aoqi@0 1591 // create arrays for the names, types and visibility of members
aoqi@0 1592 _memberNames = new String[_memberCount];
aoqi@0 1593 _memberTypes = new TypeCodeImpl[_memberCount];
aoqi@0 1594 _memberAccess = new short[_memberCount];
aoqi@0 1595
aoqi@0 1596 // read off value member visibilities
aoqi@0 1597 for (int i=0; i < _memberCount; i++) {
aoqi@0 1598 _memberNames[i] = _encap.read_string();
aoqi@0 1599 _memberTypes[i] = new TypeCodeImpl((ORB)is.orb());
aoqi@0 1600 //if (debug) System.out.println("TypeCode " + _name +
aoqi@0 1601 // " reading member " + _memberNames[i]);
aoqi@0 1602 _memberTypes[i].read_value_recursive(_encap);
aoqi@0 1603 _memberTypes[i].setParent(this);
aoqi@0 1604 _memberAccess[i] = _encap.read_short();
aoqi@0 1605 }
aoqi@0 1606 }
aoqi@0 1607 break;
aoqi@0 1608
aoqi@0 1609 default:
aoqi@0 1610 throw wrapper.invalidTypecodeKindMarshal() ;
aoqi@0 1611 }
aoqi@0 1612 break;
aoqi@0 1613 }
aoqi@0 1614 }
aoqi@0 1615 }
aoqi@0 1616
aoqi@0 1617 public void write_value(OutputStream os) {
aoqi@0 1618 // Wrap OutputStream into TypeCodeOutputStream.
aoqi@0 1619 // This test shouldn't be necessary according to the Java language spec.
aoqi@0 1620 if (os instanceof TypeCodeOutputStream) {
aoqi@0 1621 this.write_value((TypeCodeOutputStream)os);
aoqi@0 1622 } else {
aoqi@0 1623 TypeCodeOutputStream wrapperOutStream = null;
aoqi@0 1624
aoqi@0 1625 if (outBuffer == null) {
aoqi@0 1626 wrapperOutStream = TypeCodeOutputStream.wrapOutputStream(os);
aoqi@0 1627 this.write_value(wrapperOutStream);
aoqi@0 1628 if (cachingEnabled) {
aoqi@0 1629 // Cache the buffer for repeated writes
aoqi@0 1630 outBuffer = wrapperOutStream.getTypeCodeBuffer();
aoqi@0 1631 //if (outBuffer != null)
aoqi@0 1632 //System.out.println("Caching outBuffer with length = " +
aoqi@0 1633 //outBuffer.length + " for id = " + _id);
aoqi@0 1634 }
aoqi@0 1635 } else {
aoqi@0 1636 //System.out.println("Using cached outBuffer: length = " + outBuffer.length +
aoqi@0 1637 //", id = " + _id);
aoqi@0 1638 }
aoqi@0 1639 // Write the first 4 bytes first to trigger alignment.
aoqi@0 1640 // We know that it is the kind.
aoqi@0 1641 if (cachingEnabled && outBuffer != null) {
aoqi@0 1642 os.write_long(_kind);
aoqi@0 1643 os.write_octet_array(outBuffer, 0, outBuffer.length);
aoqi@0 1644 } else {
aoqi@0 1645 //System.out.println("Buffer is empty for " + _id);
aoqi@0 1646 wrapperOutStream.writeRawBuffer(os, _kind);
aoqi@0 1647 }
aoqi@0 1648 }
aoqi@0 1649 }
aoqi@0 1650
aoqi@0 1651 public void write_value(TypeCodeOutputStream tcos) {
aoqi@0 1652
aoqi@0 1653 // Don't do any work if this is native
aoqi@0 1654 if (_kind == TCKind._tk_native)
aoqi@0 1655 throw wrapper.cannotMarshalNative() ;
aoqi@0 1656
aoqi@0 1657 TypeCodeOutputStream topStream = tcos.getTopLevelStream();
aoqi@0 1658 //if (debug) tcos.printBuffer();
aoqi@0 1659
aoqi@0 1660 if (_kind == tk_indirect) {
aoqi@0 1661 //if (debug) System.out.println("Writing indirection " + _name + "to " + _id);
aoqi@0 1662 // The encoding used for indirection is the same as that used for recursive ,
aoqi@0 1663 // TypeCodes i.e., a 0xffffffff indirection marker followed by a long offset
aoqi@0 1664 // (in units of octets) from the beginning of the long offset.
aoqi@0 1665 int pos = topStream.getPositionForID(_id);
aoqi@0 1666 int topPos = tcos.getTopLevelPosition();
aoqi@0 1667 //if (debug) System.out.println("TypeCodeImpl " + tcos +
aoqi@0 1668 // " writing indirection " + _id +
aoqi@0 1669 //" to position " + pos + " at position " + topPos);
aoqi@0 1670 tcos.writeIndirection(tk_indirect, pos);
aoqi@0 1671 // All that gets written is _kind and offset.
aoqi@0 1672 return;
aoqi@0 1673 }
aoqi@0 1674
aoqi@0 1675 // The original approach changed for 5034649
aoqi@0 1676 // topStream.addIDAtPosition(_id, tcos.getTopLevelPosition());
aoqi@0 1677
aoqi@0 1678 // marshal the kind
aoqi@0 1679 tcos.write_long(_kind);
aoqi@0 1680
aoqi@0 1681 //if (debug) System.out.println("Writing " + _name + " with id " + _id);
aoqi@0 1682 // We have to remember the stream and position for EVERY type code
aoqi@0 1683 // in case some recursive or indirect type code references it.
aoqi@0 1684 //
aoqi@0 1685 // Bug fix 5034649:
aoqi@0 1686 // Do this AFTER the write of the _kind in case the alignment
aoqi@0 1687 // for the long changes the position.
aoqi@0 1688 topStream.addIDAtPosition(_id, tcos.getTopLevelPosition()-4);
aoqi@0 1689
aoqi@0 1690 switch (typeTable[_kind]) {
aoqi@0 1691 case EMPTY:
aoqi@0 1692 // nothing more to marshal
aoqi@0 1693 break;
aoqi@0 1694
aoqi@0 1695 case SIMPLE:
aoqi@0 1696 switch (_kind) {
aoqi@0 1697 case TCKind._tk_string:
aoqi@0 1698 case TCKind._tk_wstring:
aoqi@0 1699 // marshal the bound on string length
aoqi@0 1700 tcos.write_long(_length);
aoqi@0 1701 break;
aoqi@0 1702 case TCKind._tk_fixed:
aoqi@0 1703 tcos.write_ushort(_digits);
aoqi@0 1704 tcos.write_short(_scale);
aoqi@0 1705 break;
aoqi@0 1706 default:
aoqi@0 1707 // unknown typecode kind
aoqi@0 1708 throw wrapper.invalidSimpleTypecode() ;
aoqi@0 1709 }
aoqi@0 1710 break;
aoqi@0 1711
aoqi@0 1712 case COMPLEX:
aoqi@0 1713 {
aoqi@0 1714 // create an encapsulation
aoqi@0 1715 TypeCodeOutputStream _encap = tcos.createEncapsulation(tcos.orb());
aoqi@0 1716
aoqi@0 1717 switch(_kind) {
aoqi@0 1718
aoqi@0 1719 case TCKind._tk_objref:
aoqi@0 1720 case TCKind._tk_abstract_interface:
aoqi@0 1721 {
aoqi@0 1722 // put the repository id
aoqi@0 1723 _encap.write_string(_id);
aoqi@0 1724
aoqi@0 1725 // put the name
aoqi@0 1726 _encap.write_string(_name);
aoqi@0 1727 }
aoqi@0 1728 break;
aoqi@0 1729
aoqi@0 1730 case TCKind._tk_union:
aoqi@0 1731 {
aoqi@0 1732 // put the repository id
aoqi@0 1733 _encap.write_string(_id);
aoqi@0 1734
aoqi@0 1735 // put the name
aoqi@0 1736 _encap.write_string(_name);
aoqi@0 1737
aoqi@0 1738 // discriminant typecode
aoqi@0 1739 _discriminator.write_value(_encap);
aoqi@0 1740
aoqi@0 1741 // default index
aoqi@0 1742 _encap.write_long(_defaultIndex);
aoqi@0 1743
aoqi@0 1744 // put the number of members
aoqi@0 1745 _encap.write_long(_memberCount);
aoqi@0 1746
aoqi@0 1747 // marshal label values, names and types
aoqi@0 1748 for (int i=0; i < _memberCount; i++) {
aoqi@0 1749
aoqi@0 1750 // for the default case, marshal the zero octet
aoqi@0 1751 if (i == _defaultIndex)
aoqi@0 1752 _encap.write_octet(_unionLabels[i].extract_octet());
aoqi@0 1753
aoqi@0 1754 else {
aoqi@0 1755 switch (realType(_discriminator).kind().value()) {
aoqi@0 1756 case TCKind._tk_short:
aoqi@0 1757 _encap.write_short(_unionLabels[i].extract_short());
aoqi@0 1758 break;
aoqi@0 1759 case TCKind._tk_long:
aoqi@0 1760 _encap.write_long(_unionLabels[i].extract_long());
aoqi@0 1761 break;
aoqi@0 1762 case TCKind._tk_ushort:
aoqi@0 1763 _encap.write_short(_unionLabels[i].extract_ushort());
aoqi@0 1764 break;
aoqi@0 1765 case TCKind._tk_ulong:
aoqi@0 1766 _encap.write_long(_unionLabels[i].extract_ulong());
aoqi@0 1767 break;
aoqi@0 1768 case TCKind._tk_float:
aoqi@0 1769 _encap.write_float(_unionLabels[i].extract_float());
aoqi@0 1770 break;
aoqi@0 1771 case TCKind._tk_double:
aoqi@0 1772 _encap.write_double(_unionLabels[i].extract_double());
aoqi@0 1773 break;
aoqi@0 1774 case TCKind._tk_boolean:
aoqi@0 1775 _encap.write_boolean(_unionLabels[i].extract_boolean());
aoqi@0 1776 break;
aoqi@0 1777 case TCKind._tk_char:
aoqi@0 1778 _encap.write_char(_unionLabels[i].extract_char());
aoqi@0 1779 break;
aoqi@0 1780 case TCKind._tk_enum:
aoqi@0 1781 _encap.write_long(_unionLabels[i].extract_long());
aoqi@0 1782 break;
aoqi@0 1783 case TCKind._tk_longlong:
aoqi@0 1784 _encap.write_longlong(_unionLabels[i].extract_longlong());
aoqi@0 1785 break;
aoqi@0 1786 case TCKind._tk_ulonglong:
aoqi@0 1787 _encap.write_longlong(_unionLabels[i].extract_ulonglong());
aoqi@0 1788 break;
aoqi@0 1789 // _REVISIT_ figure out long double mapping
aoqi@0 1790 // case TCKind.tk_longdouble:
aoqi@0 1791 // _encap.putDouble(_unionLabels[i].extract_longdouble());
aoqi@0 1792 // break;
aoqi@0 1793 case TCKind._tk_wchar:
aoqi@0 1794 _encap.write_wchar(_unionLabels[i].extract_wchar());
aoqi@0 1795 break;
aoqi@0 1796 default:
aoqi@0 1797 throw wrapper.invalidComplexTypecode() ;
aoqi@0 1798 }
aoqi@0 1799 }
aoqi@0 1800 _encap.write_string(_memberNames[i]);
aoqi@0 1801 _memberTypes[i].write_value(_encap);
aoqi@0 1802 }
aoqi@0 1803 }
aoqi@0 1804 break;
aoqi@0 1805
aoqi@0 1806 case TCKind._tk_enum:
aoqi@0 1807 {
aoqi@0 1808 // put the repository id
aoqi@0 1809 _encap.write_string(_id);
aoqi@0 1810
aoqi@0 1811 // put the name
aoqi@0 1812 _encap.write_string(_name);
aoqi@0 1813
aoqi@0 1814 // put the number of members
aoqi@0 1815 _encap.write_long(_memberCount);
aoqi@0 1816
aoqi@0 1817 // marshal identifier names
aoqi@0 1818 for (int i=0; i < _memberCount; i++)
aoqi@0 1819 _encap.write_string(_memberNames[i]);
aoqi@0 1820 }
aoqi@0 1821 break;
aoqi@0 1822
aoqi@0 1823 case TCKind._tk_sequence:
aoqi@0 1824 {
aoqi@0 1825 // put the type of the sequence
aoqi@0 1826 lazy_content_type().write_value(_encap);
aoqi@0 1827
aoqi@0 1828 // put the bound on the length of the sequence
aoqi@0 1829 _encap.write_long(_length);
aoqi@0 1830 }
aoqi@0 1831 break;
aoqi@0 1832
aoqi@0 1833 case TCKind._tk_array:
aoqi@0 1834 {
aoqi@0 1835 // put the type of the array
aoqi@0 1836 _contentType.write_value(_encap);
aoqi@0 1837
aoqi@0 1838 // put the length of the array
aoqi@0 1839 _encap.write_long(_length);
aoqi@0 1840 }
aoqi@0 1841 break;
aoqi@0 1842
aoqi@0 1843 case TCKind._tk_alias:
aoqi@0 1844 case TCKind._tk_value_box:
aoqi@0 1845 {
aoqi@0 1846 // put the repository id
aoqi@0 1847 _encap.write_string(_id);
aoqi@0 1848
aoqi@0 1849 // put the name
aoqi@0 1850 _encap.write_string(_name);
aoqi@0 1851
aoqi@0 1852 // put the type aliased
aoqi@0 1853 _contentType.write_value(_encap);
aoqi@0 1854 }
aoqi@0 1855 break;
aoqi@0 1856
aoqi@0 1857 case TCKind._tk_struct:
aoqi@0 1858 case TCKind._tk_except:
aoqi@0 1859 {
aoqi@0 1860 // put the repository id
aoqi@0 1861 _encap.write_string(_id);
aoqi@0 1862
aoqi@0 1863 // put the name
aoqi@0 1864 _encap.write_string(_name);
aoqi@0 1865
aoqi@0 1866 // put the number of members
aoqi@0 1867 _encap.write_long(_memberCount);
aoqi@0 1868
aoqi@0 1869 // marshal member names and types
aoqi@0 1870 for (int i=0; i < _memberCount; i++) {
aoqi@0 1871 _encap.write_string(_memberNames[i]);
aoqi@0 1872 //if (debug) System.out.println("TypeCode " + _name +
aoqi@0 1873 // " writing member " + _memberNames[i]);
aoqi@0 1874 _memberTypes[i].write_value(_encap);
aoqi@0 1875 }
aoqi@0 1876 }
aoqi@0 1877 break;
aoqi@0 1878
aoqi@0 1879 case TCKind._tk_value:
aoqi@0 1880 {
aoqi@0 1881 // put the repository id
aoqi@0 1882 _encap.write_string(_id);
aoqi@0 1883
aoqi@0 1884 // put the name
aoqi@0 1885 _encap.write_string(_name);
aoqi@0 1886
aoqi@0 1887 // put the type modifier
aoqi@0 1888 _encap.write_short(_type_modifier);
aoqi@0 1889
aoqi@0 1890 // put the type aliased
aoqi@0 1891 if (_concrete_base == null) {
aoqi@0 1892 _orb.get_primitive_tc(TCKind._tk_null).write_value(_encap);
aoqi@0 1893 } else {
aoqi@0 1894 _concrete_base.write_value(_encap);
aoqi@0 1895 }
aoqi@0 1896
aoqi@0 1897 // put the number of members
aoqi@0 1898 _encap.write_long(_memberCount);
aoqi@0 1899
aoqi@0 1900 // marshal member names and types
aoqi@0 1901 for (int i=0; i < _memberCount; i++) {
aoqi@0 1902 _encap.write_string(_memberNames[i]);
aoqi@0 1903 //if (debug) System.out.println("TypeCode " + _name +
aoqi@0 1904 // " writing member " + _memberNames[i]);
aoqi@0 1905 _memberTypes[i].write_value(_encap);
aoqi@0 1906 _encap.write_short(_memberAccess[i]);
aoqi@0 1907 }
aoqi@0 1908 }
aoqi@0 1909 break;
aoqi@0 1910
aoqi@0 1911 default:
aoqi@0 1912 throw wrapper.invalidTypecodeKindMarshal() ;
aoqi@0 1913 }
aoqi@0 1914
aoqi@0 1915 // marshal the encapsulation
aoqi@0 1916 _encap.writeOctetSequenceTo(tcos);
aoqi@0 1917 break;
aoqi@0 1918 }
aoqi@0 1919 }
aoqi@0 1920 }
aoqi@0 1921
aoqi@0 1922 /**
aoqi@0 1923 * This is not a copy of the TypeCodeImpl objects, but instead it
aoqi@0 1924 * copies the value this type code is representing.
aoqi@0 1925 * See AnyImpl read_value and write_value for usage.
aoqi@0 1926 * The state of this TypeCodeImpl instance isn't changed, only used
aoqi@0 1927 * by the Any to do the correct copy.
aoqi@0 1928 */
aoqi@0 1929 protected void copy(org.omg.CORBA.portable.InputStream src,
aoqi@0 1930 org.omg.CORBA.portable.OutputStream dst)
aoqi@0 1931 {
aoqi@0 1932 switch (_kind) {
aoqi@0 1933
aoqi@0 1934 case TCKind._tk_null:
aoqi@0 1935 case TCKind._tk_void:
aoqi@0 1936 case TCKind._tk_native:
aoqi@0 1937 case TCKind._tk_abstract_interface:
aoqi@0 1938 break;
aoqi@0 1939
aoqi@0 1940 case TCKind._tk_short:
aoqi@0 1941 case TCKind._tk_ushort:
aoqi@0 1942 dst.write_short(src.read_short());
aoqi@0 1943 break;
aoqi@0 1944
aoqi@0 1945 case TCKind._tk_long:
aoqi@0 1946 case TCKind._tk_ulong:
aoqi@0 1947 dst.write_long(src.read_long());
aoqi@0 1948 break;
aoqi@0 1949
aoqi@0 1950 case TCKind._tk_float:
aoqi@0 1951 dst.write_float(src.read_float());
aoqi@0 1952 break;
aoqi@0 1953
aoqi@0 1954 case TCKind._tk_double:
aoqi@0 1955 dst.write_double(src.read_double());
aoqi@0 1956 break;
aoqi@0 1957
aoqi@0 1958 case TCKind._tk_longlong:
aoqi@0 1959 case TCKind._tk_ulonglong:
aoqi@0 1960 dst.write_longlong(src.read_longlong());
aoqi@0 1961 break;
aoqi@0 1962
aoqi@0 1963 case TCKind._tk_longdouble:
aoqi@0 1964 throw wrapper.tkLongDoubleNotSupported() ;
aoqi@0 1965
aoqi@0 1966 case TCKind._tk_boolean:
aoqi@0 1967 dst.write_boolean(src.read_boolean());
aoqi@0 1968 break;
aoqi@0 1969
aoqi@0 1970 case TCKind._tk_char:
aoqi@0 1971 dst.write_char(src.read_char());
aoqi@0 1972 break;
aoqi@0 1973
aoqi@0 1974 case TCKind._tk_wchar:
aoqi@0 1975 dst.write_wchar(src.read_wchar());
aoqi@0 1976 break;
aoqi@0 1977
aoqi@0 1978 case TCKind._tk_octet:
aoqi@0 1979 dst.write_octet(src.read_octet());
aoqi@0 1980 break;
aoqi@0 1981
aoqi@0 1982 case TCKind._tk_string:
aoqi@0 1983 {
aoqi@0 1984 String s;
aoqi@0 1985 s = src.read_string();
aoqi@0 1986 // make sure length bound in typecode is not violated
aoqi@0 1987 if ((_length != 0) && (s.length() > _length))
aoqi@0 1988 throw wrapper.badStringBounds( new Integer(s.length()),
aoqi@0 1989 new Integer(_length) ) ;
aoqi@0 1990 dst.write_string(s);
aoqi@0 1991 }
aoqi@0 1992 break;
aoqi@0 1993
aoqi@0 1994 case TCKind._tk_wstring:
aoqi@0 1995 {
aoqi@0 1996 String s;
aoqi@0 1997 s = src.read_wstring();
aoqi@0 1998 // make sure length bound in typecode is not violated
aoqi@0 1999 if ((_length != 0) && (s.length() > _length))
aoqi@0 2000 throw wrapper.badStringBounds( new Integer(s.length()),
aoqi@0 2001 new Integer(_length) ) ;
aoqi@0 2002 dst.write_wstring(s);
aoqi@0 2003 }
aoqi@0 2004 break;
aoqi@0 2005
aoqi@0 2006 case TCKind._tk_fixed:
aoqi@0 2007 {
aoqi@0 2008 dst.write_ushort(src.read_ushort());
aoqi@0 2009 dst.write_short(src.read_short());
aoqi@0 2010 }
aoqi@0 2011 break;
aoqi@0 2012
aoqi@0 2013 case TCKind._tk_any:
aoqi@0 2014 {
aoqi@0 2015 //Any tmp = new AnyImpl(_orb);
aoqi@0 2016 Any tmp = ((CDRInputStream)src).orb().create_any();
aoqi@0 2017 TypeCodeImpl t = new TypeCodeImpl((ORB)dst.orb());
aoqi@0 2018 t.read_value((org.omg.CORBA_2_3.portable.InputStream)src);
aoqi@0 2019 t.write_value((org.omg.CORBA_2_3.portable.OutputStream)dst);
aoqi@0 2020 tmp.read_value(src, t);
aoqi@0 2021 tmp.write_value(dst);
aoqi@0 2022 break;
aoqi@0 2023 }
aoqi@0 2024
aoqi@0 2025 case TCKind._tk_TypeCode:
aoqi@0 2026 {
aoqi@0 2027 dst.write_TypeCode(src.read_TypeCode());
aoqi@0 2028 break;
aoqi@0 2029 }
aoqi@0 2030
aoqi@0 2031 case TCKind._tk_Principal:
aoqi@0 2032 {
aoqi@0 2033 dst.write_Principal(src.read_Principal());
aoqi@0 2034 break;
aoqi@0 2035 }
aoqi@0 2036
aoqi@0 2037 case TCKind._tk_objref:
aoqi@0 2038 {
aoqi@0 2039 dst.write_Object(src.read_Object());
aoqi@0 2040 break;
aoqi@0 2041 }
aoqi@0 2042
aoqi@0 2043 case TCKind._tk_except:
aoqi@0 2044 // Copy repositoryId
aoqi@0 2045 dst.write_string(src.read_string());
aoqi@0 2046
aoqi@0 2047 // Fall into ...
aoqi@0 2048 // _REVISIT_ what about the inherited members of this values concrete base type?
aoqi@0 2049 case TCKind._tk_value:
aoqi@0 2050 case TCKind._tk_struct:
aoqi@0 2051 {
aoqi@0 2052 // copy each element, using the corresponding member type
aoqi@0 2053 for (int i=0; i < _memberTypes.length; i++) {
aoqi@0 2054 _memberTypes[i].copy(src, dst);
aoqi@0 2055 }
aoqi@0 2056 break;
aoqi@0 2057 }
aoqi@0 2058 case TCKind._tk_union:
aoqi@0 2059 /* _REVISIT_ More generic code?
aoqi@0 2060 {
aoqi@0 2061 Any discriminator = new AnyImpl(_orb);
aoqi@0 2062 discriminator.read_value(src, _discriminator);
aoqi@0 2063 discriminator.write_value(dst);
aoqi@0 2064 int labelIndex = currentUnionMemberIndex(discriminator);
aoqi@0 2065 if (labelIndex == -1) {
aoqi@0 2066 // check if label has not been found
aoqi@0 2067 if (_defaultIndex == -1)
aoqi@0 2068 // throw exception if default was not expected
aoqi@0 2069 throw new MARSHAL();
aoqi@0 2070 else
aoqi@0 2071 // must be of the default branch type
aoqi@0 2072 _memberTypes[_defaultIndex].copy(src, dst);
aoqi@0 2073 } else {
aoqi@0 2074 _memberTypes[labelIndex].copy(src, dst);
aoqi@0 2075 }
aoqi@0 2076 }
aoqi@0 2077 */
aoqi@0 2078 {
aoqi@0 2079 Any tagValue = new AnyImpl( (ORB)src.orb());
aoqi@0 2080
aoqi@0 2081 switch (realType(_discriminator).kind().value()) {
aoqi@0 2082 case TCKind._tk_short:
aoqi@0 2083 {
aoqi@0 2084 short value = src.read_short();
aoqi@0 2085 tagValue.insert_short(value);
aoqi@0 2086 dst.write_short(value);
aoqi@0 2087 break;
aoqi@0 2088 }
aoqi@0 2089 case TCKind._tk_long:
aoqi@0 2090 {
aoqi@0 2091 int value = src.read_long();
aoqi@0 2092 tagValue.insert_long(value);
aoqi@0 2093 dst.write_long(value);
aoqi@0 2094 break;
aoqi@0 2095 }
aoqi@0 2096 case TCKind._tk_ushort:
aoqi@0 2097 {
aoqi@0 2098 short value = src.read_short();
aoqi@0 2099 tagValue.insert_ushort(value);
aoqi@0 2100 dst.write_short(value);
aoqi@0 2101 break;
aoqi@0 2102 }
aoqi@0 2103 case TCKind._tk_ulong:
aoqi@0 2104 {
aoqi@0 2105 int value = src.read_long();
aoqi@0 2106 tagValue.insert_ulong(value);
aoqi@0 2107 dst.write_long(value);
aoqi@0 2108 break;
aoqi@0 2109 }
aoqi@0 2110 case TCKind._tk_float:
aoqi@0 2111 {
aoqi@0 2112 float value = src.read_float();
aoqi@0 2113 tagValue.insert_float(value);
aoqi@0 2114 dst.write_float(value);
aoqi@0 2115 break;
aoqi@0 2116 }
aoqi@0 2117 case TCKind._tk_double:
aoqi@0 2118 {
aoqi@0 2119 double value = src.read_double();
aoqi@0 2120 tagValue.insert_double(value);
aoqi@0 2121 dst.write_double(value);
aoqi@0 2122 break;
aoqi@0 2123 }
aoqi@0 2124 case TCKind._tk_boolean:
aoqi@0 2125 {
aoqi@0 2126 boolean value = src.read_boolean();
aoqi@0 2127 tagValue.insert_boolean(value);
aoqi@0 2128 dst.write_boolean(value);
aoqi@0 2129 break;
aoqi@0 2130 }
aoqi@0 2131 case TCKind._tk_char:
aoqi@0 2132 {
aoqi@0 2133 char value = src.read_char();
aoqi@0 2134 tagValue.insert_char(value);
aoqi@0 2135 dst.write_char(value);
aoqi@0 2136 break;
aoqi@0 2137 }
aoqi@0 2138 case TCKind._tk_enum:
aoqi@0 2139 {
aoqi@0 2140 int value = src.read_long();
aoqi@0 2141 tagValue.type(_discriminator);
aoqi@0 2142 tagValue.insert_long(value);
aoqi@0 2143 dst.write_long(value);
aoqi@0 2144 break;
aoqi@0 2145 }
aoqi@0 2146 case TCKind._tk_longlong:
aoqi@0 2147 {
aoqi@0 2148 long value = src.read_longlong();
aoqi@0 2149 tagValue.insert_longlong(value);
aoqi@0 2150 dst.write_longlong(value);
aoqi@0 2151 break;
aoqi@0 2152 }
aoqi@0 2153 case TCKind._tk_ulonglong:
aoqi@0 2154 {
aoqi@0 2155 long value = src.read_longlong();
aoqi@0 2156 tagValue.insert_ulonglong(value);
aoqi@0 2157 dst.write_longlong(value);
aoqi@0 2158 break;
aoqi@0 2159 }
aoqi@0 2160 // _REVISIT_ figure out long double mapping
aoqi@0 2161 // case TCKind.tk_longdouble:
aoqi@0 2162 // {
aoqi@0 2163 // double value = src.read_double();
aoqi@0 2164 // tagValue.insert_longdouble(value);
aoqi@0 2165 // dst.putDouble(value);
aoqi@0 2166 // break;
aoqi@0 2167 //}
aoqi@0 2168 case TCKind._tk_wchar:
aoqi@0 2169 {
aoqi@0 2170 char value = src.read_wchar();
aoqi@0 2171 tagValue.insert_wchar(value);
aoqi@0 2172 dst.write_wchar(value);
aoqi@0 2173 break;
aoqi@0 2174 }
aoqi@0 2175 default:
aoqi@0 2176 throw wrapper.illegalUnionDiscriminatorType() ;
aoqi@0 2177 }
aoqi@0 2178
aoqi@0 2179 // using the value of the tag, find out the type of the value
aoqi@0 2180 // following.
aoqi@0 2181
aoqi@0 2182 int labelIndex;
aoqi@0 2183 for (labelIndex = 0; labelIndex < _unionLabels.length; labelIndex++) {
aoqi@0 2184 // use equality over anys
aoqi@0 2185 if (tagValue.equal(_unionLabels[labelIndex])) {
aoqi@0 2186 _memberTypes[labelIndex].copy(src, dst);
aoqi@0 2187 break;
aoqi@0 2188 }
aoqi@0 2189 }
aoqi@0 2190
aoqi@0 2191 if (labelIndex == _unionLabels.length) {
aoqi@0 2192 // check if label has not been found
aoqi@0 2193 if (_defaultIndex != -1)
aoqi@0 2194 // must be of the default branch type
aoqi@0 2195 _memberTypes[_defaultIndex].copy(src, dst);
aoqi@0 2196 }
aoqi@0 2197 break;
aoqi@0 2198 }
aoqi@0 2199
aoqi@0 2200 case TCKind._tk_enum:
aoqi@0 2201 dst.write_long(src.read_long());
aoqi@0 2202 break;
aoqi@0 2203
aoqi@0 2204 case TCKind._tk_sequence:
aoqi@0 2205 // get the length of the sequence
aoqi@0 2206 int seqLength = src.read_long();
aoqi@0 2207
aoqi@0 2208 // check for sequence bound violated
aoqi@0 2209 if ((_length != 0) && (seqLength > _length))
aoqi@0 2210 throw wrapper.badSequenceBounds( new Integer(seqLength),
aoqi@0 2211 new Integer(_length) ) ;
aoqi@0 2212
aoqi@0 2213 // write the length of the sequence
aoqi@0 2214 dst.write_long(seqLength);
aoqi@0 2215
aoqi@0 2216 // copy each element of the seq using content type
aoqi@0 2217 lazy_content_type(); // make sure it's resolved
aoqi@0 2218 for (int i=0; i < seqLength; i++)
aoqi@0 2219 _contentType.copy(src, dst);
aoqi@0 2220 break;
aoqi@0 2221
aoqi@0 2222 case TCKind._tk_array:
aoqi@0 2223 // copy each element of the array using content type
aoqi@0 2224 for (int i=0; i < _length; i++)
aoqi@0 2225 _contentType.copy(src, dst);
aoqi@0 2226 break;
aoqi@0 2227
aoqi@0 2228 case TCKind._tk_alias:
aoqi@0 2229 case TCKind._tk_value_box:
aoqi@0 2230 // follow the alias
aoqi@0 2231 _contentType.copy(src, dst);
aoqi@0 2232 break;
aoqi@0 2233
aoqi@0 2234 case tk_indirect:
aoqi@0 2235 // need to follow offset, get unmarshal typecode from that
aoqi@0 2236 // offset, and use that to do the copy
aoqi@0 2237 // Don't need to read type code before using it to do the copy.
aoqi@0 2238 // It should be fully usable.
aoqi@0 2239 indirectType().copy(src, dst);
aoqi@0 2240 break;
aoqi@0 2241
aoqi@0 2242 default:
aoqi@0 2243 throw wrapper.invalidTypecodeKindMarshal() ;
aoqi@0 2244 }
aoqi@0 2245 }
aoqi@0 2246
aoqi@0 2247
aoqi@0 2248 static protected short digits(java.math.BigDecimal value) {
aoqi@0 2249 if (value == null)
aoqi@0 2250 return 0;
aoqi@0 2251 short length = (short)value.unscaledValue().toString().length();
aoqi@0 2252 if (value.signum() == -1)
aoqi@0 2253 length--;
aoqi@0 2254 return length;
aoqi@0 2255 }
aoqi@0 2256
aoqi@0 2257 static protected short scale(java.math.BigDecimal value) {
aoqi@0 2258 if (value == null)
aoqi@0 2259 return 0;
aoqi@0 2260 return (short)value.scale();
aoqi@0 2261 }
aoqi@0 2262
aoqi@0 2263 // Utility methods
aoqi@0 2264
aoqi@0 2265 // Only for union type. Returns the index of the union member
aoqi@0 2266 // corresponding to the discriminator. If not found returns the
aoqi@0 2267 // default index or -1 if there is no default index.
aoqi@0 2268 int currentUnionMemberIndex(Any discriminatorValue) throws BadKind {
aoqi@0 2269 if (_kind != TCKind._tk_union)
aoqi@0 2270 throw new BadKind();
aoqi@0 2271
aoqi@0 2272 try {
aoqi@0 2273 for (int i=0; i<member_count(); i++) {
aoqi@0 2274 if (member_label(i).equal(discriminatorValue)) {
aoqi@0 2275 return i;
aoqi@0 2276 }
aoqi@0 2277 }
aoqi@0 2278 if (_defaultIndex != -1) {
aoqi@0 2279 return _defaultIndex;
aoqi@0 2280 }
aoqi@0 2281 } catch (BadKind bad) {
aoqi@0 2282 } catch (org.omg.CORBA.TypeCodePackage.Bounds bounds) {
aoqi@0 2283 }
aoqi@0 2284 return -1;
aoqi@0 2285 }
aoqi@0 2286
aoqi@0 2287 public String description() {
aoqi@0 2288 return "TypeCodeImpl with kind " + _kind + " and id " + _id;
aoqi@0 2289 }
aoqi@0 2290
aoqi@0 2291 public String toString() {
aoqi@0 2292 ByteArrayOutputStream byteOut = new ByteArrayOutputStream(1024);
aoqi@0 2293 PrintStream printOut = new PrintStream(byteOut, true);
aoqi@0 2294 printStream(printOut);
aoqi@0 2295 return super.toString() + " =\n" + byteOut.toString();
aoqi@0 2296 }
aoqi@0 2297
aoqi@0 2298 public void printStream(PrintStream s) {
aoqi@0 2299 printStream(s, 0);
aoqi@0 2300 }
aoqi@0 2301
aoqi@0 2302 private void printStream(PrintStream s, int level) {
aoqi@0 2303 if (_kind == tk_indirect) {
aoqi@0 2304 s.print("indirect " + _id);
aoqi@0 2305 return;
aoqi@0 2306 }
aoqi@0 2307
aoqi@0 2308 switch (_kind) {
aoqi@0 2309 case TCKind._tk_null:
aoqi@0 2310 case TCKind._tk_void:
aoqi@0 2311 case TCKind._tk_short:
aoqi@0 2312 case TCKind._tk_long:
aoqi@0 2313 case TCKind._tk_ushort:
aoqi@0 2314 case TCKind._tk_ulong:
aoqi@0 2315 case TCKind._tk_float:
aoqi@0 2316 case TCKind._tk_double:
aoqi@0 2317 case TCKind._tk_boolean:
aoqi@0 2318 case TCKind._tk_char:
aoqi@0 2319 case TCKind._tk_octet:
aoqi@0 2320 case TCKind._tk_any:
aoqi@0 2321 case TCKind._tk_TypeCode:
aoqi@0 2322 case TCKind._tk_Principal:
aoqi@0 2323 case TCKind._tk_objref:
aoqi@0 2324 case TCKind._tk_longlong:
aoqi@0 2325 case TCKind._tk_ulonglong:
aoqi@0 2326 case TCKind._tk_longdouble:
aoqi@0 2327 case TCKind._tk_wchar:
aoqi@0 2328 case TCKind._tk_native:
aoqi@0 2329 s.print(kindNames[_kind] + " " + _name);
aoqi@0 2330 break;
aoqi@0 2331
aoqi@0 2332 case TCKind._tk_struct:
aoqi@0 2333 case TCKind._tk_except:
aoqi@0 2334 case TCKind._tk_value:
aoqi@0 2335 s.println(kindNames[_kind] + " " + _name + " = {");
aoqi@0 2336 for(int i=0; i<_memberCount; i++) {
aoqi@0 2337 // memberName might differ from the name of the member.
aoqi@0 2338 s.print(indent(level + 1));
aoqi@0 2339 if (_memberTypes[i] != null)
aoqi@0 2340 _memberTypes[i].printStream(s, level + 1);
aoqi@0 2341 else
aoqi@0 2342 s.print("<unknown type>");
aoqi@0 2343 s.println(" " + _memberNames[i] + ";");
aoqi@0 2344 }
aoqi@0 2345 s.print(indent(level) + "}");
aoqi@0 2346 break;
aoqi@0 2347
aoqi@0 2348 case TCKind._tk_union:
aoqi@0 2349 s.print("union " + _name + "...");
aoqi@0 2350 break;
aoqi@0 2351
aoqi@0 2352 case TCKind._tk_enum:
aoqi@0 2353 s.print("enum " + _name + "...");
aoqi@0 2354 break;
aoqi@0 2355
aoqi@0 2356 case TCKind._tk_string:
aoqi@0 2357 if (_length == 0)
aoqi@0 2358 s.print("unbounded string " + _name);
aoqi@0 2359 else
aoqi@0 2360 s.print("bounded string(" + _length + ") " + _name);
aoqi@0 2361 break;
aoqi@0 2362
aoqi@0 2363 case TCKind._tk_sequence:
aoqi@0 2364 case TCKind._tk_array:
aoqi@0 2365 s.println(kindNames[_kind] + "[" + _length + "] " + _name + " = {");
aoqi@0 2366 s.print(indent(level + 1));
aoqi@0 2367 if (lazy_content_type() != null) {
aoqi@0 2368 lazy_content_type().printStream(s, level + 1);
aoqi@0 2369 }
aoqi@0 2370 s.println(indent(level) + "}");
aoqi@0 2371 break;
aoqi@0 2372
aoqi@0 2373 case TCKind._tk_alias:
aoqi@0 2374 s.print("alias " + _name + " = " +
aoqi@0 2375 (_contentType != null ? _contentType._name : "<unresolved>"));
aoqi@0 2376 break;
aoqi@0 2377
aoqi@0 2378 case TCKind._tk_wstring:
aoqi@0 2379 s.print("wstring[" + _length + "] " + _name);
aoqi@0 2380 break;
aoqi@0 2381
aoqi@0 2382 case TCKind._tk_fixed:
aoqi@0 2383 s.print("fixed(" + _digits + ", " + _scale + ") " + _name);
aoqi@0 2384 break;
aoqi@0 2385
aoqi@0 2386 case TCKind._tk_value_box:
aoqi@0 2387 s.print("valueBox " + _name + "...");
aoqi@0 2388 break;
aoqi@0 2389
aoqi@0 2390 case TCKind._tk_abstract_interface:
aoqi@0 2391 s.print("abstractInterface " + _name + "...");
aoqi@0 2392 break;
aoqi@0 2393
aoqi@0 2394 default:
aoqi@0 2395 s.print("<unknown type>");
aoqi@0 2396 break;
aoqi@0 2397 }
aoqi@0 2398 }
aoqi@0 2399
aoqi@0 2400 private String indent(int level) {
aoqi@0 2401 String indent = "";
aoqi@0 2402 for(int i=0; i<level; i++) {
aoqi@0 2403 indent += " ";
aoqi@0 2404 }
aoqi@0 2405 return indent;
aoqi@0 2406 }
aoqi@0 2407
aoqi@0 2408 protected void setCaching(boolean enableCaching) {
aoqi@0 2409 cachingEnabled = enableCaching;
aoqi@0 2410 if (enableCaching == false)
aoqi@0 2411 outBuffer = null;
aoqi@0 2412 }
aoqi@0 2413 }

mercurial