KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > lang > AbstractStringBuilder


1 /*
2  * @(#)AbstractStringBuilder.java 1.14 05/09/26
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.lang;
9
10 import sun.misc.FloatingDecimal;
11
12 /**
13  * A mutable sequence of characters.
14  * <p>
15  * Implements a modifiable string. At any point in time it contains some
16  * particular sequence of characters, but the length and content of the
17  * sequence can be changed through certain method calls.
18  *
19  * @author Michael McCloskey
20  * @version 1.14, 09/26/05
21  * @since 1.5
22  */

23 abstract class AbstractStringBuilder implements Appendable JavaDoc, CharSequence JavaDoc {
24     /**
25      * The value is used for character storage.
26      */

27     char value[];
28
29     /**
30      * The count is the number of characters used.
31      */

32     int count;
33
34     /**
35      * This no-arg constructor is necessary for serialization of subclasses.
36      */

37     AbstractStringBuilder() {
38     }
39
40     /**
41      * Creates an AbstractStringBuilder of the specified capacity.
42      */

43     AbstractStringBuilder(int capacity) {
44         value = new char[capacity];
45     }
46
47     /**
48      * Returns the length (character count).
49      *
50      * @return the length of the sequence of characters currently
51      * represented by this object
52      */

53     public int length() {
54     return count;
55     }
56
57     /**
58      * Returns the current capacity. The capacity is the amount of storage
59      * available for newly inserted characters, beyond which an allocation
60      * will occur.
61      *
62      * @return the current capacity
63      */

64     public int capacity() {
65     return value.length;
66     }
67
68     /**
69      * Ensures that the capacity is at least equal to the specified minimum.
70      * If the current capacity is less than the argument, then a new internal
71      * array is allocated with greater capacity. The new capacity is the
72      * larger of:
73      * <ul>
74      * <li>The <code>minimumCapacity</code> argument.
75      * <li>Twice the old capacity, plus <code>2</code>.
76      * </ul>
77      * If the <code>minimumCapacity</code> argument is nonpositive, this
78      * method takes no action and simply returns.
79      *
80      * @param minimumCapacity the minimum desired capacity.
81      */

82     public void ensureCapacity(int minimumCapacity) {
83     if (minimumCapacity > value.length) {
84         expandCapacity(minimumCapacity);
85     }
86     }
87
88     /**
89      * This implements the expansion semantics of ensureCapacity with no
90      * size check or synchronization.
91      */

92     void expandCapacity(int minimumCapacity) {
93     int newCapacity = (value.length + 1) * 2;
94         if (newCapacity < 0) {
95             newCapacity = Integer.MAX_VALUE;
96         } else if (minimumCapacity > newCapacity) {
97         newCapacity = minimumCapacity;
98     }
99     char newValue[] = new char[newCapacity];
100     System.arraycopy(value, 0, newValue, 0, count);
101     value = newValue;
102     }
103
104     /**
105      * Attempts to reduce storage used for the character sequence.
106      * If the buffer is larger than necessary to hold its current sequence of
107      * characters, then it may be resized to become more space efficient.
108      * Calling this method may, but is not required to, affect the value
109      * returned by a subsequent call to the {@link #capacity()} method.
110      */

111     public void trimToSize() {
112         if (count < value.length) {
113             char[] newValue = new char[count];
114             System.arraycopy(value, 0, newValue, 0, count);
115             this.value = newValue;
116         }
117     }
118
119     /**
120      * Sets the length of the character sequence.
121      * The sequence is changed to a new character sequence
122      * whose length is specified by the argument. For every nonnegative
123      * index <i>k</i> less than <code>newLength</code>, the character at
124      * index <i>k</i> in the new character sequence is the same as the
125      * character at index <i>k</i> in the old sequence if <i>k</i> is less
126      * than the length of the old character sequence; otherwise, it is the
127      * null character <code>'&#92;u0000'</code>.
128      *
129      * In other words, if the <code>newLength</code> argument is less than
130      * the current length, the length is changed to the specified length.
131      * <p>
132      * If the <code>newLength</code> argument is greater than or equal
133      * to the current length, sufficient null characters
134      * (<code>'&#92;u0000'</code>) are appended so that
135      * length becomes the <code>newLength</code> argument.
136      * <p>
137      * The <code>newLength</code> argument must be greater than or equal
138      * to <code>0</code>.
139      *
140      * @param newLength the new length
141      * @throws IndexOutOfBoundsException if the
142      * <code>newLength</code> argument is negative.
143      */

144     public void setLength(int newLength) {
145     if (newLength < 0)
146         throw new StringIndexOutOfBoundsException JavaDoc(newLength);
147     if (newLength > value.length)
148         expandCapacity(newLength);
149
150     if (count < newLength) {
151         for (; count < newLength; count++)
152         value[count] = '\0';
153     } else {
154             count = newLength;
155         }
156     }
157
158     /**
159      * Returns the <code>char</code> value in this sequence at the specified index.
160      * The first <code>char</code> value is at index <code>0</code>, the next at index
161      * <code>1</code>, and so on, as in array indexing.
162      * <p>
163      * The index argument must be greater than or equal to
164      * <code>0</code>, and less than the length of this sequence.
165      *
166      * <p>If the <code>char</code> value specified by the index is a
167      * <a HREF="Character.html#unicode">surrogate</a>, the surrogate
168      * value is returned.
169      *
170      * @param index the index of the desired <code>char</code> value.
171      * @return the <code>char</code> value at the specified index.
172      * @throws IndexOutOfBoundsException if <code>index</code> is
173      * negative or greater than or equal to <code>length()</code>.
174      */

175     public char charAt(int index) {
176     if ((index < 0) || (index >= count))
177         throw new StringIndexOutOfBoundsException JavaDoc(index);
178     return value[index];
179     }
180
181     /**
182      * Returns the character (Unicode code point) at the specified
183      * index. The index refers to <code>char</code> values
184      * (Unicode code units) and ranges from <code>0</code> to
185      * {@link #length()}<code> - 1</code>.
186      *
187      * <p> If the <code>char</code> value specified at the given index
188      * is in the high-surrogate range, the following index is less
189      * than the length of this sequence, and the
190      * <code>char</code> value at the following index is in the
191      * low-surrogate range, then the supplementary code point
192      * corresponding to this surrogate pair is returned. Otherwise,
193      * the <code>char</code> value at the given index is returned.
194      *
195      * @param index the index to the <code>char</code> values
196      * @return the code point value of the character at the
197      * <code>index</code>
198      * @exception IndexOutOfBoundsException if the <code>index</code>
199      * argument is negative or not less than the length of this
200      * sequence.
201      */

202     public int codePointAt(int index) {
203         if ((index < 0) || (index >= count)) {
204             throw new StringIndexOutOfBoundsException JavaDoc(index);
205         }
206         return Character.codePointAt(value, index);
207     }
208
209     /**
210      * Returns the character (Unicode code point) before the specified
211      * index. The index refers to <code>char</code> values
212      * (Unicode code units) and ranges from <code>1</code> to {@link
213      * #length()}.
214      *
215      * <p> If the <code>char</code> value at <code>(index - 1)</code>
216      * is in the low-surrogate range, <code>(index - 2)</code> is not
217      * negative, and the <code>char</code> value at <code>(index -
218      * 2)</code> is in the high-surrogate range, then the
219      * supplementary code point value of the surrogate pair is
220      * returned. If the <code>char</code> value at <code>index -
221      * 1</code> is an unpaired low-surrogate or a high-surrogate, the
222      * surrogate value is returned.
223      *
224      * @param index the index following the code point that should be returned
225      * @return the Unicode code point value before the given index.
226      * @exception IndexOutOfBoundsException if the <code>index</code>
227      * argument is less than 1 or greater than the length
228      * of this sequence.
229      */

230     public int codePointBefore(int index) {
231     int i = index - 1;
232         if ((i < 0) || (i >= count)) {
233             throw new StringIndexOutOfBoundsException JavaDoc(index);
234         }
235         return Character.codePointBefore(value, index);
236     }
237
238     /**
239      * Returns the number of Unicode code points in the specified text
240      * range of this sequence. The text range begins at the specified
241      * <code>beginIndex</code> and extends to the <code>char</code> at
242      * index <code>endIndex - 1</code>. Thus the length (in
243      * <code>char</code>s) of the text range is
244      * <code>endIndex-beginIndex</code>. Unpaired surrogates within
245      * this sequence count as one code point each.
246      *
247      * @param beginIndex the index to the first <code>char</code> of
248      * the text range.
249      * @param endIndex the index after the last <code>char</code> of
250      * the text range.
251      * @return the number of Unicode code points in the specified text
252      * range
253      * @exception IndexOutOfBoundsException if the
254      * <code>beginIndex</code> is negative, or <code>endIndex</code>
255      * is larger than the length of this sequence, or
256      * <code>beginIndex</code> is larger than <code>endIndex</code>.
257      */

258     public int codePointCount(int beginIndex, int endIndex) {
259     if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
260         throw new IndexOutOfBoundsException JavaDoc();
261     }
262     return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex);
263     }
264
265     /**
266      * Returns the index within this sequence that is offset from the
267      * given <code>index</code> by <code>codePointOffset</code> code
268      * points. Unpaired surrogates within the text range given by
269      * <code>index</code> and <code>codePointOffset</code> count as
270      * one code point each.
271      *
272      * @param index the index to be offset
273      * @param codePointOffset the offset in code points
274      * @return the index within this sequence
275      * @exception IndexOutOfBoundsException if <code>index</code>
276      * is negative or larger then the length of this sequence,
277      * or if <code>codePointOffset</code> is positive and the subsequence
278      * starting with <code>index</code> has fewer than
279      * <code>codePointOffset</code> code points,
280      * or if <code>codePointOffset</code> is negative and the subsequence
281      * before <code>index</code> has fewer than the absolute value of
282      * <code>codePointOffset</code> code points.
283      */

