This commit is contained in:
jrandom
2004-06-28 13:22:03 +00:00
committed by zzz
parent caeb2bc4e3
commit 72727dacd8

View File

@@ -1,31 +1,71 @@
package net.i2p.client.streaming;
/** Like a StringBuffer, but for bytes */
/**
* Like a StringBuffer, but for bytes. This class is not internally synchronized,
* so care should be taken when using in a multithreaded environment.
*
*/
public class ByteCollector {
byte[] contents;
int size;
private static final int INITIAL_CAPACITY = 1024;
private static final int SHORT_CAPACITY = 80;
/**
* New collector with the default initial capacity
*
*/
public ByteCollector() {
contents = new byte[1024];
this(INITIAL_CAPACITY);
}
/**
* New collector with an initial capacity as specified
*
*/
public ByteCollector(int capacity) {
contents = new byte[capacity];
size = 0;
}
/**
* New collector containing the specified bytes
*
*/
public ByteCollector(byte[] b) {
this();
append(b);
}
/**
* New collector with the specified byte
*
*/
public ByteCollector(byte b) {
this();
append(b);
}
/**
* Add a new byte to the collector (extending the buffer if necessary)
*
* @param b byte to add
* @return this object
*/
public ByteCollector append(byte b) {
ensureCapacity(size + 1);
contents[size++] = b;
return this;
}
/**
* Add new bytes to the collector (extending the buffer if necessary)
*
* @param b bytes to add
* @return this object
*/
public ByteCollector append(byte[] b) {
ensureCapacity(size + b.length);
System.arraycopy(b, 0, contents, size, b.length);
@@ -33,10 +73,25 @@ public class ByteCollector {
return this;
}
/**
* Add new bytes to the collector (extending the buffer if necessary)
*
* @param b byte array to add from
* @param len number of bytes in the array to add
* @return this object
*/
public ByteCollector append(byte[] b, int len) {
return append(b, 0, len);
}
/**
* Add new bytes to the collector (extending the buffer if necessary)
*
* @param b byte array to add from
* @param off offset into the array to begin adding from
* @param len number of bytes in the array to add
* @return this object
*/
public ByteCollector append(byte[] b, int off, int len) {
ensureCapacity(size + len);
System.arraycopy(b, off, contents, size, len);
@@ -44,17 +99,36 @@ public class ByteCollector {
return this;
}
/**
* Add the contents of the byte collector to the current collector (extending the buffer if necessary)
*
* @param bc collector to copy
* @return this object
*/
public ByteCollector append(ByteCollector bc) {
// optimieren?
return append(bc.toByteArray());
}
/**
* Copy the contents of the collector into a new array and return it
*
* @return new array containing a copy of the current collector's data
*/
public byte[] toByteArray() {
byte[] result = new byte[size];
System.arraycopy(contents, 0, result, 0, size);
return result;
}
/**
* Pull off the first $maxlen bytes from the collector, shifting the remaining
* bytes into the beginning of the collector's array.
*
* @param maxlen max number of bytes we want to pull from the collector (we will get
* less if the collector doesnt have that many bytes yet)
* @return copy of the bytes pulled from the collector
*/
public byte[] startToByteArray(int maxlen) {
if (size < maxlen) {
byte[] res = toByteArray();
@@ -69,10 +143,22 @@ public class ByteCollector {
}
}
/**
* How many bytes are available for retrieval?
*
* @return number of bytes
*/
public int getCurrentSize() {
return size;
}
/**
* Make sure we have sufficient storage space.
*
* @param cap minimum number of bytes that the buffer should contain
* @return true if the the collector was expanded to meet the minimum,
* false if it was already large enough
*/
public boolean ensureCapacity(int cap) {
if (contents.length < cap) {
int l = contents.length;
@@ -87,20 +173,46 @@ public class ByteCollector {
return false;
}
/**
* Does the collector have meaningful data or is it empty?
*
* @return true if it has no data
*/
public boolean isEmpty() {
return size == 0;
}
/**
* Search through the collector for the first occurrence of the sequence of
* bytes contained within the specified collector
*
* @param bc bytes that will be searched for
* @return index into the current collector, or -1 if it isn't found
*/
public int indexOf(ByteCollector bc) {
// optimieren?
return indexOf(bc.toByteArray());
}
/**
* Search through the collector for the first occurrence of the specified
* byte
*
* @param b byte that will be searched for
* @return index into the current collector, or -1 if it isn't found
*/
public int indexOf(byte b) {
// optimieren?
return indexOf(new byte[] { b});
}
/**
* Search through the collector for the first occurrence of the sequence of
* bytes
*
* @param ba bytes that will be searched for
* @return index into the current collector, or -1 if it isn't found
*/
public int indexOf(byte[] ba) {
loop: for (int i = 0; i < size - ba.length + 1; i++) {
for (int j = 0; j < ba.length; j++) {
@@ -111,15 +223,28 @@ public class ByteCollector {
return -1;
}
/**
* Empty the collector. This does not affect its capacity.
*
*/
public void clear() {
size = 0;
}
/**
* Empty the collector and reduce its capacity.
*
*/
public void clearAndShorten() {
size = 0;
contents = new byte[80];
contents = new byte[SHORT_CAPACITY];
}
/**
* Render the bytes as a string
*
* @return the, uh, string
*/
public String toString() {
return new String(toByteArray());
}
@@ -132,6 +257,12 @@ public class ByteCollector {
return h;
}
/**
* Compare the collectors.
*
* @return true if and only if both are the same size and the
* byte arrays they contain are equal.
*/
public boolean equals(Object o) {
if (o instanceof ByteCollector) {
ByteCollector by = (ByteCollector) o;
@@ -145,7 +276,13 @@ public class ByteCollector {
}
}
public byte removeFirst() {
/**
* Remove the first byte from the collector, shifting its contents accordingly.
*
* @return byte removed
* @throws IllegalArgumentException if the collector is empty
*/
public byte removeFirst() throws IllegalArgumentException {
byte bb = contents[0];
if (size == 0) throw new IllegalArgumentException("ByteCollector is empty");
if (size > 1)