| /* |
| * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.corba.se.impl.encoding; |
| |
| import java.nio.ByteBuffer; |
| |
| |
| import com.sun.corba.se.impl.encoding.BufferManagerWrite; |
| import com.sun.corba.se.impl.orbutil.ORBUtility; |
| import com.sun.corba.se.pept.transport.ByteBufferPool; |
| import com.sun.corba.se.spi.orb.ORB; |
| |
| |
| // Notes about the class. |
| // Assumptions, the ByteBuffer's position is set by the constructor's |
| // index variable and the ByteBuffer's limit points to the end of the |
| // data. Also, since the index variable tracks the current empty |
| // position in the buffer, the ByteBuffer's position is updated |
| // any time there's a call to this class's position(). |
| // Although, a ByteBuffer's length is it's capacity(), the context in |
| // which length is used in this object, this.buflen is actually the |
| // ByteBuffer limit(). |
| |
| public class ByteBufferWithInfo |
| { |
| private ORB orb; |
| private boolean debug; |
| // REVISIT - index should eventually be replaced with byteBuffer.position() |
| private int index; // Current empty position in buffer. |
| // REVISIT - CHANGE THESE TO PRIVATE |
| public ByteBuffer byteBuffer;// Marshal buffer. |
| public int buflen; // Total length of buffer. // Unnecessary... |
| public int needed; // How many more bytes are needed on overflow. |
| public boolean fragmented; // Did the overflow operation fragment? |
| |
| public ByteBufferWithInfo(org.omg.CORBA.ORB orb, |
| ByteBuffer byteBuffer, |
| int index) |
| { |
| this.orb = (com.sun.corba.se.spi.orb.ORB)orb; |
| debug = this.orb.transportDebugFlag; |
| this.byteBuffer = byteBuffer; |
| if (byteBuffer != null) |
| { |
| this.buflen = byteBuffer.limit(); |
| } |
| position(index); |
| this.needed = 0; |
| this.fragmented = false; |
| } |
| |
| public ByteBufferWithInfo(org.omg.CORBA.ORB orb, ByteBuffer byteBuffer) |
| { |
| this(orb, byteBuffer, 0); |
| } |
| |
| public ByteBufferWithInfo(org.omg.CORBA.ORB orb, |
| BufferManagerWrite bufferManager) |
| { |
| this(orb, bufferManager, true); |
| } |
| |
| // Right now, EncapsOutputStream's do not use pooled byte buffers. |
| // EncapsOutputStream's is the only one that does not use pooled |
| // byte buffers. Hence, the reason for the boolean 'usePooledByteBuffers'. |
| // See EncapsOutputStream for additional information. |
| |
| public ByteBufferWithInfo(org.omg.CORBA.ORB orb, |
| BufferManagerWrite bufferManager, |
| boolean usePooledByteBuffers) |
| { |
| this.orb = (com.sun.corba.se.spi.orb.ORB)orb; |
| debug = this.orb.transportDebugFlag; |
| |
| int bufferSize = bufferManager.getBufferSize(); |
| |
| if (usePooledByteBuffers) |
| { |
| ByteBufferPool byteBufferPool = this.orb.getByteBufferPool(); |
| this.byteBuffer = byteBufferPool.getByteBuffer(bufferSize); |
| |
| if (debug) |
| { |
| // print address of ByteBuffer gotten from pool |
| int bbAddress = System.identityHashCode(byteBuffer); |
| StringBuffer sb = new StringBuffer(80); |
| sb.append("constructor (ORB, BufferManagerWrite) - got ") |
| .append("ByteBuffer id (").append(bbAddress) |
| .append(") from ByteBufferPool."); |
| String msgStr = sb.toString(); |
| dprint(msgStr); |
| } |
| } |
| else |
| { |
| // don't allocate from pool, allocate non-direct ByteBuffer |
| this.byteBuffer = ByteBuffer.allocate(bufferSize); |
| } |
| |
| position(0); |
| this.buflen = bufferSize; |
| this.byteBuffer.limit(this.buflen); |
| this.needed = 0; |
| this.fragmented = false; |
| } |
| |
| // Shallow copy constructor |
| public ByteBufferWithInfo (ByteBufferWithInfo bbwi) |
| { |
| this.orb = bbwi.orb; |
| this.debug = bbwi.debug; |
| this.byteBuffer = bbwi.byteBuffer; |
| this.buflen = bbwi.buflen; |
| this.byteBuffer.limit(this.buflen); |
| position(bbwi.position()); |
| this.needed = bbwi.needed; |
| this.fragmented = bbwi.fragmented; |
| } |
| |
| // So IIOPOutputStream seems more intuitive |
| public int getSize() |
| { |
| return position(); |
| } |
| |
| // accessor to buflen |
| public int getLength() |
| { |
| return buflen; |
| } |
| |
| // get position in this buffer |
| public int position() |
| { |
| // REVISIT - This should be changed to return the |
| // value of byteBuffer.position() rather |
| // than this.index. But, byteBuffer.position |
| // is manipulated via ByteBuffer writes, reads, |
| // gets and puts. These locations need to be |
| // investigated and updated before |
| // byteBuffer.position() can be returned here. |
| // return byteBuffer.position(); |
| return index; |
| } |
| |
| // set position in this buffer |
| public void position(int newPosition) |
| { |
| // REVISIT - This should be changed to set only the |
| // value of byteBuffer.position rather |
| // than this.index. This change should be made |
| // in conjunction with the change to this.position(). |
| byteBuffer.position(newPosition); |
| index = newPosition; |
| } |
| |
| // mutator to buflen |
| public void setLength(int theLength) |
| { |
| buflen = theLength; |
| byteBuffer.limit(buflen); |
| } |
| |
| // Grow byteBuffer to a size larger than position() + needed |
| public void growBuffer(com.sun.corba.se.spi.orb.ORB orb) |
| { |
| // This code used to live directly in CDROutputStream.grow. |
| |
| // Recall that the byteBuffer size is 'really' the limit or |
| // buflen. |
| |
| int newLength = byteBuffer.limit() * 2; |
| |
| while (position() + needed >= newLength) |
| newLength = newLength * 2; |
| |
| ByteBufferPool byteBufferPool = orb.getByteBufferPool(); |
| ByteBuffer newBB = byteBufferPool.getByteBuffer(newLength); |
| |
| if (debug) |
| { |
| // print address of ByteBuffer just gotten |
| int newbbAddress = System.identityHashCode(newBB); |
| StringBuffer sb = new StringBuffer(80); |
| sb.append("growBuffer() - got ByteBuffer id ("); |
| sb.append(newbbAddress).append(") from ByteBufferPool."); |
| String msgStr = sb.toString(); |
| dprint(msgStr); |
| } |
| |
| byteBuffer.position(0); |
| newBB.put(byteBuffer); |
| |
| // return 'old' byteBuffer reference to the ByteBuffer pool |
| if (debug) |
| { |
| // print address of ByteBuffer being released |
| int bbAddress = System.identityHashCode(byteBuffer); |
| StringBuffer sb = new StringBuffer(80); |
| sb.append("growBuffer() - releasing ByteBuffer id ("); |
| sb.append(bbAddress).append(") to ByteBufferPool."); |
| String msgStr2 = sb.toString(); |
| dprint(msgStr2); |
| } |
| byteBufferPool.releaseByteBuffer(byteBuffer); |
| |
| // update the byteBuffer with a larger ByteBuffer |
| byteBuffer = newBB; |
| |
| // limit and buflen must be set to newLength. |
| buflen = newLength; |
| byteBuffer.limit(buflen); |
| } |
| |
| public String toString() |
| { |
| StringBuffer str = new StringBuffer("ByteBufferWithInfo:"); |
| |
| str.append(" buflen = " + buflen); |
| str.append(" byteBuffer.limit = " + byteBuffer.limit()); |
| str.append(" index = " + index); |
| str.append(" position = " + position()); |
| str.append(" needed = " + needed); |
| str.append(" byteBuffer = " + (byteBuffer == null ? "null" : "not null")); |
| str.append(" fragmented = " + fragmented); |
| |
| return str.toString(); |
| } |
| |
| protected void dprint(String msg) |
| { |
| ORBUtility.dprint("ByteBufferWithInfo", msg); |
| } |
| } |