1. /*
  2. * @(#)CDRInputObject.java 1.38 04/06/21
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.impl.encoding;
  8. import java.nio.ByteBuffer;
  9. import com.sun.org.omg.SendingContext.CodeBase;
  10. import com.sun.corba.se.pept.encoding.InputObject;
  11. import com.sun.corba.se.spi.logging.CORBALogDomains;
  12. import com.sun.corba.se.spi.orb.ORB;
  13. import com.sun.corba.se.spi.transport.CorbaConnection;
  14. import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
  15. import com.sun.corba.se.impl.encoding.BufferManagerFactory;
  16. import com.sun.corba.se.impl.encoding.CodeSetComponentInfo;
  17. import com.sun.corba.se.impl.encoding.CodeSetConversion;
  18. import com.sun.corba.se.impl.encoding.OSFCodeSetRegistry;
  19. import com.sun.corba.se.impl.encoding.CDRInputStream;
  20. import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;
  21. import com.sun.corba.se.impl.logging.ORBUtilSystemException;
  22. import com.sun.corba.se.impl.logging.OMGSystemException;
  23. import com.sun.corba.se.impl.orbutil.ORBUtility;
  24. /**
  25. * @author Harold Carr
  26. */
  27. public class CDRInputObject extends CDRInputStream
  28. implements
  29. InputObject
  30. {
  31. private CorbaConnection corbaConnection;
  32. private Message header;
  33. private boolean unmarshaledHeader;
  34. private ORB orb ;
  35. private ORBUtilSystemException wrapper ;
  36. private OMGSystemException omgWrapper ;
  37. public CDRInputObject(ORB orb,
  38. CorbaConnection corbaConnection,
  39. ByteBuffer byteBuffer,
  40. Message header)
  41. {
  42. super(orb, byteBuffer, header.getSize(), header.isLittleEndian(),
  43. header.getGIOPVersion(), header.getEncodingVersion(),
  44. BufferManagerFactory.newBufferManagerRead(
  45. header.getGIOPVersion(),
  46. header.getEncodingVersion(),
  47. orb));
  48. this.corbaConnection = corbaConnection;
  49. this.orb = orb ;
  50. this.wrapper = ORBUtilSystemException.get( orb,
  51. CORBALogDomains.RPC_ENCODING ) ;
  52. this.omgWrapper = OMGSystemException.get( orb,
  53. CORBALogDomains.RPC_ENCODING ) ;
  54. if (orb.transportDebugFlag) {
  55. dprint(".CDRInputObject constructor:");
  56. }
  57. getBufferManager().init(header);
  58. this.header = header;
  59. unmarshaledHeader = false;
  60. setIndex(Message.GIOPMessageHeaderLength);
  61. setBufferLength(header.getSize());
  62. }
  63. // REVISIT - think about this some more.
  64. // This connection normally is accessed from the message mediator.
  65. // However, giop input needs to get code set info from the connetion
  66. // *before* the message mediator is available.
  67. public final CorbaConnection getConnection()
  68. {
  69. return corbaConnection;
  70. }
  71. // XREVISIT - Should the header be kept in the stream or the
  72. // message mediator? Or should we not have a header and
  73. // have the information stored in the message mediator
  74. // directly?
  75. public Message getMessageHeader()
  76. {
  77. return header;
  78. }
  79. /**
  80. * Unmarshal the extended GIOP header
  81. * NOTE: May be fragmented, so should not be called by the ReaderThread.
  82. * See CorbaResponseWaitingRoomImpl.waitForResponse. It is done
  83. * there in the client thread.
  84. */
  85. public void unmarshalHeader()
  86. {
  87. // Unmarshal the extended GIOP message from the buffer.
  88. if (!unmarshaledHeader) {
  89. try {
  90. if (((ORB)orb()).transportDebugFlag) {
  91. dprint(".unmarshalHeader->: " + getMessageHeader());
  92. }
  93. getMessageHeader().read(this);
  94. unmarshaledHeader= true;
  95. } catch (RuntimeException e) {
  96. if (((ORB)orb()).transportDebugFlag) {
  97. dprint(".unmarshalHeader: !!ERROR!!: "
  98. + getMessageHeader()
  99. + ": " + e);
  100. }
  101. throw e;
  102. } finally {
  103. if (((ORB)orb()).transportDebugFlag) {
  104. dprint(".unmarshalHeader<-: " + getMessageHeader());
  105. }
  106. }
  107. }
  108. }
  109. public final boolean unmarshaledHeader()
  110. {
  111. return unmarshaledHeader;
  112. }
  113. /**
  114. * Override the default CDR factory behavior to get the
  115. * negotiated code sets from the connection.
  116. *
  117. * These are only called once per message, the first time needed.
  118. *
  119. * In the local case, there is no Connection, so use the
  120. * local code sets.
  121. */
  122. protected CodeSetConversion.BTCConverter createCharBTCConverter() {
  123. CodeSetComponentInfo.CodeSetContext codesets = getCodeSets();
  124. // If the connection doesn't have its negotiated
  125. // code sets by now, fall back on the defaults defined
  126. // in CDRInputStream.
  127. if (codesets == null)
  128. return super.createCharBTCConverter();
  129. OSFCodeSetRegistry.Entry charSet
  130. = OSFCodeSetRegistry.lookupEntry(codesets.getCharCodeSet());
  131. if (charSet == null)
  132. throw wrapper.unknownCodeset( charSet ) ;
  133. return CodeSetConversion.impl().getBTCConverter(charSet, isLittleEndian());
  134. }
  135. protected CodeSetConversion.BTCConverter createWCharBTCConverter() {
  136. CodeSetComponentInfo.CodeSetContext codesets = getCodeSets();
  137. // If the connection doesn't have its negotiated
  138. // code sets by now, we have to throw an exception.
  139. // See CORBA formal 00-11-03 13.9.2.6.
  140. if (codesets == null) {
  141. if (getConnection().isServer())
  142. throw omgWrapper.noClientWcharCodesetCtx() ;
  143. else
  144. throw omgWrapper.noServerWcharCodesetCmp() ;
  145. }
  146. OSFCodeSetRegistry.Entry wcharSet
  147. = OSFCodeSetRegistry.lookupEntry(codesets.getWCharCodeSet());
  148. if (wcharSet == null)
  149. throw wrapper.unknownCodeset( wcharSet ) ;
  150. // For GIOP 1.2 and UTF-16, use big endian if there is no byte
  151. // order marker. (See issue 3405b)
  152. //
  153. // For GIOP 1.1 and UTF-16, use the byte order the stream if
  154. // there isn't (and there shouldn't be) a byte order marker.
  155. //
  156. // GIOP 1.0 doesn't have wchars. If we're talking to a legacy ORB,
  157. // we do what our old ORBs did.
  158. if (wcharSet == OSFCodeSetRegistry.UTF_16) {
  159. if (getGIOPVersion().equals(GIOPVersion.V1_2))
  160. return CodeSetConversion.impl().getBTCConverter(wcharSet, false);
  161. }
  162. return CodeSetConversion.impl().getBTCConverter(wcharSet, isLittleEndian());
  163. }
  164. // If we're local and don't have a Connection, use the
  165. // local code sets, otherwise get them from the connection.
  166. // If the connection doesn't have negotiated code sets
  167. // yet, then we use ISO8859-1 for char/string and wchar/wstring
  168. // are illegal.
  169. private CodeSetComponentInfo.CodeSetContext getCodeSets() {
  170. if (getConnection() == null)
  171. return CodeSetComponentInfo.LOCAL_CODE_SETS;
  172. else
  173. return getConnection().getCodeSetContext();
  174. }
  175. public final CodeBase getCodeBase() {
  176. if (getConnection() == null)
  177. return null;
  178. else
  179. return getConnection().getCodeBase();
  180. }
  181. // -----------------------------------------------------------
  182. // Below this point are commented out methods with features
  183. // from the old stream. We must find ways to address
  184. // these issues in the future.
  185. // -----------------------------------------------------------
  186. // XREVISIT
  187. // private XIIOPInputStream(XIIOPInputStream stream) {
  188. // super(stream);
  189. // this.conn = stream.conn;
  190. // this.msg = stream.msg;
  191. // this.unmarshaledHeader = stream.unmarshaledHeader;
  192. // }
  193. public CDRInputStream dup() {
  194. // XREVISIT
  195. return null;
  196. // return new XIIOPInputStream(this);
  197. }
  198. protected void dprint(String msg)
  199. {
  200. ORBUtility.dprint("CDRInputObject", msg);
  201. }
  202. }
  203. // End of file.