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: }
|