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