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