284     public int offsetByCodePoints(int index, int codePointOffset) {
285     if (index < 0 || index > count) {
286         throw new IndexOutOfBoundsException JavaDoc();
287     }
288     return Character.offsetByCodePointsImpl(value, 0, count,
289                         index, codePointOffset);
290     }
291
292     /**
293      * Characters are copied from this sequence into the
294      * destination character array <code>dst</code>. The first character to
295      * be copied is at index <code>srcBegin</code>; the last character to
296      * be copied is at index <code>srcEnd-1</code>. The total number of
297      * characters to be copied is <code>srcEnd-srcBegin</code>. The
298      * characters are copied into the subarray of <code>dst</code> starting
299      * at index <code>dstBegin</code> and ending at index:
300      * <p><blockquote><pre>
301      * dstbegin + (srcEnd-srcBegin) - 1
302      * </pre></blockquote>
303      *
304      * @param srcBegin start copying at this offset.
305      * @param srcEnd stop copying at this offset.
306      * @param dst the array to copy the data into.
307      * @param dstBegin offset into <code>dst</code>.
308      * @throws NullPointerException if <code>dst</code> is
309      * <code>null</code>.
310      * @throws IndexOutOfBoundsException if any of the following is true:
311      * <ul>
312      * <li><code>srcBegin</code> is negative
313      * <li><code>dstBegin</code> is negative
314      * <li>the <code>srcBegin</code> argument is greater than
315      * the <code>srcEnd</code> argument.
316      * <li><code>srcEnd</code> is greater than
317      * <code>this.length()</code>.
318      * <li><code>dstBegin+srcEnd-srcBegin</code> is greater than
319      * <code>dst.length</code>
320      * </ul>
321      */

