package org.newbiehacker.conlib; /** * Copyright 2006 James Lawrence * Date: 11-Dec-2006 * Time: 17:52:52 * Modification and redistribution without explicit permission by the creator(s) is prohibited * This source may be modified for personal use as long as the original author is accredited */ public final class Buffer { public final byte[] buffer; public int bufStart, bufEnd; /** *

Creates a new Buffer with the specified byte capacity

* @param length */ public Buffer(int length) { this.buffer = new byte[length]; this.bufStart = 0; this.bufEnd = 0; } /** *

Creates a new Buffer with a byte capacity of 10240 (10KB)

*/ public Buffer() { this(10240); } /** *

The amount of bytes currently in this Buffer

* @return The amount of bytes available for reading */ public final int size() { return bufEnd - bufStart; } /** *

Appends an array of bytes to this buffer

* @param data The bytes to copy * @param off The offset in the array to start from * @param len The length of bytes to copy */ public final void append(byte[] data, int off, int len) { if(off < 0 || off > data.length) throw new ArrayIndexOutOfBoundsException("Offset must be > 0 && < data.length"); if(len < 0 || off + len > data.length) throw new ArrayIndexOutOfBoundsException("Length must be > 0 && length + offset < data.length"); if(bufEnd + len >= buffer.length) throw new ArrayIndexOutOfBoundsException("Buffer overflow!: " + len); System.arraycopy(data, off, buffer, bufEnd, len); bufEnd += len; } /** *

Appends an array of bytes to this buffer

* @param data The bytes to copy */ public final void append(byte[] data) { append(data, 0, data.length); } /** *

Appends a byte to this buffer

* @param data The byte to append */ public final void append(int data) { append(new byte[]{(byte) data}, 0, 1); } public final void remove(int len) { _resize(len); } /** *

Reads an array of bytes into data from off until off + len

* @param data Destination array * @param off Offset to start copying * @param len Amount of bytes to copy * @return Length of bytes read */ public final int read(byte[] data, int off, int len) { if(data.length < len) len = data.length; System.arraycopy(buffer, bufStart, data, off, len); _resize(len); return len; } private void _resize(int diff) { bufStart += diff; if(bufStart > 0) { int s = size(); byte[] t = new byte[s]; System.arraycopy(buffer, bufStart, t, 0, s); bufStart = 0; bufEnd = s; System.arraycopy(t, 0, buffer, 0, s); } } /** *

Reads an array of bytes into data from 0 until data.length

* @param data The destination array * @return The length of bytes read */ public final int read(byte[] data) { return read(data, 0, data.length); } /** *

Returns the top byte from this buffer

* @return The first byte in this buffer */ public final int read() { byte[] data = new byte[1]; read(data); return data[0]; } public final int peek(byte[] data, int off, int len) { if(len > size()) len = size(); System.arraycopy(buffer, bufStart, data, off, len); return len; } public final int peek(byte[] data) { return peek(data, 0, data.length); } public final int peek() { byte[] t = new byte[1]; peek(t); return t[0]; } }