1. /*
  2. * @(#)IIOPInputStream.java 1.60 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.iiop;
  8. import java.io.IOException;
  9. import org.omg.CORBA.SystemException;
  10. import org.omg.CORBA.CompletionStatus;
  11. import org.omg.CORBA.INTERNAL;
  12. import org.omg.CORBA.MARSHAL;
  13. import org.omg.CORBA.DATA_CONVERSION;
  14. import org.omg.CORBA.BAD_PARAM;
  15. import org.omg.CORBA.INV_OBJREF;
  16. import org.omg.CORBA.Object;
  17. import org.omg.CORBA.Principal;
  18. import org.omg.CORBA.TypeCode;
  19. import org.omg.CORBA.Any;
  20. import org.omg.CORBA.CompletionStatus;
  21. import com.sun.org.omg.SendingContext.CodeBase;
  22. import com.sun.corba.se.internal.orbutil.MinorCodes;
  23. import com.sun.corba.se.internal.orbutil.ORBUtility;
  24. import com.sun.corba.se.internal.iiop.ByteBufferWithInfo;
  25. import com.sun.corba.se.internal.iiop.messages.Message;
  26. import com.sun.corba.se.internal.core.GIOPVersion;
  27. import com.sun.corba.se.internal.core.CodeSetConversion;
  28. import com.sun.corba.se.internal.core.OSFCodeSetRegistry;
  29. import com.sun.corba.se.internal.core.CodeSetComponentInfo;
  30. public class IIOPInputStream extends CDRInputStream
  31. {
  32. protected Connection conn;
  33. protected Message msg = null;
  34. private boolean unmarshaledHeader;
  35. private void dprint( String msg ) {
  36. ORBUtility.dprint( this, msg ) ;
  37. }
  38. public IIOPInputStream() {
  39. }
  40. private IIOPInputStream(IIOPInputStream stream) {
  41. super(stream);
  42. this.conn = stream.conn;
  43. this.msg = stream.msg;
  44. this.unmarshaledHeader = stream.unmarshaledHeader;
  45. }
  46. public CDRInputStream dup() {
  47. return new IIOPInputStream(this);
  48. }
  49. // Used by
  50. // IIOPOutputStream
  51. public IIOPInputStream(ORB orb, byte[] msgbuf, int msgsize, boolean endian,
  52. Message msg, Connection conn)
  53. {
  54. super(orb, msgbuf, msgsize, endian, msg.getGIOPVersion(), false);
  55. getBufferManager().init(msg);
  56. unmarshaledHeader = true;
  57. this.msg = msg;
  58. this.conn = conn;
  59. }
  60. // Used by
  61. // IIOPConnection
  62. // ClientResponseImpl
  63. // ServerRequestImpl
  64. // ...
  65. public IIOPInputStream(Connection c, byte[] msgbuf, Message header)
  66. throws java.io.IOException
  67. {
  68. super(c.getORB(),
  69. msgbuf,
  70. header.getSize(),
  71. header.isLittleEndian(),
  72. header.getGIOPVersion());
  73. getBufferManager().init(header);
  74. this.conn = c;
  75. com.sun.corba.se.internal.corba.ORB theORB = (com.sun.corba.se.internal.corba.ORB)(c.getORB()) ;
  76. if (theORB.transportDebugFlag)
  77. dprint( "Constructing IIOPInputStream object" ) ;
  78. this.msg = header;
  79. unmarshaledHeader = false;
  80. setIndex(Message.GIOPMessageHeaderLength);
  81. setBufferLength(msg.getSize());
  82. if (theORB.transportDebugFlag)
  83. dprint( "Setting the time stamp" ) ;
  84. c.stampTime();
  85. }
  86. /**
  87. * Unmarshal the extended GIOP header (may be fragmented, so
  88. * shouldn't be called by the ReaderThread)
  89. */
  90. public void unmarshalHeader()
  91. {
  92. //if (theORB.transportDebugFlag)
  93. // dprint( "Unmarshalling the GIOP message" ) ;
  94. // Unmarshal the extended GIOP message from the buffer.
  95. if (!unmarshaledHeader) {
  96. msg.read(this);
  97. unmarshaledHeader= true;
  98. }
  99. }
  100. public final boolean unmarshaledHeader() {
  101. return unmarshaledHeader;
  102. }
  103. public final Connection getConnection() {
  104. return conn;
  105. }
  106. // once response stream is created, its connection should not be altered.
  107. /*
  108. public final void setConnection(Connection c) {
  109. this.conn = c;
  110. // to avoid null pointer exception for the local case
  111. if (c != null) {
  112. orb(c.getORB());
  113. }
  114. }
  115. */
  116. public final Message getMessage() {
  117. return msg;
  118. }
  119. /*
  120. This must not be allowed. The message should be the same
  121. regardless of fragmentation.
  122. public final void setMessage(Message msg) {
  123. this.msg = msg;
  124. }
  125. */
  126. //
  127. // We ran out of things to read. We pre-read everything
  128. // off of the java.io.InputStream in IIOPConnection.createInputStream()
  129. // so this can't happen normally.
  130. //
  131. protected void grow(int align, int n) {
  132. throw new MARSHAL(MinorCodes.IIOPINPUTSTREAM_GROW,
  133. CompletionStatus.COMPLETED_MAYBE);
  134. }
  135. public CodeBase getCodeBase() {
  136. if (conn == null)
  137. return null;
  138. else
  139. return conn.getCodeBase();
  140. }
  141. /**
  142. * Override the default CDR factory behavior to get the
  143. * negotiated code sets from the connection.
  144. *
  145. * These are only called once per message, the first time needed.
  146. *
  147. * In the local case, there is no Connection, so use the
  148. * local code sets.
  149. */
  150. protected CodeSetConversion.BTCConverter createCharBTCConverter() {
  151. CodeSetComponentInfo.CodeSetContext codesets = getCodeSets();
  152. // If the connection doesn't have its negotiated
  153. // code sets by now, fall back on the defaults defined
  154. // in CDRInputStream.
  155. if (codesets == null)
  156. return super.createCharBTCConverter();
  157. OSFCodeSetRegistry.Entry charSet
  158. = OSFCodeSetRegistry.lookupEntry(codesets.getCharCodeSet());
  159. if (charSet == null)
  160. throw new MARSHAL("Unknown char set: " + charSet,
  161. MinorCodes.UNKNOWN_CODESET,
  162. CompletionStatus.COMPLETED_NO);
  163. return CodeSetConversion.impl().getBTCConverter(charSet, isLittleEndian());
  164. }
  165. protected CodeSetConversion.BTCConverter createWCharBTCConverter() {
  166. CodeSetComponentInfo.CodeSetContext codesets = getCodeSets();
  167. // If the connection doesn't have its negotiated
  168. // code sets by now, we have to throw an exception.
  169. // See CORBA formal 00-11-03 13.9.2.6.
  170. if (codesets == null) {
  171. if (conn.isServer())
  172. throw new BAD_PARAM(MinorCodes.NO_CLIENT_WCHAR_CODESET_CTX,
  173. CompletionStatus.COMPLETED_MAYBE);
  174. else
  175. throw new INV_OBJREF(MinorCodes.NO_SERVER_WCHAR_CODESET_CMP,
  176. CompletionStatus.COMPLETED_NO);
  177. }
  178. OSFCodeSetRegistry.Entry wcharSet
  179. = OSFCodeSetRegistry.lookupEntry(codesets.getWCharCodeSet());
  180. if (wcharSet == null)
  181. throw new MARSHAL("Unknown wchar set: " + wcharSet,
  182. MinorCodes.UNKNOWN_CODESET,
  183. CompletionStatus.COMPLETED_NO);
  184. // For GIOP 1.2 and UTF-16, use big endian if there is no byte
  185. // order marker. (See issue 3405b)
  186. //
  187. // For GIOP 1.1 and UTF-16, use the byte order the stream if
  188. // there isn't (and there shouldn't be) a byte order marker.
  189. //
  190. // GIOP 1.0 doesn't have wchars. If we're talking to a legacy ORB,
  191. // we do what our old ORBs did.
  192. if (wcharSet == OSFCodeSetRegistry.UTF_16) {
  193. if (getGIOPVersion().equals(GIOPVersion.V1_2))
  194. return CodeSetConversion.impl().getBTCConverter(wcharSet, false);
  195. }
  196. return CodeSetConversion.impl().getBTCConverter(wcharSet, isLittleEndian());
  197. }
  198. // If we're local and don't have a Connection, use the
  199. // local code sets, otherwise get them from the connection.
  200. // If the connection doesn't have negotiated code sets
  201. // yet, then we use ISO8859-1 for char/string and wchar/wstring
  202. // are illegal.
  203. private CodeSetComponentInfo.CodeSetContext getCodeSets() {
  204. if (conn == null)
  205. return CodeSetComponentInfo.LOCAL_CODE_SETS;
  206. else
  207. return conn.getCodeSetContext();
  208. }
  209. }