322     public void getChars(int srcBegin, int srcEnd, char dst[],
323                                       int dstBegin)
324     {
325     if (srcBegin < 0)
326         throw new StringIndexOutOfBoundsException JavaDoc(srcBegin);
327     if ((srcEnd < 0) || (srcEnd > count))
328         throw new StringIndexOutOfBoundsException JavaDoc(srcEnd);
329         if (srcBegin > srcEnd)
330             throw new StringIndexOutOfBoundsException JavaDoc("srcBegin > srcEnd");
331     System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
332     }
333
334     /**
335      * The character at the specified index is set to <code>ch</code>. This
336      * sequence is altered to represent a new character sequence that is
337      * identical to the old character sequence, except that it contains the
338      * character <code>ch</code> at position <code>index</code>.
339      * <p>
340      * The index argument must be greater than or equal to
341      * <code>0</code>, and less than the length of this sequence.
342      *
343      * @param index the index of the character to modify.
344      * @param ch the new character.
345      * @throws IndexOutOfBoundsException if <code>index</code> is
346      * negative or greater than or equal to <code>length()</code>.
347      */

348     public void setCharAt(int index, char ch) {
349     if ((index < 0) || (index >= count))
350         throw new StringIndexOutOfBoundsException JavaDoc(index);
351     value[index] = ch;
352     }
353
354     /**
355      * Appends the string representation of the <code>Object</code>
356      * argument.
357      * <p>
358      * The argument is converted to a string as if by the method
359      * <code>String.valueOf</code>, and the characters of that
360      * string are then appended to this sequence.
361      *
362      * @param obj an <code>Object</code>.
363      * @return a reference to this object.
364      */

