OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / lang / StringBuilder.java
1 /* StringBuilder.java -- Unsynchronized growable strings
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3    Free Software Foundation, Inc.
4
5 This file is part of GNU Classpath.
6
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.
11
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.
16
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.
21
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.
26
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. */
38
39 package java.lang;
40
41 import java.io.Serializable;
42
43 /**
44  * <code>StringBuilder</code> represents a changeable <code>String</code>.
45  * It provides the operations required to modify the
46  * <code>StringBuilder</code>, including insert, replace, delete, append,
47  * and reverse. It like <code>StringBuffer</code>, but is not
48  * synchronized.  It is ideal for use when it is known that the
49  * object will only be used from a single thread.
50  *
51  * <p><code>StringBuilder</code>s are variable-length in nature, so even if
52  * you initialize them to a certain size, they can still grow larger than
53  * that. <em>Capacity</em> indicates the number of characters the
54  * <code>StringBuilder</code> can have in it before it has to grow (growing
55  * the char array is an expensive operation involving <code>new</code>).
56  *
57  * <p>Incidentally, compilers often implement the String operator "+"
58  * by using a <code>StringBuilder</code> operation:<br>
59  * <code>a + b</code><br>
60  * is the same as<br>
61  * <code>new StringBuilder().append(a).append(b).toString()</code>.
62  *
63  * <p>Classpath's StringBuilder is capable of sharing memory with Strings for
64  * efficiency.  This will help when a StringBuilder is converted to a String
65  * and the StringBuilder is not changed after that (quite common when
66  * performing string concatenation).
67  *
68  * @author Paul Fisher
69  * @author John Keiser
70  * @author Tom Tromey
71  * @author Eric Blake (ebb9@email.byu.edu)
72  * @see String
73  * @see StringBuffer
74  *
75  * @since 1.5
76  */
77 public final class StringBuilder
78   implements Serializable, CharSequence, Appendable
79 {
80   // Implementation note: if you change this class, you usually will
81   // want to change StringBuffer as well.
82
83   /**
84    * For compatability with Sun's JDK
85    */
86   private static final long serialVersionUID = 4383685877147921099L;
87
88   /**
89    * Index of next available character (and thus the size of the current
90    * string contents).  Note that this has permissions set this way so that
91    * String can get the value.
92    *
93    * @serial the number of characters in the buffer
94    */
95   int count;
96
97   /**
98    * The buffer.  Note that this has permissions set this way so that String
99    * can get the value.
100    *
101    * @serial the buffer
102    */
103   char[] value;
104
105   /**
106    * The default capacity of a buffer.
107    */
108   private static final int DEFAULT_CAPACITY = 16;
109
110   /**
111    * Create a new StringBuilder with default capacity 16.
112    */
113   public StringBuilder()
114   {
115     this(DEFAULT_CAPACITY);
116   }
117
118   /**
119    * Create an empty <code>StringBuilder</code> with the specified initial
120    * capacity.
121    *
122    * @param capacity the initial capacity
123    * @throws NegativeArraySizeException if capacity is negative
124    */
125   public StringBuilder(int capacity)
126   {
127     value = new char[capacity];
128   }
129
130   /**
131    * Create a new <code>StringBuilder</code> with the characters in the
132    * specified <code>String</code>. Initial capacity will be the size of the
133    * String plus 16.
134    *
135    * @param str the <code>String</code> to convert
136    * @throws NullPointerException if str is null
137    */
138   public StringBuilder(String str)
139   {
140     // Unfortunately, because the size is 16 larger, we cannot share.
141     count = str.count;
142     value = new char[count + DEFAULT_CAPACITY];
143     str.getChars(0, count, value, 0);
144   }
145
146   /**
147    * Create a new <code>StringBuilder</code> with the characters in the
148    * specified <code>CharSequence</code>. Initial capacity will be the
149    * length of the sequence plus 16; if the sequence reports a length
150    * less than or equal to 0, then the initial capacity will be 16.
151    *
152    * @param seq the initializing <code>CharSequence</code>
153    * @throws NullPointerException if str is null
154    */
155   public StringBuilder(CharSequence seq)
156   {
157     int len = seq.length();
158     count = len <= 0 ? 0 : len;
159     value = new char[count + DEFAULT_CAPACITY];
160     for (int i = 0; i < len; ++i)
161       value[i] = seq.charAt(i);
162   }
163
164   /**
165    * Get the length of the <code>String</code> this <code>StringBuilder</code>
166    * would create. Not to be confused with the <em>capacity</em> of the
167    * <code>StringBuilder</code>.
168    *
169    * @return the length of this <code>StringBuilder</code>
170    * @see #capacity()
171    * @see #setLength(int)
172    */
173   public int length()
174   {
175     return count;
176   }
177
178   /**
179    * Get the total number of characters this <code>StringBuilder</code> can
180    * support before it must be grown.  Not to be confused with <em>length</em>.
181    *
182    * @return the capacity of this <code>StringBuilder</code>
183    * @see #length()
184    * @see #ensureCapacity(int)
185    */
186   public int capacity()
187   {
188     return value.length;
189   }
190
191   /**
192    * Increase the capacity of this <code>StringBuilder</code>. This will
193    * ensure that an expensive growing operation will not occur until
194    * <code>minimumCapacity</code> is reached. The buffer is grown to the
195    * larger of <code>minimumCapacity</code> and
196    * <code>capacity() * 2 + 2</code>, if it is not already large enough.
197    *
198    * @param minimumCapacity the new capacity
199    * @see #capacity()
200    */
201   public void ensureCapacity(int minimumCapacity)
202   {
203     if (minimumCapacity > value.length)
204       {
205         int max = value.length * 2 + 2;
206         minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
207         char[] nb = new char[minimumCapacity];
208         VMSystem.arraycopy(value, 0, nb, 0, count);
209         value = nb;
210       }
211   }
212
213   /**
214    * Set the length of this StringBuilder. If the new length is greater than
215    * the current length, all the new characters are set to '\0'. If the new
216    * length is less than the current length, the first <code>newLength</code>
217    * characters of the old array will be preserved, and the remaining
218    * characters are truncated.
219    *
220    * @param newLength the new length
221    * @throws IndexOutOfBoundsException if the new length is negative
222    *         (while unspecified, this is a StringIndexOutOfBoundsException)
223    * @see #length()
224    */
225   public void setLength(int newLength)
226   {
227     if (newLength < 0)
228       throw new StringIndexOutOfBoundsException(newLength);
229
230     int valueLength = value.length;
231
232     /* Always call ensureCapacity in order to preserve copy-on-write
233        semantics.  */
234     ensureCapacity(newLength);
235
236     if (newLength < valueLength)
237       {
238         /* If the StringBuilder's value just grew, then we know that
239            value is newly allocated and the region between count and
240            newLength is filled with '\0'.  */
241         count = newLength;
242       }
243     else
244       {
245         /* The StringBuilder's value doesn't need to grow.  However,
246            we should clear out any cruft that may exist.  */
247         while (count < newLength)
248           value[count++] = '\0';
249       }
250   }
251
252   /**
253    * Get the character at the specified index.
254    *
255    * @param index the index of the character to get, starting at 0
256    * @return the character at the specified index
257    * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
258    *         (while unspecified, this is a StringIndexOutOfBoundsException)
259    */
260   public char charAt(int index)
261   {
262     if (index < 0 || index >= count)
263       throw new StringIndexOutOfBoundsException(index);
264     return value[index];
265   }
266
267   /**
268    * Get the specified array of characters. <code>srcOffset - srcEnd</code>
269    * characters will be copied into the array you pass in.
270    *
271    * @param srcOffset the index to start copying from (inclusive)
272    * @param srcEnd the index to stop copying from (exclusive)
273    * @param dst the array to copy into
274    * @param dstOffset the index to start copying into
275    * @throws NullPointerException if dst is null
276    * @throws IndexOutOfBoundsException if any source or target indices are
277    *         out of range (while unspecified, source problems cause a
278    *         StringIndexOutOfBoundsException, and dest problems cause an
279    *         ArrayIndexOutOfBoundsException)
280    * @see System#arraycopy(Object, int, Object, int, int)
281    */
282   public void getChars(int srcOffset, int srcEnd,
283                        char[] dst, int dstOffset)
284   {
285     if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
286       throw new StringIndexOutOfBoundsException();
287     VMSystem.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
288   }
289
290   /**
291    * Set the character at the specified index.
292    *
293    * @param index the index of the character to set starting at 0
294    * @param ch the value to set that character to
295    * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
296    *         (while unspecified, this is a StringIndexOutOfBoundsException)
297    */
298   public void setCharAt(int index, char ch)
299   {
300     if (index < 0 || index >= count)
301       throw new StringIndexOutOfBoundsException(index);
302     // Call ensureCapacity to enforce copy-on-write.
303     ensureCapacity(count);
304     value[index] = ch;
305   }
306
307   /**
308    * Append the <code>String</code> value of the argument to this
309    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
310    * to <code>String</code>.
311    *
312    * @param obj the <code>Object</code> to convert and append
313    * @return this <code>StringBuilder</code>
314    * @see String#valueOf(Object)
315    * @see #append(String)
316    */
317   public StringBuilder append(Object obj)
318   {
319     return append(obj == null ? "null" : obj.toString());
320   }
321
322   /**
323    * Append the <code>String</code> to this <code>StringBuilder</code>. If
324    * str is null, the String "null" is appended.
325    *
326    * @param str the <code>String</code> to append
327    * @return this <code>StringBuilder</code>
328    */
329   public StringBuilder append(String str)
330   {
331     if (str == null)
332       str = "null";
333     int len = str.count;
334     ensureCapacity(count + len);
335     str.getChars(0, len, value, count);
336     count += len;
337     return this;
338   }
339
340   /**
341    * Append the <code>StringBuilder</code> value of the argument to this
342    * <code>StringBuilder</code>. This behaves the same as
343    * <code>append((Object) stringBuffer)</code>, except it is more efficient.
344    *
345    * @param stringBuffer the <code>StringBuilder</code> to convert and append
346    * @return this <code>StringBuilder</code>
347    * @see #append(Object)
348    */
349   public StringBuilder append(StringBuffer stringBuffer)
350   {
351     if (stringBuffer == null)
352       return append("null");
353     synchronized (stringBuffer)
354       {
355         int len = stringBuffer.count;
356         ensureCapacity(count + len);
357         VMSystem.arraycopy(stringBuffer.value, 0, value, count, len);
358         count += len;
359       }
360     return this;
361   }
362
363   /**
364    * Append the <code>char</code> array to this <code>StringBuilder</code>.
365    * This is similar (but more efficient) than
366    * <code>append(new String(data))</code>, except in the case of null.
367    *
368    * @param data the <code>char[]</code> to append
369    * @return this <code>StringBuilder</code>
370    * @throws NullPointerException if <code>str</code> is <code>null</code>
371    * @see #append(char[], int, int)
372    */
373   public StringBuilder append(char[] data)
374   {
375     return append(data, 0, data.length);
376   }
377
378   /**
379    * Append part of the <code>char</code> array to this
380    * <code>StringBuilder</code>. This is similar (but more efficient) than
381    * <code>append(new String(data, offset, count))</code>, except in the case
382    * of null.
383    *
384    * @param data the <code>char[]</code> to append
385    * @param offset the start location in <code>str</code>
386    * @param count the number of characters to get from <code>str</code>
387    * @return this <code>StringBuilder</code>
388    * @throws NullPointerException if <code>str</code> is <code>null</code>
389    * @throws IndexOutOfBoundsException if offset or count is out of range
390    *         (while unspecified, this is a StringIndexOutOfBoundsException)
391    */
392   public StringBuilder append(char[] data, int offset, int count)
393   {
394     if (offset < 0 || count < 0 || offset > data.length - count)
395       throw new StringIndexOutOfBoundsException();
396     ensureCapacity(this.count + count);
397     VMSystem.arraycopy(data, offset, value, this.count, count);
398     this.count += count;
399     return this;
400   }
401
402   /**
403    * Append the <code>String</code> value of the argument to this
404    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
405    * to <code>String</code>.
406    *
407    * @param bool the <code>boolean</code> to convert and append
408    * @return this <code>StringBuilder</code>
409    * @see String#valueOf(boolean)
410    */
411   public StringBuilder append(boolean bool)
412   {
413     return append(bool ? "true" : "false");
414   }
415
416   /**
417    * Append the <code>char</code> to this <code>StringBuilder</code>.
418    *
419    * @param ch the <code>char</code> to append
420    * @return this <code>StringBuilder</code>
421    */
422   public StringBuilder append(char ch)
423   {
424     ensureCapacity(count + 1);
425     value[count++] = ch;
426     return this;
427   }
428
429   /**
430    * Append the characters in the <code>CharSequence</code> to this
431    * buffer.
432    *
433    * @param seq the <code>CharSequence</code> providing the characters
434    * @return this <code>StringBuilder</code>
435    */
436   public StringBuilder append(CharSequence seq)
437   {
438     return append(seq, 0, seq.length());
439   }
440
441   /**
442    * Append some characters from the <code>CharSequence</code> to this
443    * buffer.  If the argument is null, the four characters "null" are
444    * appended.
445    *
446    * @param seq the <code>CharSequence</code> providing the characters
447    * @param start the starting index
448    * @param end one past the final index
449    * @return this <code>StringBuilder</code>
450    */
451   public StringBuilder append(CharSequence seq, int start,
452                               int end)
453   {
454     if (seq == null)
455       return append("null");
456     if (end - start > 0)
457       {
458         ensureCapacity(count + end - start);
459         for (; start < end; ++start)
460           value[count++] = seq.charAt(start);
461       }
462     return this;
463   }
464
465   /**
466    * Append the code point to this <code>StringBuilder</code>.
467    * This is like #append(char), but will append two characters
468    * if a supplementary code point is given.
469    *
470    * @param code the code point to append
471    * @return this <code>StringBuilder</code>
472    * @see Character#toChars(int, char[], int)
473    * @since 1.5
474    */
475   public synchronized StringBuilder appendCodePoint(int code)
476   {
477     int len = Character.charCount(code);
478     ensureCapacity(count + len);
479     Character.toChars(code, value, count);
480     count += len;
481     return this;
482   }
483
484   /**
485    * Append the <code>String</code> value of the argument to this
486    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
487    * to <code>String</code>.
488    *
489    * @param inum the <code>int</code> to convert and append
490    * @return this <code>StringBuilder</code>
491    * @see String#valueOf(int)
492    */
493   // This is native in libgcj, for efficiency.
494   public StringBuilder append(int inum)
495   {
496     return append(String.valueOf(inum));
497   }
498
499   /**
500    * Append the <code>String</code> value of the argument to this
501    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
502    * to <code>String</code>.
503    *
504    * @param lnum the <code>long</code> to convert and append
505    * @return this <code>StringBuilder</code>
506    * @see String#valueOf(long)
507    */
508   public StringBuilder append(long lnum)
509   {
510     return append(Long.toString(lnum, 10));
511   }
512
513   /**
514    * Append the <code>String</code> value of the argument to this
515    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
516    * to <code>String</code>.
517    *
518    * @param fnum the <code>float</code> to convert and append
519    * @return this <code>StringBuilder</code>
520    * @see String#valueOf(float)
521    */
522   public StringBuilder append(float fnum)
523   {
524     return append(Float.toString(fnum));
525   }
526
527   /**
528    * Append the <code>String</code> value of the argument to this
529    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
530    * to <code>String</code>.
531    *
532    * @param dnum the <code>double</code> to convert and append
533    * @return this <code>StringBuilder</code>
534    * @see String#valueOf(double)
535    */
536   public StringBuilder append(double dnum)
537   {
538     return append(Double.toString(dnum));
539   }
540
541   /**
542    * Delete characters from this <code>StringBuilder</code>.
543    * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
544    * harmless for end to be larger than length().
545    *
546    * @param start the first character to delete
547    * @param end the index after the last character to delete
548    * @return this <code>StringBuilder</code>
549    * @throws StringIndexOutOfBoundsException if start or end are out of bounds
550    */
551   public StringBuilder delete(int start, int end)
552   {
553     if (start < 0 || start > count || start > end)
554       throw new StringIndexOutOfBoundsException(start);
555     if (end > count)
556       end = count;
557     // This will unshare if required.
558     ensureCapacity(count);
559     if (count - end != 0)
560       VMSystem.arraycopy(value, end, value, start, count - end);
561     count -= end - start;
562     return this;
563   }
564
565   /**
566    * Delete a character from this <code>StringBuilder</code>.
567    *
568    * @param index the index of the character to delete
569    * @return this <code>StringBuilder</code>
570    * @throws StringIndexOutOfBoundsException if index is out of bounds
571    */
572   public StringBuilder deleteCharAt(int index)
573   {
574     return delete(index, index + 1);
575   }
576
577   /**
578    * Replace characters between index <code>start</code> (inclusive) and
579    * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
580    * is larger than the size of this StringBuilder, all characters after
581    * <code>start</code> are replaced.
582    *
583    * @param start the beginning index of characters to delete (inclusive)
584    * @param end the ending index of characters to delete (exclusive)
585    * @param str the new <code>String</code> to insert
586    * @return this <code>StringBuilder</code>
587    * @throws StringIndexOutOfBoundsException if start or end are out of bounds
588    * @throws NullPointerException if str is null
589    */
590   public StringBuilder replace(int start, int end, String str)
591   {
592     if (start < 0 || start > count || start > end)
593       throw new StringIndexOutOfBoundsException(start);
594
595     int len = str.count;
596     // Calculate the difference in 'count' after the replace.
597     int delta = len - (end > count ? count : end) + start;
598     ensureCapacity(count + delta);
599
600     if (delta != 0 && end < count)
601       VMSystem.arraycopy(value, end, value, end + delta, count - end);
602
603     str.getChars(0, len, value, start);
604     count += delta;
605     return this;
606   }
607
608   /**
609    * Creates a substring of this StringBuilder, starting at a specified index
610    * and ending at the end of this StringBuilder.
611    *
612    * @param beginIndex index to start substring (base 0)
613    * @return new String which is a substring of this StringBuilder
614    * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
615    * @see #substring(int, int)
616    */
617   public String substring(int beginIndex)
618   {
619     return substring(beginIndex, count);
620   }
621
622   /**
623    * Creates a substring of this StringBuilder, starting at a specified index
624    * and ending at one character before a specified index. This is implemented
625    * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
626    * the CharSequence interface.
627    *
628    * @param beginIndex index to start at (inclusive, base 0)
629    * @param endIndex index to end at (exclusive)
630    * @return new String which is a substring of this StringBuilder
631    * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
632    *         bounds
633    * @see #substring(int, int)
634    */
635   public CharSequence subSequence(int beginIndex, int endIndex)
636   {
637     return substring(beginIndex, endIndex);
638   }
639
640   /**
641    * Creates a substring of this StringBuilder, starting at a specified index
642    * and ending at one character before a specified index.
643    *
644    * @param beginIndex index to start at (inclusive, base 0)
645    * @param endIndex index to end at (exclusive)
646    * @return new String which is a substring of this StringBuilder
647    * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
648    *         of bounds
649    */
650   public String substring(int beginIndex, int endIndex)
651   {
652     int len = endIndex - beginIndex;
653     if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
654       throw new StringIndexOutOfBoundsException();
655     if (len == 0)
656       return "";
657     return new String(value, beginIndex, len);
658   }
659
660   /**
661    * Insert a subarray of the <code>char[]</code> argument into this
662    * <code>StringBuilder</code>.
663    *
664    * @param offset the place to insert in this buffer
665    * @param str the <code>char[]</code> to insert
666    * @param str_offset the index in <code>str</code> to start inserting from
667    * @param len the number of characters to insert
668    * @return this <code>StringBuilder</code>
669    * @throws NullPointerException if <code>str</code> is <code>null</code>
670    * @throws StringIndexOutOfBoundsException if any index is out of bounds
671    */
672   public StringBuilder insert(int offset,
673                               char[] str, int str_offset, int len)
674   {
675     if (offset < 0 || offset > count || len < 0
676         || str_offset < 0 || str_offset > str.length - len)
677       throw new StringIndexOutOfBoundsException();
678     ensureCapacity(count + len);
679     VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
680     VMSystem.arraycopy(str, str_offset, value, offset, len);
681     count += len;
682     return this;
683   }
684
685   /**
686    * Insert the <code>String</code> value of the argument into this
687    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
688    * to <code>String</code>.
689    *
690    * @param offset the place to insert in this buffer
691    * @param obj the <code>Object</code> to convert and insert
692    * @return this <code>StringBuilder</code>
693    * @exception StringIndexOutOfBoundsException if offset is out of bounds
694    * @see String#valueOf(Object)
695    */
696   public StringBuilder insert(int offset, Object obj)
697   {
698     return insert(offset, obj == null ? "null" : obj.toString());
699   }
700
701   /**
702    * Insert the <code>String</code> argument into this
703    * <code>StringBuilder</code>. If str is null, the String "null" is used
704    * instead.
705    *
706    * @param offset the place to insert in this buffer
707    * @param str the <code>String</code> to insert
708    * @return this <code>StringBuilder</code>
709    * @throws StringIndexOutOfBoundsException if offset is out of bounds
710    */
711   public StringBuilder insert(int offset, String str)
712   {
713     if (offset < 0 || offset > count)
714       throw new StringIndexOutOfBoundsException(offset);
715     if (str == null)
716       str = "null";
717     int len = str.count;
718     ensureCapacity(count + len);
719     VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
720     str.getChars(0, len, value, offset);
721     count += len;
722     return this;
723   }
724
725   /**
726    * Insert the <code>CharSequence</code> argument into this
727    * <code>StringBuilder</code>.  If the sequence is null, the String
728    * "null" is used instead.
729    *
730    * @param offset the place to insert in this buffer
731    * @param sequence the <code>CharSequence</code> to insert
732    * @return this <code>StringBuilder</code>
733    * @throws IndexOutOfBoundsException if offset is out of bounds
734    */
735   public synchronized StringBuilder insert(int offset, CharSequence sequence)
736   {
737     if (sequence == null)
738       sequence = "null";
739     return insert(offset, sequence, 0, sequence.length());
740   }
741
742   /**
743    * Insert a subsequence of the <code>CharSequence</code> argument into this
744    * <code>StringBuilder</code>.  If the sequence is null, the String
745    * "null" is used instead.
746    *
747    * @param offset the place to insert in this buffer
748    * @param sequence the <code>CharSequence</code> to insert
749    * @param start the starting index of the subsequence
750    * @param end one past the ending index of the subsequence
751    * @return this <code>StringBuilder</code>
752    * @throws IndexOutOfBoundsException if offset, start,
753    * or end are out of bounds
754    */
755   public synchronized StringBuilder insert(int offset, CharSequence sequence,
756                       int start, int end)
757   {
758     if (sequence == null)
759       sequence = "null";
760     if (start < 0 || end < 0 || start > end || end > sequence.length())
761       throw new IndexOutOfBoundsException();
762     int len = end - start;
763     ensureCapacity(count + len);
764     VMSystem.arraycopy(value, offset, value, offset + len, count - offset);
765     for (int i = start; i < end; ++i)
766       value[offset++] = sequence.charAt(i);
767     count += len;
768     return this;
769   }
770
771   /**
772    * Insert the <code>char[]</code> argument into this
773    * <code>StringBuilder</code>.
774    *
775    * @param offset the place to insert in this buffer
776    * @param data the <code>char[]</code> to insert
777    * @return this <code>StringBuilder</code>
778    * @throws NullPointerException if <code>data</code> is <code>null</code>
779    * @throws StringIndexOutOfBoundsException if offset is out of bounds
780    * @see #insert(int, char[], int, int)
781    */
782   public StringBuilder insert(int offset, char[] data)
783   {
784     return insert(offset, data, 0, data.length);
785   }
786
787   /**
788    * Insert the <code>String</code> value of the argument into this
789    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
790    * to <code>String</code>.
791    *
792    * @param offset the place to insert in this buffer
793    * @param bool the <code>boolean</code> to convert and insert
794    * @return this <code>StringBuilder</code>
795    * @throws StringIndexOutOfBoundsException if offset is out of bounds
796    * @see String#valueOf(boolean)
797    */
798   public StringBuilder insert(int offset, boolean bool)
799   {
800     return insert(offset, bool ? "true" : "false");
801   }
802
803   /**
804    * Insert the <code>char</code> argument into this <code>StringBuilder</code>.
805    *
806    * @param offset the place to insert in this buffer
807    * @param ch the <code>char</code> to insert
808    * @return this <code>StringBuilder</code>
809    * @throws StringIndexOutOfBoundsException if offset is out of bounds
810    */
811   public StringBuilder insert(int offset, char ch)
812   {
813     if (offset < 0 || offset > count)
814       throw new StringIndexOutOfBoundsException(offset);
815     ensureCapacity(count + 1);
816     VMSystem.arraycopy(value, offset, value, offset + 1, count - offset);
817     value[offset] = ch;
818     count++;
819     return this;
820   }
821
822   /**
823    * Insert the <code>String</code> value of the argument into this
824    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
825    * to <code>String</code>.
826    *
827    * @param offset the place to insert in this buffer
828    * @param inum the <code>int</code> to convert and insert
829    * @return this <code>StringBuilder</code>
830    * @throws StringIndexOutOfBoundsException if offset is out of bounds
831    * @see String#valueOf(int)
832    */
833   public StringBuilder insert(int offset, int inum)
834   {
835     return insert(offset, String.valueOf(inum));
836   }
837
838   /**
839    * Insert the <code>String</code> value of the argument into this
840    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
841    * to <code>String</code>.
842    *
843    * @param offset the place to insert in this buffer
844    * @param lnum the <code>long</code> to convert and insert
845    * @return this <code>StringBuilder</code>
846    * @throws StringIndexOutOfBoundsException if offset is out of bounds
847    * @see String#valueOf(long)
848    */
849   public StringBuilder insert(int offset, long lnum)
850   {
851     return insert(offset, Long.toString(lnum, 10));
852   }
853
854   /**
855    * Insert the <code>String</code> value of the argument into this
856    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
857    * to <code>String</code>.
858    *
859    * @param offset the place to insert in this buffer
860    * @param fnum the <code>float</code> to convert and insert
861    * @return this <code>StringBuilder</code>
862    * @throws StringIndexOutOfBoundsException if offset is out of bounds
863    * @see String#valueOf(float)
864    */
865   public StringBuilder insert(int offset, float fnum)
866   {
867     return insert(offset, Float.toString(fnum));
868   }
869
870   /**
871    * Insert the <code>String</code> value of the argument into this
872    * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
873    * to <code>String</code>.
874    *
875    * @param offset the place to insert in this buffer
876    * @param dnum the <code>double</code> to convert and insert
877    * @return this <code>StringBuilder</code>
878    * @throws StringIndexOutOfBoundsException if offset is out of bounds
879    * @see String#valueOf(double)
880    */
881   public StringBuilder insert(int offset, double dnum)
882   {
883     return insert(offset, Double.toString(dnum));
884   }
885
886   /**
887    * Finds the first instance of a substring in this StringBuilder.
888    *
889    * @param str String to find
890    * @return location (base 0) of the String, or -1 if not found
891    * @throws NullPointerException if str is null
892    * @see #indexOf(String, int)
893    */
894   public int indexOf(String str)
895   {
896     return indexOf(str, 0);
897   }
898
899   /**
900    * Finds the first instance of a String in this StringBuilder, starting at
901    * a given index.  If starting index is less than 0, the search starts at
902    * the beginning of this String.  If the starting index is greater than the
903    * length of this String, or the substring is not found, -1 is returned.
904    *
905    * @param str String to find
906    * @param fromIndex index to start the search
907    * @return location (base 0) of the String, or -1 if not found
908    * @throws NullPointerException if str is null
909    */
910   public int indexOf(String str, int fromIndex)
911   {
912     if (fromIndex < 0)
913       fromIndex = 0;
914     int limit = count - str.count;
915     for ( ; fromIndex <= limit; fromIndex++)
916       if (regionMatches(fromIndex, str))
917         return fromIndex;
918     return -1;
919   }
920
921   /**
922    * Finds the last instance of a substring in this StringBuilder.
923    *
924    * @param str String to find
925    * @return location (base 0) of the String, or -1 if not found
926    * @throws NullPointerException if str is null
927    * @see #lastIndexOf(String, int)
928    */
929   public int lastIndexOf(String str)
930   {
931     return lastIndexOf(str, count - str.count);
932   }
933
934   /**
935    * Finds the last instance of a String in this StringBuilder, starting at a
936    * given index.  If starting index is greater than the maximum valid index,
937    * then the search begins at the end of this String.  If the starting index
938    * is less than zero, or the substring is not found, -1 is returned.
939    *
940    * @param str String to find
941    * @param fromIndex index to start the search
942    * @return location (base 0) of the String, or -1 if not found
943    * @throws NullPointerException if str is null
944    */
945   public int lastIndexOf(String str, int fromIndex)
946   {
947     fromIndex = Math.min(fromIndex, count - str.count);
948     for ( ; fromIndex >= 0; fromIndex--)
949       if (regionMatches(fromIndex, str))
950         return fromIndex;
951     return -1;
952   }
953
954   /**
955    * Reverse the characters in this StringBuilder. The same sequence of
956    * characters exists, but in the reverse index ordering.
957    *
958    * @return this <code>StringBuilder</code>
959    */
960   public StringBuilder reverse()
961   {
962     // Call ensureCapacity to enforce copy-on-write.
963     ensureCapacity(count);
964     for (int i = count >> 1, j = count - i; --i >= 0; ++j)
965       {
966         char c = value[i];
967         value[i] = value[j];
968         value[j] = c;
969       }
970     return this;
971   }
972
973   /**
974    * Convert this <code>StringBuilder</code> to a <code>String</code>. The
975    * String is composed of the characters currently in this StringBuilder. Note
976    * that the result is a copy, and that future modifications to this buffer
977    * do not affect the String.
978    *
979    * @return the characters in this StringBuilder
980    */
981   public String toString()
982   {
983     return new String(this);
984   }
985
986   /**
987    * Predicate which determines if a substring of this matches another String
988    * starting at a specified offset for each String and continuing for a
989    * specified length. This is more efficient than creating a String to call
990    * indexOf on.
991    *
992    * @param toffset index to start comparison at for this String
993    * @param other non-null String to compare to region of this
994    * @return true if regions match, false otherwise
995    * @see #indexOf(String, int)
996    * @see #lastIndexOf(String, int)
997    * @see String#regionMatches(boolean, int, String, int, int)
998    */
999   private boolean regionMatches(int toffset, String other)
1000   {
1001     int len = other.count;
1002     int index = other.offset;
1003     while (--len >= 0)
1004       if (value[toffset++] != other.value[index++])
1005         return false;
1006     return true;
1007   }
1008
1009   /**
1010    * Get the code point at the specified index.  This is like #charAt(int),
1011    * but if the character is the start of a surrogate pair, and the
1012    * following character completes the pair, then the corresponding
1013    * supplementary code point is returned.
1014    * @param index the index of the codepoint to get, starting at 0
1015    * @return the codepoint at the specified index
1016    * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
1017    * @since 1.5
1018    */
1019   public int codePointAt(int index)
1020   {
1021     return Character.codePointAt(value, index, count);
1022   }
1023
1024     /**
1025    * Get the code point before the specified index.  This is like
1026    * #codePointAt(int), but checks the characters at <code>index-1</code> and
1027    * <code>index-2</code> to see if they form a supplementary code point.
1028    * @param index the index just past the codepoint to get, starting at 0
1029    * @return the codepoint at the specified index
1030    * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
1031    * @since 1.5
1032    */
1033   public int codePointBefore(int index)
1034   {
1035     // Character.codePointBefore() doesn't perform this check.  We
1036     // could use the CharSequence overload, but this is just as easy.
1037     if (index >= count)
1038       throw new IndexOutOfBoundsException();
1039     return Character.codePointBefore(value, index, 1);
1040   }
1041
1042   /**
1043    * Returns the number of Unicode code points in the specified sub sequence.
1044    * Surrogate pairs count as one code point.
1045    * @param beginIndex the start of the subarray
1046    * @param endIndex the index after the last char in the subarray
1047    * @return the number of code points
1048    * @throws IndexOutOfBoundsException if beginIndex is less than zero or 
1049    * greater than endIndex or if endIndex is greater than the length of this 
1050    * StringBuilder
1051    */
1052   public int codePointCount(int beginIndex,int endIndex)
1053   {
1054     if (beginIndex < 0 || beginIndex > endIndex || endIndex > count)
1055       throw new IndexOutOfBoundsException("invalid indices: " + beginIndex
1056                                           + ", " + endIndex);
1057     return Character.codePointCount(value, beginIndex, endIndex - beginIndex);
1058   }
1059
1060   public void trimToSize()
1061   {
1062     if (count < value.length)
1063       {
1064         char[] newValue = new char[count];
1065         VMSystem.arraycopy(value, 0, newValue, 0, count);
1066         value = newValue;
1067       }
1068   }
1069 }