001: package net.matuschek.util;
002:
003: /*********************************************
004: Copyright (c) 2001 by Daniel Matuschek
005: *********************************************/
006:
007: /**
008: * A ByteBuffer implements a growable byte array. You can simple
009: * add bytes like you do it using a Vector, but internally the buffer
010: * is implemented as a real array of bytes. This increases memory usage.
011: *
012: * @author Daniel Matuschek
013: * @version $Id $
014: */
015: public class ByteBuffer {
016:
017: protected final int INITIALSIZE = 1024;
018:
019: protected int used = 0;
020: protected int size = 0;
021: protected byte[] buff = null;
022:
023: /**
024: * Initializes a new ByteBuffer object and creates
025: * a temporary buffer array of a predefined initial size.
026: * If you want to set your own initial size, use the <code>setSize</code>
027: * method after initializing the object.
028: *
029: */
030: public ByteBuffer() {
031: size = INITIALSIZE;
032: buff = new byte[INITIALSIZE];
033: }
034:
035: /**
036: * Appends a byte to the end of the buffer
037: *
038: * If the currently reserved memory is used, the size of the
039: * internal buffer will be doubled.
040: * In this case the memory usage will temprary increase by factor 3
041: * because it need a temporary storage for the old data.
042: *
043: * Be sure that you have enough heap memory !
044: *
045: * @param b byte to append
046: */
047: public void append(byte b) {
048: if (used >= size) {
049: doubleBuffer();
050: }
051:
052: buff[used] = b;
053: used++;
054: }
055:
056: /**
057: * @return the number of bytes stored in the buffer
058: */
059: public int length() {
060: return used;
061: }
062:
063: /**
064: * @return the buffer contents as a byte array
065: */
066: public byte[] getContent() {
067: byte[] b = new byte[used];
068: for (int i = 0; i < used; i++) {
069: b[i] = buff[i];
070: }
071: return b;
072: }
073:
074: /**
075: * removes all contents in the buffer
076: */
077: public void clean() {
078: used = 0;
079: }
080:
081: /**
082: * Sets the size of the internal buffer to
083: * the given value. This is useful, if the size of the
084: * data that should be stored is known.
085: * @param size size of the buffer in Bytes
086: */
087: public void setSize(int size) {
088:
089: // if we have already used more data, ignore it !
090: if (size < used) {
091: return;
092: }
093:
094: this .size = size;
095:
096: // create a new (larger) array
097: byte[] newBuff = new byte[size];
098:
099: // copy contents
100: for (int i = 0; i < used; i++) {
101: newBuff[i] = buff[i];
102: }
103:
104: buff = newBuff;
105: }
106:
107: /**
108: * Print the buffer content as a String (use it for debugging only !)
109: * @return a String containing every byte in the buffer as a character
110: */
111: public String toString() {
112: StringBuffer sb = new StringBuffer(buff.length);
113: for (int i = 0; i < used; i++) {
114: sb.append(buff[i]);
115: }
116: return sb.toString();
117: }
118:
119: /**
120: * doubles the size of the internal buffer
121: */
122: protected void doubleBuffer() {
123: // increase size
124: setSize(size * 2);
125: }
126:
127: }
|