/*
* 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);
}
}
}