365     public AbstractStringBuilder JavaDoc append(Object JavaDoc obj) {
366     return append(String.valueOf(obj));
367     }
368
369     /**
370      * Appends the specified string to this character sequence.
371      * <p>
372      * The characters of the <code>String</code> argument are appended, in
373      * order, increasing the length of this sequence by the length of the
374      * argument. If <code>str</code> is <code>null</code>, then the four
375      * characters <code>"null"</code> are appended.
376      * <p>
377      * Let <i>n</i> be the length of this character sequence just prior to
378      * execution of the <code>append</code> method. Then the character at
379      * index <i>k</i> in the new character sequence is equal to the character
380      * at index <i>k</i> in the old character sequence, if <i>k</i> is less
381      * than <i>n</i>; otherwise, it is equal to the character at index
382      * <i>k-n</i> in the argument <code>str</code>.
383      *
384      * @param str a string.
385      * @return a reference to this object.
386      */

387     public AbstractStringBuilder JavaDoc append(String JavaDoc str) {
388     if (str == null) str = "null";
389         int len = str.length();
390     if (len == 0) return this;
391     int newCount = count + len;
392     if (newCount > value.length)
393         expandCapacity(newCount);
394     str.getChars(0, len, value, count);
395     count = newCount;
396     return this;
397     }
398
399     // Documentation in subclasses because of synchro difference
400
public AbstractStringBuilder JavaDoc append(StringBuffer JavaDoc sb) {
401     if (sb == null)
402             return append("null");
403     int len = sb.length();
404     int newCount = count + len;
405     if (newCount > value.length)
406         expandCapacity(newCount);
407     sb.getChars(0, len, value, count);
408     count = newCount;
409     return this;
410     }
411
412     // Documentation in subclasses because of synchro difference
413
public AbstractStringBuilder JavaDoc append(CharSequence JavaDoc s) {
414         if (s == null)
415             s = "null";
416         if (s instanceof String JavaDoc)
417             return this.append((String JavaDoc)s);
418         if (s instanceof StringBuffer JavaDoc)
419             return this.append((StringBuffer JavaDoc)s);
420         return this.append(s, 0, s.length());
421     }
422
423     /**
424      * Appends a subsequence of the specified <code>CharSequence</code> to this
425      * sequence.
426      * <p>
427      * Characters of the argument <code>s</code>, starting at
428      * index <code>start</code>, are appended, in order, to the contents of
429      * this sequence up to the (exclusive) index <code>end</code>. The length
430      * of this sequence is increased by the value of <code>end - start</code>.
431      * <p>
432      * Let <i>n</i> be the length of this character sequence just prior to
433      * execution of the <code>append</code> method. Then the character at
434      * index <i>k</i> in this character sequence becomes equal to the
435      * character at index <i>k</i> in this sequence, if <i>k</i> is less than
436      * <i>n</i>; otherwise, it is equal to the character at index
437      * <i>k+start-n</i> in the argument <code>s</code>.
438      * <p>
439      * If <code>s</code> is <code>null</code>, then this method appends
440      * characters as if the s parameter was a sequence containing the four
441      * characters <code>"null"</code>.
442      *
443      * @param s the sequence to append.
444      * @param start the starting index of the subsequence to be appended.
445      * @param end the end index of the subsequence to be appended.
446      * @return a reference to this object.
447      * @throws IndexOutOfBoundsException if
448      * <code>start</code> or <code>end</code> are negative, or
449      * <code>start</code> is greater than <code>end</code> or
450      * <code>end</code> is greater than <code>s.length()</code>
451      */

