Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / java / lang / StringBuffer.java
blobcaffd6e705067471f91b6a255f921c13f5af958d
1 /* StringBuffer.java -- Growable strings
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
39 package java.lang;
41 import java.io.Serializable;
43 /**
44 * <code>StringBuffer</code> represents a changeable <code>String</code>.
45 * It provides the operations required to modify the
46 * <code>StringBuffer</code>, including insert, replace, delete, append,
47 * and reverse. It is thread-safe; meaning that all modifications to a buffer
48 * are in synchronized methods.
50 * <p><code>StringBuffer</code>s are variable-length in nature, so even if
51 * you initialize them to a certain size, they can still grow larger than
52 * that. <em>Capacity</em> indicates the number of characters the
53 * <code>StringBuffer</code> can have in it before it has to grow (growing
54 * the char array is an expensive operation involving <code>new</code>).
56 * <p>Incidentally, compilers often implement the String operator "+"
57 * by using a <code>StringBuffer</code> operation:<br>
58 * <code>a + b</code><br>
59 * is the same as<br>
60 * <code>new StringBuffer().append(a).append(b).toString()</code>.
62 * <p>Classpath's StringBuffer is capable of sharing memory with Strings for
63 * efficiency. This will help when a StringBuffer is converted to a String
64 * and the StringBuffer is not changed after that (quite common when performing
65 * string concatenation).
67 * @author Paul Fisher
68 * @author John Keiser
69 * @author Tom Tromey
70 * @author Eric Blake (ebb9@email.byu.edu)
71 * @see String
72 * @since 1.0
73 * @status updated to 1.4
75 public final class StringBuffer implements Serializable, CharSequence
77 /**
78 * Compatible with JDK 1.0+.
80 private static final long serialVersionUID = 3388685877147921107L;
82 /**
83 * Index of next available character (and thus the size of the current
84 * string contents). Note that this has permissions set this way so that
85 * String can get the value.
87 * @serial the number of characters in the buffer
89 int count;
91 /**
92 * The buffer. Note that this has permissions set this way so that String
93 * can get the value.
95 * @serial the buffer
97 char[] value;
99 /**
100 * True if the buffer is shared with another object (StringBuffer or
101 * String); this means the buffer must be copied before writing to it again.
102 * Note that this has permissions set this way so that String can get the
103 * value.
105 * @serial whether the buffer is shared
107 boolean shared;
110 * The default capacity of a buffer.
112 private static final int DEFAULT_CAPACITY = 16;
115 * Create a new StringBuffer with default capacity 16.
117 public StringBuffer()
119 this(DEFAULT_CAPACITY);
123 * Create an empty <code>StringBuffer</code> with the specified initial
124 * capacity.
126 * @param capacity the initial capacity
127 * @throws NegativeArraySizeException if capacity is negative
129 public StringBuffer(int capacity)
131 value = new char[capacity];
135 * Create a new <code>StringBuffer</code> with the characters in the
136 * specified <code>String</code>. Initial capacity will be the size of the
137 * String plus 16.
139 * @param str the <code>String</code> to convert
140 * @throws NullPointerException if str is null
142 public StringBuffer(String str)
144 // Unfortunately, because the size is 16 larger, we cannot share.
145 count = str.count;
146 value = new char[count + DEFAULT_CAPACITY];
147 str.getChars(0, count, value, 0);
151 * Create a new <code>StringBuffer</code> with the characters from the
152 * specified <code>CharSequence</code>. Initial capacity will be the
153 * size of the CharSequence plus 16.
155 * @param sequence the <code>String</code> to convert
156 * @throws NullPointerException if str is null
158 * @since 1.5
160 public StringBuffer(CharSequence sequence)
162 count = Math.max(0, sequence.length());
163 value = new char[count + DEFAULT_CAPACITY];
164 for (int i = 0; i < count; ++i)
165 value[i] = sequence.charAt(i);
169 * Get the length of the <code>String</code> this <code>StringBuffer</code>
170 * would create. Not to be confused with the <em>capacity</em> of the
171 * <code>StringBuffer</code>.
173 * @return the length of this <code>StringBuffer</code>
174 * @see #capacity()
175 * @see #setLength(int)
177 public synchronized int length()
179 return count;
183 * Get the total number of characters this <code>StringBuffer</code> can
184 * support before it must be grown. Not to be confused with <em>length</em>.
186 * @return the capacity of this <code>StringBuffer</code>
187 * @see #length()
188 * @see #ensureCapacity(int)
190 public synchronized int capacity()
192 return value.length;
196 * Increase the capacity of this <code>StringBuffer</code>. This will
197 * ensure that an expensive growing operation will not occur until
198 * <code>minimumCapacity</code> is reached. The buffer is grown to the
199 * larger of <code>minimumCapacity</code> and
200 * <code>capacity() * 2 + 2</code>, if it is not already large enough.
202 * @param minimumCapacity the new capacity
203 * @see #capacity()
205 public synchronized void ensureCapacity(int minimumCapacity)
207 ensureCapacity_unsynchronized(minimumCapacity);
211 * Set the length of this StringBuffer. If the new length is greater than
212 * the current length, all the new characters are set to '\0'. If the new
213 * length is less than the current length, the first <code>newLength</code>
214 * characters of the old array will be preserved, and the remaining
215 * characters are truncated.
217 * @param newLength the new length
218 * @throws IndexOutOfBoundsException if the new length is negative
219 * (while unspecified, this is a StringIndexOutOfBoundsException)
220 * @see #length()
222 public synchronized void setLength(int newLength)
224 if (newLength < 0)
225 throw new StringIndexOutOfBoundsException(newLength);
227 int valueLength = value.length;
229 /* Always call ensureCapacity_unsynchronized in order to preserve
230 copy-on-write semantics. */
231 ensureCapacity_unsynchronized(newLength);
233 if (newLength < valueLength)
235 /* If the StringBuffer's value just grew, then we know that
236 value is newly allocated and the region between count and
237 newLength is filled with '\0'. */
238 count = newLength;
240 else
242 /* The StringBuffer's value doesn't need to grow. However,
243 we should clear out any cruft that may exist. */
244 while (count < newLength)
245 value[count++] = '\0';
250 * Get the character at the specified index.
252 * @param index the index of the character to get, starting at 0
253 * @return the character at the specified index
254 * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
256 public synchronized char charAt(int index)
258 if (index < 0 || index >= count)
259 throw new StringIndexOutOfBoundsException(index);
260 return value[index];
264 * Get the code point at the specified index. This is like #charAt(int),
265 * but if the character is the start of a surrogate pair, and the
266 * following character completes the pair, then the corresponding
267 * supplementary code point is returned.
268 * @param index the index of the codepoint to get, starting at 0
269 * @return the codepoint at the specified index
270 * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
271 * @since 1.5
273 public synchronized int codePointAt(int index)
275 return Character.codePointAt(value, index, count);
279 * Get the code point before the specified index. This is like
280 * #codePointAt(int), but checks the characters at <code>index-1</code> and
281 * <code>index-2</code> to see if they form a supplementary code point.
282 * @param index the index just past the codepoint to get, starting at 0
283 * @return the codepoint at the specified index
284 * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
285 * @since 1.5
287 public synchronized int codePointBefore(int index)
289 // Character.codePointBefore() doesn't perform this check. We
290 // could use the CharSequence overload, but this is just as easy.
291 if (index >= count)
292 throw new IndexOutOfBoundsException();
293 return Character.codePointBefore(value, index, 1);
297 * Get the specified array of characters. <code>srcOffset - srcEnd</code>
298 * characters will be copied into the array you pass in.
300 * @param srcOffset the index to start copying from (inclusive)
301 * @param srcEnd the index to stop copying from (exclusive)
302 * @param dst the array to copy into
303 * @param dstOffset the index to start copying into
304 * @throws NullPointerException if dst is null
305 * @throws IndexOutOfBoundsException if any source or target indices are
306 * out of range (while unspecified, source problems cause a
307 * StringIndexOutOfBoundsException, and dest problems cause an
308 * ArrayIndexOutOfBoundsException)
309 * @see System#arraycopy(Object, int, Object, int, int)
311 public synchronized void getChars(int srcOffset, int srcEnd,
312 char[] dst, int dstOffset)
314 if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
315 throw new StringIndexOutOfBoundsException();
316 VMSystem.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
320 * Set the character at the specified index.
322 * @param index the index of the character to set starting at 0
323 * @param ch the value to set that character to
324 * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
325 * (while unspecified, this is a StringIndexOutOfBoundsException)
327 public synchronized void setCharAt(int index, char ch)
329 if (index < 0 || index >= count)
330 throw new StringIndexOutOfBoundsException(index);
331 // Call ensureCapacity to enforce copy-on-write.
332 ensureCapacity_unsynchronized(count);
333 value[index] = ch;
337 * Append the <code>String</code> value of the argument to this
338 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
339 * to <code>String</code>.
341 * @param obj the <code>Object</code> to convert and append
342 * @return this <code>StringBuffer</code>
343 * @see String#valueOf(Object)
344 * @see #append(String)
346 public StringBuffer append(Object obj)
348 return append(obj == null ? "null" : obj.toString());
352 * Append the <code>String</code> to this <code>StringBuffer</code>. If
353 * str is null, the String "null" is appended.
355 * @param str the <code>String</code> to append
356 * @return this <code>StringBuffer</code>
358 public synchronized StringBuffer append(String str)
360 if (str == null)
361 str = "null";
362 int len = str.count;
363 ensureCapacity_unsynchronized(count + len);
364 str.getChars(0, len, value, count);
365 count += len;
366 return this;
370 * Append the <code>StringBuffer</code> value of the argument to this
371 * <code>StringBuffer</code>. This behaves the same as
372 * <code>append((Object) stringBuffer)</code>, except it is more efficient.
374 * @param stringBuffer the <code>StringBuffer</code> to convert and append
375 * @return this <code>StringBuffer</code>
376 * @see #append(Object)
377 * @since 1.4
379 public synchronized StringBuffer append(StringBuffer stringBuffer)
381 if (stringBuffer == null)
382 return append("null");
383 synchronized (stringBuffer)
385 int len = stringBuffer.count;
386 ensureCapacity_unsynchronized(count + len);
387 VMSystem.arraycopy(stringBuffer.value, 0, value, count, len);
388 count += len;
390 return this;
394 * Append the <code>CharSequence</code> value of the argument to this
395 * <code>StringBuffer</code>.
397 * @param sequence the <code>CharSequence</code> to append
398 * @return this <code>StringBuffer</code>
399 * @see #append(Object)
400 * @since 1.5
402 public synchronized StringBuffer append(CharSequence sequence)
404 if (sequence == null)
405 sequence = "null";
406 return append(sequence, 0, sequence.length());
410 * Append the specified subsequence of the <code>CharSequence</code>
411 * argument to this <code>StringBuffer</code>.
413 * @param sequence the <code>CharSequence</code> to append
414 * @param start the starting index
415 * @param end one past the ending index
416 * @return this <code>StringBuffer</code>
417 * @see #append(Object)
418 * @since 1.5
420 public synchronized StringBuffer append(CharSequence sequence,
421 int start, int end)
423 if (sequence == null)
424 sequence = "null";
425 if (start < 0 || end < 0 || start > end || end > sequence.length())
426 throw new IndexOutOfBoundsException();
427 ensureCapacity_unsynchronized(this.count + end - start);
428 for (int i = start; i < end; ++i)
429 value[count++] = sequence.charAt(i);
430 return this;
434 * Append the <code>char</code> array to this <code>StringBuffer</code>.
435 * This is similar (but more efficient) than
436 * <code>append(new String(data))</code>, except in the case of null.
438 * @param data the <code>char[]</code> to append
439 * @return this <code>StringBuffer</code>
440 * @throws NullPointerException if <code>str</code> is <code>null</code>
441 * @see #append(char[], int, int)
443 public StringBuffer append(char[] data)
445 return append(data, 0, data.length);
449 * Append part of the <code>char</code> array to this
450 * <code>StringBuffer</code>. This is similar (but more efficient) than
451 * <code>append(new String(data, offset, count))</code>, except in the case
452 * of null.
454 * @param data the <code>char[]</code> to append
455 * @param offset the start location in <code>str</code>
456 * @param count the number of characters to get from <code>str</code>
457 * @return this <code>StringBuffer</code>
458 * @throws NullPointerException if <code>str</code> is <code>null</code>
459 * @throws IndexOutOfBoundsException if offset or count is out of range
460 * (while unspecified, this is a StringIndexOutOfBoundsException)
462 public synchronized StringBuffer append(char[] data, int offset, int count)
464 if (offset < 0 || count < 0 || offset > data.length - count)
465 throw new StringIndexOutOfBoundsException();
466 ensureCapacity_unsynchronized(this.count + count);
467 VMSystem.arraycopy(data, offset, value, this.count, count);
468 this.count += count;
469 return this;
473 * Append the <code>String</code> value of the argument to this
474 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
475 * to <code>String</code>.
477 * @param bool the <code>boolean</code> to convert and append
478 * @return this <code>StringBuffer</code>
479 * @see String#valueOf(boolean)
481 public StringBuffer append(boolean bool)
483 return append(bool ? "true" : "false");
487 * Append the <code>char</code> to this <code>StringBuffer</code>.
489 * @param ch the <code>char</code> to append
490 * @return this <code>StringBuffer</code>
492 public synchronized StringBuffer append(char ch)
494 ensureCapacity_unsynchronized(count + 1);
495 value[count++] = ch;
496 return this;
500 * Append the code point to this <code>StringBuffer</code>.
501 * This is like #append(char), but will append two characters
502 * if a supplementary code point is given.
504 * @param code the code point to append
505 * @return this <code>StringBuffer</code>
506 * @see Character#toChars(int, char[], int)
507 * @since 1.5
509 public synchronized StringBuffer appendCodePoint(int code)
511 int len = Character.charCount(code);
512 ensureCapacity_unsynchronized(count + len);
513 Character.toChars(code, value, count);
514 count += len;
515 return this;
519 * Append the <code>String</code> value of the argument to this
520 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
521 * to <code>String</code>.
523 * @param inum the <code>int</code> to convert and append
524 * @return this <code>StringBuffer</code>
525 * @see String#valueOf(int)
527 // This is native in libgcj, for efficiency.
528 public StringBuffer append(int inum)
530 return append(String.valueOf(inum));
534 * Append the <code>String</code> value of the argument to this
535 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
536 * to <code>String</code>.
538 * @param lnum the <code>long</code> to convert and append
539 * @return this <code>StringBuffer</code>
540 * @see String#valueOf(long)
542 public StringBuffer append(long lnum)
544 return append(Long.toString(lnum, 10));
548 * Append the <code>String</code> value of the argument to this
549 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
550 * to <code>String</code>.
552 * @param fnum the <code>float</code> to convert and append
553 * @return this <code>StringBuffer</code>
554 * @see String#valueOf(float)
556 public StringBuffer append(float fnum)
558 return append(Float.toString(fnum));
562 * Append the <code>String</code> value of the argument to this
563 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
564 * to <code>String</code>.
566 * @param dnum the <code>double</code> to convert and append
567 * @return this <code>StringBuffer</code>
568 * @see String#valueOf(double)
570 public StringBuffer append(double dnum)
572 return append(Double.toString(dnum));
576 * Delete characters from this <code>StringBuffer</code>.
577 * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
578 * harmless for end to be larger than length().
580 * @param start the first character to delete
581 * @param end the index after the last character to delete
582 * @return this <code>StringBuffer</code>
583 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
584 * @since 1.2
586 public synchronized StringBuffer delete(int start, int end)
588 if (start < 0 || start > count || start > end)
589 throw new StringIndexOutOfBoundsException(start);
590 if (end > count)
591 end = count;
592 // This will unshare if required.
593 ensureCapacity_unsynchronized(count);
594 if (count - end != 0)
595 VMSystem.arraycopy(value, end, value, start, count - end);
596 count -= end - start;
597 return this;
601 * Delete a character from this <code>StringBuffer</code>.
603 * @param index the index of the character to delete
604 * @return this <code>StringBuffer</code>
605 * @throws StringIndexOutOfBoundsException if index is out of bounds
606 * @since 1.2
608 public StringBuffer deleteCharAt(int index)
610 return delete(index, index + 1);
614 * Replace characters between index <code>start</code> (inclusive) and
615 * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
616 * is larger than the size of this StringBuffer, all characters after
617 * <code>start</code> are replaced.
619 * @param start the beginning index of characters to delete (inclusive)
620 * @param end the ending index of characters to delete (exclusive)
621 * @param str the new <code>String</code> to insert
622 * @return this <code>StringBuffer</code>
623 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
624 * @throws NullPointerException if str is null
625 * @since 1.2
627 public synchronized StringBuffer replace(int start, int end, String str)
629 if (start < 0 || start > count || start > end)
630 throw new StringIndexOutOfBoundsException(start);
632 int len = str.count;
633 // Calculate the difference in 'count' after the replace.
634 int delta = len - (end > count ? count : end) + start;
635 ensureCapacity_unsynchronized(count + delta);
637 if (delta != 0 && end < count)
638 VMSystem.arraycopy(value, end, value, end + delta, count - end);
640 str.getChars(0, len, value, start);
641 count += delta;
642 return this;
646 * Creates a substring of this StringBuffer, starting at a specified index
647 * and ending at the end of this StringBuffer.
649 * @param beginIndex index to start substring (base 0)
650 * @return new String which is a substring of this StringBuffer
651 * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
652 * @see #substring(int, int)
653 * @since 1.2
655 public String substring(int beginIndex)
657 return substring(beginIndex, count);
661 * Creates a substring of this StringBuffer, starting at a specified index
662 * and ending at one character before a specified index. This is implemented
663 * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
664 * the CharSequence interface.
666 * @param beginIndex index to start at (inclusive, base 0)
667 * @param endIndex index to end at (exclusive)
668 * @return new String which is a substring of this StringBuffer
669 * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
670 * bounds
671 * @see #substring(int, int)
672 * @since 1.4
674 public CharSequence subSequence(int beginIndex, int endIndex)
676 return substring(beginIndex, endIndex);
680 * Creates a substring of this StringBuffer, starting at a specified index
681 * and ending at one character before a specified index.
683 * @param beginIndex index to start at (inclusive, base 0)
684 * @param endIndex index to end at (exclusive)
685 * @return new String which is a substring of this StringBuffer
686 * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
687 * of bounds
688 * @since 1.2
690 public synchronized String substring(int beginIndex, int endIndex)
692 int len = endIndex - beginIndex;
693 if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
694 throw new StringIndexOutOfBoundsException();
695 if (len == 0)
696 return "";
697 // Don't copy unless substring is smaller than 1/4 of the buffer.
698 boolean share_buffer = ((len << 2) >= value.length);
699 if (share_buffer)
700 this.shared = true;
701 // Package constructor avoids an array copy.
702 return new String(value, beginIndex, len, share_buffer);
706 * Insert a subarray of the <code>char[]</code> argument into this
707 * <code>StringBuffer</code>.
709 * @param offset the place to insert in this buffer
710 * @param str the <code>char[]</code> to insert
711 * @param str_offset the index in <code>str</code> to start inserting from
712 * @param len the number of characters to insert
713 * @return this <code>StringBuffer</code>
714 * @throws NullPointerException if <code>str</code> is <code>null</code>
715 * @throws StringIndexOutOfBoundsException if any index is out of bounds
716 * @since 1.2
718 public synchronized StringBuffer insert(int offset,
719 char[] str, int str_offset, int len)
721 if (offset < 0 || offset > count || len < 0
722 || str_offset < 0 || str_offset > str.length - len)
723 throw new StringIndexOutOfBoundsException();
724 ensureCapacity_unsynchronized(count + len);
725 VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
726 VMSystem.arraycopy(str, str_offset, value, offset, len);
727 count += len;
728 return this;
732 * Insert the <code>String</code> value of the argument into this
733 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
734 * to <code>String</code>.
736 * @param offset the place to insert in this buffer
737 * @param obj the <code>Object</code> to convert and insert
738 * @return this <code>StringBuffer</code>
739 * @exception StringIndexOutOfBoundsException if offset is out of bounds
740 * @see String#valueOf(Object)
742 public StringBuffer insert(int offset, Object obj)
744 return insert(offset, obj == null ? "null" : obj.toString());
748 * Insert the <code>String</code> argument into this
749 * <code>StringBuffer</code>. If str is null, the String "null" is used
750 * instead.
752 * @param offset the place to insert in this buffer
753 * @param str the <code>String</code> to insert
754 * @return this <code>StringBuffer</code>
755 * @throws StringIndexOutOfBoundsException if offset is out of bounds
757 public synchronized StringBuffer insert(int offset, String str)
759 if (offset < 0 || offset > count)
760 throw new StringIndexOutOfBoundsException(offset);
761 if (str == null)
762 str = "null";
763 int len = str.count;
764 ensureCapacity_unsynchronized(count + len);
765 VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
766 str.getChars(0, len, value, offset);
767 count += len;
768 return this;
772 * Insert the <code>CharSequence</code> argument into this
773 * <code>StringBuffer</code>. If the sequence is null, the String
774 * "null" is used instead.
776 * @param offset the place to insert in this buffer
777 * @param sequence the <code>CharSequence</code> to insert
778 * @return this <code>StringBuffer</code>
779 * @throws IndexOutOfBoundsException if offset is out of bounds
780 * @since 1.5
782 public synchronized StringBuffer insert(int offset, CharSequence sequence)
784 if (sequence == null)
785 sequence = "null";
786 return insert(offset, sequence, 0, sequence.length());
790 * Insert a subsequence of the <code>CharSequence</code> argument into this
791 * <code>StringBuffer</code>. If the sequence is null, the String
792 * "null" is used instead.
794 * @param offset the place to insert in this buffer
795 * @param sequence the <code>CharSequence</code> to insert
796 * @param start the starting index of the subsequence
797 * @param end one past the ending index of the subsequence
798 * @return this <code>StringBuffer</code>
799 * @throws IndexOutOfBoundsException if offset, start,
800 * or end are out of bounds
801 * @since 1.5
803 public synchronized StringBuffer insert(int offset, CharSequence sequence,
804 int start, int end)
806 if (sequence == null)
807 sequence = "null";
808 if (start < 0 || end < 0 || start > end || end > sequence.length())
809 throw new IndexOutOfBoundsException();
810 int len = end - start;
811 ensureCapacity_unsynchronized(count + len);
812 VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
813 for (int i = start; i < end; ++i)
814 value[offset++] = sequence.charAt(i);
815 count += len;
816 return this;
820 * Insert the <code>char[]</code> argument into this
821 * <code>StringBuffer</code>.
823 * @param offset the place to insert in this buffer
824 * @param data the <code>char[]</code> to insert
825 * @return this <code>StringBuffer</code>
826 * @throws NullPointerException if <code>data</code> is <code>null</code>
827 * @throws StringIndexOutOfBoundsException if offset is out of bounds
828 * @see #insert(int, char[], int, int)
830 public StringBuffer insert(int offset, char[] data)
832 return insert(offset, data, 0, data.length);
836 * Insert the <code>String</code> value of the argument into this
837 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
838 * to <code>String</code>.
840 * @param offset the place to insert in this buffer
841 * @param bool the <code>boolean</code> to convert and insert
842 * @return this <code>StringBuffer</code>
843 * @throws StringIndexOutOfBoundsException if offset is out of bounds
844 * @see String#valueOf(boolean)
846 public StringBuffer insert(int offset, boolean bool)
848 return insert(offset, bool ? "true" : "false");
852 * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
854 * @param offset the place to insert in this buffer
855 * @param ch the <code>char</code> to insert
856 * @return this <code>StringBuffer</code>
857 * @throws StringIndexOutOfBoundsException if offset is out of bounds
859 public synchronized StringBuffer insert(int offset, char ch)
861 if (offset < 0 || offset > count)
862 throw new StringIndexOutOfBoundsException(offset);
863 ensureCapacity_unsynchronized(count + 1);
864 VMSystem.arraycopy(value, offset, value, offset + 1, count - offset);
865 value[offset] = ch;
866 count++;
867 return this;
871 * Insert the <code>String</code> value of the argument into this
872 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
873 * to <code>String</code>.
875 * @param offset the place to insert in this buffer
876 * @param inum the <code>int</code> to convert and insert
877 * @return this <code>StringBuffer</code>
878 * @throws StringIndexOutOfBoundsException if offset is out of bounds
879 * @see String#valueOf(int)
881 public StringBuffer insert(int offset, int inum)
883 return insert(offset, String.valueOf(inum));
887 * Insert the <code>String</code> value of the argument into this
888 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
889 * to <code>String</code>.
891 * @param offset the place to insert in this buffer
892 * @param lnum the <code>long</code> to convert and insert
893 * @return this <code>StringBuffer</code>
894 * @throws StringIndexOutOfBoundsException if offset is out of bounds
895 * @see String#valueOf(long)
897 public StringBuffer insert(int offset, long lnum)
899 return insert(offset, Long.toString(lnum, 10));
903 * Insert the <code>String</code> value of the argument into this
904 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
905 * to <code>String</code>.
907 * @param offset the place to insert in this buffer
908 * @param fnum the <code>float</code> to convert and insert
909 * @return this <code>StringBuffer</code>
910 * @throws StringIndexOutOfBoundsException if offset is out of bounds
911 * @see String#valueOf(float)
913 public StringBuffer insert(int offset, float fnum)
915 return insert(offset, Float.toString(fnum));
919 * Insert the <code>String</code> value of the argument into this
920 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
921 * to <code>String</code>.
923 * @param offset the place to insert in this buffer
924 * @param dnum the <code>double</code> to convert and insert
925 * @return this <code>StringBuffer</code>
926 * @throws StringIndexOutOfBoundsException if offset is out of bounds
927 * @see String#valueOf(double)
929 public StringBuffer insert(int offset, double dnum)
931 return insert(offset, Double.toString(dnum));
935 * Finds the first instance of a substring in this StringBuffer.
937 * @param str String to find
938 * @return location (base 0) of the String, or -1 if not found
939 * @throws NullPointerException if str is null
940 * @see #indexOf(String, int)
941 * @since 1.4
943 public int indexOf(String str)
945 return indexOf(str, 0);
949 * Finds the first instance of a String in this StringBuffer, starting at
950 * a given index. If starting index is less than 0, the search starts at
951 * the beginning of this String. If the starting index is greater than the
952 * length of this String, or the substring is not found, -1 is returned.
954 * @param str String to find
955 * @param fromIndex index to start the search
956 * @return location (base 0) of the String, or -1 if not found
957 * @throws NullPointerException if str is null
958 * @since 1.4
960 public synchronized int indexOf(String str, int fromIndex)
962 if (fromIndex < 0)
963 fromIndex = 0;
964 int limit = count - str.count;
965 for ( ; fromIndex <= limit; fromIndex++)
966 if (regionMatches(fromIndex, str))
967 return fromIndex;
968 return -1;
972 * Finds the last instance of a substring in this StringBuffer.
974 * @param str String to find
975 * @return location (base 0) of the String, or -1 if not found
976 * @throws NullPointerException if str is null
977 * @see #lastIndexOf(String, int)
978 * @since 1.4
980 public int lastIndexOf(String str)
982 return lastIndexOf(str, count - str.count);
986 * Finds the last instance of a String in this StringBuffer, starting at a
987 * given index. If starting index is greater than the maximum valid index,
988 * then the search begins at the end of this String. If the starting index
989 * is less than zero, or the substring is not found, -1 is returned.
991 * @param str String to find
992 * @param fromIndex index to start the search
993 * @return location (base 0) of the String, or -1 if not found
994 * @throws NullPointerException if str is null
995 * @since 1.4
997 public synchronized int lastIndexOf(String str, int fromIndex)
999 fromIndex = Math.min(fromIndex, count - str.count);
1000 for ( ; fromIndex >= 0; fromIndex--)
1001 if (regionMatches(fromIndex, str))
1002 return fromIndex;
1003 return -1;
1007 * Reverse the characters in this StringBuffer. The same sequence of
1008 * characters exists, but in the reverse index ordering.
1010 * @return this <code>StringBuffer</code>
1012 public synchronized StringBuffer reverse()
1014 // Call ensureCapacity to enforce copy-on-write.
1015 ensureCapacity_unsynchronized(count);
1016 for (int i = count >> 1, j = count - i; --i >= 0; ++j)
1018 char c = value[i];
1019 value[i] = value[j];
1020 value[j] = c;
1022 return this;
1026 * Convert this <code>StringBuffer</code> to a <code>String</code>. The
1027 * String is composed of the characters currently in this StringBuffer. Note
1028 * that the result is a copy, and that future modifications to this buffer
1029 * do not affect the String.
1031 * @return the characters in this StringBuffer
1033 public String toString()
1035 // The string will set this.shared = true.
1036 return new String(this);
1040 * This may reduce the amount of memory used by the StringBuffer,
1041 * by resizing the internal array to remove unused space. However,
1042 * this method is not required to resize, so this behavior cannot
1043 * be relied upon.
1044 * @since 1.5
1046 public synchronized void trimToSize()
1048 int wouldSave = value.length - count;
1049 // Some random heuristics: if we save less than 20 characters, who
1050 // cares.
1051 if (wouldSave < 20)
1052 return;
1053 // If we save more than 200 characters, shrink.
1054 // If we save more than 1/4 of the buffer, shrink.
1055 if (wouldSave > 200 || wouldSave * 4 > value.length)
1057 char[] newValue = new char[count];
1058 VMSystem.arraycopy(value, 0, newValue, 0, count);
1059 value = newValue;
1064 * Return the number of code points between two indices in the
1065 * <code>StringBuffer</code>. An unpaired surrogate counts as a
1066 * code point for this purpose. Characters outside the indicated
1067 * range are not examined, even if the range ends in the middle of a
1068 * surrogate pair.
1070 * @param start the starting index
1071 * @param end one past the ending index
1072 * @return the number of code points
1073 * @since 1.5
1075 public synchronized int codePointCount(int start, int end)
1077 if (start < 0 || end >= count || start > end)
1078 throw new StringIndexOutOfBoundsException();
1080 int count = 0;
1081 while (start < end)
1083 char base = value[start];
1084 if (base < Character.MIN_HIGH_SURROGATE
1085 || base > Character.MAX_HIGH_SURROGATE
1086 || start == end
1087 || start == count
1088 || value[start + 1] < Character.MIN_LOW_SURROGATE
1089 || value[start + 1] > Character.MAX_LOW_SURROGATE)
1091 // Nothing.
1093 else
1095 // Surrogate pair.
1096 ++start;
1098 ++start;
1099 ++count;
1101 return count;
1105 * Starting at the given index, this counts forward by the indicated
1106 * number of code points, and then returns the resulting index. An
1107 * unpaired surrogate counts as a single code point for this
1108 * purpose.
1110 * @param start the starting index
1111 * @param codePoints the number of code points
1112 * @return the resulting index
1113 * @since 1.5
1115 public synchronized int offsetByCodePoints(int start, int codePoints)
1117 while (codePoints > 0)
1119 char base = value[start];
1120 if (base < Character.MIN_HIGH_SURROGATE
1121 || base > Character.MAX_HIGH_SURROGATE
1122 || start == count
1123 || value[start + 1] < Character.MIN_LOW_SURROGATE
1124 || value[start + 1] > Character.MAX_LOW_SURROGATE)
1126 // Nothing.
1128 else
1130 // Surrogate pair.
1131 ++start;
1133 ++start;
1134 --codePoints;
1136 return start;
1140 * An unsynchronized version of ensureCapacity, used internally to avoid
1141 * the cost of a second lock on the same object. This also has the side
1142 * effect of duplicating the array, if it was shared (to form copy-on-write
1143 * semantics).
1145 * @param minimumCapacity the minimum capacity
1146 * @see #ensureCapacity(int)
1148 private void ensureCapacity_unsynchronized(int minimumCapacity)
1150 if (shared || minimumCapacity > value.length)
1152 // We don't want to make a larger vector when `shared' is
1153 // set. If we do, then setLength becomes very inefficient
1154 // when repeatedly reusing a StringBuffer in a loop.
1155 int max = (minimumCapacity > value.length
1156 ? value.length * 2 + 2
1157 : value.length);
1158 minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
1159 char[] nb = new char[minimumCapacity];
1160 VMSystem.arraycopy(value, 0, nb, 0, count);
1161 value = nb;
1162 shared = false;
1167 * Predicate which determines if a substring of this matches another String
1168 * starting at a specified offset for each String and continuing for a
1169 * specified length. This is more efficient than creating a String to call
1170 * indexOf on.
1172 * @param toffset index to start comparison at for this String
1173 * @param other non-null String to compare to region of this
1174 * @return true if regions match, false otherwise
1175 * @see #indexOf(String, int)
1176 * @see #lastIndexOf(String, int)
1177 * @see String#regionMatches(boolean, int, String, int, int)
1179 private boolean regionMatches(int toffset, String other)
1181 int len = other.count;
1182 int index = other.offset;
1183 while (--len >= 0)
1184 if (value[toffset++] != other.value[index++])
1185 return false;
1186 return true;