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