452     public AbstractStringBuilder JavaDoc append(CharSequence JavaDoc s, int start, int end) {
453         if (s == null)
454             s = "null";
455     if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
456         throw new IndexOutOfBoundsException JavaDoc(
457                 "start " + start + ", end " + end + ", s.length() "
458                 + s.length());
459     int len = end - start;
460     if (len == 0)
461             return this;
462     int newCount = count + len;
463     if (newCount > value.length)
464         expandCapacity(newCount);
465         for (int i=start; i<end; i++)
466             value[count++] = s.charAt(i);
467         count = newCount;
468     return this;
469     }
470
471     /**
472      * Appends the string representation of the <code>char</code> array
473      * argument to this sequence.
474      * <p>
475      * The characters of the array argument are appended, in order, to
476      * the contents of this sequence. The length of this sequence
477      * increases by the length of the argument.
478      * <p>
479      * The overall effect is exactly as if the argument were converted to
480      * a string by the method {@link String#valueOf(char[])} and the
481      * characters of that string were then {@link #append(String) appended}
482      * to this character sequence.
483      *
484      * @param str the characters to be appended.
485      * @return a reference to this object.
486      */

487     public AbstractStringBuilder JavaDoc append(char str[]) {
488     int newCount = count + str.length;
489     if (newCount > value.length)
490         expandCapacity(newCount);
491         System.arraycopy(str, 0, value, count, str.length);
492         count = newCount;
493         return this;
494     }
495
496     /**
497      * Appends the string representation of a subarray of the
498      * <code>char</code> array argument to this sequence.
499      * <p>
500      * Characters of the <code>char</code> array <code>str</code>, starting at
501      * index <code>offset</code>, are appended, in order, to the contents
502      * of this sequence. The length of this sequence increases
503      * by the value of <code>len</code>.
504      * <p>
505      * The overall effect is exactly as if the arguments were converted to
506      * a string by the method {@link String#valueOf(char[],int,int)} and the
507      * characters of that string were then {@link #append(String) appended}
508      * to this character sequence.
509      *
510      * @param str the characters to be appended.
511      * @param offset the index of the first <code>char</code> to append.
512      * @param len the number of <code>char</code>s to append.
513      * @return a reference to this object.
514      */

515     public AbstractStringBuilder JavaDoc append(char str[], int offset, int len) {
516         int newCount = count + len;
517     if (newCount > value.length)
518         expandCapacity(newCount);
519     System.arraycopy(str, offset, value, count, len);
520     count = newCount;
521     return this;
522     }
523
524     /**
525      * Appends the string representation of the <code>boolean</code>
526      * argument to the sequence.
527      * <p>
528      * The argument is converted to a string as if by the method
529      * <code>String.valueOf</code>, and the characters of that
530      * string are then appended to this sequence.
531      *
532      * @param b a <code>boolean</code>.
533      * @return a reference to this object.
534      */

535     public AbstractStringBuilder JavaDoc append(boolean b) {
536         if (b) {
537             int newCount = count + 4;
538             if (newCount > value.length)
539                 expandCapacity(newCount);
540             value[count++] = 't';
541             value[count++] = 'r';
542             value[count++] = 'u';
543             value[count++] = 'e';
544         } else {
545             int newCount = count + 5;
546             if (newCount > value.length)
547                 expandCapacity(newCount);
548             value[count++] = 'f';
549             value[count++] = 'a';
550             value[count++] = 'l';
551             value[count++] = 's';
552             value[count++] = 'e';
553         }
554     return this;
555     }
556
557     /**
558      * Appends the string representation of the <code>char</code>
559      * argument to this sequence.
560      * <p>
561      * The argument is appended to the contents of this sequence.
562      * The length of this sequence increases by <code>1</code>.
563      * <p>
564      * The overall effect is exactly as if the argument were converted to
565      * a string by the method {@link String#valueOf(char)} and the character
566      * in that string were then {@link #append(String) appended} to this
567      * character sequence.
568      *
569      * @param c a <code>char</code>.
570      * @return a reference to this object.
571      */

