package iax.protocol.util; /** * Utility class that imepements a byte buffer and needed functionality. * */ public class ByteBuffer { //Number of bit in a byte. private final static int BYTE_BITS = 8; //Mask to get the little byte. private final static int BYTE_MASK = 0xff; /** * Number of bytes in 8 bits. */ public final static int SIZE_8BITS = 1; /** * Number of bytes in 16 bits. */ public final static int SIZE_16BITS = 2; /** * Number of bytes in 32 bits. */ public final static int SIZE_32BITS = 4; //Las position written. private int pos; //Buffer. private byte[] buffer; /** * Constructor. Initizalizes the buffer for a given size. * @param i Size of the new buffer. * @throws ByteBufferException */ public ByteBuffer(int i) throws ByteBufferException { if (i>0) { this.buffer = new byte[i]; this.pos = 0; } else throw new ByteBufferException("ByteBuffer's length isn't greater than zero"); } /** * Csontructor. Creates a byte buffer from a given byte array. * @param buff Byte array to initialize the buffer. */ public ByteBuffer(byte[] buff) { this.buffer = buff; this.pos = 0; } /** * Gets the number of free bytes in the buffer. * @return The number of free bytes in the buffer. */ public int getRemaining() { return buffer.length - pos; } /** * Indicates if the buffer has free space. * @return true if buffer has some free space, false otherwise. */ public boolean hasRemaining() { return pos <= buffer.length; } /** * Gets the buffer data. * @return The buffer in a byte array. */ public byte[] getBuffer() { return buffer; } /** * Gets the next 8 bits in the buffer. * @return An 8 bits number stored in an integer. * @throws ByteBufferException */ public int get8bits() throws ByteBufferException { if (pos + SIZE_8BITS <= buffer.length) { int result = buffer[pos]; pos+=SIZE_8BITS; return result; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Gets 8 bits from the buffer given a position. * @param pos The position to read. * @return An 8 bits number stored in an integer. * @throws ByteBufferException */ public int get8bits(int pos) throws ByteBufferException { if (pos + SIZE_8BITS <= buffer.length) { int result = buffer[pos]; return result; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Gets the next 16 bits in the buffer. * @return An 16 bits number stored in an integer. * @throws ByteBufferException */ public int get16bits() throws ByteBufferException { if (pos + SIZE_16BITS <= buffer.length) { int result = 0; for (int i=0, j=SIZE_16BITS-1; i < SIZE_16BITS; i++, j--) { result += (int) ((buffer[pos+i] & BYTE_MASK) << (j*BYTE_BITS)); } pos+=SIZE_16BITS; return result; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Gets 16 bits from the buffer given a position. * @param pos The position to read. * @return An 16 bits number stored in an integer. * @throws ByteBufferException */ public int get16bits(int pos) throws ByteBufferException { if (pos + SIZE_16BITS <= buffer.length) { int result = 0; for (int i=0, j=SIZE_16BITS-1; i < SIZE_16BITS; i++, j--) { result += (int) ((buffer[pos+i] & BYTE_MASK) << (j*BYTE_BITS)); } return result; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Gets the next 32 bits in the buffer. * @return An 32 bits number stored in an integer. * @throws ByteBufferException */ public long get32bits() throws ByteBufferException { if (pos + SIZE_32BITS <= buffer.length) { long result = 0; for (int i=0, j=SIZE_32BITS-1; i < SIZE_32BITS; i++, j--) { result += (long) ((buffer[pos+i] & BYTE_MASK) << (j*BYTE_BITS)); } pos+=SIZE_32BITS; return result; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Gets 32 bits from the buffer given a position. * @param pos The position to read. * @return An 32 bits number stored in an integer. * @throws ByteBufferException */ public long get32bits(int pos) throws ByteBufferException { if (pos + SIZE_32BITS <= buffer.length) { long result = 0; for (int i=0, j=SIZE_32BITS-1; i < SIZE_32BITS; i++, j--) { result += (long) ((buffer[pos+i] & BYTE_MASK) << (j*BYTE_BITS)); } return result; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Gets the unread bytes from the buffer. * @return The bytes that haven't been read in a byte array. * @throws ByteBufferException */ public byte[] getByteArray() throws ByteBufferException { if (pos <= buffer.length) { byte[] result = new byte[buffer.length-pos]; System.arraycopy(buffer, pos, result, 0, result.length); pos+=result.length; return result; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Gets the bytes from pos to buffer end. * @param pos A given position in the buffer. Must be smaller than buffer size. * @return The bytes from pos to buffer end stored in a byte array. * @throws ByteBufferException */ public byte[] getByteArray(int pos) throws ByteBufferException { if (pos <= buffer.length) { byte[] result = new byte[buffer.length-pos]; System.arraycopy(buffer, pos, result, 0, result.length); return result; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Stores 8 bits in the buffer. * @param value The 8 bits to be stored given as integer. * @throws ByteBufferException */ public void put8bits(int value) throws ByteBufferException { if (pos + SIZE_8BITS <= buffer.length) { buffer[pos] = (byte)value; pos+=SIZE_8BITS; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Stores 8 bits in the buffer in a given position. * Postion must be smaller than buffer size minus 1. * @param value The 8 bits to be stored given as integer. * @param pos The position to store the 8 bits. * @throws ByteBufferException */ public void put8bits(int value, int pos) throws ByteBufferException { if (pos + SIZE_8BITS <= buffer.length) { buffer[pos] = (byte)value; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Stores 16 bits in the buffer. * @param value The 16 bits to be stored given as integer. * @throws ByteBufferException */ public void put16bits(int value) throws ByteBufferException { if (pos + SIZE_16BITS <= buffer.length) { for (int i=0, j=SIZE_16BITS-1; i < SIZE_16BITS; i++, j--) { buffer [pos+i] = (byte) (value >> (j*BYTE_BITS) & BYTE_MASK); } pos+=SIZE_16BITS; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Stores 16 bits in the buffer in a given position. * Postion must be smaller than buffer size minus 2. * @param value The 16 bits to be stored given as integer. * @param pos The position to store the 32 bits. * @throws ByteBufferException */ public void put16bits(int value, int pos) throws ByteBufferException { if (pos + SIZE_16BITS <= buffer.length) { for (int i=0, j=SIZE_16BITS-1; i < SIZE_16BITS; i++, j--) { buffer [pos+i] = (byte) (value >> (j*BYTE_BITS) & BYTE_MASK); } } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Stores 32 bits in the buffer. * @param value The 32 bits to be stored given as integer. * @throws ByteBufferException */ public void put32bits(long value) throws ByteBufferException { if (pos + SIZE_32BITS <= buffer.length) { for (int i=0, j=SIZE_32BITS-1; i < SIZE_32BITS; i++, j--) { buffer [pos+i] = (byte) (value >> (j*BYTE_BITS) & BYTE_MASK); } pos+=SIZE_32BITS; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Stores 32 bits in the buffer in a given position. * Postion must be smaller than buffer size minus 4. * @param value The 32 bits to be stored given as integer. * @param pos The position to store the 32 bits. * @throws ByteBufferException */ public void put32bits(long value, int pos) throws ByteBufferException { if (pos + SIZE_32BITS <= buffer.length) { for (int i=0, j=SIZE_32BITS-1; i < SIZE_32BITS; i++, j--) { buffer [pos+i] = (byte) (value >> (j*BYTE_BITS) & BYTE_MASK); } } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Stores a byte array in the buffer. * @param byteArray The byte array to be stored. * @throws ByteBufferException */ public void putByteArray(byte byteArray[]) throws ByteBufferException { if (pos + byteArray.length <= buffer.length) { System.arraycopy(byteArray, 0, buffer, pos, byteArray.length); pos+=byteArray.length; } else throw new ByteBufferException("ByteBuffer index of bound"); } /** * Stores a byte array in a given position of the buffer. * The position plus the byte array length must be smaller than the buffer size. * @param byteArray The byte array to store. * @param pos The position to store the byte array. * @throws ByteBufferException */ public void putByteArray(byte byteArray[], int pos) throws ByteBufferException { if (pos + byteArray.length <= buffer.length) { System.arraycopy(byteArray, 0, buffer, pos, byteArray.length); } else throw new ByteBufferException("ByteBuffer index of bound"); } }