1. /*
  2. * @(#)ByteBufferWithInfo.java 1.10 03/12/19
  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.corba.se.impl.encoding.BufferManagerWrite;
  10. import com.sun.corba.se.impl.orbutil.ORBUtility;
  11. import com.sun.corba.se.pept.transport.ByteBufferPool;
  12. import com.sun.corba.se.spi.orb.ORB;
  13. // Notes about the class.
  14. // Assumptions, the ByteBuffer's position is set by the constructor's
  15. // index variable and the ByteBuffer's limit points to the end of the
  16. // data. Also, since the index variable tracks the current empty
  17. // position in the buffer, the ByteBuffer's position is updated
  18. // any time there's a call to this class's position().
  19. // Although, a ByteBuffer's length is it's capacity(), the context in
  20. // which length is used in this object, this.buflen is actually the
  21. // ByteBuffer limit().
  22. public class ByteBufferWithInfo
  23. {
  24. private ORB orb;
  25. private boolean debug;
  26. // REVISIT - index should eventually be replaced with byteBuffer.position()
  27. private int index; // Current empty position in buffer.
  28. // REVISIT - CHANGE THESE TO PRIVATE
  29. public ByteBuffer byteBuffer;// Marshal buffer.
  30. public int buflen; // Total length of buffer. // Unnecessary...
  31. public int needed; // How many more bytes are needed on overflow.
  32. public boolean fragmented; // Did the overflow operation fragment?
  33. public ByteBufferWithInfo(org.omg.CORBA.ORB orb,
  34. ByteBuffer byteBuffer,
  35. int index)
  36. {
  37. this.orb = (com.sun.corba.se.spi.orb.ORB)orb;
  38. debug = this.orb.transportDebugFlag;
  39. this.byteBuffer = byteBuffer;
  40. if (byteBuffer != null)
  41. {
  42. this.buflen = byteBuffer.limit();
  43. }
  44. position(index);
  45. this.needed = 0;
  46. this.fragmented = false;
  47. }
  48. public ByteBufferWithInfo(org.omg.CORBA.ORB orb, ByteBuffer byteBuffer)
  49. {
  50. this(orb, byteBuffer, 0);
  51. }
  52. public ByteBufferWithInfo(org.omg.CORBA.ORB orb,
  53. BufferManagerWrite bufferManager)
  54. {
  55. this(orb, bufferManager, true);
  56. }
  57. // Right now, EncapsOutputStream's do not use pooled byte buffers.
  58. // EncapsOutputStream's is the only one that does not use pooled
  59. // byte buffers. Hence, the reason for the boolean 'usePooledByteBuffers'.
  60. // See EncapsOutputStream for additional information.
  61. public ByteBufferWithInfo(org.omg.CORBA.ORB orb,
  62. BufferManagerWrite bufferManager,
  63. boolean usePooledByteBuffers)
  64. {
  65. this.orb = (com.sun.corba.se.spi.orb.ORB)orb;
  66. debug = this.orb.transportDebugFlag;
  67. int bufferSize = bufferManager.getBufferSize();
  68. if (usePooledByteBuffers)
  69. {
  70. ByteBufferPool byteBufferPool = this.orb.getByteBufferPool();
  71. this.byteBuffer = byteBufferPool.getByteBuffer(bufferSize);
  72. if (debug)
  73. {
  74. // print address of ByteBuffer gotten from pool
  75. int bbAddress = System.identityHashCode(byteBuffer);
  76. StringBuffer sb = new StringBuffer(80);
  77. sb.append("constructor (ORB, BufferManagerWrite) - got ")
  78. .append("ByteBuffer id (").append(bbAddress)
  79. .append(") from ByteBufferPool.");
  80. String msgStr = sb.toString();
  81. dprint(msgStr);
  82. }
  83. }
  84. else
  85. {
  86. // don't allocate from pool, allocate non-direct ByteBuffer
  87. this.byteBuffer = ByteBuffer.allocate(bufferSize);
  88. }
  89. position(0);
  90. this.buflen = bufferSize;
  91. this.byteBuffer.limit(this.buflen);
  92. this.needed = 0;
  93. this.fragmented = false;
  94. }
  95. // Shallow copy constructor
  96. public ByteBufferWithInfo (ByteBufferWithInfo bbwi)
  97. {
  98. this.orb = bbwi.orb;
  99. this.debug = bbwi.debug;
  100. this.byteBuffer = bbwi.byteBuffer;
  101. this.buflen = bbwi.buflen;
  102. this.byteBuffer.limit(this.buflen);
  103. position(bbwi.position());
  104. this.needed = bbwi.needed;
  105. this.fragmented = bbwi.fragmented;
  106. }
  107. // So IIOPOutputStream seems more intuitive
  108. public int getSize()
  109. {
  110. return position();
  111. }
  112. // accessor to buflen
  113. public int getLength()
  114. {
  115. return buflen;
  116. }
  117. // get position in this buffer
  118. public int position()
  119. {
  120. // REVISIT - This should be changed to return the
  121. // value of byteBuffer.position() rather
  122. // than this.index. But, byteBuffer.position
  123. // is manipulated via ByteBuffer writes, reads,
  124. // gets and puts. These locations need to be
  125. // investigated and updated before
  126. // byteBuffer.position() can be returned here.
  127. // return byteBuffer.position();
  128. return index;
  129. }
  130. // set position in this buffer
  131. public void position(int newPosition)
  132. {
  133. // REVISIT - This should be changed to set only the
  134. // value of byteBuffer.position rather
  135. // than this.index. This change should be made
  136. // in conjunction with the change to this.position().
  137. byteBuffer.position(newPosition);
  138. index = newPosition;
  139. }
  140. // mutator to buflen
  141. public void setLength(int theLength)
  142. {
  143. buflen = theLength;
  144. byteBuffer.limit(buflen);
  145. }
  146. // Grow byteBuffer to a size larger than position() + needed
  147. public void growBuffer(com.sun.corba.se.spi.orb.ORB orb)
  148. {
  149. // This code used to live directly in CDROutputStream.grow.
  150. // Recall that the byteBuffer size is 'really' the limit or
  151. // buflen.
  152. int newLength = byteBuffer.limit() * 2;
  153. while (position() + needed >= newLength)
  154. newLength = newLength * 2;
  155. ByteBufferPool byteBufferPool = orb.getByteBufferPool();
  156. ByteBuffer newBB = byteBufferPool.getByteBuffer(newLength);
  157. if (debug)
  158. {
  159. // print address of ByteBuffer just gotten
  160. int newbbAddress = System.identityHashCode(newBB);
  161. StringBuffer sb = new StringBuffer(80);
  162. sb.append("growBuffer() - got ByteBuffer id (");
  163. sb.append(newbbAddress).append(") from ByteBufferPool.");
  164. String msgStr = sb.toString();
  165. dprint(msgStr);
  166. }
  167. byteBuffer.position(0);
  168. newBB.put(byteBuffer);
  169. // return 'old' byteBuffer reference to the ByteBuffer pool
  170. if (debug)
  171. {
  172. // print address of ByteBuffer being released
  173. int bbAddress = System.identityHashCode(byteBuffer);
  174. StringBuffer sb = new StringBuffer(80);
  175. sb.append("growBuffer() - releasing ByteBuffer id (");
  176. sb.append(bbAddress).append(") to ByteBufferPool.");
  177. String msgStr2 = sb.toString();
  178. dprint(msgStr2);
  179. }
  180. byteBufferPool.releaseByteBuffer(byteBuffer);
  181. // update the byteBuffer with a larger ByteBuffer
  182. byteBuffer = newBB;
  183. // limit and buflen must be set to newLength.
  184. buflen = newLength;
  185. byteBuffer.limit(buflen);
  186. }
  187. public String toString()
  188. {
  189. StringBuffer str = new StringBuffer("ByteBufferWithInfo:");
  190. str.append(" buflen = " + buflen);
  191. str.append(" byteBuffer.limit = " + byteBuffer.limit());
  192. str.append(" index = " + index);
  193. str.append(" position = " + position());
  194. str.append(" needed = " + needed);
  195. str.append(" byteBuffer = " + (byteBuffer == null ? "null" : "not null"));
  196. str.append(" fragmented = " + fragmented);
  197. return str.toString();
  198. }
  199. protected void dprint(String msg)
  200. {
  201. ORBUtility.dprint("ByteBufferWithInfo", msg);
  202. }
  203. }