/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ 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; import java.io.Serializable; /** * 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 implements Serializable { static final long serialVersionUID = -786393456618166871L; 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 to initially store in the buffer * @param offset index where you want the initial value to start in the array * @param length length of the buffer 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 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 to copy * @param srcEnd index identifying the end of the section * of the byte buffer 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 to which the byte buffer is copied * @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 to set * @param b the new value 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 to append 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 to append to this buffer * @param offset the index in the array marking the start of the * section to copy * @param len the number of bytes 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 to append 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 b the byte to append 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 to append 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 to append 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 to append 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 to append 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 from which to read the bytes * @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 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 from which * to read the bytes * @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 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 * dexception IOException An I/O error has occurred. */ public void write(RandomAccessFile out) throws IOException { out.write(value, 0, count); } }