572     public AbstractStringBuilder JavaDoc append(char c) {
573         int newCount = count + 1;
574     if (newCount > value.length)
575         expandCapacity(newCount);
576     value[count++] = c;
577     return this;
578     }
579
580     /**
581      * Appends the string representation of the <code>int</code>
582      * argument to this sequence.
583      * <p>
584      * The argument is converted to a string as if by the method
585      * <code>String.valueOf</code>, and the characters of that
586      * string are then appended to this sequence.
587      *
588      * @param i an <code>int</code>.
589      * @return a reference to this object.
590      */

591     public AbstractStringBuilder JavaDoc append(int i) {
592         if (i == Integer.MIN_VALUE) {
593             append("-2147483648");
594             return this;
595         }
596         int appendedLength = (i < 0) ? stringSizeOfInt(-i) + 1
597                                      : stringSizeOfInt(i);
598         int spaceNeeded = count + appendedLength;
599         if (spaceNeeded > value.length)
600             expandCapacity(spaceNeeded);
601     Integer.getChars(i, spaceNeeded, value);
602         count = spaceNeeded;
603         return this;
604     }
605
606     final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
607                                      99999999, 999999999, Integer.MAX_VALUE };
608
609     // Requires positive x
610
static int stringSizeOfInt(int x) {
611         for (int i=0; ; i++)
612             if (x <= sizeTable[i])
613                 return i+1;
614     }
615
616     /**
617      * Appends the string representation of the <code>long</code>
618      * argument to this sequence.
619      * <p>
620      * The argument is converted to a string as if by the method
621      * <code>String.valueOf</code>, and the characters of that
622      * string are then appended to this sequence.
623      *
624      * @param l a <code>long</code>.
625      * @return a reference to this object.
626      */

627     public AbstractStringBuilder JavaDoc append(long l) {
628         if (l == Long.MIN_VALUE) {
629             append("-9223372036854775808");
630             return this;
631         }
632         int appendedLength = (l < 0) ? stringSizeOfLong(-l) + 1
633                                      : stringSizeOfLong(l);
634         int spaceNeeded = count + appendedLength;
635         if (spaceNeeded > value.length)
636             expandCapacity(spaceNeeded);
637     Long.getChars(l, spaceNeeded, value);
638         count = spaceNeeded;
639         return this;
640     }
641
642     // Requires positive x
643
static int stringSizeOfLong(long x) {
644         long p = 10;
645         for (int i=1; i<19; i++) {
646             if (x < p)
647                 return i;
648             p = 10*p;
649         }
650         return 19;
651     }
652
653     /**
654      * Appends the string representation of the <code>float</code>
655      * argument to this sequence.
656      * <p>
657      * The argument is converted to a string as if by the method
658      * <code>String.valueOf</code>, and the characters of that
659      * string are then appended to this string sequence.
660      *
661      * @param f a <code>float</code>.
662      * @return a reference to this object.
663      */

664     public AbstractStringBuilder JavaDoc append(float f) {
665     new FloatingDecimal(f).appendTo(this);
666     return this;
667     }
668
669     /**
670      * Appends the string representation of the <code>double</code>
671      * argument to this sequence.
672      * <p>
673      * The argument is converted to a string as if by the method
674      * <code>String.valueOf</code>, and the characters of that
675      * string are then appended to this sequence.
676      *
677      * @param d a <code>double</code>.
678      * @return a reference to this object.
679      */

680     public AbstractStringBuilder JavaDoc append(double d) {
681     new FloatingDecimal(d).appendTo(this);
682     return this;
683     }
684
685     /**
686      * Removes the characters in a substring of this sequence.
687      * The substring begins at the specified <code>start</code> and extends to
688      * the character at index <code>end - 1</code> or to the end of the
689      * sequence if no such character exists. If
690      * <code>start</code> is equal to <code>end</code>, no changes are made.
691      *
692      * @param start The beginning index, inclusive.
693      * @param end The ending index, exclusive.
694      * @return This object.
695      * @throws StringIndexOutOfBoundsException if <code>start</code>
696      * is negative, greater than <code>length()</code>, or
697      * greater than <code>end</code>.
698      */

