jdk/src/share/classes/java/lang/AbstractStringBuilder.java
changeset 2 90ce3da70b43
child 1223 5c1037124466
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package java.lang;
       
    27 
       
    28 import sun.misc.FloatingDecimal;
       
    29 import java.util.Arrays;
       
    30 
       
    31 /**
       
    32  * A mutable sequence of characters.
       
    33  * <p>
       
    34  * Implements a modifiable string. At any point in time it contains some
       
    35  * particular sequence of characters, but the length and content of the
       
    36  * sequence can be changed through certain method calls.
       
    37  *
       
    38  * @author      Michael McCloskey
       
    39  * @since       1.5
       
    40  */
       
    41 abstract class AbstractStringBuilder implements Appendable, CharSequence {
       
    42     /**
       
    43      * The value is used for character storage.
       
    44      */
       
    45     char value[];
       
    46 
       
    47     /**
       
    48      * The count is the number of characters used.
       
    49      */
       
    50     int count;
       
    51 
       
    52     /**
       
    53      * This no-arg constructor is necessary for serialization of subclasses.
       
    54      */
       
    55     AbstractStringBuilder() {
       
    56     }
       
    57 
       
    58     /**
       
    59      * Creates an AbstractStringBuilder of the specified capacity.
       
    60      */
       
    61     AbstractStringBuilder(int capacity) {
       
    62         value = new char[capacity];
       
    63     }
       
    64 
       
    65     /**
       
    66      * Returns the length (character count).
       
    67      *
       
    68      * @return  the length of the sequence of characters currently
       
    69      *          represented by this object
       
    70      */
       
    71     public int length() {
       
    72         return count;
       
    73     }
       
    74 
       
    75     /**
       
    76      * Returns the current capacity. The capacity is the amount of storage
       
    77      * available for newly inserted characters, beyond which an allocation
       
    78      * will occur.
       
    79      *
       
    80      * @return  the current capacity
       
    81      */
       
    82     public int capacity() {
       
    83         return value.length;
       
    84     }
       
    85 
       
    86     /**
       
    87      * Ensures that the capacity is at least equal to the specified minimum.
       
    88      * If the current capacity is less than the argument, then a new internal
       
    89      * array is allocated with greater capacity. The new capacity is the
       
    90      * larger of:
       
    91      * <ul>
       
    92      * <li>The <code>minimumCapacity</code> argument.
       
    93      * <li>Twice the old capacity, plus <code>2</code>.
       
    94      * </ul>
       
    95      * If the <code>minimumCapacity</code> argument is nonpositive, this
       
    96      * method takes no action and simply returns.
       
    97      *
       
    98      * @param   minimumCapacity   the minimum desired capacity.
       
    99      */
       
   100     public void ensureCapacity(int minimumCapacity) {
       
   101         if (minimumCapacity > value.length) {
       
   102             expandCapacity(minimumCapacity);
       
   103         }
       
   104     }
       
   105 
       
   106     /**
       
   107      * This implements the expansion semantics of ensureCapacity with no
       
   108      * size check or synchronization.
       
   109      */
       
   110     void expandCapacity(int minimumCapacity) {
       
   111         int newCapacity = (value.length + 1) * 2;
       
   112         if (newCapacity < 0) {
       
   113             newCapacity = Integer.MAX_VALUE;
       
   114         } else if (minimumCapacity > newCapacity) {
       
   115             newCapacity = minimumCapacity;
       
   116         }
       
   117         value = Arrays.copyOf(value, newCapacity);
       
   118     }
       
   119 
       
   120     /**
       
   121      * Attempts to reduce storage used for the character sequence.
       
   122      * If the buffer is larger than necessary to hold its current sequence of
       
   123      * characters, then it may be resized to become more space efficient.
       
   124      * Calling this method may, but is not required to, affect the value
       
   125      * returned by a subsequent call to the {@link #capacity()} method.
       
   126      */
       
   127     public void trimToSize() {
       
   128         if (count < value.length) {
       
   129             value = Arrays.copyOf(value, count);
       
   130         }
       
   131     }
       
   132 
       
   133     /**
       
   134      * Sets the length of the character sequence.
       
   135      * The sequence is changed to a new character sequence
       
   136      * whose length is specified by the argument. For every nonnegative
       
   137      * index <i>k</i> less than <code>newLength</code>, the character at
       
   138      * index <i>k</i> in the new character sequence is the same as the
       
   139      * character at index <i>k</i> in the old sequence if <i>k</i> is less
       
   140      * than the length of the old character sequence; otherwise, it is the
       
   141      * null character <code>'&#92;u0000'</code>.
       
   142      *
       
   143      * In other words, if the <code>newLength</code> argument is less than
       
   144      * the current length, the length is changed to the specified length.
       
   145      * <p>
       
   146      * If the <code>newLength</code> argument is greater than or equal
       
   147      * to the current length, sufficient null characters
       
   148      * (<code>'&#92;u0000'</code>) are appended so that
       
   149      * length becomes the <code>newLength</code> argument.
       
   150      * <p>
       
   151      * The <code>newLength</code> argument must be greater than or equal
       
   152      * to <code>0</code>.
       
   153      *
       
   154      * @param      newLength   the new length
       
   155      * @throws     IndexOutOfBoundsException  if the
       
   156      *               <code>newLength</code> argument is negative.
       
   157      */
       
   158     public void setLength(int newLength) {
       
   159         if (newLength < 0)
       
   160             throw new StringIndexOutOfBoundsException(newLength);
       
   161         if (newLength > value.length)
       
   162             expandCapacity(newLength);
       
   163 
       
   164         if (count < newLength) {
       
   165             for (; count < newLength; count++)
       
   166                 value[count] = '\0';
       
   167         } else {
       
   168             count = newLength;
       
   169         }
       
   170     }
       
   171 
       
   172     /**
       
   173      * Returns the <code>char</code> value in this sequence at the specified index.
       
   174      * The first <code>char</code> value is at index <code>0</code>, the next at index
       
   175      * <code>1</code>, and so on, as in array indexing.
       
   176      * <p>
       
   177      * The index argument must be greater than or equal to
       
   178      * <code>0</code>, and less than the length of this sequence.
       
   179      *
       
   180      * <p>If the <code>char</code> value specified by the index is a
       
   181      * <a href="Character.html#unicode">surrogate</a>, the surrogate
       
   182      * value is returned.
       
   183      *
       
   184      * @param      index   the index of the desired <code>char</code> value.
       
   185      * @return     the <code>char</code> value at the specified index.
       
   186      * @throws     IndexOutOfBoundsException  if <code>index</code> is
       
   187      *             negative or greater than or equal to <code>length()</code>.
       
   188      */
       
   189     public char charAt(int index) {
       
   190         if ((index < 0) || (index >= count))
       
   191             throw new StringIndexOutOfBoundsException(index);
       
   192         return value[index];
       
   193     }
       
   194 
       
   195     /**
       
   196      * Returns the character (Unicode code point) at the specified
       
   197      * index. The index refers to <code>char</code> values
       
   198      * (Unicode code units) and ranges from <code>0</code> to
       
   199      * {@link #length()}<code> - 1</code>.
       
   200      *
       
   201      * <p> If the <code>char</code> value specified at the given index
       
   202      * is in the high-surrogate range, the following index is less
       
   203      * than the length of this sequence, and the
       
   204      * <code>char</code> value at the following index is in the
       
   205      * low-surrogate range, then the supplementary code point
       
   206      * corresponding to this surrogate pair is returned. Otherwise,
       
   207      * the <code>char</code> value at the given index is returned.
       
   208      *
       
   209      * @param      index the index to the <code>char</code> values
       
   210      * @return     the code point value of the character at the
       
   211      *             <code>index</code>
       
   212      * @exception  IndexOutOfBoundsException  if the <code>index</code>
       
   213      *             argument is negative or not less than the length of this
       
   214      *             sequence.
       
   215      */
       
   216     public int codePointAt(int index) {
       
   217         if ((index < 0) || (index >= count)) {
       
   218             throw new StringIndexOutOfBoundsException(index);
       
   219         }
       
   220         return Character.codePointAt(value, index);
       
   221     }
       
   222 
       
   223     /**
       
   224      * Returns the character (Unicode code point) before the specified
       
   225      * index. The index refers to <code>char</code> values
       
   226      * (Unicode code units) and ranges from <code>1</code> to {@link
       
   227      * #length()}.
       
   228      *
       
   229      * <p> If the <code>char</code> value at <code>(index - 1)</code>
       
   230      * is in the low-surrogate range, <code>(index - 2)</code> is not
       
   231      * negative, and the <code>char</code> value at <code>(index -
       
   232      * 2)</code> is in the high-surrogate range, then the
       
   233      * supplementary code point value of the surrogate pair is
       
   234      * returned. If the <code>char</code> value at <code>index -
       
   235      * 1</code> is an unpaired low-surrogate or a high-surrogate, the
       
   236      * surrogate value is returned.
       
   237      *
       
   238      * @param     index the index following the code point that should be returned
       
   239      * @return    the Unicode code point value before the given index.
       
   240      * @exception IndexOutOfBoundsException if the <code>index</code>
       
   241      *            argument is less than 1 or greater than the length
       
   242      *            of this sequence.
       
   243      */
       
   244     public int codePointBefore(int index) {
       
   245         int i = index - 1;
       
   246         if ((i < 0) || (i >= count)) {
       
   247             throw new StringIndexOutOfBoundsException(index);
       
   248         }
       
   249         return Character.codePointBefore(value, index);
       
   250     }
       
   251 
       
   252     /**
       
   253      * Returns the number of Unicode code points in the specified text
       
   254      * range of this sequence. The text range begins at the specified
       
   255      * <code>beginIndex</code> and extends to the <code>char</code> at
       
   256      * index <code>endIndex - 1</code>. Thus the length (in
       
   257      * <code>char</code>s) of the text range is
       
   258      * <code>endIndex-beginIndex</code>. Unpaired surrogates within
       
   259      * this sequence count as one code point each.
       
   260      *
       
   261      * @param beginIndex the index to the first <code>char</code> of
       
   262      * the text range.
       
   263      * @param endIndex the index after the last <code>char</code> of
       
   264      * the text range.
       
   265      * @return the number of Unicode code points in the specified text
       
   266      * range
       
   267      * @exception IndexOutOfBoundsException if the
       
   268      * <code>beginIndex</code> is negative, or <code>endIndex</code>
       
   269      * is larger than the length of this sequence, or
       
   270      * <code>beginIndex</code> is larger than <code>endIndex</code>.
       
   271      */
       
   272     public int codePointCount(int beginIndex, int endIndex) {
       
   273         if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
       
   274             throw new IndexOutOfBoundsException();
       
   275         }
       
   276         return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex);
       
   277     }
       
   278 
       
   279     /**
       
   280      * Returns the index within this sequence that is offset from the
       
   281      * given <code>index</code> by <code>codePointOffset</code> code
       
   282      * points. Unpaired surrogates within the text range given by
       
   283      * <code>index</code> and <code>codePointOffset</code> count as
       
   284      * one code point each.
       
   285      *
       
   286      * @param index the index to be offset
       
   287      * @param codePointOffset the offset in code points
       
   288      * @return the index within this sequence
       
   289      * @exception IndexOutOfBoundsException if <code>index</code>
       
   290      *   is negative or larger then the length of this sequence,
       
   291      *   or if <code>codePointOffset</code> is positive and the subsequence
       
   292      *   starting with <code>index</code> has fewer than
       
   293      *   <code>codePointOffset</code> code points,
       
   294      *   or if <code>codePointOffset</code> is negative and the subsequence
       
   295      *   before <code>index</code> has fewer than the absolute value of
       
   296      *   <code>codePointOffset</code> code points.
       
   297      */
       
   298     public int offsetByCodePoints(int index, int codePointOffset) {
       
   299         if (index < 0 || index > count) {
       
   300             throw new IndexOutOfBoundsException();
       
   301         }
       
   302         return Character.offsetByCodePointsImpl(value, 0, count,
       
   303                                                 index, codePointOffset);
       
   304     }
       
   305 
       
   306     /**
       
   307      * Characters are copied from this sequence into the
       
   308      * destination character array <code>dst</code>. The first character to
       
   309      * be copied is at index <code>srcBegin</code>; the last character to
       
   310      * be copied is at index <code>srcEnd-1</code>. The total number of
       
   311      * characters to be copied is <code>srcEnd-srcBegin</code>. The
       
   312      * characters are copied into the subarray of <code>dst</code> starting
       
   313      * at index <code>dstBegin</code> and ending at index:
       
   314      * <p><blockquote><pre>
       
   315      * dstbegin + (srcEnd-srcBegin) - 1
       
   316      * </pre></blockquote>
       
   317      *
       
   318      * @param      srcBegin   start copying at this offset.
       
   319      * @param      srcEnd     stop copying at this offset.
       
   320      * @param      dst        the array to copy the data into.
       
   321      * @param      dstBegin   offset into <code>dst</code>.
       
   322      * @throws     NullPointerException if <code>dst</code> is
       
   323      *             <code>null</code>.
       
   324      * @throws     IndexOutOfBoundsException  if any of the following is true:
       
   325      *             <ul>
       
   326      *             <li><code>srcBegin</code> is negative
       
   327      *             <li><code>dstBegin</code> is negative
       
   328      *             <li>the <code>srcBegin</code> argument is greater than
       
   329      *             the <code>srcEnd</code> argument.
       
   330      *             <li><code>srcEnd</code> is greater than
       
   331      *             <code>this.length()</code>.
       
   332      *             <li><code>dstBegin+srcEnd-srcBegin</code> is greater than
       
   333      *             <code>dst.length</code>
       
   334      *             </ul>
       
   335      */
       
   336     public void getChars(int srcBegin, int srcEnd, char dst[],
       
   337                                       int dstBegin)
       
   338     {
       
   339         if (srcBegin < 0)
       
   340             throw new StringIndexOutOfBoundsException(srcBegin);
       
   341         if ((srcEnd < 0) || (srcEnd > count))
       
   342             throw new StringIndexOutOfBoundsException(srcEnd);
       
   343         if (srcBegin > srcEnd)
       
   344             throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
       
   345         System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
       
   346     }
       
   347 
       
   348     /**
       
   349      * The character at the specified index is set to <code>ch</code>. This
       
   350      * sequence is altered to represent a new character sequence that is
       
   351      * identical to the old character sequence, except that it contains the
       
   352      * character <code>ch</code> at position <code>index</code>.
       
   353      * <p>
       
   354      * The index argument must be greater than or equal to
       
   355      * <code>0</code>, and less than the length of this sequence.
       
   356      *
       
   357      * @param      index   the index of the character to modify.
       
   358      * @param      ch      the new character.
       
   359      * @throws     IndexOutOfBoundsException  if <code>index</code> is
       
   360      *             negative or greater than or equal to <code>length()</code>.
       
   361      */
       
   362     public void setCharAt(int index, char ch) {
       
   363         if ((index < 0) || (index >= count))
       
   364             throw new StringIndexOutOfBoundsException(index);
       
   365         value[index] = ch;
       
   366     }
       
   367 
       
   368     /**
       
   369      * Appends the string representation of the <code>Object</code>
       
   370      * argument.
       
   371      * <p>
       
   372      * The argument is converted to a string as if by the method
       
   373      * <code>String.valueOf</code>, and the characters of that
       
   374      * string are then appended to this sequence.
       
   375      *
       
   376      * @param   obj   an <code>Object</code>.
       
   377      * @return  a reference to this object.
       
   378      */
       
   379     public AbstractStringBuilder append(Object obj) {
       
   380         return append(String.valueOf(obj));
       
   381     }
       
   382 
       
   383     /**
       
   384      * Appends the specified string to this character sequence.
       
   385      * <p>
       
   386      * The characters of the <code>String</code> argument are appended, in
       
   387      * order, increasing the length of this sequence by the length of the
       
   388      * argument. If <code>str</code> is <code>null</code>, then the four
       
   389      * characters <code>"null"</code> are appended.
       
   390      * <p>
       
   391      * Let <i>n</i> be the length of this character sequence just prior to
       
   392      * execution of the <code>append</code> method. Then the character at
       
   393      * index <i>k</i> in the new character sequence is equal to the character
       
   394      * at index <i>k</i> in the old character sequence, if <i>k</i> is less
       
   395      * than <i>n</i>; otherwise, it is equal to the character at index
       
   396      * <i>k-n</i> in the argument <code>str</code>.
       
   397      *
       
   398      * @param   str   a string.
       
   399      * @return  a reference to this object.
       
   400      */
       
   401     public AbstractStringBuilder append(String str) {
       
   402         if (str == null) str = "null";
       
   403         int len = str.length();
       
   404         if (len == 0) return this;
       
   405         int newCount = count + len;
       
   406         if (newCount > value.length)
       
   407             expandCapacity(newCount);
       
   408         str.getChars(0, len, value, count);
       
   409         count = newCount;
       
   410         return this;
       
   411     }
       
   412 
       
   413     // Documentation in subclasses because of synchro difference
       
   414     public AbstractStringBuilder append(StringBuffer sb) {
       
   415         if (sb == null)
       
   416             return append("null");
       
   417         int len = sb.length();
       
   418         int newCount = count + len;
       
   419         if (newCount > value.length)
       
   420             expandCapacity(newCount);
       
   421         sb.getChars(0, len, value, count);
       
   422         count = newCount;
       
   423         return this;
       
   424     }
       
   425 
       
   426     // Documentation in subclasses because of synchro difference
       
   427     public AbstractStringBuilder append(CharSequence s) {
       
   428         if (s == null)
       
   429             s = "null";
       
   430         if (s instanceof String)
       
   431             return this.append((String)s);
       
   432         if (s instanceof StringBuffer)
       
   433             return this.append((StringBuffer)s);
       
   434         return this.append(s, 0, s.length());
       
   435     }
       
   436 
       
   437     /**
       
   438      * Appends a subsequence of the specified <code>CharSequence</code> to this
       
   439      * sequence.
       
   440      * <p>
       
   441      * Characters of the argument <code>s</code>, starting at
       
   442      * index <code>start</code>, are appended, in order, to the contents of
       
   443      * this sequence up to the (exclusive) index <code>end</code>. The length
       
   444      * of this sequence is increased by the value of <code>end - start</code>.
       
   445      * <p>
       
   446      * Let <i>n</i> be the length of this character sequence just prior to
       
   447      * execution of the <code>append</code> method. Then the character at
       
   448      * index <i>k</i> in this character sequence becomes equal to the
       
   449      * character at index <i>k</i> in this sequence, if <i>k</i> is less than
       
   450      * <i>n</i>; otherwise, it is equal to the character at index
       
   451      * <i>k+start-n</i> in the argument <code>s</code>.
       
   452      * <p>
       
   453      * If <code>s</code> is <code>null</code>, then this method appends
       
   454      * characters as if the s parameter was a sequence containing the four
       
   455      * characters <code>"null"</code>.
       
   456      *
       
   457      * @param   s the sequence to append.
       
   458      * @param   start   the starting index of the subsequence to be appended.
       
   459      * @param   end     the end index of the subsequence to be appended.
       
   460      * @return  a reference to this object.
       
   461      * @throws     IndexOutOfBoundsException if
       
   462      *                  <code>start</code> or <code>end</code> are negative, or
       
   463      *             <code>start</code> is greater than <code>end</code> or
       
   464      *             <code>end</code> is greater than <code>s.length()</code>
       
   465      */
       
   466     public AbstractStringBuilder append(CharSequence s, int start, int end) {
       
   467         if (s == null)
       
   468             s = "null";
       
   469         if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
       
   470             throw new IndexOutOfBoundsException(
       
   471                 "start " + start + ", end " + end + ", s.length() "
       
   472                 + s.length());
       
   473         int len = end - start;
       
   474         if (len == 0)
       
   475             return this;
       
   476         int newCount = count + len;
       
   477         if (newCount > value.length)
       
   478             expandCapacity(newCount);
       
   479         for (int i=start; i<end; i++)
       
   480             value[count++] = s.charAt(i);
       
   481         count = newCount;
       
   482         return this;
       
   483     }
       
   484 
       
   485     /**
       
   486      * Appends the string representation of the <code>char</code> array
       
   487      * argument to this sequence.
       
   488      * <p>
       
   489      * The characters of the array argument are appended, in order, to
       
   490      * the contents of this sequence. The length of this sequence
       
   491      * increases by the length of the argument.
       
   492      * <p>
       
   493      * The overall effect is exactly as if the argument were converted to
       
   494      * a string by the method {@link String#valueOf(char[])} and the
       
   495      * characters of that string were then {@link #append(String) appended}
       
   496      * to this character sequence.
       
   497      *
       
   498      * @param   str   the characters to be appended.
       
   499      * @return  a reference to this object.
       
   500      */
       
   501     public AbstractStringBuilder append(char str[]) {
       
   502         int newCount = count + str.length;
       
   503         if (newCount > value.length)
       
   504             expandCapacity(newCount);
       
   505         System.arraycopy(str, 0, value, count, str.length);
       
   506         count = newCount;
       
   507         return this;
       
   508     }
       
   509 
       
   510     /**
       
   511      * Appends the string representation of a subarray of the
       
   512      * <code>char</code> array argument to this sequence.
       
   513      * <p>
       
   514      * Characters of the <code>char</code> array <code>str</code>, starting at
       
   515      * index <code>offset</code>, are appended, in order, to the contents
       
   516      * of this sequence. The length of this sequence increases
       
   517      * by the value of <code>len</code>.
       
   518      * <p>
       
   519      * The overall effect is exactly as if the arguments were converted to
       
   520      * a string by the method {@link String#valueOf(char[],int,int)} and the
       
   521      * characters of that string were then {@link #append(String) appended}
       
   522      * to this character sequence.
       
   523      *
       
   524      * @param   str      the characters to be appended.
       
   525      * @param   offset   the index of the first <code>char</code> to append.
       
   526      * @param   len      the number of <code>char</code>s to append.
       
   527      * @return  a reference to this object.
       
   528      */
       
   529     public AbstractStringBuilder append(char str[], int offset, int len) {
       
   530         int newCount = count + len;
       
   531         if (newCount > value.length)
       
   532             expandCapacity(newCount);
       
   533         System.arraycopy(str, offset, value, count, len);
       
   534         count = newCount;
       
   535         return this;
       
   536     }
       
   537 
       
   538     /**
       
   539      * Appends the string representation of the <code>boolean</code>
       
   540      * argument to the sequence.
       
   541      * <p>
       
   542      * The argument is converted to a string as if by the method
       
   543      * <code>String.valueOf</code>, and the characters of that
       
   544      * string are then appended to this sequence.
       
   545      *
       
   546      * @param   b   a <code>boolean</code>.
       
   547      * @return  a reference to this object.
       
   548      */
       
   549     public AbstractStringBuilder append(boolean b) {
       
   550         if (b) {
       
   551             int newCount = count + 4;
       
   552             if (newCount > value.length)
       
   553                 expandCapacity(newCount);
       
   554             value[count++] = 't';
       
   555             value[count++] = 'r';
       
   556             value[count++] = 'u';
       
   557             value[count++] = 'e';
       
   558         } else {
       
   559             int newCount = count + 5;
       
   560             if (newCount > value.length)
       
   561                 expandCapacity(newCount);
       
   562             value[count++] = 'f';
       
   563             value[count++] = 'a';
       
   564             value[count++] = 'l';
       
   565             value[count++] = 's';
       
   566             value[count++] = 'e';
       
   567         }
       
   568         return this;
       
   569     }
       
   570 
       
   571     /**
       
   572      * Appends the string representation of the <code>char</code>
       
   573      * argument to this sequence.
       
   574      * <p>
       
   575      * The argument is appended to the contents of this sequence.
       
   576      * The length of this sequence increases by <code>1</code>.
       
   577      * <p>
       
   578      * The overall effect is exactly as if the argument were converted to
       
   579      * a string by the method {@link String#valueOf(char)} and the character
       
   580      * in that string were then {@link #append(String) appended} to this
       
   581      * character sequence.
       
   582      *
       
   583      * @param   c   a <code>char</code>.
       
   584      * @return  a reference to this object.
       
   585      */
       
   586     public AbstractStringBuilder append(char c) {
       
   587         int newCount = count + 1;
       
   588         if (newCount > value.length)
       
   589             expandCapacity(newCount);
       
   590         value[count++] = c;
       
   591         return this;
       
   592     }
       
   593 
       
   594     /**
       
   595      * Appends the string representation of the <code>int</code>
       
   596      * argument to this sequence.
       
   597      * <p>
       
   598      * The argument is converted to a string as if by the method
       
   599      * <code>String.valueOf</code>, and the characters of that
       
   600      * string are then appended to this sequence.
       
   601      *
       
   602      * @param   i   an <code>int</code>.
       
   603      * @return  a reference to this object.
       
   604      */
       
   605     public AbstractStringBuilder append(int i) {
       
   606         if (i == Integer.MIN_VALUE) {
       
   607             append("-2147483648");
       
   608             return this;
       
   609         }
       
   610         int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
       
   611                                      : Integer.stringSize(i);
       
   612         int spaceNeeded = count + appendedLength;
       
   613         if (spaceNeeded > value.length)
       
   614             expandCapacity(spaceNeeded);
       
   615         Integer.getChars(i, spaceNeeded, value);
       
   616         count = spaceNeeded;
       
   617         return this;
       
   618     }
       
   619 
       
   620     /**
       
   621      * Appends the string representation of the <code>long</code>
       
   622      * argument to this sequence.
       
   623      * <p>
       
   624      * The argument is converted to a string as if by the method
       
   625      * <code>String.valueOf</code>, and the characters of that
       
   626      * string are then appended to this sequence.
       
   627      *
       
   628      * @param   l   a <code>long</code>.
       
   629      * @return  a reference to this object.
       
   630      */
       
   631     public AbstractStringBuilder append(long l) {
       
   632         if (l == Long.MIN_VALUE) {
       
   633             append("-9223372036854775808");
       
   634             return this;
       
   635         }
       
   636         int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
       
   637                                      : Long.stringSize(l);
       
   638         int spaceNeeded = count + appendedLength;
       
   639         if (spaceNeeded > value.length)
       
   640             expandCapacity(spaceNeeded);
       
   641         Long.getChars(l, spaceNeeded, value);
       
   642         count = spaceNeeded;
       
   643         return this;
       
   644     }
       
   645 
       
   646     /**
       
   647      * Appends the string representation of the <code>float</code>
       
   648      * argument to this sequence.
       
   649      * <p>
       
   650      * The argument is converted to a string as if by the method
       
   651      * <code>String.valueOf</code>, and the characters of that
       
   652      * string are then appended to this string sequence.
       
   653      *
       
   654      * @param   f   a <code>float</code>.
       
   655      * @return  a reference to this object.
       
   656      */
       
   657     public AbstractStringBuilder append(float f) {
       
   658         new FloatingDecimal(f).appendTo(this);
       
   659         return this;
       
   660     }
       
   661 
       
   662     /**
       
   663      * Appends the string representation of the <code>double</code>
       
   664      * argument to this sequence.
       
   665      * <p>
       
   666      * The argument is converted to a string as if by the method
       
   667      * <code>String.valueOf</code>, and the characters of that
       
   668      * string are then appended to this sequence.
       
   669      *
       
   670      * @param   d   a <code>double</code>.
       
   671      * @return  a reference to this object.
       
   672      */
       
   673     public AbstractStringBuilder append(double d) {
       
   674         new FloatingDecimal(d).appendTo(this);
       
   675         return this;
       
   676     }
       
   677 
       
   678     /**
       
   679      * Removes the characters in a substring of this sequence.
       
   680      * The substring begins at the specified <code>start</code> and extends to
       
   681      * the character at index <code>end - 1</code> or to the end of the
       
   682      * sequence if no such character exists. If
       
   683      * <code>start</code> is equal to <code>end</code>, no changes are made.
       
   684      *
       
   685      * @param      start  The beginning index, inclusive.
       
   686      * @param      end    The ending index, exclusive.
       
   687      * @return     This object.
       
   688      * @throws     StringIndexOutOfBoundsException  if <code>start</code>
       
   689      *             is negative, greater than <code>length()</code>, or
       
   690      *             greater than <code>end</code>.
       
   691      */
       
   692     public AbstractStringBuilder delete(int start, int end) {
       
   693         if (start < 0)
       
   694             throw new StringIndexOutOfBoundsException(start);
       
   695         if (end > count)
       
   696             end = count;
       
   697         if (start > end)
       
   698             throw new StringIndexOutOfBoundsException();
       
   699         int len = end - start;
       
   700         if (len > 0) {
       
   701             System.arraycopy(value, start+len, value, start, count-end);
       
   702             count -= len;
       
   703         }
       
   704         return this;
       
   705     }
       
   706 
       
   707     /**
       
   708      * Appends the string representation of the <code>codePoint</code>
       
   709      * argument to this sequence.
       
   710      *
       
   711      * <p> The argument is appended to the contents of this sequence.
       
   712      * The length of this sequence increases by
       
   713      * {@link Character#charCount(int) Character.charCount(codePoint)}.
       
   714      *
       
   715      * <p> The overall effect is exactly as if the argument were
       
   716      * converted to a <code>char</code> array by the method {@link
       
   717      * Character#toChars(int)} and the character in that array were
       
   718      * then {@link #append(char[]) appended} to this character
       
   719      * sequence.
       
   720      *
       
   721      * @param   codePoint   a Unicode code point
       
   722      * @return  a reference to this object.
       
   723      * @exception IllegalArgumentException if the specified
       
   724      * <code>codePoint</code> isn't a valid Unicode code point
       
   725      */
       
   726     public AbstractStringBuilder appendCodePoint(int codePoint) {
       
   727         if (!Character.isValidCodePoint(codePoint)) {
       
   728             throw new IllegalArgumentException();
       
   729         }
       
   730         int n = 1;
       
   731         if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
       
   732             n++;
       
   733         }
       
   734         int newCount = count + n;
       
   735         if (newCount > value.length) {
       
   736             expandCapacity(newCount);
       
   737         }
       
   738         if (n == 1) {
       
   739             value[count++] = (char) codePoint;
       
   740         } else {
       
   741             Character.toSurrogates(codePoint, value, count);
       
   742             count += n;
       
   743         }
       
   744         return this;
       
   745     }
       
   746 
       
   747     /**
       
   748      * Removes the <code>char</code> at the specified position in this
       
   749      * sequence. This sequence is shortened by one <code>char</code>.
       
   750      *
       
   751      * <p>Note: If the character at the given index is a supplementary
       
   752      * character, this method does not remove the entire character. If
       
   753      * correct handling of supplementary characters is required,
       
   754      * determine the number of <code>char</code>s to remove by calling
       
   755      * <code>Character.charCount(thisSequence.codePointAt(index))</code>,
       
   756      * where <code>thisSequence</code> is this sequence.
       
   757      *
       
   758      * @param       index  Index of <code>char</code> to remove
       
   759      * @return      This object.
       
   760      * @throws      StringIndexOutOfBoundsException  if the <code>index</code>
       
   761      *              is negative or greater than or equal to
       
   762      *              <code>length()</code>.
       
   763      */
       
   764     public AbstractStringBuilder deleteCharAt(int index) {
       
   765         if ((index < 0) || (index >= count))
       
   766             throw new StringIndexOutOfBoundsException(index);
       
   767         System.arraycopy(value, index+1, value, index, count-index-1);
       
   768         count--;
       
   769         return this;
       
   770     }
       
   771 
       
   772     /**
       
   773      * Replaces the characters in a substring of this sequence
       
   774      * with characters in the specified <code>String</code>. The substring
       
   775      * begins at the specified <code>start</code> and extends to the character
       
   776      * at index <code>end - 1</code> or to the end of the
       
   777      * sequence if no such character exists. First the
       
   778      * characters in the substring are removed and then the specified
       
   779      * <code>String</code> is inserted at <code>start</code>. (This
       
   780      * sequence will be lengthened to accommodate the
       
   781      * specified String if necessary.)
       
   782      *
       
   783      * @param      start    The beginning index, inclusive.
       
   784      * @param      end      The ending index, exclusive.
       
   785      * @param      str   String that will replace previous contents.
       
   786      * @return     This object.
       
   787      * @throws     StringIndexOutOfBoundsException  if <code>start</code>
       
   788      *             is negative, greater than <code>length()</code>, or
       
   789      *             greater than <code>end</code>.
       
   790      */
       
   791     public AbstractStringBuilder replace(int start, int end, String str) {
       
   792         if (start < 0)
       
   793             throw new StringIndexOutOfBoundsException(start);
       
   794         if (start > count)
       
   795             throw new StringIndexOutOfBoundsException("start > length()");
       
   796         if (start > end)
       
   797             throw new StringIndexOutOfBoundsException("start > end");
       
   798 
       
   799         if (end > count)
       
   800             end = count;
       
   801         int len = str.length();
       
   802         int newCount = count + len - (end - start);
       
   803         if (newCount > value.length)
       
   804             expandCapacity(newCount);
       
   805 
       
   806         System.arraycopy(value, end, value, start + len, count - end);
       
   807         str.getChars(value, start);
       
   808         count = newCount;
       
   809         return this;
       
   810     }
       
   811 
       
   812     /**
       
   813      * Returns a new <code>String</code> that contains a subsequence of
       
   814      * characters currently contained in this character sequence. The
       
   815      * substring begins at the specified index and extends to the end of
       
   816      * this sequence.
       
   817      *
       
   818      * @param      start    The beginning index, inclusive.
       
   819      * @return     The new string.
       
   820      * @throws     StringIndexOutOfBoundsException  if <code>start</code> is
       
   821      *             less than zero, or greater than the length of this object.
       
   822      */
       
   823     public String substring(int start) {
       
   824         return substring(start, count);
       
   825     }
       
   826 
       
   827     /**
       
   828      * Returns a new character sequence that is a subsequence of this sequence.
       
   829      *
       
   830      * <p> An invocation of this method of the form
       
   831      *
       
   832      * <blockquote><pre>
       
   833      * sb.subSequence(begin,&nbsp;end)</pre></blockquote>
       
   834      *
       
   835      * behaves in exactly the same way as the invocation
       
   836      *
       
   837      * <blockquote><pre>
       
   838      * sb.substring(begin,&nbsp;end)</pre></blockquote>
       
   839      *
       
   840      * This method is provided so that this class can
       
   841      * implement the {@link CharSequence} interface. </p>
       
   842      *
       
   843      * @param      start   the start index, inclusive.
       
   844      * @param      end     the end index, exclusive.
       
   845      * @return     the specified subsequence.
       
   846      *
       
   847      * @throws  IndexOutOfBoundsException
       
   848      *          if <tt>start</tt> or <tt>end</tt> are negative,
       
   849      *          if <tt>end</tt> is greater than <tt>length()</tt>,
       
   850      *          or if <tt>start</tt> is greater than <tt>end</tt>
       
   851      * @spec JSR-51
       
   852      */
       
   853     public CharSequence subSequence(int start, int end) {
       
   854         return substring(start, end);
       
   855     }
       
   856 
       
   857     /**
       
   858      * Returns a new <code>String</code> that contains a subsequence of
       
   859      * characters currently contained in this sequence. The
       
   860      * substring begins at the specified <code>start</code> and
       
   861      * extends to the character at index <code>end - 1</code>.
       
   862      *
       
   863      * @param      start    The beginning index, inclusive.
       
   864      * @param      end      The ending index, exclusive.
       
   865      * @return     The new string.
       
   866      * @throws     StringIndexOutOfBoundsException  if <code>start</code>
       
   867      *             or <code>end</code> are negative or greater than
       
   868      *             <code>length()</code>, or <code>start</code> is
       
   869      *             greater than <code>end</code>.
       
   870      */
       
   871     public String substring(int start, int end) {
       
   872         if (start < 0)
       
   873             throw new StringIndexOutOfBoundsException(start);
       
   874         if (end > count)
       
   875             throw new StringIndexOutOfBoundsException(end);
       
   876         if (start > end)
       
   877             throw new StringIndexOutOfBoundsException(end - start);
       
   878         return new String(value, start, end - start);
       
   879     }
       
   880 
       
   881     /**
       
   882      * Inserts the string representation of a subarray of the <code>str</code>
       
   883      * array argument into this sequence. The subarray begins at the
       
   884      * specified <code>offset</code> and extends <code>len</code> <code>char</code>s.
       
   885      * The characters of the subarray are inserted into this sequence at
       
   886      * the position indicated by <code>index</code>. The length of this
       
   887      * sequence increases by <code>len</code> <code>char</code>s.
       
   888      *
       
   889      * @param      index    position at which to insert subarray.
       
   890      * @param      str       A <code>char</code> array.
       
   891      * @param      offset   the index of the first <code>char</code> in subarray to
       
   892      *             be inserted.
       
   893      * @param      len      the number of <code>char</code>s in the subarray to
       
   894      *             be inserted.
       
   895      * @return     This object
       
   896      * @throws     StringIndexOutOfBoundsException  if <code>index</code>
       
   897      *             is negative or greater than <code>length()</code>, or
       
   898      *             <code>offset</code> or <code>len</code> are negative, or
       
   899      *             <code>(offset+len)</code> is greater than
       
   900      *             <code>str.length</code>.
       
   901      */
       
   902     public AbstractStringBuilder insert(int index, char str[], int offset,
       
   903                                         int len)
       
   904     {
       
   905         if ((index < 0) || (index > length()))
       
   906             throw new StringIndexOutOfBoundsException(index);
       
   907         if ((offset < 0) || (len < 0) || (offset > str.length - len))
       
   908             throw new StringIndexOutOfBoundsException(
       
   909                 "offset " + offset + ", len " + len + ", str.length "
       
   910                 + str.length);
       
   911         int newCount = count + len;
       
   912         if (newCount > value.length)
       
   913             expandCapacity(newCount);
       
   914         System.arraycopy(value, index, value, index + len, count - index);
       
   915         System.arraycopy(str, offset, value, index, len);
       
   916         count = newCount;
       
   917         return this;
       
   918     }
       
   919 
       
   920     /**
       
   921      * Inserts the string representation of the <code>Object</code>
       
   922      * argument into this character sequence.
       
   923      * <p>
       
   924      * The second argument is converted to a string as if by the method
       
   925      * <code>String.valueOf</code>, and the characters of that
       
   926      * string are then inserted into this sequence at the indicated
       
   927      * offset.
       
   928      * <p>
       
   929      * The offset argument must be greater than or equal to
       
   930      * <code>0</code>, and less than or equal to the length of this
       
   931      * sequence.
       
   932      *
       
   933      * @param      offset   the offset.
       
   934      * @param      obj      an <code>Object</code>.
       
   935      * @return     a reference to this object.
       
   936      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
       
   937      */
       
   938     public AbstractStringBuilder insert(int offset, Object obj) {
       
   939         return insert(offset, String.valueOf(obj));
       
   940     }
       
   941 
       
   942     /**
       
   943      * Inserts the string into this character sequence.
       
   944      * <p>
       
   945      * The characters of the <code>String</code> argument are inserted, in
       
   946      * order, into this sequence at the indicated offset, moving up any
       
   947      * characters originally above that position and increasing the length
       
   948      * of this sequence by the length of the argument. If
       
   949      * <code>str</code> is <code>null</code>, then the four characters
       
   950      * <code>"null"</code> are inserted into this sequence.
       
   951      * <p>
       
   952      * The character at index <i>k</i> in the new character sequence is
       
   953      * equal to:
       
   954      * <ul>
       
   955      * <li>the character at index <i>k</i> in the old character sequence, if
       
   956      * <i>k</i> is less than <code>offset</code>
       
   957      * <li>the character at index <i>k</i><code>-offset</code> in the
       
   958      * argument <code>str</code>, if <i>k</i> is not less than
       
   959      * <code>offset</code> but is less than <code>offset+str.length()</code>
       
   960      * <li>the character at index <i>k</i><code>-str.length()</code> in the
       
   961      * old character sequence, if <i>k</i> is not less than
       
   962      * <code>offset+str.length()</code>
       
   963      * </ul><p>
       
   964      * The offset argument must be greater than or equal to
       
   965      * <code>0</code>, and less than or equal to the length of this
       
   966      * sequence.
       
   967      *
       
   968      * @param      offset   the offset.
       
   969      * @param      str      a string.
       
   970      * @return     a reference to this object.
       
   971      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
       
   972      */
       
   973     public AbstractStringBuilder insert(int offset, String str) {
       
   974         if ((offset < 0) || (offset > length()))
       
   975             throw new StringIndexOutOfBoundsException(offset);
       
   976         if (str == null)
       
   977             str = "null";
       
   978         int len = str.length();
       
   979         int newCount = count + len;
       
   980         if (newCount > value.length)
       
   981             expandCapacity(newCount);
       
   982         System.arraycopy(value, offset, value, offset + len, count - offset);
       
   983         str.getChars(value, offset);
       
   984         count = newCount;
       
   985         return this;
       
   986     }
       
   987 
       
   988     /**
       
   989      * Inserts the string representation of the <code>char</code> array
       
   990      * argument into this sequence.
       
   991      * <p>
       
   992      * The characters of the array argument are inserted into the
       
   993      * contents of this sequence at the position indicated by
       
   994      * <code>offset</code>. The length of this sequence increases by
       
   995      * the length of the argument.
       
   996      * <p>
       
   997      * The overall effect is exactly as if the argument were converted to
       
   998      * a string by the method {@link String#valueOf(char[])} and the
       
   999      * characters of that string were then
       
  1000      * {@link #insert(int,String) inserted} into this
       
  1001      * character sequence at the position indicated by
       
  1002      * <code>offset</code>.
       
  1003      *
       
  1004      * @param      offset   the offset.
       
  1005      * @param      str      a character array.
       
  1006      * @return     a reference to this object.
       
  1007      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
       
  1008      */
       
  1009     public AbstractStringBuilder insert(int offset, char str[]) {
       
  1010         if ((offset < 0) || (offset > length()))
       
  1011             throw new StringIndexOutOfBoundsException(offset);
       
  1012         int len = str.length;
       
  1013         int newCount = count + len;
       
  1014         if (newCount > value.length)
       
  1015             expandCapacity(newCount);
       
  1016         System.arraycopy(value, offset, value, offset + len, count - offset);
       
  1017         System.arraycopy(str, 0, value, offset, len);
       
  1018         count = newCount;
       
  1019         return this;
       
  1020     }
       
  1021 
       
  1022     /**
       
  1023      * Inserts the specified <code>CharSequence</code> into this sequence.
       
  1024      * <p>
       
  1025      * The characters of the <code>CharSequence</code> argument are inserted,
       
  1026      * in order, into this sequence at the indicated offset, moving up
       
  1027      * any characters originally above that position and increasing the length
       
  1028      * of this sequence by the length of the argument s.
       
  1029      * <p>
       
  1030      * The result of this method is exactly the same as if it were an
       
  1031      * invocation of this object's insert(dstOffset, s, 0, s.length()) method.
       
  1032      *
       
  1033      * <p>If <code>s</code> is <code>null</code>, then the four characters
       
  1034      * <code>"null"</code> are inserted into this sequence.
       
  1035      *
       
  1036      * @param      dstOffset   the offset.
       
  1037      * @param      s the sequence to be inserted
       
  1038      * @return     a reference to this object.
       
  1039      * @throws     IndexOutOfBoundsException  if the offset is invalid.
       
  1040      */
       
  1041     public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
       
  1042         if (s == null)
       
  1043             s = "null";
       
  1044         if (s instanceof String)
       
  1045             return this.insert(dstOffset, (String)s);
       
  1046         return this.insert(dstOffset, s, 0, s.length());
       
  1047     }
       
  1048 
       
  1049     /**
       
  1050      * Inserts a subsequence of the specified <code>CharSequence</code> into
       
  1051      * this sequence.
       
  1052      * <p>
       
  1053      * The subsequence of the argument <code>s</code> specified by
       
  1054      * <code>start</code> and <code>end</code> are inserted,
       
  1055      * in order, into this sequence at the specified destination offset, moving
       
  1056      * up any characters originally above that position. The length of this
       
  1057      * sequence is increased by <code>end - start</code>.
       
  1058      * <p>
       
  1059      * The character at index <i>k</i> in this sequence becomes equal to:
       
  1060      * <ul>
       
  1061      * <li>the character at index <i>k</i> in this sequence, if
       
  1062      * <i>k</i> is less than <code>dstOffset</code>
       
  1063      * <li>the character at index <i>k</i><code>+start-dstOffset</code> in
       
  1064      * the argument <code>s</code>, if <i>k</i> is greater than or equal to
       
  1065      * <code>dstOffset</code> but is less than <code>dstOffset+end-start</code>
       
  1066      * <li>the character at index <i>k</i><code>-(end-start)</code> in this
       
  1067      * sequence, if <i>k</i> is greater than or equal to
       
  1068      * <code>dstOffset+end-start</code>
       
  1069      * </ul><p>
       
  1070      * The dstOffset argument must be greater than or equal to
       
  1071      * <code>0</code>, and less than or equal to the length of this
       
  1072      * sequence.
       
  1073      * <p>The start argument must be nonnegative, and not greater than
       
  1074      * <code>end</code>.
       
  1075      * <p>The end argument must be greater than or equal to
       
  1076      * <code>start</code>, and less than or equal to the length of s.
       
  1077      *
       
  1078      * <p>If <code>s</code> is <code>null</code>, then this method inserts
       
  1079      * characters as if the s parameter was a sequence containing the four
       
  1080      * characters <code>"null"</code>.
       
  1081      *
       
  1082      * @param      dstOffset   the offset in this sequence.
       
  1083      * @param      s       the sequence to be inserted.
       
  1084      * @param      start   the starting index of the subsequence to be inserted.
       
  1085      * @param      end     the end index of the subsequence to be inserted.
       
  1086      * @return     a reference to this object.
       
  1087      * @throws     IndexOutOfBoundsException  if <code>dstOffset</code>
       
  1088      *             is negative or greater than <code>this.length()</code>, or
       
  1089      *              <code>start</code> or <code>end</code> are negative, or
       
  1090      *              <code>start</code> is greater than <code>end</code> or
       
  1091      *              <code>end</code> is greater than <code>s.length()</code>
       
  1092      */
       
  1093      public AbstractStringBuilder insert(int dstOffset, CharSequence s,
       
  1094                                            int start, int end) {
       
  1095         if (s == null)
       
  1096             s = "null";
       
  1097         if ((dstOffset < 0) || (dstOffset > this.length()))
       
  1098             throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
       
  1099         if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
       
  1100             throw new IndexOutOfBoundsException(
       
  1101                 "start " + start + ", end " + end + ", s.length() "
       
  1102                 + s.length());
       
  1103         int len = end - start;
       
  1104         if (len == 0)
       
  1105             return this;
       
  1106         int newCount = count + len;
       
  1107         if (newCount > value.length)
       
  1108             expandCapacity(newCount);
       
  1109         System.arraycopy(value, dstOffset, value, dstOffset + len,
       
  1110                          count - dstOffset);
       
  1111         for (int i=start; i<end; i++)
       
  1112             value[dstOffset++] = s.charAt(i);
       
  1113         count = newCount;
       
  1114         return this;
       
  1115     }
       
  1116 
       
  1117     /**
       
  1118      * Inserts the string representation of the <code>boolean</code>
       
  1119      * argument into this sequence.
       
  1120      * <p>
       
  1121      * The second argument is converted to a string as if by the method
       
  1122      * <code>String.valueOf</code>, and the characters of that
       
  1123      * string are then inserted into this sequence at the indicated
       
  1124      * offset.
       
  1125      * <p>
       
  1126      * The offset argument must be greater than or equal to
       
  1127      * <code>0</code>, and less than or equal to the length of this
       
  1128      * sequence.
       
  1129      *
       
  1130      * @param      offset   the offset.
       
  1131      * @param      b        a <code>boolean</code>.
       
  1132      * @return     a reference to this object.
       
  1133      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
       
  1134      */
       
  1135     public AbstractStringBuilder insert(int offset, boolean b) {
       
  1136         return insert(offset, String.valueOf(b));
       
  1137     }
       
  1138 
       
  1139     /**
       
  1140      * Inserts the string representation of the <code>char</code>
       
  1141      * argument into this sequence.
       
  1142      * <p>
       
  1143      * The second argument is inserted into the contents of this sequence
       
  1144      * at the position indicated by <code>offset</code>. The length
       
  1145      * of this sequence increases by one.
       
  1146      * <p>
       
  1147      * The overall effect is exactly as if the argument were converted to
       
  1148      * a string by the method {@link String#valueOf(char)} and the character
       
  1149      * in that string were then {@link #insert(int, String) inserted} into
       
  1150      * this character sequence at the position indicated by
       
  1151      * <code>offset</code>.
       
  1152      * <p>
       
  1153      * The offset argument must be greater than or equal to
       
  1154      * <code>0</code>, and less than or equal to the length of this
       
  1155      * sequence.
       
  1156      *
       
  1157      * @param      offset   the offset.
       
  1158      * @param      c        a <code>char</code>.
       
  1159      * @return     a reference to this object.
       
  1160      * @throws     IndexOutOfBoundsException  if the offset is invalid.
       
  1161      */
       
  1162     public AbstractStringBuilder insert(int offset, char c) {
       
  1163         int newCount = count + 1;
       
  1164         if (newCount > value.length)
       
  1165             expandCapacity(newCount);
       
  1166         System.arraycopy(value, offset, value, offset + 1, count - offset);
       
  1167         value[offset] = c;
       
  1168         count = newCount;
       
  1169         return this;
       
  1170     }
       
  1171 
       
  1172     /**
       
  1173      * Inserts the string representation of the second <code>int</code>
       
  1174      * argument into this sequence.
       
  1175      * <p>
       
  1176      * The second argument is converted to a string as if by the method
       
  1177      * <code>String.valueOf</code>, and the characters of that
       
  1178      * string are then inserted into this sequence at the indicated
       
  1179      * offset.
       
  1180      * <p>
       
  1181      * The offset argument must be greater than or equal to
       
  1182      * <code>0</code>, and less than or equal to the length of this
       
  1183      * sequence.
       
  1184      *
       
  1185      * @param      offset   the offset.
       
  1186      * @param      i        an <code>int</code>.
       
  1187      * @return     a reference to this object.
       
  1188      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
       
  1189      */
       
  1190     public AbstractStringBuilder insert(int offset, int i) {
       
  1191         return insert(offset, String.valueOf(i));
       
  1192     }
       
  1193 
       
  1194     /**
       
  1195      * Inserts the string representation of the <code>long</code>
       
  1196      * argument into this sequence.
       
  1197      * <p>
       
  1198      * The second argument is converted to a string as if by the method
       
  1199      * <code>String.valueOf</code>, and the characters of that
       
  1200      * string are then inserted into this sequence at the position
       
  1201      * indicated by <code>offset</code>.
       
  1202      * <p>
       
  1203      * The offset argument must be greater than or equal to
       
  1204      * <code>0</code>, and less than or equal to the length of this
       
  1205      * sequence.
       
  1206      *
       
  1207      * @param      offset   the offset.
       
  1208      * @param      l        a <code>long</code>.
       
  1209      * @return     a reference to this object.
       
  1210      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
       
  1211      */
       
  1212     public AbstractStringBuilder insert(int offset, long l) {
       
  1213         return insert(offset, String.valueOf(l));
       
  1214     }
       
  1215 
       
  1216     /**
       
  1217      * Inserts the string representation of the <code>float</code>
       
  1218      * argument into this sequence.
       
  1219      * <p>
       
  1220      * The second argument is converted to a string as if by the method
       
  1221      * <code>String.valueOf</code>, and the characters of that
       
  1222      * string are then inserted into this sequence at the indicated
       
  1223      * offset.
       
  1224      * <p>
       
  1225      * The offset argument must be greater than or equal to
       
  1226      * <code>0</code>, and less than or equal to the length of this
       
  1227      * sequence.
       
  1228      *
       
  1229      * @param      offset   the offset.
       
  1230      * @param      f        a <code>float</code>.
       
  1231      * @return     a reference to this object.
       
  1232      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
       
  1233      */
       
  1234     public AbstractStringBuilder insert(int offset, float f) {
       
  1235         return insert(offset, String.valueOf(f));
       
  1236     }
       
  1237 
       
  1238     /**
       
  1239      * Inserts the string representation of the <code>double</code>
       
  1240      * argument into this sequence.
       
  1241      * <p>
       
  1242      * The second argument is converted to a string as if by the method
       
  1243      * <code>String.valueOf</code>, and the characters of that
       
  1244      * string are then inserted into this sequence at the indicated
       
  1245      * offset.
       
  1246      * <p>
       
  1247      * The offset argument must be greater than or equal to
       
  1248      * <code>0</code>, and less than or equal to the length of this
       
  1249      * sequence.
       
  1250      *
       
  1251      * @param      offset   the offset.
       
  1252      * @param      d        a <code>double</code>.
       
  1253      * @return     a reference to this object.
       
  1254      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
       
  1255      */
       
  1256     public AbstractStringBuilder insert(int offset, double d) {
       
  1257         return insert(offset, String.valueOf(d));
       
  1258     }
       
  1259 
       
  1260     /**
       
  1261      * Returns the index within this string of the first occurrence of the
       
  1262      * specified substring. The integer returned is the smallest value
       
  1263      * <i>k</i> such that:
       
  1264      * <blockquote><pre>
       
  1265      * this.toString().startsWith(str, <i>k</i>)
       
  1266      * </pre></blockquote>
       
  1267      * is <code>true</code>.
       
  1268      *
       
  1269      * @param   str   any string.
       
  1270      * @return  if the string argument occurs as a substring within this
       
  1271      *          object, then the index of the first character of the first
       
  1272      *          such substring is returned; if it does not occur as a
       
  1273      *          substring, <code>-1</code> is returned.
       
  1274      * @throws  java.lang.NullPointerException if <code>str</code> is
       
  1275      *          <code>null</code>.
       
  1276      */
       
  1277     public int indexOf(String str) {
       
  1278         return indexOf(str, 0);
       
  1279     }
       
  1280 
       
  1281     /**
       
  1282      * Returns the index within this string of the first occurrence of the
       
  1283      * specified substring, starting at the specified index.  The integer
       
  1284      * returned is the smallest value <tt>k</tt> for which:
       
  1285      * <blockquote><pre>
       
  1286      *     k >= Math.min(fromIndex, str.length()) &&
       
  1287      *                   this.toString().startsWith(str, k)
       
  1288      * </pre></blockquote>
       
  1289      * If no such value of <i>k</i> exists, then -1 is returned.
       
  1290      *
       
  1291      * @param   str         the substring for which to search.
       
  1292      * @param   fromIndex   the index from which to start the search.
       
  1293      * @return  the index within this string of the first occurrence of the
       
  1294      *          specified substring, starting at the specified index.
       
  1295      * @throws  java.lang.NullPointerException if <code>str</code> is
       
  1296      *            <code>null</code>.
       
  1297      */
       
  1298     public int indexOf(String str, int fromIndex) {
       
  1299         return String.indexOf(value, 0, count,
       
  1300                               str.toCharArray(), 0, str.length(), fromIndex);
       
  1301     }
       
  1302 
       
  1303     /**
       
  1304      * Returns the index within this string of the rightmost occurrence
       
  1305      * of the specified substring.  The rightmost empty string "" is
       
  1306      * considered to occur at the index value <code>this.length()</code>.
       
  1307      * The returned index is the largest value <i>k</i> such that
       
  1308      * <blockquote><pre>
       
  1309      * this.toString().startsWith(str, k)
       
  1310      * </pre></blockquote>
       
  1311      * is true.
       
  1312      *
       
  1313      * @param   str   the substring to search for.
       
  1314      * @return  if the string argument occurs one or more times as a substring
       
  1315      *          within this object, then the index of the first character of
       
  1316      *          the last such substring is returned. If it does not occur as
       
  1317      *          a substring, <code>-1</code> is returned.
       
  1318      * @throws  java.lang.NullPointerException  if <code>str</code> is
       
  1319      *          <code>null</code>.
       
  1320      */
       
  1321     public int lastIndexOf(String str) {
       
  1322         return lastIndexOf(str, count);
       
  1323     }
       
  1324 
       
  1325     /**
       
  1326      * Returns the index within this string of the last occurrence of the
       
  1327      * specified substring. The integer returned is the largest value <i>k</i>
       
  1328      * such that:
       
  1329      * <blockquote><pre>
       
  1330      *     k <= Math.min(fromIndex, str.length()) &&
       
  1331      *                   this.toString().startsWith(str, k)
       
  1332      * </pre></blockquote>
       
  1333      * If no such value of <i>k</i> exists, then -1 is returned.
       
  1334      *
       
  1335      * @param   str         the substring to search for.
       
  1336      * @param   fromIndex   the index to start the search from.
       
  1337      * @return  the index within this sequence of the last occurrence of the
       
  1338      *          specified substring.
       
  1339      * @throws  java.lang.NullPointerException if <code>str</code> is
       
  1340      *          <code>null</code>.
       
  1341      */
       
  1342     public int lastIndexOf(String str, int fromIndex) {
       
  1343         return String.lastIndexOf(value, 0, count,
       
  1344                               str.toCharArray(), 0, str.length(), fromIndex);
       
  1345     }
       
  1346 
       
  1347     /**
       
  1348      * Causes this character sequence to be replaced by the reverse of
       
  1349      * the sequence. If there are any surrogate pairs included in the
       
  1350      * sequence, these are treated as single characters for the
       
  1351      * reverse operation. Thus, the order of the high-low surrogates
       
  1352      * is never reversed.
       
  1353      *
       
  1354      * Let <i>n</i> be the character length of this character sequence
       
  1355      * (not the length in <code>char</code> values) just prior to
       
  1356      * execution of the <code>reverse</code> method. Then the
       
  1357      * character at index <i>k</i> in the new character sequence is
       
  1358      * equal to the character at index <i>n-k-1</i> in the old
       
  1359      * character sequence.
       
  1360      *
       
  1361      * <p>Note that the reverse operation may result in producing
       
  1362      * surrogate pairs that were unpaired low-surrogates and
       
  1363      * high-surrogates before the operation. For example, reversing
       
  1364      * "&#92;uDC00&#92;uD800" produces "&#92;uD800&#92;uDC00" which is
       
  1365      * a valid surrogate pair.
       
  1366      *
       
  1367      * @return  a reference to this object.
       
  1368      */
       
  1369     public AbstractStringBuilder reverse() {
       
  1370         boolean hasSurrogate = false;
       
  1371         int n = count - 1;
       
  1372         for (int j = (n-1) >> 1; j >= 0; --j) {
       
  1373             char temp = value[j];
       
  1374             char temp2 = value[n - j];
       
  1375             if (!hasSurrogate) {
       
  1376                 hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
       
  1377                     || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
       
  1378             }
       
  1379             value[j] = temp2;
       
  1380             value[n - j] = temp;
       
  1381         }
       
  1382         if (hasSurrogate) {
       
  1383             // Reverse back all valid surrogate pairs
       
  1384             for (int i = 0; i < count - 1; i++) {
       
  1385                 char c2 = value[i];
       
  1386                 if (Character.isLowSurrogate(c2)) {
       
  1387                     char c1 = value[i + 1];
       
  1388                     if (Character.isHighSurrogate(c1)) {
       
  1389                         value[i++] = c1;
       
  1390                         value[i] = c2;
       
  1391                     }
       
  1392                 }
       
  1393             }
       
  1394         }
       
  1395         return this;
       
  1396     }
       
  1397 
       
  1398     /**
       
  1399      * Returns a string representing the data in this sequence.
       
  1400      * A new <code>String</code> object is allocated and initialized to
       
  1401      * contain the character sequence currently represented by this
       
  1402      * object. This <code>String</code> is then returned. Subsequent
       
  1403      * changes to this sequence do not affect the contents of the
       
  1404      * <code>String</code>.
       
  1405      *
       
  1406      * @return  a string representation of this sequence of characters.
       
  1407      */
       
  1408     public abstract String toString();
       
  1409 
       
  1410     /**
       
  1411      * Needed by <tt>String</tt> for the contentEquals method.
       
  1412      */
       
  1413     final char[] getValue() {
       
  1414         return value;
       
  1415     }
       
  1416 
       
  1417 }