OSDN Git Service

PR libgcj/27352
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / StringBuffer.java
1 /* StringBuffer.java -- Growable strings
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
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>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.
49  *
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>).
55  *
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>.
61  *
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).
66  *
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
74  */
75 public final class StringBuffer implements Serializable, CharSequence
76 {
77   /**
78    * Compatible with JDK 1.0+.
79    */
80   private static final long serialVersionUID = 3388685877147921107L;
81
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.
86    *
87    * @serial the number of characters in the buffer
88    */
89   int count;
90
91   /**
92    * The buffer.  Note that this has permissions set this way so that String
93    * can get the value.
94    *
95    * @serial the buffer
96    */
97   char[] value;
98
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.
104    *
105    * @serial whether the buffer is shared
106    */
107   boolean shared;
108
109   /**
110    * The default capacity of a buffer.
111    */
112   private static final int DEFAULT_CAPACITY = 16;
113
114   /**
115    * Create a new StringBuffer with default capacity 16.
116    */
117   public StringBuffer()
118   {
119     this(DEFAULT_CAPACITY);
120   }
121
122   /**
123    * Create an empty <code>StringBuffer</code> with the specified initial
124    * capacity.
125    *
126    * @param capacity the initial capacity
127    * @throws NegativeArraySizeException if capacity is negative
128    */
129   public StringBuffer(int capacity)
130   {
131     value = new char[capacity];
132   }
133
134   /**
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.
138    *
139    * @param str the <code>String</code> to convert
140    * @throws NullPointerException if str is null
141    */
142   public StringBuffer(String str)
143   {
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);
148   }
149
150   /**
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.
154    *
155    * @param sequence the <code>String</code> to convert
156    * @throws NullPointerException if str is null
157    *
158    * @since 1.5
159    */
160   public StringBuffer(CharSequence sequence)
161   {
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);
166   }
167
168   /**
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>.
172    *
173    * @return the length of this <code>StringBuffer</code>
174    * @see #capacity()
175    * @see #setLength(int)
176    */
177   public synchronized int length()
178   {
179     return count;
180   }
181
182   /**
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>.
185    *
186    * @return the capacity of this <code>StringBuffer</code>
187    * @see #length()
188    * @see #ensureCapacity(int)
189    */
190   public synchronized int capacity()
191   {
192     return value.length;
193   }
194
195   /**
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.
201    *
202    * @param minimumCapacity the new capacity
203    * @see #capacity()
204    */
205   public synchronized void ensureCapacity(int minimumCapacity)
206   {
207     ensureCapacity_unsynchronized(minimumCapacity);
208   }
209
210   /**
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.
216    *
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()
221    */
222   public synchronized void setLength(int newLength)
223   {
224     if (newLength < 0)
225       throw new StringIndexOutOfBoundsException(newLength);
226
227     int valueLength = value.length;
228
229     /* Always call ensureCapacity_unsynchronized in order to preserve
230        copy-on-write semantics.  */
231     ensureCapacity_unsynchronized(newLength);
232
233     if (newLength < valueLength)
234       {
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;
239       }
240     else
241       {
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';
246       }
247   }
248
249   /**
250    * Get the character at the specified index.
251    *
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()
255    */
256   public synchronized char charAt(int index)
257   {
258     if (index < 0 || index >= count)
259       throw new StringIndexOutOfBoundsException(index);
260     return value[index];
261   }
262
263   /**
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
272    */
273   public synchronized int codePointAt(int index)
274   {
275     return Character.codePointAt(value, index, count);
276   }
277
278   /**
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
286    */
287   public synchronized int codePointBefore(int index)
288   {
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);
294   }
295
296   /**
297    * Get the specified array of characters. <code>srcOffset - srcEnd</code>
298    * characters will be copied into the array you pass in.
299    *
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)
310    */
311   public synchronized void getChars(int srcOffset, int srcEnd,
312                                     char[] dst, int dstOffset)
313   {
314     if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
315       throw new StringIndexOutOfBoundsException();
316     System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
317   }
318
319   /**
320    * Set the character at the specified index.
321    *
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)
326    */
327   public synchronized void setCharAt(int index, char ch)
328   {
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;
334   }
335
336   /**
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>.
340    *
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)
345    */
346   public StringBuffer append(Object obj)
347   {
348     return append(obj == null ? "null" : obj.toString());
349   }
350
351   /**
352    * Append the <code>String</code> to this <code>StringBuffer</code>. If
353    * str is null, the String "null" is appended.
354    *
355    * @param str the <code>String</code> to append
356    * @return this <code>StringBuffer</code>
357    */
358   public synchronized StringBuffer append(String str)
359   {
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;
367   }
368
369   /**
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.
373    *
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
378    */
379   public synchronized StringBuffer append(StringBuffer stringBuffer)
380   {
381     if (stringBuffer == null)
382       return append("null");
383     synchronized (stringBuffer)
384       {
385         int len = stringBuffer.count;
386         ensureCapacity_unsynchronized(count + len);
387         System.arraycopy(stringBuffer.value, 0, value, count, len);
388         count += len;
389       }
390     return this;
391   }
392
393   /**
394    * Append the <code>CharSequence</code> value of the argument to this
395    * <code>StringBuffer</code>.
396    *
397    * @param sequence the <code>CharSequence</code> to append
398    * @return this <code>StringBuffer</code>
399    * @see #append(Object)
400    * @since 1.5
401    */
402   public synchronized StringBuffer append(CharSequence sequence)
403   {
404     if (sequence == null)
405       sequence = "null";
406     return append(sequence, 0, sequence.length());
407   }
408
409   /**
410    * Append the specified subsequence of the <code>CharSequence</code>
411    * argument to this <code>StringBuffer</code>.
412    *
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
419    */
420   public synchronized StringBuffer append(CharSequence sequence,
421                                           int start, int end)
422   {
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;
431   }
432
433   /**
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.
437    *
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)
442    */
443   public StringBuffer append(char[] data)
444   {
445     return append(data, 0, data.length);
446   }
447
448   /**
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.
453    *
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)
461    */
462   public synchronized StringBuffer append(char[] data, int offset, int count)
463   {
464     if (offset < 0 || count < 0 || offset > data.length - count)
465       throw new StringIndexOutOfBoundsException();
466     ensureCapacity_unsynchronized(this.count + count);
467     System.arraycopy(data, offset, value, this.count, count);
468     this.count += count;
469     return this;
470   }
471
472   /**
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>.
476    *
477    * @param bool the <code>boolean</code> to convert and append
478    * @return this <code>StringBuffer</code>
479    * @see String#valueOf(boolean)
480    */
481   public StringBuffer append(boolean bool)
482   {
483     return append(bool ? "true" : "false");
484   }
485
486   /**
487    * Append the <code>char</code> to this <code>StringBuffer</code>.
488    *
489    * @param ch the <code>char</code> to append
490    * @return this <code>StringBuffer</code>
491    */
492   public synchronized StringBuffer append(char ch)
493   {
494     ensureCapacity_unsynchronized(count + 1);
495     value[count++] = ch;
496     return this;
497   }
498
499   /**
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.
503    *
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
508    */
509   public synchronized StringBuffer appendCodePoint(int code)
510   {
511     int len = Character.charCount(code);
512     ensureCapacity_unsynchronized(count + len);
513     Character.toChars(code, value, count);
514     count += len;
515     return this;
516   }
517
518   /**
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>.
522    *
523    * @param inum the <code>int</code> to convert and append
524    * @return this <code>StringBuffer</code>
525    * @see String#valueOf(int)
526    */
527   // GCJ LOCAL: this is native for efficiency.
528   public native StringBuffer append (int inum);
529
530   /**
531    * Append the <code>String</code> value of the argument to this
532    * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
533    * to <code>String</code>.
534    *
535    * @param lnum the <code>long</code> to convert and append
536    * @return this <code>StringBuffer</code>
537    * @see String#valueOf(long)
538    */
539   public StringBuffer append(long lnum)
540   {
541     return append(Long.toString(lnum, 10));
542   }
543
544   /**
545    * Append the <code>String</code> value of the argument to this
546    * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
547    * to <code>String</code>.
548    *
549    * @param fnum the <code>float</code> to convert and append
550    * @return this <code>StringBuffer</code>
551    * @see String#valueOf(float)
552    */
553   public StringBuffer append(float fnum)
554   {
555     return append(Float.toString(fnum));
556   }
557
558   /**
559    * Append the <code>String</code> value of the argument to this
560    * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
561    * to <code>String</code>.
562    *
563    * @param dnum the <code>double</code> to convert and append
564    * @return this <code>StringBuffer</code>
565    * @see String#valueOf(double)
566    */
567   public StringBuffer append(double dnum)
568   {
569     return append(Double.toString(dnum));
570   }
571
572   /**
573    * Delete characters from this <code>StringBuffer</code>.
574    * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
575    * harmless for end to be larger than length().
576    *
577    * @param start the first character to delete
578    * @param end the index after the last character to delete
579    * @return this <code>StringBuffer</code>
580    * @throws StringIndexOutOfBoundsException if start or end are out of bounds
581    * @since 1.2
582    */
583   public synchronized StringBuffer delete(int start, int end)
584   {
585     if (start < 0 || start > count || start > end)
586       throw new StringIndexOutOfBoundsException(start);
587     if (end > count)
588       end = count;
589     // This will unshare if required.
590     ensureCapacity_unsynchronized(count);
591     if (count - end != 0)
592       System.arraycopy(value, end, value, start, count - end);
593     count -= end - start;
594     return this;
595   }
596
597   /**
598    * Delete a character from this <code>StringBuffer</code>.
599    *
600    * @param index the index of the character to delete
601    * @return this <code>StringBuffer</code>
602    * @throws StringIndexOutOfBoundsException if index is out of bounds
603    * @since 1.2
604    */
605   public StringBuffer deleteCharAt(int index)
606   {
607     return delete(index, index + 1);
608   }
609
610   /**
611    * Replace characters between index <code>start</code> (inclusive) and
612    * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
613    * is larger than the size of this StringBuffer, all characters after
614    * <code>start</code> are replaced.
615    *
616    * @param start the beginning index of characters to delete (inclusive)
617    * @param end the ending index of characters to delete (exclusive)
618    * @param str the new <code>String</code> to insert
619    * @return this <code>StringBuffer</code>
620    * @throws StringIndexOutOfBoundsException if start or end are out of bounds
621    * @throws NullPointerException if str is null
622    * @since 1.2
623    */
624   public synchronized StringBuffer replace(int start, int end, String str)
625   {
626     if (start < 0 || start > count || start > end)
627       throw new StringIndexOutOfBoundsException(start);
628
629     int len = str.count;
630     // Calculate the difference in 'count' after the replace.
631     int delta = len - (end > count ? count : end) + start;
632     ensureCapacity_unsynchronized(count + delta);
633
634     if (delta != 0 && end < count)
635       System.arraycopy(value, end, value, end + delta, count - end);
636
637     str.getChars(0, len, value, start);
638     count += delta;
639     return this;
640   }
641
642   /**
643    * Creates a substring of this StringBuffer, starting at a specified index
644    * and ending at the end of this StringBuffer.
645    *
646    * @param beginIndex index to start substring (base 0)
647    * @return new String which is a substring of this StringBuffer
648    * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
649    * @see #substring(int, int)
650    * @since 1.2
651    */
652   public String substring(int beginIndex)
653   {
654     return substring(beginIndex, count);
655   }
656
657   /**
658    * Creates a substring of this StringBuffer, starting at a specified index
659    * and ending at one character before a specified index. This is implemented
660    * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
661    * the CharSequence interface.
662    *
663    * @param beginIndex index to start at (inclusive, base 0)
664    * @param endIndex index to end at (exclusive)
665    * @return new String which is a substring of this StringBuffer
666    * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
667    *         bounds
668    * @see #substring(int, int)
669    * @since 1.4
670    */
671   public CharSequence subSequence(int beginIndex, int endIndex)
672   {
673     return substring(beginIndex, endIndex);
674   }
675
676   /**
677    * Creates a substring of this StringBuffer, starting at a specified index
678    * and ending at one character before a specified index.
679    *
680    * @param beginIndex index to start at (inclusive, base 0)
681    * @param endIndex index to end at (exclusive)
682    * @return new String which is a substring of this StringBuffer
683    * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
684    *         of bounds
685    * @since 1.2
686    */
687   public synchronized String substring(int beginIndex, int endIndex)
688   {
689     int len = endIndex - beginIndex;
690     if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
691       throw new StringIndexOutOfBoundsException();
692     if (len == 0)
693       return "";
694     // Don't copy unless substring is smaller than 1/4 of the buffer.
695     boolean share_buffer = ((len << 2) >= value.length);
696     if (share_buffer)
697       this.shared = true;
698     // Package constructor avoids an array copy.
699     return new String(value, beginIndex, len, share_buffer);
700   }
701
702   /**
703    * Insert a subarray of the <code>char[]</code> argument into this
704    * <code>StringBuffer</code>.
705    *
706    * @param offset the place to insert in this buffer
707    * @param str the <code>char[]</code> to insert
708    * @param str_offset the index in <code>str</code> to start inserting from
709    * @param len the number of characters to insert
710    * @return this <code>StringBuffer</code>
711    * @throws NullPointerException if <code>str</code> is <code>null</code>
712    * @throws StringIndexOutOfBoundsException if any index is out of bounds
713    * @since 1.2
714    */
715   public synchronized StringBuffer insert(int offset,
716                                           char[] str, int str_offset, int len)
717   {
718     if (offset < 0 || offset > count || len < 0
719         || str_offset < 0 || str_offset > str.length - len)
720       throw new StringIndexOutOfBoundsException();
721     ensureCapacity_unsynchronized(count + len);
722     System.arraycopy(value, offset, value, offset + len, count - offset);
723     System.arraycopy(str, str_offset, value, offset, len);
724     count += len;
725     return this;
726   }
727
728   /**
729    * Insert the <code>String</code> value of the argument into this
730    * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
731    * to <code>String</code>.
732    *
733    * @param offset the place to insert in this buffer
734    * @param obj the <code>Object</code> to convert and insert
735    * @return this <code>StringBuffer</code>
736    * @exception StringIndexOutOfBoundsException if offset is out of bounds
737    * @see String#valueOf(Object)
738    */
739   public StringBuffer insert(int offset, Object obj)
740   {
741     return insert(offset, obj == null ? "null" : obj.toString());
742   }
743
744   /**
745    * Insert the <code>String</code> argument into this
746    * <code>StringBuffer</code>. If str is null, the String "null" is used
747    * instead.
748    *
749    * @param offset the place to insert in this buffer
750    * @param str the <code>String</code> to insert
751    * @return this <code>StringBuffer</code>
752    * @throws StringIndexOutOfBoundsException if offset is out of bounds
753    */
754   public synchronized StringBuffer insert(int offset, String str)
755   {
756     if (offset < 0 || offset > count)
757       throw new StringIndexOutOfBoundsException(offset);
758     if (str == null)
759       str = "null";
760     int len = str.count;
761     ensureCapacity_unsynchronized(count + len);
762     System.arraycopy(value, offset, value, offset + len, count - offset);
763     str.getChars(0, len, value, offset);
764     count += len;
765     return this;
766   }
767
768   /**
769    * Insert the <code>CharSequence</code> argument into this
770    * <code>StringBuffer</code>.  If the sequence is null, the String
771    * "null" is used instead.
772    *
773    * @param offset the place to insert in this buffer
774    * @param sequence the <code>CharSequence</code> to insert
775    * @return this <code>StringBuffer</code>
776    * @throws IndexOutOfBoundsException if offset is out of bounds
777    * @since 1.5
778    */
779   public synchronized StringBuffer insert(int offset, CharSequence sequence)
780   {
781     if (sequence == null)
782       sequence = "null";
783     return insert(offset, sequence, 0, sequence.length());
784   }
785
786   /**
787    * Insert a subsequence of the <code>CharSequence</code> argument into this
788    * <code>StringBuffer</code>.  If the sequence is null, the String
789    * "null" is used instead.
790    *
791    * @param offset the place to insert in this buffer
792    * @param sequence the <code>CharSequence</code> to insert
793    * @param start the starting index of the subsequence
794    * @param end one past the ending index of the subsequence
795    * @return this <code>StringBuffer</code>
796    * @throws IndexOutOfBoundsException if offset, start,
797    * or end are out of bounds
798    * @since 1.5
799    */
800   public synchronized StringBuffer insert(int offset, CharSequence sequence,
801                                           int start, int end)
802   {
803     if (sequence == null)
804       sequence = "null";
805     if (start < 0 || end < 0 || start > end || end > sequence.length())
806       throw new IndexOutOfBoundsException();
807     int len = end - start;
808     ensureCapacity_unsynchronized(count + len);
809     System.arraycopy(value, offset, value, offset + len, count - offset);
810     for (int i = start; i < end; ++i)
811       value[offset++] = sequence.charAt(i);
812     count += len;
813     return this;
814   }
815
816   /**
817    * Insert the <code>char[]</code> argument into this
818    * <code>StringBuffer</code>.
819    *
820    * @param offset the place to insert in this buffer
821    * @param data the <code>char[]</code> to insert
822    * @return this <code>StringBuffer</code>
823    * @throws NullPointerException if <code>data</code> is <code>null</code>
824    * @throws StringIndexOutOfBoundsException if offset is out of bounds
825    * @see #insert(int, char[], int, int)
826    */
827   public StringBuffer insert(int offset, char[] data)
828   {
829     return insert(offset, data, 0, data.length);
830   }
831
832   /**
833    * Insert the <code>String</code> value of the argument into this
834    * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
835    * to <code>String</code>.
836    *
837    * @param offset the place to insert in this buffer
838    * @param bool the <code>boolean</code> to convert and insert
839    * @return this <code>StringBuffer</code>
840    * @throws StringIndexOutOfBoundsException if offset is out of bounds
841    * @see String#valueOf(boolean)
842    */
843   public StringBuffer insert(int offset, boolean bool)
844   {
845     return insert(offset, bool ? "true" : "false");
846   }
847
848   /**
849    * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
850    *
851    * @param offset the place to insert in this buffer
852    * @param ch the <code>char</code> to insert
853    * @return this <code>StringBuffer</code>
854    * @throws StringIndexOutOfBoundsException if offset is out of bounds
855    */
856   public synchronized StringBuffer insert(int offset, char ch)
857   {
858     if (offset < 0 || offset > count)
859       throw new StringIndexOutOfBoundsException(offset);
860     ensureCapacity_unsynchronized(count + 1);
861     System.arraycopy(value, offset, value, offset + 1, count - offset);
862     value[offset] = ch;
863     count++;
864     return this;
865   }
866
867   /**
868    * Insert the <code>String</code> value of the argument into this
869    * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
870    * to <code>String</code>.
871    *
872    * @param offset the place to insert in this buffer
873    * @param inum the <code>int</code> to convert and insert
874    * @return this <code>StringBuffer</code>
875    * @throws StringIndexOutOfBoundsException if offset is out of bounds
876    * @see String#valueOf(int)
877    */
878   public StringBuffer insert(int offset, int inum)
879   {
880     return insert(offset, String.valueOf(inum));
881   }
882
883   /**
884    * Insert the <code>String</code> value of the argument into this
885    * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
886    * to <code>String</code>.
887    *
888    * @param offset the place to insert in this buffer
889    * @param lnum the <code>long</code> to convert and insert
890    * @return this <code>StringBuffer</code>
891    * @throws StringIndexOutOfBoundsException if offset is out of bounds
892    * @see String#valueOf(long)
893    */
894   public StringBuffer insert(int offset, long lnum)
895   {
896     return insert(offset, Long.toString(lnum, 10));
897   }
898
899   /**
900    * Insert the <code>String</code> value of the argument into this
901    * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
902    * to <code>String</code>.
903    *
904    * @param offset the place to insert in this buffer
905    * @param fnum the <code>float</code> to convert and insert
906    * @return this <code>StringBuffer</code>
907    * @throws StringIndexOutOfBoundsException if offset is out of bounds
908    * @see String#valueOf(float)
909    */
910   public StringBuffer insert(int offset, float fnum)
911   {
912     return insert(offset, Float.toString(fnum));
913   }
914
915   /**
916    * Insert the <code>String</code> value of the argument into this
917    * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
918    * to <code>String</code>.
919    *
920    * @param offset the place to insert in this buffer
921    * @param dnum the <code>double</code> to convert and insert
922    * @return this <code>StringBuffer</code>
923    * @throws StringIndexOutOfBoundsException if offset is out of bounds
924    * @see String#valueOf(double)
925    */
926   public StringBuffer insert(int offset, double dnum)
927   {
928     return insert(offset, Double.toString(dnum));
929   }
930
931   /**
932    * Finds the first instance of a substring in this StringBuffer.
933    *
934    * @param str String to find
935    * @return location (base 0) of the String, or -1 if not found
936    * @throws NullPointerException if str is null
937    * @see #indexOf(String, int)
938    * @since 1.4
939    */
940   public int indexOf(String str)
941   {
942     return indexOf(str, 0);
943   }
944
945   /**
946    * Finds the first instance of a String in this StringBuffer, starting at
947    * a given index.  If starting index is less than 0, the search starts at
948    * the beginning of this String.  If the starting index is greater than the
949    * length of this String, or the substring is not found, -1 is returned.
950    *
951    * @param str String to find
952    * @param fromIndex index to start the search
953    * @return location (base 0) of the String, or -1 if not found
954    * @throws NullPointerException if str is null
955    * @since 1.4
956    */
957   public synchronized int indexOf(String str, int fromIndex)
958   {
959     if (fromIndex < 0)
960       fromIndex = 0;
961     int limit = count - str.count;
962     for ( ; fromIndex <= limit; fromIndex++)
963       if (regionMatches(fromIndex, str))
964         return fromIndex;
965     return -1;
966   }
967
968   /**
969    * Finds the last instance of a substring in this StringBuffer.
970    *
971    * @param str String to find
972    * @return location (base 0) of the String, or -1 if not found
973    * @throws NullPointerException if str is null
974    * @see #lastIndexOf(String, int)
975    * @since 1.4
976    */
977   public int lastIndexOf(String str)
978   {
979     return lastIndexOf(str, count - str.count);
980   }
981
982   /**
983    * Finds the last instance of a String in this StringBuffer, starting at a
984    * given index.  If starting index is greater than the maximum valid index,
985    * then the search begins at the end of this String.  If the starting index
986    * is less than zero, or the substring is not found, -1 is returned.
987    *
988    * @param str String to find
989    * @param fromIndex index to start the search
990    * @return location (base 0) of the String, or -1 if not found
991    * @throws NullPointerException if str is null
992    * @since 1.4
993    */
994   public synchronized int lastIndexOf(String str, int fromIndex)
995   {
996     fromIndex = Math.min(fromIndex, count - str.count);
997     for ( ; fromIndex >= 0; fromIndex--)
998       if (regionMatches(fromIndex, str))
999         return fromIndex;
1000     return -1;
1001   }
1002
1003   /**
1004    * Reverse the characters in this StringBuffer. The same sequence of
1005    * characters exists, but in the reverse index ordering.
1006    *
1007    * @return this <code>StringBuffer</code>
1008    */
1009   public synchronized StringBuffer reverse()
1010   {
1011     // Call ensureCapacity to enforce copy-on-write.
1012     ensureCapacity_unsynchronized(count);
1013     for (int i = count >> 1, j = count - i; --i >= 0; ++j)
1014       {
1015         char c = value[i];
1016         value[i] = value[j];
1017         value[j] = c;
1018       }
1019     return this;
1020   }
1021
1022   /**
1023    * Convert this <code>StringBuffer</code> to a <code>String</code>. The
1024    * String is composed of the characters currently in this StringBuffer. Note
1025    * that the result is a copy, and that future modifications to this buffer
1026    * do not affect the String.
1027    *
1028    * @return the characters in this StringBuffer
1029    */
1030   public String toString()
1031   {
1032     // The string will set this.shared = true.
1033     return new String(this);
1034   }
1035
1036   /**
1037    * This may reduce the amount of memory used by the StringBuffer,
1038    * by resizing the internal array to remove unused space.  However,
1039    * this method is not required to resize, so this behavior cannot
1040    * be relied upon.
1041    * @since 1.5
1042    */
1043   public synchronized void trimToSize()
1044   {
1045     int wouldSave = value.length - count;
1046     // Some random heuristics: if we save less than 20 characters, who
1047     // cares.
1048     if (wouldSave < 20)
1049       return;
1050     // If we save more than 200 characters, shrink.
1051     // If we save more than 1/4 of the buffer, shrink.
1052     if (wouldSave > 200 || wouldSave * 4 > value.length)
1053       {
1054         char[] newValue = new char[count];
1055         System.arraycopy(value, 0, newValue, 0, count);
1056         value = newValue;
1057       }
1058   }
1059
1060   /**
1061    * Return the number of code points between two indices in the
1062    * <code>StringBuffer</code>.  An unpaired surrogate counts as a
1063    * code point for this purpose.  Characters outside the indicated
1064    * range are not examined, even if the range ends in the middle of a
1065    * surrogate pair.
1066    *
1067    * @param start the starting index
1068    * @param end one past the ending index
1069    * @return the number of code points
1070    * @since 1.5
1071    */
1072   public synchronized int codePointCount(int start, int end)
1073   {
1074     if (start < 0 || end >= count || start > end)
1075       throw new StringIndexOutOfBoundsException();
1076
1077     int count = 0;
1078     while (start < end)
1079       {
1080         char base = value[start];
1081         if (base < Character.MIN_HIGH_SURROGATE
1082             || base > Character.MAX_HIGH_SURROGATE
1083             || start == end
1084             || start == count
1085             || value[start + 1] < Character.MIN_LOW_SURROGATE
1086             || value[start + 1] > Character.MAX_LOW_SURROGATE)
1087           {
1088             // Nothing.
1089           }
1090         else
1091           {
1092             // Surrogate pair.
1093             ++start;
1094           }
1095         ++start;
1096         ++count;
1097       }
1098     return count;
1099   }
1100
1101   /**
1102    * Starting at the given index, this counts forward by the indicated
1103    * number of code points, and then returns the resulting index.  An
1104    * unpaired surrogate counts as a single code point for this
1105    * purpose.
1106    *
1107    * @param start the starting index
1108    * @param codePoints the number of code points
1109    * @return the resulting index
1110    * @since 1.5
1111    */
1112   public synchronized int offsetByCodePoints(int start, int codePoints)
1113   {
1114     while (codePoints > 0)
1115       {
1116         char base = value[start];
1117         if (base < Character.MIN_HIGH_SURROGATE
1118             || base > Character.MAX_HIGH_SURROGATE
1119             || start == count
1120             || value[start + 1] < Character.MIN_LOW_SURROGATE
1121             || value[start + 1] > Character.MAX_LOW_SURROGATE)
1122           {
1123             // Nothing.
1124           }
1125         else
1126           {
1127             // Surrogate pair.
1128             ++start;
1129           }
1130         ++start;
1131         --codePoints;
1132       }
1133     return start;
1134   }
1135
1136   /**
1137    * An unsynchronized version of ensureCapacity, used internally to avoid
1138    * the cost of a second lock on the same object. This also has the side
1139    * effect of duplicating the array, if it was shared (to form copy-on-write
1140    * semantics).
1141    *
1142    * @param minimumCapacity the minimum capacity
1143    * @see #ensureCapacity(int)
1144    */
1145   private void ensureCapacity_unsynchronized(int minimumCapacity)
1146   {
1147     if (shared || minimumCapacity > value.length)
1148       {
1149         // We don't want to make a larger vector when `shared' is
1150         // set.  If we do, then setLength becomes very inefficient
1151         // when repeatedly reusing a StringBuffer in a loop.
1152         int max = (minimumCapacity > value.length
1153                    ? value.length * 2 + 2
1154                    : value.length);
1155         minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
1156         char[] nb = new char[minimumCapacity];
1157         System.arraycopy(value, 0, nb, 0, count);
1158         value = nb;
1159         shared = false;
1160       }
1161   }
1162
1163   /**
1164    * Predicate which determines if a substring of this matches another String
1165    * starting at a specified offset for each String and continuing for a
1166    * specified length. This is more efficient than creating a String to call
1167    * indexOf on.
1168    *
1169    * @param toffset index to start comparison at for this String
1170    * @param other non-null String to compare to region of this
1171    * @return true if regions match, false otherwise
1172    * @see #indexOf(String, int)
1173    * @see #lastIndexOf(String, int)
1174    * @see String#regionMatches(boolean, int, String, int, int)
1175    */
1176   // GCJ LOCAL: native for gcj.
1177   private native boolean regionMatches(int toffset, String other);
1178 }