699     public AbstractStringBuilder JavaDoc delete(int start, int end) {
700     if (start < 0)
701         throw new StringIndexOutOfBoundsException JavaDoc(start);
702     if (end > count)
703         end = count;
704     if (start > end)
705         throw new StringIndexOutOfBoundsException JavaDoc();
706         int len = end - start;
707         if (len > 0) {
708             System.arraycopy(value, start+len, value, start, count-end);
709             count -= len;
710         }
711         return this;
712     }
713
714     /**
715      * Appends the string representation of the <code>codePoint</code>
716      * argument to this sequence.
717      *
718      * <p> The argument is appended to the contents of this sequence.
719      * The length of this sequence increases by
720      * {@link Character#charCount(int) Character.charCount(codePoint)}.
721      *
722      * <p> The overall effect is exactly as if the argument were
723      * converted to a <code>char</code> array by the method {@link
724      * Character#toChars(int)} and the character in that array were
725      * then {@link #append(char[]) appended} to this character
726      * sequence.
727      *
728      * @param codePoint a Unicode code point
729      * @return a reference to this object.
730      * @exception IllegalArgumentException if the specified
731      * <code>codePoint</code> isn't a valid Unicode code point
732      */

733     public AbstractStringBuilder JavaDoc appendCodePoint(int codePoint) {
734     if (!Character.isValidCodePoint(codePoint)) {
735         throw new IllegalArgumentException JavaDoc();
736     }
737     int n = 1;
738     if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
739         n++;
740     }
741     int newCount = count + n;
742     if (newCount > value.length) {
743         expandCapacity(newCount);
744     }
745     if (n == 1) {
746         value[count++] = (char) codePoint;
747     } else {
748         Character.toSurrogates(codePoint, value, count);
749         count += n;
750     }
751     return this;
752     }
753
754     /**
755      * Removes the <code>char</code> at the specified position in this
756      * sequence. This sequence is shortened by one <code>char</code>.
757      *
758      * <p>Note: If the character at the given index is a supplementary
759      * character, this method does not remove the entire character. If
760      * correct handling of supplementary characters is required,
761      * determine the number of <code>char</code>s to remove by calling
762      * <code>Character.charCount(thisSequence.codePointAt(index))</code>,
763      * where <code>thisSequence</code> is this sequence.
764      *
765      * @param index Index of <code>char</code> to remove
766      * @return This object.
767      * @throws StringIndexOutOfBoundsException if the <code>index</code>
768      * is negative or greater than or equal to
769      * <code>length()</code>.
770      */

771     public AbstractStringBuilder JavaDoc deleteCharAt(int index) {
772         if ((index < 0) || (index >= count))
773         throw new StringIndexOutOfBoundsException JavaDoc(index);
774     System.arraycopy(value, index+1, value, index, count-index-1);
775     count--;
776         return this;
777     }
778
779     /**
780      * Replaces the characters in a substring of this sequence
781      * with characters in the specified <code>String</code>. The substring
782      * begins at the specified <code>start</code> and extends to the character
783      * at index <code>end - 1</code> or to the end of the
784      * sequence if no such character exists. First the
785      * characters in the substring are removed and then the specified
786      * <code>String</code> is inserted at <code>start</code>. (This
787      * sequence will be lengthened to accommodate the
788      * specified String if necessary.)
789      *
790      * @param start The beginning index, inclusive.
791      * @param end The ending index, exclusive.
792      * @param str String that will replace previous contents.
793      * @return This object.
794      * @throws StringIndexOutOfBoundsException if <code>start</code>
795      * is negative, greater than <code>length()</code>, or
796      * greater than <code>end</code>.
797      */

