package org.bson.io;
import org.bson.ByteBuf;
import org.bson.ByteBufNIO;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import static java.lang.String.format;
import static java.nio.ByteOrder.LITTLE_ENDIAN;
public class BasicOutputBuffer extends OutputBuffer {
private byte[] buffer = new byte[1024];
private int position;
public BasicOutputBuffer() {
this(1024);
}
public BasicOutputBuffer(final int initialSize) {
buffer = new byte[initialSize];
}
public byte[] getInternalBuffer() {
return buffer;
}
@Override
public void write(final byte[] b) {
ensureOpen();
write(b, 0, b.length);
}
@Override
public void writeBytes(final byte[] bytes, final int offset, final int length) {
ensureOpen();
ensure(length);
System.arraycopy(bytes, offset, buffer, position, length);
position += length;
}
@Override
public void writeByte(final int value) {
ensureOpen();
ensure(1);
buffer[position++] = (byte) (0xFF & value);
}
@Override
protected void write(final int absolutePosition, final int value) {
ensureOpen();
if (absolutePosition < 0) {
throw new IllegalArgumentException(format("position must be >= 0 but was %d", absolutePosition));
}
if (absolutePosition > position - 1) {
throw new IllegalArgumentException(format("position must be <= %d but was %d", position - 1, absolutePosition));
}
buffer[absolutePosition] = (byte) (0xFF & value);
}
@Override
public int getPosition() {
ensureOpen();
return position;
}
@Override
public int getSize() {
ensureOpen();
return position;
}
@Override
public int pipe(final OutputStream out) throws IOException {
ensureOpen();
out.write(buffer, 0, position);
return position;
}
@Override
public void truncateToPosition(final int newPosition) {
ensureOpen();
if (newPosition > position || newPosition < 0) {
throw new IllegalArgumentException();
}
position = newPosition;
}
@Override
public List<ByteBuf> getByteBuffers() {
ensureOpen();
return Arrays.<ByteBuf>asList(new ByteBufNIO(ByteBuffer.wrap(buffer, 0, position).duplicate().order(LITTLE_ENDIAN)));
}
@Override
public void close() {
buffer = null;
}
private void ensureOpen() {
if (buffer == null) {
throw new IllegalStateException("The output is closed");
}
}
private void ensure(final int more) {
int need = position + more;
if (need <= buffer.length) {
return;
}
int newSize = buffer.length * 2;
if (newSize < need) {
newSize = need + 128;
}
byte[] n = new byte[newSize];
System.arraycopy(buffer, 0, n, 0, position);
buffer = n;
}
}