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