001: /*
002: * $Id: FastStringBuffer.java,v 1.36 2007/03/15 17:08:30 agoubard Exp $
003: *
004: * Copyright 2003-2007 Orange Nederland Breedband B.V.
005: * See the COPYRIGHT file for redistribution and use restrictions.
006: */
007: package org.xins.common.text;
008:
009: import org.xins.common.Log;
010:
011: /**
012: * Fast, unsynchronized string buffer implementation.
013: *
014: * This class should not be used.
015: * Performance tests have shown that simple String concatenation
016: * using the '+' operator is faster.
017: *
018: * @version $Revision: 1.36 $ $Date: 2007/03/15 17:08:30 $
019: * @author <a href="mailto:ernst@ernstdehaan.com">Ernst de Haan</a>
020: *
021: * @since XINS 1.0.0
022: * @deprecated since 2.0 use Stringbuffer or String
023: */
024: public class FastStringBuffer {
025:
026: /**
027: * The underlying character buffer. The size of this buffer is the capacity
028: * of this string buffer object.
029: */
030: private char[] _buffer;
031:
032: /**
033: * The actual length of the contained content. Is always less than or equal
034: * to the capacity.
035: */
036: private int _length;
037:
038: /**
039: * Constructs a new <code>FastStringBuffer</code> object with the specified
040: * initial capacity.
041: *
042: * @param capacity
043: * the initial capacity, must be >= 0.
044: *
045: * @throws IllegalArgumentException
046: * if <code>capacity < 0</code>.
047: */
048: public FastStringBuffer(int capacity)
049: throws IllegalArgumentException {
050:
051: // Check preconditions
052: if (capacity < 0) {
053: throw new IllegalArgumentException("capacity (" + capacity
054: + ") < 0");
055: }
056:
057: // Initialize fields
058: _buffer = new char[capacity];
059: _length = 0;
060: }
061:
062: /**
063: * Constructs a new <code>FastStringBuffer</code> object with the specified
064: * initial content. The capacity will be equal to the length of the
065: * specified string.
066: *
067: * @param s
068: * the initial content, cannot be <code>null</code>.
069: *
070: * @throws IllegalArgumentException
071: * if <code>s == null</code>.
072: */
073: public FastStringBuffer(String s) throws IllegalArgumentException {
074:
075: // Check preconditions
076: if (s == null) {
077: throw new IllegalArgumentException("s == null");
078: }
079:
080: // Initialize fields
081: _buffer = s.toCharArray();
082: _length = _buffer.length;
083: }
084:
085: /**
086: * Constructs a new <code>FastStringBuffer</code> object with the specified
087: * initial capacity and content.
088: *
089: * @param capacity
090: * the initial capacity, must be
091: * >= <code>s.</code>{@link String#length()}.
092: *
093: * @param s
094: * the initial content, cannot be <code>null</code>.
095: *
096: * @throws IllegalArgumentException
097: * if <code>s == null
098: * || capacity < s.</code>{@link String#length()}.
099: */
100: public FastStringBuffer(int capacity, String s)
101: throws IllegalArgumentException {
102:
103: // Check preconditions
104: if (s == null) {
105: throw new IllegalArgumentException("s == null");
106: }
107: if (capacity < s.length()) {
108: throw new IllegalArgumentException("capacity (" + capacity
109: + ") < s.length() (" + s.length() + ')');
110: }
111:
112: // Initialize fields
113: _buffer = new char[capacity];
114: _length = s.length();
115: s.getChars(0, _length, _buffer, 0);
116: }
117:
118: /**
119: * Ensures that the specified needed capacity is actually available. If it
120: * is not, then the internal buffer will be expanded. The new capacity will
121: * be larger than or equal to the needed capacity.
122: *
123: * @param needed
124: * the needed capacity.
125: */
126: private void ensureCapacity(int needed) {
127:
128: // Determine current capacity
129: int current = _buffer.length;
130:
131: // Increase capacity if needed
132: if (current < needed) {
133: int newCapacity = needed << 2;
134:
135: Log.log_1250(current, newCapacity);
136:
137: char[] newBuffer = new char[newCapacity];
138: System.arraycopy(_buffer, 0, newBuffer, 0, current);
139: _buffer = newBuffer;
140: }
141: }
142:
143: /**
144: * Appends the specified boolean. If necessary, the capacity of this
145: * string buffer will be increased.
146: *
147: * @param b
148: * the boolean to append, if it is <code>true</code> then the string
149: * <code>"true"</code> will be appended, otherwise the string
150: * <code>"false"</code> will be appended..
151: */
152: public void append(boolean b) {
153: append(b ? "true" : "false");
154: }
155:
156: /**
157: * Appends the specified character. If necessary, the capacity of this
158: * string buffer will be increased.
159: *
160: * @param c
161: * the character to append.
162: */
163: public void append(char c) {
164:
165: // Ensure there is enough capacity
166: ensureCapacity(_length + 1);
167:
168: // Append the character
169: _buffer[_length++] = c;
170: }
171:
172: /**
173: * Appends all characters in the specified character buffer. If necessary,
174: * the capacity of this string buffer will be increased.
175: *
176: * @param cbuf
177: * the character array to copy characters from, not <code>null</code>.
178: *
179: * @throws IllegalArgumentException
180: * if <code>cbuf == null</code>.
181: */
182: public void append(char[] cbuf) throws IllegalArgumentException {
183:
184: // Check preconditions
185: if (cbuf == null) {
186: throw new IllegalArgumentException("cbuf == null");
187: }
188:
189: int newLength = _length + cbuf.length;
190:
191: // Ensure there is enough capacity
192: ensureCapacity(newLength);
193:
194: // Copy the data into the internal buffer
195: System.arraycopy(cbuf, 0, _buffer, _length, cbuf.length);
196:
197: _length = newLength;
198: }
199:
200: /**
201: * Appends characters from the specified character buffer. If necessary,
202: * the capacity of this string buffer will be increased.
203: *
204: * @param cbuf
205: * the character array to copy characters from, not <code>null</code>.
206: *
207: * @param off
208: * the offset in <code>cbuf</code>, must be >= 0 and <
209: * <code>cbuf.length</code>.
210: *
211: * @param len
212: * the number of characters to copy, must be >= 0 and <code>(off +
213: * len)</code> must be <= <code>cbuf.length</code>.
214: *
215: * @throws IllegalArgumentException
216: * if <code>cbuf == null
217: * || off < 0
218: * || off > cbuf.length
219: * || len < 0
220: * || (off + len > cbuf.length)</code>.
221: */
222: public void append(char[] cbuf, int off, int len)
223: throws IllegalArgumentException {
224:
225: // Check preconditions
226: if (cbuf == null) {
227: throw new IllegalArgumentException("cbuf == null");
228: }
229: if (off < 0) {
230: throw new IllegalArgumentException("off (" + off + ") < 0");
231: } else if (off > cbuf.length) {
232: throw new IllegalArgumentException("off (" + off
233: + ") >= cbuf.length (" + cbuf.length + ')');
234: } else if (len < 0) {
235: throw new IllegalArgumentException("len (" + len + ") < 0");
236: } else if (off + len > cbuf.length) {
237: throw new IllegalArgumentException("off (" + off
238: + ") + len (" + len + ") > cbuf.length ("
239: + cbuf.length + ')');
240: }
241:
242: if (len == 0) {
243: return;
244: }
245:
246: int newLength = _length + len;
247:
248: // Ensure there is enough capacity
249: ensureCapacity(newLength);
250:
251: // Copy the data into the internal buffer
252: System.arraycopy(cbuf, off, _buffer, _length, len);
253:
254: _length = newLength;
255: }
256:
257: /**
258: * Appends all characters in the specified character string. If necessary,
259: * the capacity of this string buffer will be increased.
260: *
261: * @param str
262: * the character string to copy characters from, not <code>null</code>.
263: *
264: * @throws IllegalArgumentException
265: * if <code>str == null</code>.
266: */
267: public void append(String str) throws IllegalArgumentException {
268:
269: // Check preconditions
270: if (str == null) {
271: throw new IllegalArgumentException("str == null");
272: }
273:
274: int strLength = str.length();
275: int newLength = _length + strLength;
276:
277: // Ensure there is enough capacity
278: ensureCapacity(newLength);
279:
280: // Copy the string chars into the buffer
281: str.getChars(0, strLength, _buffer, _length);
282: _length = newLength;
283: }
284:
285: /**
286: * Appends the string representation of the specified <code>byte</code>.
287: * If necessary, the capacity of this string buffer will be increased.
288: *
289: * @param n
290: * the number of which the string representation should be added to this
291: * buffer.
292: */
293: public void append(byte n) {
294: append(String.valueOf(n));
295: }
296:
297: /**
298: * Appends the string representation of the specified <code>short</code>.
299: * If necessary, the capacity of this string buffer will be increased.
300: *
301: * @param n
302: * the number of which the string representation should be added to this
303: * buffer.
304: */
305: public void append(short n) {
306: append(String.valueOf(n));
307: }
308:
309: /**
310: * Appends the string representation of the specified <code>int</code>.
311: * If necessary, the capacity of this string buffer will be increased.
312: *
313: * @param n
314: * the number of which the string representation should be added to this
315: * buffer.
316: */
317: public void append(int n) {
318: append(String.valueOf(n));
319: }
320:
321: /**
322: * Appends the string representation of the specified <code>long</code>.
323: * If necessary, the capacity of this string buffer will be increased.
324: *
325: * @param n
326: * the number of which the string representation should be added to this
327: * buffer.
328: */
329: public void append(long n) {
330: append(String.valueOf(n));
331: }
332:
333: /**
334: * Appends the string representation of the specified <code>float</code>.
335: * If necessary, the capacity of this string buffer will be increased.
336: *
337: * @param n
338: * the number of which the string representation should be added to this
339: * buffer.
340: */
341: public void append(float n) {
342: append(String.valueOf(n));
343: }
344:
345: /**
346: * Appends the string representation of the specified <code>double</code>.
347: * If necessary, the capacity of this string buffer will be increased.
348: *
349: * @param n
350: * the number of which the string representation should be added to this
351: * buffer.
352: */
353: public void append(double n) {
354: append(String.valueOf(n));
355: }
356:
357: /**
358: * Gets the length of this string buffer. This is always <= the
359: * capacity.
360: *
361: * @return
362: * the number of characters in this buffer, always
363: * <= {@link #getCapacity()}.
364: */
365: public int getLength() {
366: return _length;
367: }
368:
369: /**
370: * Gets the capacity of this string buffer. This is always >= the
371: * length.
372: *
373: * @return
374: * the number of characters that fits in this buffer without having to
375: * extend the internal data structure, always >=
376: * {@link #getLength()}.
377: */
378: public int getCapacity() {
379: return _buffer.length;
380: }
381:
382: /**
383: * Sets the character at the specified index.
384: *
385: * @param index
386: * the index at which to set the character, must be <
387: * {@link #getLength()}.
388: *
389: * @param newChar
390: * the new character value.
391: *
392: * @return
393: * the old character value.
394: *
395: * @throws IndexOutOfBoundsException
396: * if <code>index < 0 || index >= </code>{@link #getLength()}.
397: */
398: public char setChar(int index, char newChar)
399: throws IndexOutOfBoundsException {
400:
401: if (index >= _length) {
402: throw new IndexOutOfBoundsException("index (" + index
403: + ") >= getLength() (" + _length + ')');
404: }
405:
406: char oldChar = _buffer[index];
407: _buffer[index] = newChar;
408: return oldChar;
409: }
410:
411: /**
412: * Reduces the length of this string buffer. The capacity will remain
413: * untouched.
414: *
415: * @param newLength
416: * the new length, must be less than or equal to the current length (see
417: * {@link #getLength()}).
418: *
419: * @throws IllegalArgumentException
420: * if <code>newLength < 0
421: * || newLength > {@link #getLength()}</code>.
422: *
423: * @since XINS 1.2.0
424: */
425: public void crop(int newLength) throws IllegalArgumentException {
426:
427: // Check preconditions
428: if (newLength < 0) {
429: throw new IllegalArgumentException("newLength ("
430: + newLength + ") < 0");
431: } else if (newLength > _length) {
432: throw new IllegalArgumentException("newLength ("
433: + newLength + ") > getLength() (" + _length + ')');
434: }
435:
436: _length = newLength;
437: }
438:
439: /**
440: * Clears this string buffer. The capacity will remain untouched, though.
441: */
442: public void clear() {
443: crop(0);
444: }
445:
446: /**
447: * Converts the contents of this buffer to a <code>String</code> object. A
448: * new {@link String} object is created each time this method is called.
449: *
450: * @return
451: * a newly constructed {@link String} that contains the same characters
452: * as this string buffer object, never <code>null</code>.
453: */
454: public String toString() {
455: return new String(_buffer, 0, _length);
456: }
457: }
|