| FastStringBuffer.java |
/*
* $Id: FastStringBuffer.java,v 1.38 2010/09/29 17:21:48 agoubard Exp $
*
* See the COPYRIGHT file for redistribution and use restrictions.
*/
package org.xins.common.text;
import org.xins.common.Log;
/**
* Fast, unsynchronized string buffer implementation.
*
* This class should not be used.
* Performance tests have shown that simple String concatenation
* using the '+' operator is faster.
*
* @version $Revision: 1.38 $ $Date: 2010/09/29 17:21:48 $
* @author <a href="mailto:ernst@ernstdehaan.com">Ernst de Haan</a>
*
* @since XINS 1.0.0
* @deprecated since 2.0 use Stringbuffer or String
*/
public class FastStringBuffer {
/**
* The underlying character buffer. The size of this buffer is the capacity
* of this string buffer object.
*/
private char[] _buffer;
/**
* The actual length of the contained content. Is always less than or equal
* to the capacity.
*/
private int _length;
/**
* Constructs a new <code>FastStringBuffer</code> object with the specified
* initial capacity.
*
* @param capacity
* the initial capacity, must be >= 0.
*
* @throws IllegalArgumentException
* if <code>capacity < 0</code>.
*/
public FastStringBuffer(int capacity)
throws IllegalArgumentException {
// Check preconditions
if (capacity < 0) {
throw new IllegalArgumentException(
"capacity (" + capacity + ") < 0");
}
// Initialize fields
_buffer = new char[capacity];
_length = 0;
}
/**
* Constructs a new <code>FastStringBuffer</code> object with the specified
* initial content. The capacity will be equal to the length of the
* specified string.
*
* @param s
* the initial content, cannot be <code>null</code>.
*
* @throws IllegalArgumentException
* if <code>s == null</code>.
*/
public FastStringBuffer(String s)
throws IllegalArgumentException {
// Check preconditions
if (s == null) {
throw new IllegalArgumentException("s == null");
}
// Initialize fields
_buffer = s.toCharArray();
_length = _buffer.length;
}
/**
* Constructs a new <code>FastStringBuffer</code> object with the specified
* initial capacity and content.
*
* @param capacity
* the initial capacity, must be
* >= <code>s.</code>{@link String#length()}.
*
* @param s
* the initial content, cannot be <code>null</code>.
*
* @throws IllegalArgumentException
* if <code>s == null
* || capacity < s.</code>{@link String#length()}.
*/
public FastStringBuffer(int capacity, String s)
throws IllegalArgumentException {
// Check preconditions
if (s == null) {
throw new IllegalArgumentException("s == null");
}
if (capacity < s.length()) {
throw new IllegalArgumentException(
"capacity (" + capacity + ") < s.length() (" + s.length() + ')');
}
// Initialize fields
_buffer = new char[capacity];
_length = s.length();
s.getChars(0, _length, _buffer, 0);
}
/**
* Ensures that the specified needed capacity is actually available. If it
* is not, then the internal buffer will be expanded. The new capacity will
* be larger than or equal to the needed capacity.
*
* @param needed
* the needed capacity.
*/
private void ensureCapacity(int needed) {
// Determine current capacity
int current = _buffer.length;
// Increase capacity if needed
if (current < needed) {
int newCapacity = needed << 2;
Log.log_1250(current, newCapacity);
char[] newBuffer = new char[newCapacity];
System.arraycopy(_buffer, 0, newBuffer, 0, current);
_buffer = newBuffer;
}
}
/**
* Appends the specified boolean. If necessary, the capacity of this
* string buffer will be increased.
*
* @param b
* the boolean to append, if it is <code>true</code> then the string
* <code>"true"</code> will be appended, otherwise the string
* <code>"false"</code> will be appended..
*/
public void append(boolean b) {
append(b ? "true" : "false");
}
/**
* Appends the specified character. If necessary, the capacity of this
* string buffer will be increased.
*
* @param c
* the character to append.
*/
public void append(char c) {
// Ensure there is enough capacity
ensureCapacity(_length + 1);
// Append the character
_buffer[_length++] = c;
}
/**
* Appends all characters in the specified character buffer. If necessary,
* the capacity of this string buffer will be increased.
*
* @param cbuf
* the character array to copy characters from, not <code>null</code>.
*
* @throws IllegalArgumentException
* if <code>cbuf == null</code>.
*/
public void append(char[] cbuf)
throws IllegalArgumentException {
// Check preconditions
if (cbuf == null) {
throw new IllegalArgumentException("cbuf == null");
}
int newLength = _length + cbuf.length;
// Ensure there is enough capacity
ensureCapacity(newLength);
// Copy the data into the internal buffer
System.arraycopy(cbuf, 0, _buffer, _length, cbuf.length);
_length = newLength;
}
/**
* Appends characters from the specified character buffer. If necessary,
* the capacity of this string buffer will be increased.
*
* @param cbuf
* the character array to copy characters from, not <code>null</code>.
*
* @param off
* the offset in <code>cbuf</code>, must be >= 0 and <
* <code>cbuf.length</code>.
*
* @param len
* the number of characters to copy, must be >= 0 and <code>(off +
* len)</code> must be <= <code>cbuf.length</code>.
*
* @throws IllegalArgumentException
* if <code>cbuf == null
* || off < 0
* || off > cbuf.length
* || len < 0
* || (off + len > cbuf.length)</code>.
*/
public void append(char[] cbuf, int off, int len)
throws IllegalArgumentException {
// Check preconditions
if (cbuf == null) {
throw new IllegalArgumentException("cbuf == null");
}
if (off < 0) {
throw new IllegalArgumentException("off (" + off + ") < 0");
} else if (off > cbuf.length) {
throw new IllegalArgumentException(
"off (" + off + ") >= cbuf.length (" + cbuf.length + ')');
} else if (len < 0) {
throw new IllegalArgumentException("len (" + len + ") < 0");
} else if (off + len > cbuf.length) {
throw new IllegalArgumentException(
"off (" + off + ") + len (" + len + ") > cbuf.length (" +
cbuf.length + ')');
}
if (len == 0) {
return;
}
int newLength = _length + len;
// Ensure there is enough capacity
ensureCapacity(newLength);
// Copy the data into the internal buffer
System.arraycopy(cbuf, off, _buffer, _length, len);
_length = newLength;
}
/**
* Appends all characters in the specified character string. If necessary,
* the capacity of this string buffer will be increased.
*
* @param str
* the character string to copy characters from, not <code>null</code>.
*
* @throws IllegalArgumentException
* if <code>str == null</code>.
*/
public void append(String str)
throws IllegalArgumentException {
// Check preconditions
if (str == null) {
throw new IllegalArgumentException("str == null");
}
int strLength = str.length();
int newLength = _length + strLength;
// Ensure there is enough capacity
ensureCapacity(newLength);
// Copy the string chars into the buffer
str.getChars(0, strLength, _buffer, _length);
_length = newLength;
}
/**
* Appends the string representation of the specified <code>byte</code>.
* If necessary, the capacity of this string buffer will be increased.
*
* @param n
* the number of which the string representation should be added to this
* buffer.
*/
public void append(byte n) {
append(String.valueOf(n));
}
/**
* Appends the string representation of the specified <code>short</code>.
* If necessary, the capacity of this string buffer will be increased.
*
* @param n
* the number of which the string representation should be added to this
* buffer.
*/
public void append(short n) {
append(String.valueOf(n));
}
/**
* Appends the string representation of the specified <code>int</code>.
* If necessary, the capacity of this string buffer will be increased.
*
* @param n
* the number of which the string representation should be added to this
* buffer.
*/
public void append(int n) {
append(String.valueOf(n));
}
/**
* Appends the string representation of the specified <code>long</code>.
* If necessary, the capacity of this string buffer will be increased.
*
* @param n
* the number of which the string representation should be added to this
* buffer.
*/
public void append(long n) {
append(String.valueOf(n));
}
/**
* Appends the string representation of the specified <code>float</code>.
* If necessary, the capacity of this string buffer will be increased.
*
* @param n
* the number of which the string representation should be added to this
* buffer.
*/
public void append(float n) {
append(String.valueOf(n));
}
/**
* Appends the string representation of the specified <code>double</code>.
* If necessary, the capacity of this string buffer will be increased.
*
* @param n
* the number of which the string representation should be added to this
* buffer.
*/
public void append(double n) {
append(String.valueOf(n));
}
/**
* Gets the length of this string buffer. This is always <= the
* capacity.
*
* @return
* the number of characters in this buffer, always
* <= {@link #getCapacity()}.
*/
public int getLength() {
return _length;
}
/**
* Gets the capacity of this string buffer. This is always >= the
* length.
*
* @return
* the number of characters that fits in this buffer without having to
* extend the internal data structure, always >=
* {@link #getLength()}.
*/
public int getCapacity() {
return _buffer.length;
}
/**
* Sets the character at the specified index.
*
* @param index
* the index at which to set the character, must be <
* {@link #getLength()}.
*
* @param newChar
* the new character value.
*
* @return
* the old character value.
*
* @throws IndexOutOfBoundsException
* if <code>index < 0 || index >= </code>{@link #getLength()}.
*/
public char setChar(int index, char newChar)
throws IndexOutOfBoundsException {
if (index >= _length) {
throw new IndexOutOfBoundsException(
"index (" + index + ") >= getLength() (" + _length + ')');
}
char oldChar = _buffer[index];
_buffer[index] = newChar;
return oldChar;
}
/**
* Reduces the length of this string buffer. The capacity will remain
* untouched.
*
* @param newLength
* the new length, must be less than or equal to the current length (see
* {@link #getLength()}).
*
* @throws IllegalArgumentException
* if <code>newLength < 0
* || newLength > {@link #getLength()}</code>.
*
* @since XINS 1.2.0
*/
public void crop(int newLength)
throws IllegalArgumentException {
// Check preconditions
if (newLength < 0) {
throw new IllegalArgumentException(
"newLength (" + newLength + ") < 0");
} else if (newLength > _length) {
throw new IllegalArgumentException(
"newLength (" + newLength + ") > getLength() (" + _length + ')');
}
_length = newLength;
}
/**
* Clears this string buffer. The capacity will remain untouched, though.
*/
public void clear() {
crop(0);
}
/**
* Converts the contents of this buffer to a <code>String</code> object. A
* new {@link String} object is created each time this method is called.
*
* @return
* a newly constructed {@link String} that contains the same characters
* as this string buffer object, never <code>null</code>.
*/
public String toString() {
return new String(_buffer, 0, _length);
}
}