org.jgroups.util.ByteArrayDataOutputStream Maven / Gradle / Ivy
package org.jgroups.util;
import java.nio.ByteBuffer;
import java.util.Arrays;
/**
* Implements {@link java.io.DataOutput} over a byte[] buffer. The byte[] buffer expands when needed; however, it
* doesn't double but only expands minimally, to accommodate the additional data.
* It is therefore recommended to always size the buffer to the actual number of bytes needed.
* This class is not thread safe.
* @author Bela Ban
* @since 3.5
*/
public class ByteArrayDataOutputStream extends BaseDataOutputStream {
protected byte[] buf;
protected boolean grow_exponentially; // if true, the buffer will double every time
public ByteArrayDataOutputStream() {
this(32, false);
}
public ByteArrayDataOutputStream(int capacity) {
this(capacity, false);
}
public ByteArrayDataOutputStream(int capacity, boolean grow_exponentially) {
this.buf=new byte[capacity];
this.grow_exponentially=grow_exponentially;
}
public byte[] buffer() {return buf;}
public ByteArray getBuffer() {return new ByteArray(buf, 0, pos);}
public ByteBuffer byteBuffer() {return ByteBuffer.wrap(buf, 0, pos);}
public int capacity() {return buf.length;}
public boolean growExponentially() {return grow_exponentially;}
public ByteArrayDataOutputStream growExponentially(boolean b) {grow_exponentially=b; return this;}
public void write(int b) {
ensureCapacity(1);
buf[pos++]=(byte)b;
}
public void write(byte[] b) {
write(b, 0, b.length);
}
public void write(byte[] b, int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) - b.length > 0))
throw new IndexOutOfBoundsException(String.format("off=%d, len=%d, b.length=%d", off, len, b.length));
ensureCapacity(len);
System.arraycopy(b, off, buf, pos, len);
pos+=len;
}
public String toString() {
return super.toString() + String.format(", lim=%d", buf.length);
}
protected int checkBounds(int pos) {
super.checkBounds(pos);
if(pos > buf.length)
throw new IndexOutOfBoundsException("length=" + buf.length);
return pos;
}
/** Grows the buffer; whether it grow linearly or exponentially depends on grow_exponentially */
protected void ensureCapacity(int bytes) {
int minCapacity=pos+bytes;
if(minCapacity - buf.length > 0) {
int newCapacity=this.grow_exponentially? buf.length << 1 : pos + bytes + 32;
if(newCapacity - minCapacity < 0)
newCapacity=minCapacity;
if(newCapacity < 0) {
if(minCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity=Integer.MAX_VALUE;
}
buf=Arrays.copyOf(buf, newCapacity);
}
}
}