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