/** * Adds a byte array to this buffer. If the free space remaining in the buffer * is not large enough, this method will throw a BufferSizeException. A byte * array consisting of a length of 0 will immediately return. * @param bytes A byte array to add to this buffer. Its size must less than or equal to this buffer's free space * @throws BufferSizeException If this buffer's free space is not large enough to store add the byte array */ public void add(byte[] bytes) throws BufferSizeException { this.add(bytes, 0, bytes.length); }
/** * Constructs a new instance of <code>ByteBuffer</code> with an * initial default capacity of 1024 bytes (DEFAULT_BUFFER_CAPACITY) */ public ByteBuffer() { try { this.circularByteBufferInitializer(DEFAULT_BUFFER_CAPACITY+1, 0, 0, 0); } catch (IllegalArgumentException e) { logger.error("Impossible case reached constructing ByteBuffer"); } }
/** * Gets a hash code for this ByteBuffer object based on actual sequence * of bytes stored in this buffer. That means this object is safe to * store in Hashtables or Hashmaps since the same sequence of bytes in * different instances will generate the same hashCode, regardless of * capacity, internal read position, write position, etc. * <br> * This method is implemented using logic from Jakarta Commons Lang * library in the HashCodeBuilder class. * @return A hash code for this ByteBuffer object for the sequence of bytes * stored in this buffer. */ @Override public int hashCode() { // use two hard-coded constant -- any value would do final int hashingConstant = 37; int hashCode = 17 * hashingConstant; int size = size(); // adding entire array of bytes in sequence for (int i = 0; i < size; i++) { hashCode = hashCode * hashingConstant + getUnchecked(i); } return hashCode; }
return new ByteBuffer(1); ByteBuffer.checkOffsetLength(size(), offset, length); ByteBuffer copyBuffer = new ByteBuffer(capacity); this.toArray(offset, length, copyBuffer.buffer, 0);
/** * Return a hexidecimal String representation of the current buffer with each byte * displayed in a 2 character hexidecimal format. Useful for debugging. * Convert a ByteBuffer to a String with a hexidecimal format. * @param offset * @param length * @return The string in hex representation */ public String toHexString(int offset, int length) { // is offset, length valid for the current size() of our internal byte[] checkOffsetLength(size(), offset, length); // if length is 0, return an empty string if (length == 0 || size() == 0) { return ""; } StringBuilder s = new StringBuilder(length * 2); int end = offset + length; for (int i = offset; i < end; i++) { HexUtil.appendHexString(s, getUnchecked(i)); } return s.toString(); } }
/** * Adds a byte array to this buffer starting from the offset up to the * length requested. If the free space remaining in the buffer * is not large enough, this method will throw a BufferSizeException. * @param bytes A byte array to add to this buffer. * @param offset The offset within the byte array to begin to add * @param length The length starting from offset to begin to add * @throws BufferSizeException If this buffer's free space is not large enough to store add the byte array */ public void add(byte[] bytes, int offset, int length) throws IllegalArgumentException, BufferSizeException { // validate the bytes, offset, length checkOffsetLength(bytes.length, offset, length); // is there enough free space in this buffer to add the entire array if (length > free()) { throw new BufferSizeException("Buffer does not have enough free space (" + free() + " bytes) to add " + length + " bytes of data"); } // add each byte to this array for (int i = 0; i < length; i++) { try { this.add(bytes[i+offset]); } catch (BufferIsFullException e) { // this should be an impossible case since we checked the size() above logger.error("Buffer is full even though this method checked its size() ahead of time", e); throw new BufferSizeException(e.getMessage()); } } }
/** * Gets a copy of the current buffer as byte array, but the new byte[] * has the specified capacity. Useful if you need to store additional bytes * in the returned byte[] and dont' want to do an additional System.arraycopy() * afterwards. Method will allocate memory to hold a copy of the current array * and return it. * @param offset The offset to start from * @param length The length from the offset * @param capacity The size of the new byte[]. Must be >= this buffer's size() * @return A byte array. Could be empty. * @throws IllegalArgumentException If capacity isn't large enough enough * to hold the new byte[] */ public byte[] toArray(int offset, int length, int capacity) { // validate the offset, length are ok ByteBuffer.checkOffsetLength(size(), offset, length); // will we have a large enough byte[] allocated? if (capacity < length) { throw new IllegalArgumentException("Capacity must be large enough to hold a byte[] of at least a size=" + length); } byte[] arrayCopy = new byte[capacity]; this.toArray(offset, length, arrayCopy, 0); return arrayCopy; }
if ((count < 0) || (count > capacity())) { throw new IllegalArgumentException("Tried to remove " + count + " bytes from buffer. The count must be a value between 0 and " + capacity()); if (count > size()) { throw new BufferSizeException("Buffer size (" + size() + ") not large enough to remove (" + count + ") bytes"); removedBuffer[currentPos] = this.remove(); } catch (BufferIsEmptyException e) {
/** * Adds one byte to the buffer and throws an exception if the buffer is * full. * @param b Byte to add to the buffer. * @throws BufferIsFullException If the buffer is full and the byte cannot * be stored. */ public void add(byte b) throws BufferIsFullException { if (isFull()) { throw new BufferIsFullException("Buffer is full and has reached maximum capacity (" + capacity() + ")"); } // buffer is not full this.buffer[this.currentWritePosition] = b; this.currentWritePosition = (this.currentWritePosition + 1) % this.buffer.length; this.currentBufferSize += 1; }
/** * Counts the number of occurrences of the byte array in this * <code>ByteBuffer</code>. This method will not overlap any bytes during its * search. For example, if you're search for bytes of "AA" in a buffer containing "AAA", this * method will only return a value of 1. * @param bytes The byte[] to search for * @return -1 if bytes is a length of zero, otherwise the number of occurrences. */ public int occurrences(byte[] bytes) { if (bytes.length == 0) { return -1; } int occurrences = 0; int currentPos = -1; int offset = 0; while (offset < size()) { // search for the delimiter currentPos = indexOf(bytes, offset); if (currentPos < 0) { break; } occurrences++; offset = currentPos + bytes.length; } return occurrences; }
/** * Constructs a new instance of <code>ByteBuffer</code> with the specified * capacity. Buffer is initialized with the byte[] bytes starting from * <code>offset</code> and added up to <code>length</code> bytes. Capacity * must be large enough to store the length. * @param bytes The byte array to initialize buffer with * @param offset The offset in the byte array to start from * @param length The length starting from offset within the byte array * @param capacity The buffer capacity. Must be >= 1. * @throws IllegalArgumentException Thrown if offset or length is negative, * capacity is too small, or if the offset+length would cause a read * past the length of the byte array. */ public ByteBuffer(byte[] bytes, int offset, int length, int capacity) throws IllegalArgumentException { this(capacity); // will check for valid capacity checkOffsetLength(bytes.length, offset, length); // user should have requested >= the length of the bytes they passed in if (capacity < length) { throw new IllegalArgumentException("Buffer capacity (" + capacity + ") must be >= the byte[] length (" + bytes.length + ")"); } // at this point, guaranteed to have enough capacity to add this // entire byte array to this buffer -- we can at least prevent // any BufferSizeException try { this.add(bytes, offset, length); } catch (BufferSizeException e) { logger.error("Impossible case of BufferSizeException in ByteBuffer constructor", e); } }
ByteBuffer.checkOffsetLength(size(), offset, length); ByteBuffer.checkOffsetLength(targetBuffer.length, targetOffset, length);
/** * Tests if the buffer has enough free space to store N bytes. Same * as free() >= N. * @return True if the buffer has enough free space to store N bytes, * otherwise false. */ public boolean isFree(int count) { if (count < 0) { throw new IllegalArgumentException("Count cannot be negative"); } return (free() >= count); }
/** * Most efficient copy of this <code>ByteBuffer</code>. The internal buffer * is copied to the new ByteBuffer using either 1 or 2 calls to System.arraycopy(). * @param offset The offset in the buffer to start from * @param length The length from the offset * @return The new ByteBuffer with copied data */ public ByteBuffer copy(int offset, int length) { return copy(offset, length, length); }
/** * Returns the index within this buffer of the first occurrence of the * specified bytes. The bytes to search for must have a size lower than * or equal to the current buffer size. This method will return -1 if the * bytes are not contained within this byte buffer. * @param bytes The byte array to search for * @return The index where the bytes start to match within the buffer. */ public int indexOf(byte[] bytes) { return indexOf(bytes, 0); }
protected static void checkBytes(byte[] bytes, int offset, int length, int expectedLength) { checkBytesNotNull(bytes); ByteBuffer.checkOffsetLength(bytes.length, offset, length); if (length != expectedLength) { throw new IllegalArgumentException("Unexpected length of byte array [expected=" + expectedLength + ", actual=" + length + "]"); } }
return new ByteBuffer(1); ByteBuffer.checkOffsetLength(size(), offset, length); ByteBuffer copyBuffer = new ByteBuffer(capacity); this.toArray(offset, length, copyBuffer.buffer, 0);