1/* 2 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.corba.se.impl.encoding; 27 28import java.nio.ByteBuffer; 29 30 31import com.sun.corba.se.impl.encoding.BufferManagerWrite; 32import com.sun.corba.se.impl.orbutil.ORBUtility; 33import com.sun.corba.se.pept.transport.ByteBufferPool; 34import com.sun.corba.se.spi.orb.ORB; 35 36 37// Notes about the class. 38// Assumptions, the ByteBuffer's position is set by the constructor's 39// index variable and the ByteBuffer's limit points to the end of the 40// data. Also, since the index variable tracks the current empty 41// position in the buffer, the ByteBuffer's position is updated 42// any time there's a call to this class's position(). 43// Although, a ByteBuffer's length is it's capacity(), the context in 44// which length is used in this object, this.buflen is actually the 45// ByteBuffer limit(). 46 47public class ByteBufferWithInfo 48{ 49 private ORB orb; 50 private boolean debug; 51 // REVISIT - index should eventually be replaced with byteBuffer.position() 52 private int index; // Current empty position in buffer. 53 // REVISIT - CHANGE THESE TO PRIVATE 54 public ByteBuffer byteBuffer;// Marshal buffer. 55 public int buflen; // Total length of buffer. // Unnecessary... 56 public int needed; // How many more bytes are needed on overflow. 57 public boolean fragmented; // Did the overflow operation fragment? 58 59 public ByteBufferWithInfo(org.omg.CORBA.ORB orb, 60 ByteBuffer byteBuffer, 61 int index) 62 { 63 this.orb = (com.sun.corba.se.spi.orb.ORB)orb; 64 debug = this.orb.transportDebugFlag; 65 this.byteBuffer = byteBuffer; 66 if (byteBuffer != null) 67 { 68 this.buflen = byteBuffer.limit(); 69 } 70 position(index); 71 this.needed = 0; 72 this.fragmented = false; 73 } 74 75 public ByteBufferWithInfo(org.omg.CORBA.ORB orb, ByteBuffer byteBuffer) 76 { 77 this(orb, byteBuffer, 0); 78 } 79 80 public ByteBufferWithInfo(org.omg.CORBA.ORB orb, 81 BufferManagerWrite bufferManager) 82 { 83 this(orb, bufferManager, true); 84 } 85 86 // Right now, EncapsOutputStream's do not use pooled byte buffers. 87 // EncapsOutputStream's is the only one that does not use pooled 88 // byte buffers. Hence, the reason for the boolean 'usePooledByteBuffers'. 89 // See EncapsOutputStream for additional information. 90 91 public ByteBufferWithInfo(org.omg.CORBA.ORB orb, 92 BufferManagerWrite bufferManager, 93 boolean usePooledByteBuffers) 94 { 95 this.orb = (com.sun.corba.se.spi.orb.ORB)orb; 96 debug = this.orb.transportDebugFlag; 97 98 int bufferSize = bufferManager.getBufferSize(); 99 100 if (usePooledByteBuffers) 101 { 102 ByteBufferPool byteBufferPool = this.orb.getByteBufferPool(); 103 this.byteBuffer = byteBufferPool.getByteBuffer(bufferSize); 104 105 if (debug) 106 { 107 // print address of ByteBuffer gotten from pool 108 int bbAddress = System.identityHashCode(byteBuffer); 109 StringBuffer sb = new StringBuffer(80); 110 sb.append("constructor (ORB, BufferManagerWrite) - got ") 111 .append("ByteBuffer id (").append(bbAddress) 112 .append(") from ByteBufferPool."); 113 String msgStr = sb.toString(); 114 dprint(msgStr); 115 } 116 } 117 else 118 { 119 // don't allocate from pool, allocate non-direct ByteBuffer 120 this.byteBuffer = ByteBuffer.allocate(bufferSize); 121 } 122 123 position(0); 124 this.buflen = bufferSize; 125 this.byteBuffer.limit(this.buflen); 126 this.needed = 0; 127 this.fragmented = false; 128 } 129 130 // Shallow copy constructor 131 public ByteBufferWithInfo (ByteBufferWithInfo bbwi) 132 { 133 this.orb = bbwi.orb; 134 this.debug = bbwi.debug; 135 this.byteBuffer = bbwi.byteBuffer; 136 this.buflen = bbwi.buflen; 137 this.byteBuffer.limit(this.buflen); 138 position(bbwi.position()); 139 this.needed = bbwi.needed; 140 this.fragmented = bbwi.fragmented; 141 } 142 143 // So IIOPOutputStream seems more intuitive 144 public int getSize() 145 { 146 return position(); 147 } 148 149 // accessor to buflen 150 public int getLength() 151 { 152 return buflen; 153 } 154 155 // get position in this buffer 156 public int position() 157 { 158 // REVISIT - This should be changed to return the 159 // value of byteBuffer.position() rather 160 // than this.index. But, byteBuffer.position 161 // is manipulated via ByteBuffer writes, reads, 162 // gets and puts. These locations need to be 163 // investigated and updated before 164 // byteBuffer.position() can be returned here. 165 // return byteBuffer.position(); 166 return index; 167 } 168 169 // set position in this buffer 170 public void position(int newPosition) 171 { 172 // REVISIT - This should be changed to set only the 173 // value of byteBuffer.position rather 174 // than this.index. This change should be made 175 // in conjunction with the change to this.position(). 176 byteBuffer.position(newPosition); 177 index = newPosition; 178 } 179 180 // mutator to buflen 181 public void setLength(int theLength) 182 { 183 buflen = theLength; 184 byteBuffer.limit(buflen); 185 } 186 187 // Grow byteBuffer to a size larger than position() + needed 188 public void growBuffer(com.sun.corba.se.spi.orb.ORB orb) 189 { 190 // This code used to live directly in CDROutputStream.grow. 191 192 // Recall that the byteBuffer size is 'really' the limit or 193 // buflen. 194 195 int newLength = byteBuffer.limit() * 2; 196 197 while (position() + needed >= newLength) 198 newLength = newLength * 2; 199 200 ByteBufferPool byteBufferPool = orb.getByteBufferPool(); 201 ByteBuffer newBB = byteBufferPool.getByteBuffer(newLength); 202 203 if (debug) 204 { 205 // print address of ByteBuffer just gotten 206 int newbbAddress = System.identityHashCode(newBB); 207 StringBuffer sb = new StringBuffer(80); 208 sb.append("growBuffer() - got ByteBuffer id ("); 209 sb.append(newbbAddress).append(") from ByteBufferPool."); 210 String msgStr = sb.toString(); 211 dprint(msgStr); 212 } 213 214 byteBuffer.position(0); 215 newBB.put(byteBuffer); 216 217 // return 'old' byteBuffer reference to the ByteBuffer pool 218 if (debug) 219 { 220 // print address of ByteBuffer being released 221 int bbAddress = System.identityHashCode(byteBuffer); 222 StringBuffer sb = new StringBuffer(80); 223 sb.append("growBuffer() - releasing ByteBuffer id ("); 224 sb.append(bbAddress).append(") to ByteBufferPool."); 225 String msgStr2 = sb.toString(); 226 dprint(msgStr2); 227 } 228 byteBufferPool.releaseByteBuffer(byteBuffer); 229 230 // update the byteBuffer with a larger ByteBuffer 231 byteBuffer = newBB; 232 233 // limit and buflen must be set to newLength. 234 buflen = newLength; 235 byteBuffer.limit(buflen); 236 } 237 238 public String toString() 239 { 240 StringBuffer str = new StringBuffer("ByteBufferWithInfo:"); 241 242 str.append(" buflen = " + buflen); 243 str.append(" byteBuffer.limit = " + byteBuffer.limit()); 244 str.append(" index = " + index); 245 str.append(" position = " + position()); 246 str.append(" needed = " + needed); 247 str.append(" byteBuffer = " + (byteBuffer == null ? "null" : "not null")); 248 str.append(" fragmented = " + fragmented); 249 250 return str.toString(); 251 } 252 253 protected void dprint(String msg) 254 { 255 ORBUtility.dprint("ByteBufferWithInfo", msg); 256 } 257} 258