798     public AbstractStringBuilder JavaDoc replace(int start, int end, String JavaDoc str) {
799         if (start < 0)
800         throw new StringIndexOutOfBoundsException JavaDoc(start);
801         if (start > count)
802             throw new StringIndexOutOfBoundsException JavaDoc("start > length()");
803     if (start > end)
804         throw new StringIndexOutOfBoundsException JavaDoc("start > end");
805         if (end > count)
806             end = count;
807
808         if (end > count)
809             end = count;
810     int len = str.length();
811     int newCount = count + len - (end - start);
812     if (newCount > value.length)
813         expandCapacity(newCount);
814
815         System.arraycopy(value, end, value, start + len, count - end);
816         str.getChars(value, start);
817         count = newCount;
818         return this;
819     }
820
821     /**
822      * Returns a new <code>String</code> that contains a subsequence of
823      * characters currently contained in this character sequence. The
824      * substring begins at the specified index and extends to the end of
825      * this sequence.
826      *
827      * @param start The beginning index, inclusive.
828      * @return The new string.
829      * @throws StringIndexOutOfBoundsException if <code>start</code> is
830      * less than zero, or greater than the length of this object.
831      */

832     public String JavaDoc substring(int start) {
833         return substring(start, count);
834     }
835
836     /**
837      * Returns a new character sequence that is a subsequence of this sequence.
838      *
839      * <p> An invocation of this method of the form
840      *
841      * <blockquote><pre>
842      * sb.subSequence(begin,&nbsp;end)</pre></blockquote>
843      *
844      * behaves in exactly the same way as the invocation
845      *
846      * <blockquote><pre>
847      * sb.substring(begin,&nbsp;end)</pre></blockquote>
848      *
849      * This method is provided so that this class can
850      * implement the {@link CharSequence} interface. </p>
851      *
852      * @param start the start index, inclusive.
853      * @param end the end index, exclusive.
854      * @return the specified subsequence.
855      *
856      * @throws IndexOutOfBoundsException
857      * if <tt>start</tt> or <tt>end</tt> are negative,
858      * if <tt>end</tt> is greater than <tt>length()</tt>,
859      * or if <tt>start</tt> is greater than <tt>end</tt>
860      * @spec JSR-51
861      */

862     public CharSequence JavaDoc subSequence(int start, int end) {
863         return substring(start, end);
864     }
865
866     /**
867      * Returns a new <code>String</code> that contains a subsequence of
868      * characters currently contained in this sequence. The
869      * substring begins at the specified <code>start</code> and
870      * extends to the character at index <code>end - 1</code>.
871      *
872      * @param start The beginning index, inclusive.
873      * @param end The ending index, exclusive.
874      * @return The new string.
875      * @throws StringIndexOutOfBoundsException if <code>start</code>
876      * or <code>end</code> are negative or greater than
877      * <code>length()</code>, or <code>start</code> is
878      * greater than <code>end</code>.
879      */

880     public String JavaDoc substring(int start, int end) {
881     if (start < 0)
882         throw new StringIndexOutOfBoundsException JavaDoc(start);
883     if (end > count)
884         throw new StringIndexOutOfBoundsException JavaDoc(end);
885     if (start > end)
886         throw new StringIndexOutOfBoundsException JavaDoc(end - start);
887         return new String JavaDoc(value, start, end - start);
888     }
889
890     /**
891      * Inserts the string representation of a subarray of the <code>str</code>
892      * array argument into this sequence. The subarray begins at the
893      * specified <code>offset</code> and extends <code>len</code> <code>char</code>s.
894      * The characters of the subarray are inserted into this sequence at
895      * the position indicated by <code>index</code>. The length of this
896      * sequence increases by <code>len</code> <code>char</code>s.
897      *
898      * @param index position at which to insert subarray.
899      * @param str A <code>char</code> array.
900      * @param offset the index of the first <code>char</code> in subarray to
901      * be inserted.
902      * @param len the number of <code>char</code>s in the subarray to
903      * be inserted.
904      * @return This object
905      * @throws StringIndexOutOfBoundsException if <code>index</code>
906      * is negative or greater than <code>length()</code>, or
907      * <code>offset</code> or <code>len</code> are negative, or
908      * <code>(offset+len)</code> is greater than
909      * <code>str.length</code>.
910      */

911     public AbstractStringBuilder JavaDoc insert(int index, char str[], int offset,
912                                         int len)
913     {
914         if ((index < 0) || (index > length()))
915         throw new StringIndexOutOfBoundsException JavaDoc(index);
916         if ((offset < 0) || (len < 0) || (offset > str.length - len))
917             throw new StringIndexOutOfBoundsException JavaDoc(
918                 "offset " + offset + ", len " + len + ", str.length "
919