001    /* StringBuilder.java -- Unsynchronized growable strings
002       Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
003       Free Software Foundation, Inc.
004    
005    This file is part of GNU Classpath.
006    
007    GNU Classpath is free software; you can redistribute it and/or modify
008    it under the terms of the GNU General Public License as published by
009    the Free Software Foundation; either version 2, or (at your option)
010    any later version.
011    
012    GNU Classpath is distributed in the hope that it will be useful, but
013    WITHOUT ANY WARRANTY; without even the implied warranty of
014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015    General Public License for more details.
016    
017    You should have received a copy of the GNU General Public License
018    along with GNU Classpath; see the file COPYING.  If not, write to the
019    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
020    02110-1301 USA.
021    
022    Linking this library statically or dynamically with other modules is
023    making a combined work based on this library.  Thus, the terms and
024    conditions of the GNU General Public License cover the whole
025    combination.
026    
027    As a special exception, the copyright holders of this library give you
028    permission to link this library with independent modules to produce an
029    executable, regardless of the license terms of these independent
030    modules, and to copy and distribute the resulting executable under
031    terms of your choice, provided that you also meet, for each linked
032    independent module, the terms and conditions of the license of that
033    module.  An independent module is a module which is not derived from
034    or based on this library.  If you modify this library, you may extend
035    this exception to your version of the library, but you are not
036    obligated to do so.  If you do not wish to do so, delete this
037    exception statement from your version. */
038    
039    package java.lang;
040    
041    import java.io.Serializable;
042    
043    /**
044     * <code>StringBuilder</code> represents a changeable <code>String</code>.
045     * It provides the operations required to modify the
046     * <code>StringBuilder</code>, including insert, replace, delete, append,
047     * and reverse. It like <code>StringBuffer</code>, but is not
048     * synchronized.  It is ideal for use when it is known that the
049     * object will only be used from a single thread.
050     *
051     * <p><code>StringBuilder</code>s are variable-length in nature, so even if
052     * you initialize them to a certain size, they can still grow larger than
053     * that. <em>Capacity</em> indicates the number of characters the
054     * <code>StringBuilder</code> can have in it before it has to grow (growing
055     * the char array is an expensive operation involving <code>new</code>).
056     *
057     * <p>Incidentally, compilers often implement the String operator "+"
058     * by using a <code>StringBuilder</code> operation:<br>
059     * <code>a + b</code><br>
060     * is the same as<br>
061     * <code>new StringBuilder().append(a).append(b).toString()</code>.
062     *
063     * <p>Classpath's StringBuilder is capable of sharing memory with Strings for
064     * efficiency.  This will help when a StringBuilder is converted to a String
065     * and the StringBuilder is not changed after that (quite common when
066     * performing string concatenation).
067     *
068     * @author Paul Fisher
069     * @author John Keiser
070     * @author Tom Tromey
071     * @author Eric Blake (ebb9@email.byu.edu)
072     * @see String
073     * @see StringBuffer
074     *
075     * @since 1.5
076     */
077    public final class StringBuilder
078      implements Serializable, CharSequence, Appendable
079    {
080      // Implementation note: if you change this class, you usually will
081      // want to change StringBuffer as well.
082    
083      /**
084       * For compatability with Sun's JDK
085       */
086      private static final long serialVersionUID = 4383685877147921099L;
087    
088      /**
089       * Index of next available character (and thus the size of the current
090       * string contents).  Note that this has permissions set this way so that
091       * String can get the value.
092       *
093       * @serial the number of characters in the buffer
094       */
095      int count;
096    
097      /**
098       * The buffer.  Note that this has permissions set this way so that String
099       * 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            System.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        System.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            System.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        System.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      // FIXME: this is native in libgcj in StringBuffer.
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          System.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          System.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        System.arraycopy(value, offset, value, offset + len, count - offset);
680        System.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        System.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        System.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        System.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      // GCJ LOCAL: Native to access String internals properly.
1000      private native boolean regionMatches(int toffset, String other);
1001    
1002      /**
1003       * Get the code point at the specified index.  This is like #charAt(int),
1004       * but if the character is the start of a surrogate pair, and the
1005       * following character completes the pair, then the corresponding
1006       * supplementary code point is returned.
1007       * @param index the index of the codepoint to get, starting at 0
1008       * @return the codepoint at the specified index
1009       * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
1010       * @since 1.5
1011       */
1012      public int codePointAt(int index)
1013      {
1014        return Character.codePointAt(value, index, count);
1015      }
1016    
1017        /**
1018       * Get the code point before the specified index.  This is like
1019       * #codePointAt(int), but checks the characters at <code>index-1</code> and
1020       * <code>index-2</code> to see if they form a supplementary code point.
1021       * @param index the index just past the codepoint to get, starting at 0
1022       * @return the codepoint at the specified index
1023       * @throws IndexOutOfBoundsException if index is negative or &gt;= length()
1024       * @since 1.5
1025       */
1026      public int codePointBefore(int index)
1027      {
1028        // Character.codePointBefore() doesn't perform this check.  We
1029        // could use the CharSequence overload, but this is just as easy.
1030        if (index >= count)
1031          throw new IndexOutOfBoundsException();
1032        return Character.codePointBefore(value, index, 1);
1033      }
1034    
1035      /**
1036       * Returns the number of Unicode code points in the specified sub sequence.
1037       * Surrogate pairs count as one code point.
1038       * @param beginIndex the start of the subarray
1039       * @param endIndex the index after the last char in the subarray
1040       * @return the number of code points
1041       * @throws IndexOutOfBoundsException if beginIndex is less than zero or 
1042       * greater than endIndex or if endIndex is greater than the length of this 
1043       * StringBuilder
1044       */
1045      public int codePointCount(int beginIndex,int endIndex)
1046      {
1047        if (beginIndex < 0 || beginIndex > endIndex || endIndex > count)
1048          throw new IndexOutOfBoundsException("invalid indices: " + beginIndex
1049                                              + ", " + endIndex);
1050        return Character.codePointCount(value, beginIndex, endIndex - beginIndex);
1051      }
1052    
1053      public void trimToSize()
1054      {
1055        if (count < value.length)
1056          {
1057            char[] newValue = new char[count];
1058            System.arraycopy(value, 0, newValue, 0, count);
1059            value = newValue;
1060          }
1061      }
1062    }