0001 /*
0002 * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
0003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004 *
0005 * This code is free software; you can redistribute it and/or modify it
0006 * under the terms of the GNU General Public License version 2 only, as
0007 * published by the Free Software Foundation. Sun designates this
0008 * particular file as subject to the "Classpath" exception as provided
0009 * by Sun in the LICENSE file that accompanied this code.
0010 *
0011 * This code is distributed in the hope that it will be useful, but WITHOUT
0012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014 * version 2 for more details (a copy is included in the LICENSE file that
0015 * accompanied this code).
0016 *
0017 * You should have received a copy of the GNU General Public License version
0018 * 2 along with this work; if not, write to the Free Software Foundation,
0019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020 *
0021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022 * CA 95054 USA or visit www.sun.com if you need additional information or
0023 * have any questions.
0024 */
0025
0026 package java.lang;
0027
0028 import sun.misc.FloatingDecimal;
0029 import java.util.Arrays;
0030
0031 /**
0032 * A mutable sequence of characters.
0033 * <p>
0034 * Implements a modifiable string. At any point in time it contains some
0035 * particular sequence of characters, but the length and content of the
0036 * sequence can be changed through certain method calls.
0037 *
0038 * @author Michael McCloskey
0039 * @version 1.22, 05/05/07
0040 * @since 1.5
0041 */
0042 abstract class AbstractStringBuilder implements Appendable,
0043 CharSequence {
0044 /**
0045 * The value is used for character storage.
0046 */
0047 char value[];
0048
0049 /**
0050 * The count is the number of characters used.
0051 */
0052 int count;
0053
0054 /**
0055 * This no-arg constructor is necessary for serialization of subclasses.
0056 */
0057 AbstractStringBuilder() {
0058 }
0059
0060 /**
0061 * Creates an AbstractStringBuilder of the specified capacity.
0062 */
0063 AbstractStringBuilder(int capacity) {
0064 value = new char[capacity];
0065 }
0066
0067 /**
0068 * Returns the length (character count).
0069 *
0070 * @return the length of the sequence of characters currently
0071 * represented by this object
0072 */
0073 public int length() {
0074 return count;
0075 }
0076
0077 /**
0078 * Returns the current capacity. The capacity is the amount of storage
0079 * available for newly inserted characters, beyond which an allocation
0080 * will occur.
0081 *
0082 * @return the current capacity
0083 */
0084 public int capacity() {
0085 return value.length;
0086 }
0087
0088 /**
0089 * Ensures that the capacity is at least equal to the specified minimum.
0090 * If the current capacity is less than the argument, then a new internal
0091 * array is allocated with greater capacity. The new capacity is the
0092 * larger of:
0093 * <ul>
0094 * <li>The <code>minimumCapacity</code> argument.
0095 * <li>Twice the old capacity, plus <code>2</code>.
0096 * </ul>
0097 * If the <code>minimumCapacity</code> argument is nonpositive, this
0098 * method takes no action and simply returns.
0099 *
0100 * @param minimumCapacity the minimum desired capacity.
0101 */
0102 public void ensureCapacity(int minimumCapacity) {
0103 if (minimumCapacity > value.length) {
0104 expandCapacity(minimumCapacity);
0105 }
0106 }
0107
0108 /**
0109 * This implements the expansion semantics of ensureCapacity with no
0110 * size check or synchronization.
0111 */
0112 void expandCapacity(int minimumCapacity) {
0113 int newCapacity = (value.length + 1) * 2;
0114 if (newCapacity < 0) {
0115 newCapacity = Integer.MAX_VALUE;
0116 } else if (minimumCapacity > newCapacity) {
0117 newCapacity = minimumCapacity;
0118 }
0119 value = Arrays.copyOf(value, newCapacity);
0120 }
0121
0122 /**
0123 * Attempts to reduce storage used for the character sequence.
0124 * If the buffer is larger than necessary to hold its current sequence of
0125 * characters, then it may be resized to become more space efficient.
0126 * Calling this method may, but is not required to, affect the value
0127 * returned by a subsequent call to the {@link #capacity()} method.
0128 */
0129 public void trimToSize() {
0130 if (count < value.length) {
0131 value = Arrays.copyOf(value, count);
0132 }
0133 }
0134
0135 /**
0136 * Sets the length of the character sequence.
0137 * The sequence is changed to a new character sequence
0138 * whose length is specified by the argument. For every nonnegative
0139 * index <i>k</i> less than <code>newLength</code>, the character at
0140 * index <i>k</i> in the new character sequence is the same as the
0141 * character at index <i>k</i> in the old sequence if <i>k</i> is less
0142 * than the length of the old character sequence; otherwise, it is the
0143 * null character <code>'\u0000'</code>.
0144 *
0145 * In other words, if the <code>newLength</code> argument is less than
0146 * the current length, the length is changed to the specified length.
0147 * <p>
0148 * If the <code>newLength</code> argument is greater than or equal
0149 * to the current length, sufficient null characters
0150 * (<code>'\u0000'</code>) are appended so that
0151 * length becomes the <code>newLength</code> argument.
0152 * <p>
0153 * The <code>newLength</code> argument must be greater than or equal
0154 * to <code>0</code>.
0155 *
0156 * @param newLength the new length
0157 * @throws IndexOutOfBoundsException if the
0158 * <code>newLength</code> argument is negative.
0159 */
0160 public void setLength(int newLength) {
0161 if (newLength < 0)
0162 throw new StringIndexOutOfBoundsException(newLength);
0163 if (newLength > value.length)
0164 expandCapacity(newLength);
0165
0166 if (count < newLength) {
0167 for (; count < newLength; count++)
0168 value[count] = '\0';
0169 } else {
0170 count = newLength;
0171 }
0172 }
0173
0174 /**
0175 * Returns the <code>char</code> value in this sequence at the specified index.
0176 * The first <code>char</code> value is at index <code>0</code>, the next at index
0177 * <code>1</code>, and so on, as in array indexing.
0178 * <p>
0179 * The index argument must be greater than or equal to
0180 * <code>0</code>, and less than the length of this sequence.
0181 *
0182 * <p>If the <code>char</code> value specified by the index is a
0183 * <a href="Character.html#unicode">surrogate</a>, the surrogate
0184 * value is returned.
0185 *
0186 * @param index the index of the desired <code>char</code> value.
0187 * @return the <code>char</code> value at the specified index.
0188 * @throws IndexOutOfBoundsException if <code>index</code> is
0189 * negative or greater than or equal to <code>length()</code>.
0190 */
0191 public char charAt(int index) {
0192 if ((index < 0) || (index >= count))
0193 throw new StringIndexOutOfBoundsException(index);
0194 return value[index];
0195 }
0196
0197 /**
0198 * Returns the character (Unicode code point) at the specified
0199 * index. The index refers to <code>char</code> values
0200 * (Unicode code units) and ranges from <code>0</code> to
0201 * {@link #length()}<code> - 1</code>.
0202 *
0203 * <p> If the <code>char</code> value specified at the given index
0204 * is in the high-surrogate range, the following index is less
0205 * than the length of this sequence, and the
0206 * <code>char</code> value at the following index is in the
0207 * low-surrogate range, then the supplementary code point
0208 * corresponding to this surrogate pair is returned. Otherwise,
0209 * the <code>char</code> value at the given index is returned.
0210 *
0211 * @param index the index to the <code>char</code> values
0212 * @return the code point value of the character at the
0213 * <code>index</code>
0214 * @exception IndexOutOfBoundsException if the <code>index</code>
0215 * argument is negative or not less than the length of this
0216 * sequence.
0217 */
0218 public int codePointAt(int index) {
0219 if ((index < 0) || (index >= count)) {
0220 throw new StringIndexOutOfBoundsException(index);
0221 }
0222 return Character.codePointAt(value, index);
0223 }
0224
0225 /**
0226 * Returns the character (Unicode code point) before the specified
0227 * index. The index refers to <code>char</code> values
0228 * (Unicode code units) and ranges from <code>1</code> to {@link
0229 * #length()}.
0230 *
0231 * <p> If the <code>char</code> value at <code>(index - 1)</code>
0232 * is in the low-surrogate range, <code>(index - 2)</code> is not
0233 * negative, and the <code>char</code> value at <code>(index -
0234 * 2)</code> is in the high-surrogate range, then the
0235 * supplementary code point value of the surrogate pair is
0236 * returned. If the <code>char</code> value at <code>index -
0237 * 1</code> is an unpaired low-surrogate or a high-surrogate, the
0238 * surrogate value is returned.
0239 *
0240 * @param index the index following the code point that should be returned
0241 * @return the Unicode code point value before the given index.
0242 * @exception IndexOutOfBoundsException if the <code>index</code>
0243 * argument is less than 1 or greater than the length
0244 * of this sequence.
0245 */
0246 public int codePointBefore(int index) {
0247 int i = index - 1;
0248 if ((i < 0) || (i >= count)) {
0249 throw new StringIndexOutOfBoundsException(index);
0250 }
0251 return Character.codePointBefore(value, index);
0252 }
0253
0254 /**
0255 * Returns the number of Unicode code points in the specified text
0256 * range of this sequence. The text range begins at the specified
0257 * <code>beginIndex</code> and extends to the <code>char</code> at
0258 * index <code>endIndex - 1</code>. Thus the length (in
0259 * <code>char</code>s) of the text range is
0260 * <code>endIndex-beginIndex</code>. Unpaired surrogates within
0261 * this sequence count as one code point each.
0262 *
0263 * @param beginIndex the index to the first <code>char</code> of
0264 * the text range.
0265 * @param endIndex the index after the last <code>char</code> of
0266 * the text range.
0267 * @return the number of Unicode code points in the specified text
0268 * range
0269 * @exception IndexOutOfBoundsException if the
0270 * <code>beginIndex</code> is negative, or <code>endIndex</code>
0271 * is larger than the length of this sequence, or
0272 * <code>beginIndex</code> is larger than <code>endIndex</code>.
0273 */
0274 public int codePointCount(int beginIndex, int endIndex) {
0275 if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
0276 throw new IndexOutOfBoundsException();
0277 }
0278 return Character.codePointCountImpl(value, beginIndex, endIndex
0279 - beginIndex);
0280 }
0281
0282 /**
0283 * Returns the index within this sequence that is offset from the
0284 * given <code>index</code> by <code>codePointOffset</code> code
0285 * points. Unpaired surrogates within the text range given by
0286 * <code>index</code> and <code>codePointOffset</code> count as
0287 * one code point each.
0288 *
0289 * @param index the index to be offset
0290 * @param codePointOffset the offset in code points
0291 * @return the index within this sequence
0292 * @exception IndexOutOfBoundsException if <code>index</code>
0293 * is negative or larger then the length of this sequence,
0294 * or if <code>codePointOffset</code> is positive and the subsequence
0295 * starting with <code>index</code> has fewer than
0296 * <code>codePointOffset</code> code points,
0297 * or if <code>codePointOffset</code> is negative and the subsequence
0298 * before <code>index</code> has fewer than the absolute value of
0299 * <code>codePointOffset</code> code points.
0300 */
0301 public int offsetByCodePoints(int index, int codePointOffset) {
0302 if (index < 0 || index > count) {
0303 throw new IndexOutOfBoundsException();
0304 }
0305 return Character.offsetByCodePointsImpl(value, 0, count, index,
0306 codePointOffset);
0307 }
0308
0309 /**
0310 * Characters are copied from this sequence into the
0311 * destination character array <code>dst</code>. The first character to
0312 * be copied is at index <code>srcBegin</code>; the last character to
0313 * be copied is at index <code>srcEnd-1</code>. The total number of
0314 * characters to be copied is <code>srcEnd-srcBegin</code>. The
0315 * characters are copied into the subarray of <code>dst</code> starting
0316 * at index <code>dstBegin</code> and ending at index:
0317 * <p><blockquote><pre>
0318 * dstbegin + (srcEnd-srcBegin) - 1
0319 * </pre></blockquote>
0320 *
0321 * @param srcBegin start copying at this offset.
0322 * @param srcEnd stop copying at this offset.
0323 * @param dst the array to copy the data into.
0324 * @param dstBegin offset into <code>dst</code>.
0325 * @throws NullPointerException if <code>dst</code> is
0326 * <code>null</code>.
0327 * @throws IndexOutOfBoundsException if any of the following is true:
0328 * <ul>
0329 * <li><code>srcBegin</code> is negative
0330 * <li><code>dstBegin</code> is negative
0331 * <li>the <code>srcBegin</code> argument is greater than
0332 * the <code>srcEnd</code> argument.
0333 * <li><code>srcEnd</code> is greater than
0334 * <code>this.length()</code>.
0335 * <li><code>dstBegin+srcEnd-srcBegin</code> is greater than
0336 * <code>dst.length</code>
0337 * </ul>
0338 */
0339 public void getChars(int srcBegin, int srcEnd, char dst[],
0340 int dstBegin) {
0341 if (srcBegin < 0)
0342 throw new StringIndexOutOfBoundsException(srcBegin);
0343 if ((srcEnd < 0) || (srcEnd > count))
0344 throw new StringIndexOutOfBoundsException(srcEnd);
0345 if (srcBegin > srcEnd)
0346 throw new StringIndexOutOfBoundsException(
0347 "srcBegin > srcEnd");
0348 System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd
0349 - srcBegin);
0350 }
0351
0352 /**
0353 * The character at the specified index is set to <code>ch</code>. This
0354 * sequence is altered to represent a new character sequence that is
0355 * identical to the old character sequence, except that it contains the
0356 * character <code>ch</code> at position <code>index</code>.
0357 * <p>
0358 * The index argument must be greater than or equal to
0359 * <code>0</code>, and less than the length of this sequence.
0360 *
0361 * @param index the index of the character to modify.
0362 * @param ch the new character.
0363 * @throws IndexOutOfBoundsException if <code>index</code> is
0364 * negative or greater than or equal to <code>length()</code>.
0365 */
0366 public void setCharAt(int index, char ch) {
0367 if ((index < 0) || (index >= count))
0368 throw new StringIndexOutOfBoundsException(index);
0369 value[index] = ch;
0370 }
0371
0372 /**
0373 * Appends the string representation of the <code>Object</code>
0374 * argument.
0375 * <p>
0376 * The argument is converted to a string as if by the method
0377 * <code>String.valueOf</code>, and the characters of that
0378 * string are then appended to this sequence.
0379 *
0380 * @param obj an <code>Object</code>.
0381 * @return a reference to this object.
0382 */
0383 public AbstractStringBuilder append(Object obj) {
0384 return append(String.valueOf(obj));
0385 }
0386
0387 /**
0388 * Appends the specified string to this character sequence.
0389 * <p>
0390 * The characters of the <code>String</code> argument are appended, in
0391 * order, increasing the length of this sequence by the length of the
0392 * argument. If <code>str</code> is <code>null</code>, then the four
0393 * characters <code>"null"</code> are appended.
0394 * <p>
0395 * Let <i>n</i> be the length of this character sequence just prior to
0396 * execution of the <code>append</code> method. Then the character at
0397 * index <i>k</i> in the new character sequence is equal to the character
0398 * at index <i>k</i> in the old character sequence, if <i>k</i> is less
0399 * than <i>n</i>; otherwise, it is equal to the character at index
0400 * <i>k-n</i> in the argument <code>str</code>.
0401 *
0402 * @param str a string.
0403 * @return a reference to this object.
0404 */
0405 public AbstractStringBuilder append(String str) {
0406 if (str == null)
0407 str = "null";
0408 int len = str.length();
0409 if (len == 0)
0410 return this ;
0411 int newCount = count + len;
0412 if (newCount > value.length)
0413 expandCapacity(newCount);
0414 str.getChars(0, len, value, count);
0415 count = newCount;
0416 return this ;
0417 }
0418
0419 // Documentation in subclasses because of synchro difference
0420 public AbstractStringBuilder append(StringBuffer sb) {
0421 if (sb == null)
0422 return append("null");
0423 int len = sb.length();
0424 int newCount = count + len;
0425 if (newCount > value.length)
0426 expandCapacity(newCount);
0427 sb.getChars(0, len, value, count);
0428 count = newCount;
0429 return this ;
0430 }
0431
0432 // Documentation in subclasses because of synchro difference
0433 public AbstractStringBuilder append(CharSequence s) {
0434 if (s == null)
0435 s = "null";
0436 if (s instanceof String)
0437 return this .append((String) s);
0438 if (s instanceof StringBuffer)
0439 return this .append((StringBuffer) s);
0440 return this .append(s, 0, s.length());
0441 }
0442
0443 /**
0444 * Appends a subsequence of the specified <code>CharSequence</code> to this
0445 * sequence.
0446 * <p>
0447 * Characters of the argument <code>s</code>, starting at
0448 * index <code>start</code>, are appended, in order, to the contents of
0449 * this sequence up to the (exclusive) index <code>end</code>. The length
0450 * of this sequence is increased by the value of <code>end - start</code>.
0451 * <p>
0452 * Let <i>n</i> be the length of this character sequence just prior to
0453 * execution of the <code>append</code> method. Then the character at
0454 * index <i>k</i> in this character sequence becomes equal to the
0455 * character at index <i>k</i> in this sequence, if <i>k</i> is less than
0456 * <i>n</i>; otherwise, it is equal to the character at index
0457 * <i>k+start-n</i> in the argument <code>s</code>.
0458 * <p>
0459 * If <code>s</code> is <code>null</code>, then this method appends
0460 * characters as if the s parameter was a sequence containing the four
0461 * characters <code>"null"</code>.
0462 *
0463 * @param s the sequence to append.
0464 * @param start the starting index of the subsequence to be appended.
0465 * @param end the end index of the subsequence to be appended.
0466 * @return a reference to this object.
0467 * @throws IndexOutOfBoundsException if
0468 * <code>start</code> or <code>end</code> are negative, or
0469 * <code>start</code> is greater than <code>end</code> or
0470 * <code>end</code> is greater than <code>s.length()</code>
0471 */
0472 public AbstractStringBuilder append(CharSequence s, int start,
0473 int end) {
0474 if (s == null)
0475 s = "null";
0476 if ((start < 0) || (end < 0) || (start > end)
0477 || (end > s.length()))
0478 throw new IndexOutOfBoundsException("start " + start
0479 + ", end " + end + ", s.length() " + s.length());
0480 int len = end - start;
0481 if (len == 0)
0482 return this ;
0483 int newCount = count + len;
0484 if (newCount > value.length)
0485 expandCapacity(newCount);
0486 for (int i = start; i < end; i++)
0487 value[count++] = s.charAt(i);
0488 count = newCount;
0489 return this ;
0490 }
0491
0492 /**
0493 * Appends the string representation of the <code>char</code> array
0494 * argument to this sequence.
0495 * <p>
0496 * The characters of the array argument are appended, in order, to
0497 * the contents of this sequence. The length of this sequence
0498 * increases by the length of the argument.
0499 * <p>
0500 * The overall effect is exactly as if the argument were converted to
0501 * a string by the method {@link String#valueOf(char[])} and the
0502 * characters of that string were then {@link #append(String) appended}
0503 * to this character sequence.
0504 *
0505 * @param str the characters to be appended.
0506 * @return a reference to this object.
0507 */
0508 public AbstractStringBuilder append(char str[]) {
0509 int newCount = count + str.length;
0510 if (newCount > value.length)
0511 expandCapacity(newCount);
0512 System.arraycopy(str, 0, value, count, str.length);
0513 count = newCount;
0514 return this ;
0515 }
0516
0517 /**
0518 * Appends the string representation of a subarray of the
0519 * <code>char</code> array argument to this sequence.
0520 * <p>
0521 * Characters of the <code>char</code> array <code>str</code>, starting at
0522 * index <code>offset</code>, are appended, in order, to the contents
0523 * of this sequence. The length of this sequence increases
0524 * by the value of <code>len</code>.
0525 * <p>
0526 * The overall effect is exactly as if the arguments were converted to
0527 * a string by the method {@link String#valueOf(char[],int,int)} and the
0528 * characters of that string were then {@link #append(String) appended}
0529 * to this character sequence.
0530 *
0531 * @param str the characters to be appended.
0532 * @param offset the index of the first <code>char</code> to append.
0533 * @param len the number of <code>char</code>s to append.
0534 * @return a reference to this object.
0535 */
0536 public AbstractStringBuilder append(char str[], int offset, int len) {
0537 int newCount = count + len;
0538 if (newCount > value.length)
0539 expandCapacity(newCount);
0540 System.arraycopy(str, offset, value, count, len);
0541 count = newCount;
0542 return this ;
0543 }
0544
0545 /**
0546 * Appends the string representation of the <code>boolean</code>
0547 * argument to the sequence.
0548 * <p>
0549 * The argument is converted to a string as if by the method
0550 * <code>String.valueOf</code>, and the characters of that
0551 * string are then appended to this sequence.
0552 *
0553 * @param b a <code>boolean</code>.
0554 * @return a reference to this object.
0555 */
0556 public AbstractStringBuilder append(boolean b) {
0557 if (b) {
0558 int newCount = count + 4;
0559 if (newCount > value.length)
0560 expandCapacity(newCount);
0561 value[count++] = 't';
0562 value[count++] = 'r';
0563 value[count++] = 'u';
0564 value[count++] = 'e';
0565 } else {
0566 int newCount = count + 5;
0567 if (newCount > value.length)
0568 expandCapacity(newCount);
0569 value[count++] = 'f';
0570 value[count++] = 'a';
0571 value[count++] = 'l';
0572 value[count++] = 's';
0573 value[count++] = 'e';
0574 }
0575 return this ;
0576 }
0577
0578 /**
0579 * Appends the string representation of the <code>char</code>
0580 * argument to this sequence.
0581 * <p>
0582 * The argument is appended to the contents of this sequence.
0583 * The length of this sequence increases by <code>1</code>.
0584 * <p>
0585 * The overall effect is exactly as if the argument were converted to
0586 * a string by the method {@link String#valueOf(char)} and the character
0587 * in that string were then {@link #append(String) appended} to this
0588 * character sequence.
0589 *
0590 * @param c a <code>char</code>.
0591 * @return a reference to this object.
0592 */
0593 public AbstractStringBuilder append(char c) {
0594 int newCount = count + 1;
0595 if (newCount > value.length)
0596 expandCapacity(newCount);
0597 value[count++] = c;
0598 return this ;
0599 }
0600
0601 /**
0602 * Appends the string representation of the <code>int</code>
0603 * argument to this sequence.
0604 * <p>
0605 * The argument is converted to a string as if by the method
0606 * <code>String.valueOf</code>, and the characters of that
0607 * string are then appended to this sequence.
0608 *
0609 * @param i an <code>int</code>.
0610 * @return a reference to this object.
0611 */
0612 public AbstractStringBuilder append(int i) {
0613 if (i == Integer.MIN_VALUE) {
0614 append("-2147483648");
0615 return this ;
0616 }
0617 int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
0618 : Integer.stringSize(i);
0619 int spaceNeeded = count + appendedLength;
0620 if (spaceNeeded > value.length)
0621 expandCapacity(spaceNeeded);
0622 Integer.getChars(i, spaceNeeded, value);
0623 count = spaceNeeded;
0624 return this ;
0625 }
0626
0627 /**
0628 * Appends the string representation of the <code>long</code>
0629 * argument to this sequence.
0630 * <p>
0631 * The argument is converted to a string as if by the method
0632 * <code>String.valueOf</code>, and the characters of that
0633 * string are then appended to this sequence.
0634 *
0635 * @param l a <code>long</code>.
0636 * @return a reference to this object.
0637 */
0638 public AbstractStringBuilder append(long l) {
0639 if (l == Long.MIN_VALUE) {
0640 append("-9223372036854775808");
0641 return this ;
0642 }
0643 int appendedLength = (l < 0) ? Long.stringSize(-l) + 1 : Long
0644 .stringSize(l);
0645 int spaceNeeded = count + appendedLength;
0646 if (spaceNeeded > value.length)
0647 expandCapacity(spaceNeeded);
0648 Long.getChars(l, spaceNeeded, value);
0649 count = spaceNeeded;
0650 return this ;
0651 }
0652
0653 /**
0654 * Appends the string representation of the <code>float</code>
0655 * argument to this sequence.
0656 * <p>
0657 * The argument is converted to a string as if by the method
0658 * <code>String.valueOf</code>, and the characters of that
0659 * string are then appended to this string sequence.
0660 *
0661 * @param f a <code>float</code>.
0662 * @return a reference to this object.
0663 */
0664 public AbstractStringBuilder append(float f) {
0665 new FloatingDecimal(f).appendTo(this );
0666 return this ;
0667 }
0668
0669 /**
0670 * Appends the string representation of the <code>double</code>
0671 * argument to this sequence.
0672 * <p>
0673 * The argument is converted to a string as if by the method
0674 * <code>String.valueOf</code>, and the characters of that
0675 * string are then appended to this sequence.
0676 *
0677 * @param d a <code>double</code>.
0678 * @return a reference to this object.
0679 */
0680 public AbstractStringBuilder append(double d) {
0681 new FloatingDecimal(d).appendTo(this );
0682 return this ;
0683 }
0684
0685 /**
0686 * Removes the characters in a substring of this sequence.
0687 * The substring begins at the specified <code>start</code> and extends to
0688 * the character at index <code>end - 1</code> or to the end of the
0689 * sequence if no such character exists. If
0690 * <code>start</code> is equal to <code>end</code>, no changes are made.
0691 *
0692 * @param start The beginning index, inclusive.
0693 * @param end The ending index, exclusive.
0694 * @return This object.
0695 * @throws StringIndexOutOfBoundsException if <code>start</code>
0696 * is negative, greater than <code>length()</code>, or
0697 * greater than <code>end</code>.
0698 */
0699 public AbstractStringBuilder delete(int start, int end) {
0700 if (start < 0)
0701 throw new StringIndexOutOfBoundsException(start);
0702 if (end > count)
0703 end = count;
0704 if (start > end)
0705 throw new StringIndexOutOfBoundsException();
0706 int len = end - start;
0707 if (len > 0) {
0708 System.arraycopy(value, start + len, value, start, count
0709 - end);
0710 count -= len;
0711 }
0712 return this ;
0713 }
0714
0715 /**
0716 * Appends the string representation of the <code>codePoint</code>
0717 * argument to this sequence.
0718 *
0719 * <p> The argument is appended to the contents of this sequence.
0720 * The length of this sequence increases by
0721 * {@link Character#charCount(int) Character.charCount(codePoint)}.
0722 *
0723 * <p> The overall effect is exactly as if the argument were
0724 * converted to a <code>char</code> array by the method {@link
0725 * Character#toChars(int)} and the character in that array were
0726 * then {@link #append(char[]) appended} to this character
0727 * sequence.
0728 *
0729 * @param codePoint a Unicode code point
0730 * @return a reference to this object.
0731 * @exception IllegalArgumentException if the specified
0732 * <code>codePoint</code> isn't a valid Unicode code point
0733 */
0734 public AbstractStringBuilder appendCodePoint(int codePoint) {
0735 if (!Character.isValidCodePoint(codePoint)) {
0736 throw new IllegalArgumentException();
0737 }
0738 int n = 1;
0739 if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
0740 n++;
0741 }
0742 int newCount = count + n;
0743 if (newCount > value.length) {
0744 expandCapacity(newCount);
0745 }
0746 if (n == 1) {
0747 value[count++] = (char) codePoint;
0748 } else {
0749 Character.toSurrogates(codePoint, value, count);
0750 count += n;
0751 }
0752 return this ;
0753 }
0754
0755 /**
0756 * Removes the <code>char</code> at the specified position in this
0757 * sequence. This sequence is shortened by one <code>char</code>.
0758 *
0759 * <p>Note: If the character at the given index is a supplementary
0760 * character, this method does not remove the entire character. If
0761 * correct handling of supplementary characters is required,
0762 * determine the number of <code>char</code>s to remove by calling
0763 * <code>Character.charCount(thisSequence.codePointAt(index))</code>,
0764 * where <code>thisSequence</code> is this sequence.
0765 *
0766 * @param index Index of <code>char</code> to remove
0767 * @return This object.
0768 * @throws StringIndexOutOfBoundsException if the <code>index</code>
0769 * is negative or greater than or equal to
0770 * <code>length()</code>.
0771 */
0772 public AbstractStringBuilder deleteCharAt(int index) {
0773 if ((index < 0) || (index >= count))
0774 throw new StringIndexOutOfBoundsException(index);
0775 System.arraycopy(value, index + 1, value, index, count - index
0776 - 1);
0777 count--;
0778 return this ;
0779 }
0780
0781 /**
0782 * Replaces the characters in a substring of this sequence
0783 * with characters in the specified <code>String</code>. The substring
0784 * begins at the specified <code>start</code> and extends to the character
0785 * at index <code>end - 1</code> or to the end of the
0786 * sequence if no such character exists. First the
0787 * characters in the substring are removed and then the specified
0788 * <code>String</code> is inserted at <code>start</code>. (This
0789 * sequence will be lengthened to accommodate the
0790 * specified String if necessary.)
0791 *
0792 * @param start The beginning index, inclusive.
0793 * @param end The ending index, exclusive.
0794 * @param str String that will replace previous contents.
0795 * @return This object.
0796 * @throws StringIndexOutOfBoundsException if <code>start</code>
0797 * is negative, greater than <code>length()</code>, or
0798 * greater than <code>end</code>.
0799 */
0800 public AbstractStringBuilder replace(int start, int end, String str) {
0801 if (start < 0)
0802 throw new StringIndexOutOfBoundsException(start);
0803 if (start > count)
0804 throw new StringIndexOutOfBoundsException(
0805 "start > length()");
0806 if (start > end)
0807 throw new StringIndexOutOfBoundsException("start > end");
0808
0809 if (end > count)
0810 end = count;
0811 int len = str.length();
0812 int newCount = count + len - (end - start);
0813 if (newCount > value.length)
0814 expandCapacity(newCount);
0815
0816 System.arraycopy(value, end, value, start + len, count - end);
0817 str.getChars(value, start);
0818 count = newCount;
0819 return this ;
0820 }
0821
0822 /**
0823 * Returns a new <code>String</code> that contains a subsequence of
0824 * characters currently contained in this character sequence. The
0825 * substring begins at the specified index and extends to the end of
0826 * this sequence.
0827 *
0828 * @param start The beginning index, inclusive.
0829 * @return The new string.
0830 * @throws StringIndexOutOfBoundsException if <code>start</code> is
0831 * less than zero, or greater than the length of this object.
0832 */
0833 public String substring(int start) {
0834 return substring(start, count);
0835 }
0836
0837 /**
0838 * Returns a new character sequence that is a subsequence of this sequence.
0839 *
0840 * <p> An invocation of this method of the form
0841 *
0842 * <blockquote><pre>
0843 * sb.subSequence(begin, end)</pre></blockquote>
0844 *
0845 * behaves in exactly the same way as the invocation
0846 *
0847 * <blockquote><pre>
0848 * sb.substring(begin, end)</pre></blockquote>
0849 *
0850 * This method is provided so that this class can
0851 * implement the {@link CharSequence} interface. </p>
0852 *
0853 * @param start the start index, inclusive.
0854 * @param end the end index, exclusive.
0855 * @return the specified subsequence.
0856 *
0857 * @throws IndexOutOfBoundsException
0858 * if <tt>start</tt> or <tt>end</tt> are negative,
0859 * if <tt>end</tt> is greater than <tt>length()</tt>,
0860 * or if <tt>start</tt> is greater than <tt>end</tt>
0861 * @spec JSR-51
0862 */
0863 public CharSequence subSequence(int start, int end) {
0864 return substring(start, end);
0865 }
0866
0867 /**
0868 * Returns a new <code>String</code> that contains a subsequence of
0869 * characters currently contained in this sequence. The
0870 * substring begins at the specified <code>start</code> and
0871 * extends to the character at index <code>end - 1</code>.
0872 *
0873 * @param start The beginning index, inclusive.
0874 * @param end The ending index, exclusive.
0875 * @return The new string.
0876 * @throws StringIndexOutOfBoundsException if <code>start</code>
0877 * or <code>end</code> are negative or greater than
0878 * <code>length()</code>, or <code>start</code> is
0879 * greater than <code>end</code>.
0880 */
0881 public String substring(int start, int end) {
0882 if (start < 0)
0883 throw new StringIndexOutOfBoundsException(start);
0884 if (end > count)
0885 throw new StringIndexOutOfBoundsException(end);
0886 if (start > end)
0887 throw new StringIndexOutOfBoundsException(end - start);
0888 return new String(value, start, end - start);
0889 }
0890
0891 /**
0892 * Inserts the string representation of a subarray of the <code>str</code>
0893 * array argument into this sequence. The subarray begins at the
0894 * specified <code>offset</code> and extends <code>len</code> <code>char</code>s.
0895 * The characters of the subarray are inserted into this sequence at
0896 * the position indicated by <code>index</code>. The length of this
0897 * sequence increases by <code>len</code> <code>char</code>s.
0898 *
0899 * @param index position at which to insert subarray.
0900 * @param str A <code>char</code> array.
0901 * @param offset the index of the first <code>char</code> in subarray to
0902 * be inserted.
0903 * @param len the number of <code>char</code>s in the subarray to
0904 * be inserted.
0905 * @return This object
0906 * @throws StringIndexOutOfBoundsException if <code>index</code>
0907 * is negative or greater than <code>length()</code>, or
0908 * <code>offset</code> or <code>len</code> are negative, or
0909 * <code>(offset+len)</code> is greater than
0910 * <code>str.length</code>.
0911 */
0912 public AbstractStringBuilder insert(int index, char str[],
0913 int offset, int len) {
0914 if ((index < 0) || (index > length()))
0915 throw new StringIndexOutOfBoundsException(index);
0916 if ((offset < 0) || (len < 0) || (offset > str.length - len))
0917 throw new StringIndexOutOfBoundsException("offset "
0918 + offset + ", len " + len + ", str.length "
0919 + str.length);
0920 int newCount = count + len;
0921 if (newCount > value.length)
0922 expandCapacity(newCount);
0923 System.arraycopy(value, index, value, index + len, count
0924 - index);
0925 System.arraycopy(str, offset, value, index, len);
0926 count = newCount;
0927 return this ;
0928 }
0929
0930 /**
0931 * Inserts the string representation of the <code>Object</code>
0932 * argument into this character sequence.
0933 * <p>
0934 * The second argument is converted to a string as if by the method
0935 * <code>String.valueOf</code>, and the characters of that
0936 * string are then inserted into this sequence at the indicated
0937 * offset.
0938 * <p>
0939 * The offset argument must be greater than or equal to
0940 * <code>0</code>, and less than or equal to the length of this
0941 * sequence.
0942 *
0943 * @param offset the offset.
0944 * @param obj an <code>Object</code>.
0945 * @return a reference to this object.
0946 * @throws StringIndexOutOfBoundsException if the offset is invalid.
0947 */
0948 public AbstractStringBuilder insert(int offset, Object obj) {
0949 return insert(offset, String.valueOf(obj));
0950 }
0951
0952 /**
0953 * Inserts the string into this character sequence.
0954 * <p>
0955 * The characters of the <code>String</code> argument are inserted, in
0956 * order, into this sequence at the indicated offset, moving up any
0957 * characters originally above that position and increasing the length
0958 * of this sequence by the length of the argument. If
0959 * <code>str</code> is <code>null</code>, then the four characters
0960 * <code>"null"</code> are inserted into this sequence.
0961 * <p>
0962 * The character at index <i>k</i> in the new character sequence is
0963 * equal to:
0964 * <ul>
0965 * <li>the character at index <i>k</i> in the old character sequence, if
0966 * <i>k</i> is less than <code>offset</code>
0967 * <li>the character at index <i>k</i><code>-offset</code> in the
0968 * argument <code>str</code>, if <i>k</i> is not less than
0969 * <code>offset</code> but is less than <code>offset+str.length()</code>
0970 * <li>the character at index <i>k</i><code>-str.length()</code> in the
0971 * old character sequence, if <i>k</i> is not less than
0972 * <code>offset+str.length()</code>
0973 * </ul><p>
0974 * The offset argument must be greater than or equal to
0975 * <code>0</code>, and less than or equal to the length of this
0976 * sequence.
0977 *
0978 * @param offset the offset.
0979 * @param str a string.
0980 * @return a reference to this object.
0981 * @throws StringIndexOutOfBoundsException if the offset is invalid.
0982 */
0983 public AbstractStringBuilder insert(int offset, String str) {
0984 if ((offset < 0) || (offset > length()))
0985 throw new StringIndexOutOfBoundsException(offset);
0986 if (str == null)
0987 str = "null";
0988 int len = str.length();
0989 int newCount = count + len;
0990 if (newCount > value.length)
0991 expandCapacity(newCount);
0992 System.arraycopy(value, offset, value, offset + len, count
0993 - offset);
0994 str.getChars(value, offset);
0995 count = newCount;
0996 return this ;
0997 }
0998
0999 /**
1000 * Inserts the string representation of the <code>char</code> array
1001 * argument into this sequence.
1002 * <p>
1003 * The characters of the array argument are inserted into the
1004 * contents of this sequence at the position indicated by
1005 * <code>offset</code>. The length of this sequence increases by
1006 * the length of the argument.
1007 * <p>
1008 * The overall effect is exactly as if the argument were converted to
1009 * a string by the method {@link String#valueOf(char[])} and the
1010 * characters of that string were then
1011 * {@link #insert(int,String) inserted} into this
1012 * character sequence at the position indicated by
1013 * <code>offset</code>.
1014 *
1015 * @param offset the offset.
1016 * @param str a character array.
1017 * @return a reference to this object.
1018 * @throws StringIndexOutOfBoundsException if the offset is invalid.
1019 */
1020 public AbstractStringBuilder insert(int offset, char str[]) {
1021 if ((offset < 0) || (offset > length()))
1022 throw new StringIndexOutOfBoundsException(offset);
1023 int len = str.length;
1024 int newCount = count + len;
1025 if (newCount > value.length)
1026 expandCapacity(newCount);
1027 System.arraycopy(value, offset, value, offset + len, count
1028 - offset);
1029 System.arraycopy(str, 0, value, offset, len);
1030 count = newCount;
1031 return this ;
1032 }
1033
1034 /**
1035 * Inserts the specified <code>CharSequence</code> into this sequence.
1036 * <p>
1037 * The characters of the <code>CharSequence</code> argument are inserted,
1038 * in order, into this sequence at the indicated offset, moving up
1039 * any characters originally above that position and increasing the length
1040 * of this sequence by the length of the argument s.
1041 * <p>
1042 * The result of this method is exactly the same as if it were an
1043 * invocation of this object's insert(dstOffset, s, 0, s.length()) method.
1044 *
1045 * <p>If <code>s</code> is <code>null</code>, then the four characters
1046 * <code>"null"</code> are inserted into this sequence.
1047 *
1048 * @param dstOffset the offset.
1049 * @param s the sequence to be inserted
1050 * @return a reference to this object.
1051 * @throws IndexOutOfBoundsException if the offset is invalid.
1052 */
1053 public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
1054 if (s == null)
1055 s = "null";
1056 if (s instanceof String)
1057 return this .insert(dstOffset, (String) s);
1058 return this .insert(dstOffset, s, 0, s.length());
1059 }
1060
1061 /**
1062 * Inserts a subsequence of the specified <code>CharSequence</code> into
1063 * this sequence.
1064 * <p>
1065 * The subsequence of the argument <code>s</code> specified by
1066 * <code>start</code> and <code>end</code> are inserted,
1067 * in order, into this sequence at the specified destination offset, moving
1068 * up any characters originally above that position. The length of this
1069 * sequence is increased by <code>end - start</code>.
1070 * <p>
1071 * The character at index <i>k</i> in this sequence becomes equal to:
1072 * <ul>
1073 * <li>the character at index <i>k</i> in this sequence, if
1074 * <i>k</i> is less than <code>dstOffset</code>
1075 * <li>the character at index <i>k</i><code>+start-dstOffset</code> in
1076 * the argument <code>s</code>, if <i>k</i> is greater than or equal to
1077 * <code>dstOffset</code> but is less than <code>dstOffset+end-start</code>
1078 * <li>the character at index <i>k</i><code>-(end-start)</code> in this
1079 * sequence, if <i>k</i> is greater than or equal to
1080 * <code>dstOffset+end-start</code>
1081 * </ul><p>
1082 * The dstOffset argument must be greater than or equal to
1083 * <code>0</code>, and less than or equal to the length of this
1084 * sequence.
1085 * <p>The start argument must be nonnegative, and not greater than
1086 * <code>end</code>.
1087 * <p>The end argument must be greater than or equal to
1088 * <code>start</code>, and less than or equal to the length of s.
1089 *
1090 * <p>If <code>s</code> is <code>null</code>, then this method inserts
1091 * characters as if the s parameter was a sequence containing the four
1092 * characters <code>"null"</code>.
1093 *
1094 * @param dstOffset the offset in this sequence.
1095 * @param s the sequence to be inserted.
1096 * @param start the starting index of the subsequence to be inserted.
1097 * @param end the end index of the subsequence to be inserted.
1098 * @return a reference to this object.
1099 * @throws IndexOutOfBoundsException if <code>dstOffset</code>
1100 * is negative or greater than <code>this.length()</code>, or
1101 * <code>start</code> or <code>end</code> are negative, or
1102 * <code>start</code> is greater than <code>end</code> or
1103 * <code>end</code> is greater than <code>s.length()</code>
1104 */
1105 public AbstractStringBuilder insert(int dstOffset, CharSequence s,
1106 int start, int end) {
1107 if (s == null)
1108 s = "null";
1109 if ((dstOffset < 0) || (dstOffset > this .length()))
1110 throw new IndexOutOfBoundsException("dstOffset "
1111 + dstOffset);
1112 if ((start < 0) || (end < 0) || (start > end)
1113 || (end > s.length()))
1114 throw new IndexOutOfBoundsException("start " + start
1115 + ", end " + end + ", s.length() " + s.length());
1116 int len = end - start;
1117 if (len == 0)
1118 return this ;
1119 int newCount = count + len;
1120 if (newCount > value.length)
1121 expandCapacity(newCount);
1122 System.arraycopy(value, dstOffset, value, dstOffset + len,
1123 count - dstOffset);
1124 for (int i = start; i < end; i++)
1125 value[dstOffset++] = s.charAt(i);
1126 count = newCount;
1127 return this ;
1128 }
1129
1130 /**
1131 * Inserts the string representation of the <code>boolean</code>
1132 * argument into this sequence.
1133 * <p>
1134 * The second argument is converted to a string as if by the method
1135 * <code>String.valueOf</code>, and the characters of that
1136 * string are then inserted into this sequence at the indicated
1137 * offset.
1138 * <p>
1139 * The offset argument must be greater than or equal to
1140 * <code>0</code>, and less than or equal to the length of this
1141 * sequence.
1142 *
1143 * @param offset the offset.
1144 * @param b a <code>boolean</code>.
1145 * @return a reference to this object.
1146 * @throws StringIndexOutOfBoundsException if the offset is invalid.
1147 */
1148 public AbstractStringBuilder insert(int offset, boolean b) {
1149 return insert(offset, String.valueOf(b));
1150 }
1151
1152 /**
1153 * Inserts the string representation of the <code>char</code>
1154 * argument into this sequence.
1155 * <p>
1156 * The second argument is inserted into the contents of this sequence
1157 * at the position indicated by <code>offset</code>. The length
1158 * of this sequence increases by one.
1159 * <p>
1160 * The overall effect is exactly as if the argument were converted to
1161 * a string by the method {@link String#valueOf(char)} and the character
1162 * in that string were then {@link #insert(int, String) inserted} into
1163 * this character sequence at the position indicated by
1164 * <code>offset</code>.
1165 * <p>
1166 * The offset argument must be greater than or equal to
1167 * <code>0</code>, and less than or equal to the length of this
1168 * sequence.
1169 *
1170 * @param offset the offset.
1171 * @param c a <code>char</code>.
1172 * @return a reference to this object.
1173 * @throws IndexOutOfBoundsException if the offset is invalid.
1174 */
1175 public AbstractStringBuilder insert(int offset, char c) {
1176 int newCount = count + 1;
1177 if (newCount > value.length)
1178 expandCapacity(newCount);
1179 System.arraycopy(value, offset, value, offset + 1, count
1180 - offset);
1181 value[offset] = c;
1182 count = newCount;
1183 return this ;
1184 }
1185
1186 /**
1187 * Inserts the string representation of the second <code>int</code>
1188 * argument into this sequence.
1189 * <p>
1190 * The second argument is converted to a string as if by the method
1191 * <code>String.valueOf</code>, and the characters of that
1192 * string are then inserted into this sequence at the indicated
1193 * offset.
1194 * <p>
1195 * The offset argument must be greater than or equal to
1196 * <code>0</code>, and less than or equal to the length of this
1197 * sequence.
1198 *
1199 * @param offset the offset.
1200 * @param i an <code>int</code>.
1201 * @return a reference to this object.
1202 * @throws StringIndexOutOfBoundsException if the offset is invalid.
1203 */
1204 public AbstractStringBuilder insert(int offset, int i) {
1205 return insert(offset, String.valueOf(i));
1206 }
1207
1208 /**
1209 * Inserts the string representation of the <code>long</code>
1210 * argument into this sequence.
1211 * <p>
1212 * The second argument is converted to a string as if by the method
1213 * <code>String.valueOf</code>, and the characters of that
1214 * string are then inserted into this sequence at the position
1215 * indicated by <code>offset</code>.
1216 * <p>
1217 * The offset argument must be greater than or equal to
1218 * <code>0</code>, and less than or equal to the length of this
1219 * sequence.
1220 *
1221 * @param offset the offset.
1222 * @param l a <code>long</code>.
1223 * @return a reference to this object.
1224 * @throws StringIndexOutOfBoundsException if the offset is invalid.
1225 */
1226 public AbstractStringBuilder insert(int offset, long l) {
1227 return insert(offset, String.valueOf(l));
1228 }
1229
1230 /**
1231 * Inserts the string representation of the <code>float</code>
1232 * argument into this sequence.
1233 * <p>
1234 * The second argument is converted to a string as if by the method
1235 * <code>String.valueOf</code>, and the characters of that
1236 * string are then inserted into this sequence at the indicated
1237 * offset.
1238 * <p>
1239 * The offset argument must be greater than or equal to
1240 * <code>0</code>, and less than or equal to the length of this
1241 * sequence.
1242 *
1243 * @param offset the offset.
1244 * @param f a <code>float</code>.
1245 * @return a reference to this object.
1246 * @throws StringIndexOutOfBoundsException if the offset is invalid.
1247 */
1248 public AbstractStringBuilder insert(int offset, float f) {
1249 return insert(offset, String.valueOf(f));
1250 }
1251
1252 /**
1253 * Inserts the string representation of the <code>double</code>
1254 * argument into this sequence.
1255 * <p>
1256 * The second argument is converted to a string as if by the method
1257 * <code>String.valueOf</code>, and the characters of that
1258 * string are then inserted into this sequence at the indicated
1259 * offset.
1260 * <p>
1261 * The offset argument must be greater than or equal to
1262 * <code>0</code>, and less than or equal to the length of this
1263 * sequence.
1264 *
1265 * @param offset the offset.
1266 * @param d a <code>double</code>.
1267 * @return a reference to this object.
1268 * @throws StringIndexOutOfBoundsException if the offset is invalid.
1269 */
1270 public AbstractStringBuilder insert(int offset, double d) {
1271 return insert(offset, String.valueOf(d));
1272 }
1273
1274 /**
1275 * Returns the index within this string of the first occurrence of the
1276 * specified substring. The integer returned is the smallest value
1277 * <i>k</i> such that:
1278 * <blockquote><pre>
1279 * this.toString().startsWith(str, <i>k</i>)
1280 * </pre></blockquote>
1281 * is <code>true</code>.
1282 *
1283 * @param str any string.
1284 * @return if the string argument occurs as a substring within this
1285 * object, then the index of the first character of the first
1286 * such substring is returned; if it does not occur as a
1287 * substring, <code>-1</code> is returned.
1288 * @throws java.lang.NullPointerException if <code>str</code> is
1289 * <code>null</code>.
1290 */
1291 public int indexOf(String str) {
1292 return indexOf(str, 0);
1293 }
1294
1295 /**
1296 * Returns the index within this string of the first occurrence of the
1297 * specified substring, starting at the specified index. The integer
1298 * returned is the smallest value <tt>k</tt> for which:
1299 * <blockquote><pre>
1300 * k >= Math.min(fromIndex, str.length()) &&
1301 * this.toString().startsWith(str, k)
1302 * </pre></blockquote>
1303 * If no such value of <i>k</i> exists, then -1 is returned.
1304 *
1305 * @param str the substring for which to search.
1306 * @param fromIndex the index from which to start the search.
1307 * @return the index within this string of the first occurrence of the
1308 * specified substring, starting at the specified index.
1309 * @throws java.lang.NullPointerException if <code>str</code> is
1310 * <code>null</code>.
1311 */
1312 public int indexOf(String str, int fromIndex) {
1313 return String.indexOf(value, 0, count, str.toCharArray(), 0,
1314 str.length(), fromIndex);
1315 }
1316
1317 /**
1318 * Returns the index within this string of the rightmost occurrence
1319 * of the specified substring. The rightmost empty string "" is
1320 * considered to occur at the index value <code>this.length()</code>.
1321 * The returned index is the largest value <i>k</i> such that
1322 * <blockquote><pre>
1323 * this.toString().startsWith(str, k)
1324 * </pre></blockquote>
1325 * is true.
1326 *
1327 * @param str the substring to search for.
1328 * @return if the string argument occurs one or more times as a substring
1329 * within this object, then the index of the first character of
1330 * the last such substring is returned. If it does not occur as
1331 * a substring, <code>-1</code> is returned.
1332 * @throws java.lang.NullPointerException if <code>str</code> is
1333 * <code>null</code>.
1334 */
1335 public int lastIndexOf(String str) {
1336 return lastIndexOf(str, count);
1337 }
1338
1339 /**
1340 * Returns the index within this string of the last occurrence of the
1341 * specified substring. The integer returned is the largest value <i>k</i>
1342 * such that:
1343 * <blockquote><pre>
1344 * k <= Math.min(fromIndex, str.length()) &&
1345 * this.toString().startsWith(str, k)
1346 * </pre></blockquote>
1347 * If no such value of <i>k</i> exists, then -1 is returned.
1348 *
1349 * @param str the substring to search for.
1350 * @param fromIndex the index to start the search from.
1351 * @return the index within this sequence of the last occurrence of the
1352 * specified substring.
1353 * @throws java.lang.NullPointerException if <code>str</code> is
1354 * <code>null</code>.
1355 */
1356 public int lastIndexOf(String str, int fromIndex) {
1357 return String.lastIndexOf(value, 0, count, str.toCharArray(),
1358 0, str.length(), fromIndex);
1359 }
1360
1361 /**
1362 * Causes this character sequence to be replaced by the reverse of
1363 * the sequence. If there are any surrogate pairs included in the
1364 * sequence, these are treated as single characters for the
1365 * reverse operation. Thus, the order of the high-low surrogates
1366 * is never reversed.
1367 *
1368 * Let <i>n</i> be the character length of this character sequence
1369 * (not the length in <code>char</code> values) just prior to
1370 * execution of the <code>reverse</code> method. Then the
1371 * character at index <i>k</i> in the new character sequence is
1372 * equal to the character at index <i>n-k-1</i> in the old
1373 * character sequence.
1374 *
1375 * <p>Note that the reverse operation may result in producing
1376 * surrogate pairs that were unpaired low-surrogates and
1377 * high-surrogates before the operation. For example, reversing
1378 * "\uDC00\uD800" produces "\uD800\uDC00" which is
1379 * a valid surrogate pair.
1380 *
1381 * @return a reference to this object.
1382 */
1383 public AbstractStringBuilder reverse() {
1384 boolean hasSurrogate = false;
1385 int n = count - 1;
1386 for (int j = (n - 1) >> 1; j >= 0; --j) {
1387 char temp = value[j];
1388 char temp2 = value[n - j];
1389 if (!hasSurrogate) {
1390 hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
1391 || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
1392 }
1393 value[j] = temp2;
1394 value[n - j] = temp;
1395 }
1396 if (hasSurrogate) {
1397 // Reverse back all valid surrogate pairs
1398 for (int i = 0; i < count - 1; i++) {
1399 char c2 = value[i];
1400 if (Character.isLowSurrogate(c2)) {
1401 char c1 = value[i + 1];
1402 if (Character.isHighSurrogate(c1)) {
1403 value[i++] = c1;
1404 value[i] = c2;
1405 }
1406 }
1407 }
1408 }
1409 return this ;
1410 }
1411
1412 /**
1413 * Returns a string representing the data in this sequence.
1414 * A new <code>String</code> object is allocated and initialized to
1415 * contain the character sequence currently represented by this
1416 * object. This <code>String</code> is then returned. Subsequent
1417 * changes to this sequence do not affect the contents of the
1418 * <code>String</code>.
1419 *
1420 * @return a string representation of this sequence of characters.
1421 */
1422 public abstract String toString();
1423
1424 /**
1425 * Needed by <tt>String</tt> for the contentEquals method.
1426 */
1427 final char[] getValue() {
1428 return value;
1429 }
1430
1431 }
|