/* * StreamBuffer.java - A chunk of data stream using a channel * * Copyright (c) 1996 Chuck McManis, All Rights Reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL purposes and without * fee is hereby granted provided that this copyright notice * appears in all copies. * * CHUCK MCMANIS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. CHUCK MCMANIS * SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT * OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ package util.comm; import util.Recyclable; class StreamBuffer implements Referenced, Recyclable { // Amount of data in the buffer private int len; // The data buffer itself. byte data[]; // Link list pointer to another StreamBuffer StreamBuffer next; // This is who will recycle the exhausted buffer. Recyclable src; // monotonically increasing Identifier. private int myID; /** * Construct a new StreamBuffer with the given size * and a reference to its recycler. (usually its * allocator) */ StreamBuffer(int size, Recyclable s) { data = new byte[size]; src = s; len = 0; myID = serialNumber++; } public String toString() { return ("StreamBuffer["+myID+"]: Size ("+data.length+"), Used ("+ space()+"), Read ("+avail()+")."); } /** * return how much data the buffer can hold. */ int space() { return (data.length - len); } /** * return how much data the buffer is holding. */ int avail() { return (len); } /** * Put a byte into the buffer (return true if full) */ boolean write(byte z) { data[len++] = z; return len == data.length; } /** * Read a byte from the buffer, return -1 if empty. * note that 0xff reads as 255. */ int read(int hasBeenRead) { int r; if ((len - hasBeenRead) <= 0) return -1; r = (data[hasBeenRead] & 0xff); return r; } // keep around a unique ID. private static int serialNumber = 1; private int numRefs = 0; /** increment the reference count */ public synchronized int addRefCount() { return ++numRefs; } /** Decrement the reference count by one. */ public synchronized int decRefCount() { numRefs--; if (numRefs < 0) numRefs = 0; return numRefs; } /** Return the current refence count */ public int refCount() { return numRefs; } public void recycle(Object x) { recycle(); } public void recycle() { if (numRefs == 0) { len = 0; src.recycle(this); } } }