/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ package netscape.ldap.util; import java.util.*; import java.io.FileInputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.io.RandomAccessFile; /** * This class is similar to the java.lang.StringBuffer * class. Instead of storing a string, an object of this class * stores an array of bytes. (This is referred to as a "byte buffer".) *

* * This class also differs from StringBuffer in the * following ways: *

*/ public final class ByteBuf { private byte value[]; private int count; /** * Constructs an empty byte buffer with the default length of 16. */ public ByteBuf() { this(16); } /** * Constructs an empty byte buffer with the specified initial length. * @param length Initial number of bytes that this buffer should hold. */ public ByteBuf(int length) { value = new byte[length]; } /** * Constructs a byte buffer with the specified initial value. * The new byte buffer is 16 bytes longer than the initial value. * @param str Initial value that this buffer should hold. */ public ByteBuf(String str) { this(str.length() + 16); append(str); } /** * Constructs a byte buffer with the specified length. * An initial value is stored in this buffer, starting * at the specified offset. * @param bytes Array of bytes that you want to store in * the buffer initially. * @param offset Index in the array where you want the * initial value to start. * @param length Length of the buffer that you want to * allocate. */ public ByteBuf(byte bytes[], int offset, int length) { value = new byte[length]; System.arraycopy(bytes, offset, value, 0, length); count = length; } /** * Returns the length (character count) of the byte buffer. */ public int length() { return count; } /** * Returns the current capacity of the byte buffer. The capacity * is the amount of storage available for newly inserted bytes. * If the capacity is exceeded, more space will be allocated. */ public int capacity() { return value.length; } /** * Ensures that the capacity of the buffer is at least equal to the * specified minimum capacity. * @param minimumCapacity The minimum number of bytes that you want * the byte buffer to hold. */ public void ensureCapacity(int minimumCapacity) { int maxCapacity = value.length; if (minimumCapacity > maxCapacity) { int newCapacity = (maxCapacity + 1) * 2; if (minimumCapacity > newCapacity) { newCapacity = minimumCapacity; } byte newValue[] = new byte[newCapacity]; System.arraycopy(value, 0, newValue, 0, count); value = newValue; } } /** * Sets the length of the byte buffer. If you set a length that is * shorter than the current length, bytes at the end of the buffer * are lost. If you increase the length of the buffer, the values * of the new bytes in the buffer are set to 0. * @param newLength The new length of the buffer * @exception StringIndexOutOfBoundsException You have specified * an invalid length. */ public void setLength(int newLength) { if (newLength < 0) { throw new StringIndexOutOfBoundsException(newLength); } if (count < newLength) { ensureCapacity(newLength); for (; count < newLength; count++) { value[count] = '\0'; } } count = newLength; } /** * Returns the byte at the specified index. The value of an index * can range from 0 to length - 1. * @param index Index of the byte you want to find. * @exception StringIndexOutOfBoundsException You have specified an * invalid index. */ public byte byteAt(int index) { if ((index < 0) || (index >= count)) { throw new StringIndexOutOfBoundsException(index); } return value[index]; } /** * Copies the bytes (from the section of the byte buffer from the index * srcBegin to the index srcEnd - 1 ) * into the specified byte array. The copied * bytes are inserted in the byte array at the index specified by * dstBegin. Both srcBegin and * srcEnd must be valid indexes in the buffer. * @param srcBegin Index identifying the start of the section * of the byte buffer that you want to copy. * @param srcEnd Index identifying the end of the section * of the byte buffer that you want to copy. (Copy all bytes * before the byte identified by this index.) * @param dst The byte array to copy the data to * @param dstBegin Index of the byte array identifying the * location where you want the byte buffer copied to. * @exception StringIndexOutOfBoundsException You specified an invalid index into the buffer. */ public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) { if ((srcBegin < 0) || (srcBegin >= count)) { throw new StringIndexOutOfBoundsException(srcBegin); } if ((srcEnd < 0) || (srcEnd > count)) { throw new StringIndexOutOfBoundsException(srcEnd); } if (srcBegin < srcEnd) { System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); } } /** * Sets the value of the byte at the specified index. * @param index The index of the byte that you want to set. * @param b The new value that you want to set. * @exception StringIndexOutOfBoundsException You have specified * an invalid index. */ public void setByteAt(int index, byte b) { if ((index < 0) || (index >= count)) { throw new StringIndexOutOfBoundsException(index); } value[index] = b; } /** * Appends an object to the end of this byte buffer. * @param obj The object that you want appended to the buffer. * @return The same ByteBuf object (not a new object) * with the string representation of the specified object appended. */ public ByteBuf append(Object obj) { return append(String.valueOf(obj)); } /** * Appends a string to the end of this byte buffer. * This method appends one byte for each character in the string. * The upper 8 bits of the character are stripped off. *

* * If you want to retain all bits in the character (not just * the lower 8 bits), use append(String.getBytes()) * instead. * @param str The string that you want appended to the buffer. * @return The same ByteBuf object (not a new object) * with the specified string appended. */ public ByteBuf append(String str) { if (str == null) { str = String.valueOf(str); } int len = str.length(); ensureCapacity(count + len); for (int i=0 ; iByteBuf object (not a new object) * with the specified bytes appended. */ public ByteBuf append(byte str[]) { int len = str.length; ensureCapacity(count + len); System.arraycopy(str, 0, value, count, len); count += len; return this; } /** * Appends a part of an array of bytes to the end of this byte buffer. * @param str The array of bytes that you want appended to this buffer. * @param offset The index in the array marking the start of the * section that you want to copy. * @param len The number of bytes that you want to add. * @return The same ByteBuf object (not a new object) * with the specified section of the byte array appended. */ public ByteBuf append(byte str[], int offset, int len) { ensureCapacity(count + len); System.arraycopy(str, offset, value, count, len); count += len; return this; } /** * Appends a byte buffer to the end of this byte buffer. * @param buf The byte buffer that you want appended to this buffer. * @return The original ByteBuf object (not a new object) * with bytes from the specified byte buffer appended. */ public ByteBuf append(ByteBuf buf) { append(buf.toBytes(), 0, buf.length()); return this; } /** * Appends a boolean to the end of this byte buffer. * @param b The boolean value that you want appended to this buffer. * @return The original ByteBuf object (not a new object) * with bytes from the string representation of the boolean value appended. */ public ByteBuf append(boolean b) { return append(String.valueOf(b)); } /** * Appends a byte to the end of this byte buffer. * @param ch The byte that you want appended to this buffer. * @return The original ByteBuf object (not a new object) * with the specified byte appended. */ public ByteBuf append(byte b) { ensureCapacity(count + 1); value[count++] = b; return this; } /** * Appends an integer to the end of this byte buffer. * @param i The integer that you want appended to this byte buffer. * @return The original ByteBuf object (not a new object) * with the string representation of the specified integer appended. */ public ByteBuf append(int i) { return append(String.valueOf(i)); } /** * Appends a long value to the end of this byte buffer. * @param l The long value that you want appended * to this buffer. * @return The original ByteBuf object (not a new object) * with the string representation of the specified long * value appended. */ public ByteBuf append(long l) { return append(String.valueOf(l)); } /** * Appends a float to the end of this byte buffer. * @param f The float value that you want appended * to this buffer. * @return The original ByteBuf object (not a new object) * with the string representation of the specified float * value appended. */ public ByteBuf append(float f) { return append(String.valueOf(f)); } /** * Appends a double to the end of this byte buffer. * @param d The double value that you want appended to * this buffer. * @return The original ByteBuf object (not a new object) * with the string representation of the specified double * value appended. */ public ByteBuf append(double d) { return append(String.valueOf(d)); } /** * Returns the data in the byte buffer to a string. * @return The string representation of the data in the byte buffer. */ public String toString() { return new String(value, 0, count); } /** * Returns the data in the byte buffer as a byte array. * @return The byte array containing data in the byte buffer. */ public byte[] toBytes() { byte[] b = new byte[count]; System.arraycopy(value, 0, b, 0, count); return b; } /** * Invokes the InputStream.read method and appends the * the bytes read to this byte buffer. * @param file The input stream that you want to read the bytes from. * @param max_bytes The maximum number of bytes to read into the * byte buffer. * @return The number of bytes read, or -1 if there is no more data * to be read. * @exception IOException An I/O error has occurred. */ public int read(InputStream file, int max_bytes) throws IOException { ensureCapacity(count + max_bytes); int i = file.read(value, count, max_bytes); if (i > 0) count += i; return i; } /** * Invokes the RandomAccessFile.read method, appending * the bytes read to this byte buffer. * @param file The RandomAccessFile object that you want * to read the bytes from. * @param max_bytes The maximum number of bytes to read into the * byte buffer. * @return The number of bytes read, or -1 if there is no more data * to be read. * @exception IOException An I/O error has occurred. */ public int read(RandomAccessFile file, int max_bytes) throws IOException { ensureCapacity(count + max_bytes); int i = file.read(value, count, max_bytes); if (i > 0) count += i; return i; } /** * Writes the contents of the byte buffer to the specified output stream. * @param out The output stream. * @exception IOException An I/O error has occurred. */ public void write(OutputStream out) throws IOException { out.write(value, 0, count); } /** * Writes the contents of the byte buffer to the specified * RandomAccessFile object. * @param out The RandomAccessFile object. * @exception IOException An I/O error has occurred. */ public void write(RandomAccessFile out) throws IOException { out.write(value, 0, count); } }