0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017: package org.apache.wicket.util.string;
0018:
0019: import java.io.IOException;
0020:
0021: /**
0022: * This is a copy or combination of <code>java.lang.StringBuffer</code> and
0023: * <code>java.lang.String</code> It has a special method getValue() which
0024: * returns the internal char array.
0025: *
0026: * Hashcode and equals methods are also implemented.
0027: *
0028: * This AppendingStringBuffer is not synchronized.
0029: *
0030: * @author Johan Compagner
0031: * @see java.lang.StringBuffer
0032: */
0033:
0034: public final class AppendingStringBuffer implements
0035: java.io.Serializable, CharSequence {
0036: /** use serialVersionUID from JDK 1.0.2 for interoperability */
0037: static final long serialVersionUID = 1L;
0038:
0039: private static final AppendingStringBuffer NULL = new AppendingStringBuffer(
0040: "null");
0041: private static final StringBuffer SB_NULL = new StringBuffer("null");
0042:
0043: /**
0044: * The value is used for character storage.
0045: *
0046: * @serial
0047: */
0048: private char value[];
0049:
0050: /**
0051: * The count is the number of characters in the buffer.
0052: *
0053: * @serial
0054: */
0055: private int count;
0056:
0057: /**
0058: * Constructs a string buffer with no characters in it and an initial
0059: * capacity of 16 characters.
0060: */
0061: public AppendingStringBuffer() {
0062: this (16);
0063: }
0064:
0065: /**
0066: * Constructs a string buffer with no characters in it and an initial
0067: * capacity specified by the <code>length</code> argument.
0068: *
0069: * @param length
0070: * the initial capacity.
0071: * @exception NegativeArraySizeException
0072: * if the <code>length</code> argument is less than
0073: * <code>0</code>.
0074: */
0075: public AppendingStringBuffer(int length) {
0076: value = new char[length];
0077: }
0078:
0079: /**
0080: * Constructs a string buffer so that it represents the same sequence of
0081: * characters as the string argument; in other words, the initial contents
0082: * of the string buffer is a copy of the argument string. The initial
0083: * capacity of the string buffer is <code>16</code> plus the length of the
0084: * string argument.
0085: *
0086: * @param str
0087: * the initial contents of the buffer.
0088: * @exception NullPointerException
0089: * if <code>str</code> is <code>null</code>
0090: */
0091: public AppendingStringBuffer(CharSequence str) {
0092: this (str.length() + 16);
0093: append(str);
0094: }
0095:
0096: /**
0097: * Returns the length (character count) of this string buffer.
0098: *
0099: * @return the length of the sequence of characters currently represented by
0100: * this string buffer.
0101: */
0102: public int length() {
0103: return count;
0104: }
0105:
0106: /**
0107: * Returns the current capacity of the String buffer. The capacity is the
0108: * amount of storage available for newly inserted characters; beyond which
0109: * an allocation will occur.
0110: *
0111: * @return the current capacity of this string buffer.
0112: */
0113: public int capacity() {
0114: return value.length;
0115: }
0116:
0117: /**
0118: * Ensures that the capacity of the buffer is at least equal to the
0119: * specified minimum. If the current capacity of this string buffer is less
0120: * than the argument, then a new internal buffer is allocated with greater
0121: * capacity. The new capacity is the larger of:
0122: * <ul>
0123: * <li>The <code>minimumCapacity</code> argument.
0124: * <li>Twice the old capacity, plus <code>2</code>.
0125: * </ul>
0126: * If the <code>minimumCapacity</code> argument is nonpositive, this
0127: * method takes no action and simply returns.
0128: *
0129: * @param minimumCapacity
0130: * the minimum desired capacity.
0131: */
0132: public void ensureCapacity(int minimumCapacity) {
0133: if (minimumCapacity > value.length) {
0134: expandCapacity(minimumCapacity);
0135: }
0136: }
0137:
0138: /**
0139: * This implements the expansion semantics of ensureCapacity but is
0140: * unsynchronized for use internally by methods which are already
0141: * synchronized.
0142: *
0143: * @param minimumCapacity
0144: *
0145: * @see java.lang.StringBuffer#ensureCapacity(int)
0146: */
0147: private void expandCapacity(int minimumCapacity) {
0148: int newCapacity = (value.length + 1) * 2;
0149: if (newCapacity < 0) {
0150: newCapacity = Integer.MAX_VALUE;
0151: } else if (minimumCapacity > newCapacity) {
0152: newCapacity = minimumCapacity;
0153: }
0154:
0155: char newValue[] = new char[newCapacity];
0156: System.arraycopy(value, 0, newValue, 0, count);
0157: value = newValue;
0158: }
0159:
0160: /**
0161: * Sets the length of this String buffer. This string buffer is altered to
0162: * represent a new character sequence whose length is specified by the
0163: * argument. For every nonnegative index <i>k</i> less than
0164: * <code>newLength</code>, the character at index <i>k</i> in the new
0165: * character sequence is the same as the character at index <i>k</i> in the
0166: * old sequence if <i>k</i> is less than the length of the old character
0167: * sequence; otherwise, it is the null character <code>'\u0000'</code>.
0168: *
0169: * In other words, if the <code>newLength</code> argument is less than the
0170: * current length of the string buffer, the string buffer is truncated to
0171: * contain exactly the number of characters given by the
0172: * <code>newLength</code> argument.
0173: * <p>
0174: * If the <code>newLength</code> argument is greater than or equal to the
0175: * current length, sufficient null characters (<code>'\u0000'</code>)
0176: * are appended to the string buffer so that length becomes the
0177: * <code>newLength</code> argument.
0178: * <p>
0179: * The <code>newLength</code> argument must be greater than or equal to
0180: * <code>0</code>.
0181: *
0182: * @param newLength
0183: * the new length of the buffer.
0184: * @exception IndexOutOfBoundsException
0185: * if the <code>newLength</code> argument is negative.
0186: * @see java.lang.StringBuffer#length()
0187: */
0188: public void setLength(int newLength) {
0189: if (newLength < 0) {
0190: throw new StringIndexOutOfBoundsException(newLength);
0191: }
0192:
0193: if (newLength > value.length) {
0194: expandCapacity(newLength);
0195: }
0196:
0197: if (count < newLength) {
0198: for (; count < newLength; count++) {
0199: value[count] = '\0';
0200: }
0201: } else {
0202: count = newLength;
0203: }
0204: }
0205:
0206: /**
0207: * The specified character of the sequence currently represented by the
0208: * string buffer, as indicated by the <code>index</code> argument, is
0209: * returned. The first character of a string buffer is at index
0210: * <code>0</code>, the next at index <code>1</code>, and so on, for
0211: * array indexing.
0212: * <p>
0213: * The index argument must be greater than or equal to <code>0</code>,
0214: * and less than the length of this string buffer.
0215: *
0216: * @param index
0217: * the index of the desired character.
0218: * @return the character at the specified index of this string buffer.
0219: * @exception IndexOutOfBoundsException
0220: * if <code>index</code> is negative or greater than or
0221: * equal to <code>length()</code>.
0222: * @see java.lang.StringBuffer#length()
0223: */
0224: public char charAt(int index) {
0225: if ((index < 0) || (index >= count)) {
0226: throw new StringIndexOutOfBoundsException(index);
0227: }
0228: return value[index];
0229: }
0230:
0231: /**
0232: * Characters are copied from this string buffer into the destination
0233: * character array <code>dst</code>. The first character to be copied is
0234: * at index <code>srcBegin</code>; the last character to be copied is at
0235: * index <code>srcEnd-1</code>. The total number of characters to be
0236: * copied is <code>srcEnd-srcBegin</code>. The characters are copied into
0237: * the subarray of <code>dst</code> starting at index
0238: * <code>dstBegin</code> and ending at index:
0239: * <p>
0240: * <blockquote>
0241: *
0242: * <pre>
0243: * dstbegin + (srcEnd - srcBegin) - 1
0244: * </pre>
0245: *
0246: * </blockquote>
0247: *
0248: * @param srcBegin
0249: * start copying at this offset in the string buffer.
0250: * @param srcEnd
0251: * stop copying at this offset in the string buffer.
0252: * @param dst
0253: * the array to copy the data into.
0254: * @param dstBegin
0255: * offset into <code>dst</code>.
0256: * @exception NullPointerException
0257: * if <code>dst</code> is <code>null</code>.
0258: * @exception IndexOutOfBoundsException
0259: * if any of the following is true:
0260: * <ul>
0261: * <li><code>srcBegin</code> is negative
0262: * <li><code>dstBegin</code> is negative
0263: * <li>the <code>srcBegin</code> argument is greater than
0264: * the <code>srcEnd</code> argument.
0265: * <li><code>srcEnd</code> is greater than
0266: * <code>this.length()</code>, the current length of this
0267: * string buffer.
0268: * <li><code>dstBegin+srcEnd-srcBegin</code> is greater
0269: * than <code>dst.length</code>
0270: * </ul>
0271: */
0272: public void getChars(int srcBegin, int srcEnd, char dst[],
0273: int dstBegin) {
0274: if (srcBegin < 0) {
0275: throw new StringIndexOutOfBoundsException(srcBegin);
0276: }
0277: if ((srcEnd < 0) || (srcEnd > count)) {
0278: throw new StringIndexOutOfBoundsException(srcEnd);
0279: }
0280: if (srcBegin > srcEnd) {
0281: throw new StringIndexOutOfBoundsException(
0282: "srcBegin > srcEnd");
0283: }
0284: System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd
0285: - srcBegin);
0286: }
0287:
0288: /**
0289: * The character at the specified index of this string buffer is set to
0290: * <code>ch</code>. The string buffer is altered to represent a new
0291: * character sequence that is identical to the old character sequence,
0292: * except that it contains the character <code>ch</code> at position
0293: * <code>index</code>.
0294: * <p>
0295: * The index argument must be greater than or equal to <code>0</code>,
0296: * and less than the length of this string buffer.
0297: *
0298: * @param index
0299: * the index of the character to modify.
0300: * @param ch
0301: * the new character.
0302: * @exception IndexOutOfBoundsException
0303: * if <code>index</code> is negative or greater than or
0304: * equal to <code>length()</code>.
0305: * @see java.lang.StringBuffer#length()
0306: */
0307: public void setCharAt(int index, char ch) {
0308: if ((index < 0) || (index >= count)) {
0309: throw new StringIndexOutOfBoundsException(index);
0310: }
0311: value[index] = ch;
0312: }
0313:
0314: /**
0315: * Appends the string representation of the <code>Object</code> argument
0316: * to this string buffer.
0317: * <p>
0318: * The argument is converted to a string as if by the method
0319: * <code>String.valueOf</code>, and the characters of that string are
0320: * then appended to this string buffer.
0321: *
0322: * @param obj
0323: * an <code>Object</code>.
0324: * @return a reference to this <code>AppendingStringBuffer</code> object.
0325: * @see java.lang.String#valueOf(java.lang.Object)
0326: * @see java.lang.StringBuffer#append(java.lang.String)
0327: */
0328: public AppendingStringBuffer append(Object obj) {
0329: if (obj instanceof AppendingStringBuffer) {
0330: return append((AppendingStringBuffer) obj);
0331: } else if (obj instanceof StringBuffer) {
0332: return append((StringBuffer) obj);
0333: }
0334: return append(String.valueOf(obj));
0335: }
0336:
0337: /**
0338: * Appends the string to this string buffer.
0339: * <p>
0340: * The characters of the <code>String</code> argument are appended, in
0341: * order, to the contents of this string buffer, increasing the length of
0342: * this string buffer by the length of the argument. If <code>str</code>
0343: * is <code>null</code>, then the four characters <code>"null"</code>
0344: * are appended to this string buffer.
0345: * <p>
0346: * Let <i>n</i> be the length of the old character sequence, the one
0347: * contained in the string buffer just prior to execution of the
0348: * <code>append</code> method. Then the character at index <i>k</i> in
0349: * the new character sequence is equal to the character at index <i>k</i>
0350: * in the old character sequence, if <i>k</i> is less than <i>n</i>;
0351: * otherwise, it is equal to the character at index <i>k-n</i> in the
0352: * argument <code>str</code>.
0353: *
0354: * @param str
0355: * a string.
0356: * @return a reference to this <code>AppendingStringBuffer</code>.
0357: */
0358: public AppendingStringBuffer append(String str) {
0359: if (str == null) {
0360: str = String.valueOf(str);
0361: }
0362:
0363: int len = str.length();
0364: int newcount = count + len;
0365: if (newcount > value.length) {
0366: expandCapacity(newcount);
0367: }
0368: str.getChars(0, len, value, count);
0369: count = newcount;
0370: return this ;
0371: }
0372:
0373: /**
0374: * Appends the specified <tt>AppendingStringBuffer</tt> to this
0375: * <tt>AppendingStringBuffer</tt>.
0376: * <p>
0377: * The characters of the <tt>AppendingStringBuffer</tt> argument are
0378: * appended, in order, to the contents of this
0379: * <tt>AppendingStringBuffer</tt>, increasing the length of this
0380: * <tt>AppendingStringBuffer</tt> by the length of the argument. If
0381: * <tt>sb</tt> is <tt>null</tt>, then the four characters
0382: * <tt>"null"</tt> are appended to this <tt>AppendingStringBuffer</tt>.
0383: * <p>
0384: * Let <i>n</i> be the length of the old character sequence, the one
0385: * contained in the <tt>AppendingStringBuffer</tt> just prior to execution
0386: * of the <tt>append</tt> method. Then the character at index <i>k</i> in
0387: * the new character sequence is equal to the character at index <i>k</i>
0388: * in the old character sequence, if <i>k</i> is less than <i>n</i>;
0389: * otherwise, it is equal to the character at index <i>k-n</i> in the
0390: * argument <code>sb</code>.
0391: * <p>
0392: * The method <tt>ensureCapacity</tt> is first called on this
0393: * <tt>AppendingStringBuffer</tt> with the new buffer length as its
0394: * argument. (This ensures that the storage of this
0395: * <tt>AppendingStringBuffer</tt> is adequate to contain the additional
0396: * characters being appended.)
0397: *
0398: * @param sb
0399: * the <tt>AppendingStringBuffer</tt> to append.
0400: * @return a reference to this <tt>AppendingStringBuffer</tt>.
0401: * @since 1.4
0402: */
0403: public AppendingStringBuffer append(AppendingStringBuffer sb) {
0404: if (sb == null) {
0405: sb = NULL;
0406: }
0407:
0408: int len = sb.length();
0409: int newcount = count + len;
0410: if (newcount > value.length) {
0411: expandCapacity(newcount);
0412: }
0413: sb.getChars(0, len, value, count);
0414: count = newcount;
0415: return this ;
0416: }
0417:
0418: /**
0419: * Appends the specified <tt>AppendingStringBuffer</tt> to this
0420: * <tt>AppendingStringBuffer</tt>.
0421: * <p>
0422: * The characters of the <tt>AppendingStringBuffer</tt> argument are
0423: * appended, in order, to the contents of this
0424: * <tt>AppendingStringBuffer</tt>, increasing the length of this
0425: * <tt>AppendingStringBuffer</tt> by the length of the argument. If
0426: * <tt>sb</tt> is <tt>null</tt>, then the four characters
0427: * <tt>"null"</tt> are appended to this <tt>AppendingStringBuffer</tt>.
0428: * <p>
0429: * Let <i>n</i> be the length of the old character sequence, the one
0430: * contained in the <tt>AppendingStringBuffer</tt> just prior to execution
0431: * of the <tt>append</tt> method. Then the character at index <i>k</i> in
0432: * the new character sequence is equal to the character at index <i>k</i>
0433: * in the old character sequence, if <i>k</i> is less than <i>n</i>;
0434: * otherwise, it is equal to the character at index <i>k-n</i> in the
0435: * argument <code>sb</code>.
0436: * <p>
0437: * The method <tt>ensureCapacity</tt> is first called on this
0438: * <tt>AppendingStringBuffer</tt> with the new buffer length as its
0439: * argument. (This ensures that the storage of this
0440: * <tt>AppendingStringBuffer</tt> is adequate to contain the additional
0441: * characters being appended.)
0442: *
0443: * @param sb
0444: * the <tt>AppendingStringBuffer</tt> to append.
0445: * @return a reference to this <tt>AppendingStringBuffer</tt>.
0446: * @since 1.4
0447: */
0448: public AppendingStringBuffer append(StringBuffer sb) {
0449: if (sb == null) {
0450: sb = SB_NULL;
0451: }
0452:
0453: int len = sb.length();
0454: int newcount = count + len;
0455: if (newcount > value.length) {
0456: expandCapacity(newcount);
0457: }
0458: sb.getChars(0, len, value, count);
0459: count = newcount;
0460: return this ;
0461: }
0462:
0463: /**
0464: * Appends the specified <tt>AppendingStringBuffer</tt> to this
0465: * <tt>AppendingStringBuffer</tt>.
0466: * <p>
0467: * The characters of the <tt>AppendingStringBuffer</tt> argument are
0468: * appended, in order, to the contents of this
0469: * <tt>AppendingStringBuffer</tt>, increasing the length of this
0470: * <tt>AppendingStringBuffer</tt> by the length of the argument. If
0471: * <tt>sb</tt> is <tt>null</tt>, then the four characters
0472: * <tt>"null"</tt> are appended to this <tt>AppendingStringBuffer</tt>.
0473: * <p>
0474: * Let <i>n</i> be the length of the old character sequence, the one
0475: * contained in the <tt>AppendingStringBuffer</tt> just prior to execution
0476: * of the <tt>append</tt> method. Then the character at index <i>k</i> in
0477: * the new character sequence is equal to the character at index <i>k</i>
0478: * in the old character sequence, if <i>k</i> is less than <i>n</i>;
0479: * otherwise, it is equal to the character at index <i>k-n</i> in the
0480: * argument <code>sb</code>.
0481: * <p>
0482: * The method <tt>ensureCapacity</tt> is first called on this
0483: * <tt>AppendingStringBuffer</tt> with the new buffer length as its
0484: * argument. (This ensures that the storage of this
0485: * <tt>AppendingStringBuffer</tt> is adequate to contain the additional
0486: * characters being appended.)
0487: *
0488: * @param sb
0489: * the <tt>AppendingStringBuffer</tt> to append.
0490: * @param from
0491: * The index where it must start from
0492: * @param length
0493: * The length that must be copied
0494: * @return a reference to this <tt>AppendingStringBuffer</tt>.
0495: */
0496: public AppendingStringBuffer append(StringBuffer sb, int from,
0497: int length) {
0498: if (sb == null) {
0499: sb = SB_NULL;
0500: }
0501:
0502: int newcount = count + length;
0503: if (newcount > value.length) {
0504: expandCapacity(newcount);
0505: }
0506: sb.getChars(from, length, value, count);
0507: count = newcount;
0508: return this ;
0509: }
0510:
0511: /**
0512: * Appends the string representation of the <code>char</code> array
0513: * argument to this string buffer.
0514: * <p>
0515: * The characters of the array argument are appended, in order, to the
0516: * contents of this string buffer. The length of this string buffer
0517: * increases by the length of the argument.
0518: * <p>
0519: * The overall effect is exactly as if the argument were converted to a
0520: * string by the method {@link String#valueOf(char[])} and the characters of
0521: * that string were then {@link #append(String) appended} to this
0522: * <code>AppendingStringBuffer</code> object.
0523: *
0524: * @param str
0525: * the characters to be appended.
0526: * @return a reference to this <code>AppendingStringBuffer</code> object.
0527: */
0528: public AppendingStringBuffer append(char str[]) {
0529: int len = str.length;
0530: int newcount = count + len;
0531: if (newcount > value.length) {
0532: expandCapacity(newcount);
0533: }
0534: System.arraycopy(str, 0, value, count, len);
0535: count = newcount;
0536: return this ;
0537: }
0538:
0539: /**
0540: * Appends the string representation of a subarray of the <code>char</code>
0541: * array argument to this string buffer.
0542: * <p>
0543: * Characters of the character array <code>str</code>, starting at index
0544: * <code>offset</code>, are appended, in order, to the contents of this
0545: * string buffer. The length of this string buffer increases by the value of
0546: * <code>len</code>.
0547: * <p>
0548: * The overall effect is exactly as if the arguments were converted to a
0549: * string by the method {@link String#valueOf(char[],int,int)} and the
0550: * characters of that string were then {@link #append(String) appended} to
0551: * this <code>AppendingStringBuffer</code> object.
0552: *
0553: * @param str
0554: * the characters to be appended.
0555: * @param offset
0556: * the index of the first character to append.
0557: * @param len
0558: * the number of characters to append.
0559: * @return a reference to this <code>AppendingStringBuffer</code> object.
0560: */
0561: public AppendingStringBuffer append(char str[], int offset, int len) {
0562: int newcount = count + len;
0563: if (newcount > value.length) {
0564: expandCapacity(newcount);
0565: }
0566: System.arraycopy(str, offset, value, count, len);
0567: count = newcount;
0568: return this ;
0569: }
0570:
0571: /**
0572: * Appends the string representation of the <code>boolean</code> argument
0573: * to the string buffer.
0574: * <p>
0575: * The argument is converted to a string as if by the method
0576: * <code>String.valueOf</code>, and the characters of that string are
0577: * then appended to this string buffer.
0578: *
0579: * @param b
0580: * a <code>boolean</code>.
0581: * @return a reference to this <code>AppendingStringBuffer</code>.
0582: * @see java.lang.String#valueOf(boolean)
0583: * @see java.lang.StringBuffer#append(java.lang.String)
0584: */
0585: public AppendingStringBuffer append(boolean b) {
0586: if (b) {
0587: int newcount = count + 4;
0588: if (newcount > value.length) {
0589: expandCapacity(newcount);
0590: }
0591: value[count++] = 't';
0592: value[count++] = 'r';
0593: value[count++] = 'u';
0594: value[count++] = 'e';
0595: } else {
0596: int newcount = count + 5;
0597: if (newcount > value.length) {
0598: expandCapacity(newcount);
0599: }
0600: value[count++] = 'f';
0601: value[count++] = 'a';
0602: value[count++] = 'l';
0603: value[count++] = 's';
0604: value[count++] = 'e';
0605: }
0606: return this ;
0607: }
0608:
0609: /**
0610: * Appends the string representation of the <code>char</code> argument to
0611: * this string buffer.
0612: * <p>
0613: * The argument is appended to the contents of this string buffer. The
0614: * length of this string buffer increases by <code>1</code>.
0615: * <p>
0616: * The overall effect is exactly as if the argument were converted to a
0617: * string by the method {@link String#valueOf(char)} and the character in
0618: * that string were then {@link #append(String) appended} to this
0619: * <code>AppendingStringBuffer</code> object.
0620: *
0621: * @param c
0622: * a <code>char</code>.
0623: * @return a reference to this <code>AppendingStringBuffer</code> object.
0624: */
0625: public AppendingStringBuffer append(char c) {
0626: int newcount = count + 1;
0627: if (newcount > value.length) {
0628: expandCapacity(newcount);
0629: }
0630: value[count++] = c;
0631: return this ;
0632: }
0633:
0634: /**
0635: * Appends the string representation of the <code>int</code> argument to
0636: * this string buffer.
0637: * <p>
0638: * The argument is converted to a string as if by the method
0639: * <code>String.valueOf</code>, and the characters of that string are
0640: * then appended to this string buffer.
0641: *
0642: * @param i
0643: * an <code>int</code>.
0644: * @return a reference to this <code>AppendingStringBuffer</code> object.
0645: * @see java.lang.String#valueOf(int)
0646: * @see java.lang.StringBuffer#append(java.lang.String)
0647: */
0648: public AppendingStringBuffer append(int i) {
0649: return append(String.valueOf(i));
0650: }
0651:
0652: /**
0653: * Appends the string representation of the <code>long</code> argument to
0654: * this string buffer.
0655: * <p>
0656: * The argument is converted to a string as if by the method
0657: * <code>String.valueOf</code>, and the characters of that string are
0658: * then appended to this string buffer.
0659: *
0660: * @param l
0661: * a <code>long</code>.
0662: * @return a reference to this <code>AppendingStringBuffer</code> object.
0663: * @see java.lang.String#valueOf(long)
0664: * @see java.lang.StringBuffer#append(java.lang.String)
0665: */
0666: public AppendingStringBuffer append(long l) {
0667: return append(String.valueOf(l));
0668: }
0669:
0670: /**
0671: * Appends the string representation of the <code>float</code> argument to
0672: * this string buffer.
0673: * <p>
0674: * The argument is converted to a string as if by the method
0675: * <code>String.valueOf</code>, and the characters of that string are
0676: * then appended to this string buffer.
0677: *
0678: * @param f
0679: * a <code>float</code>.
0680: * @return a reference to this <code>AppendingStringBuffer</code> object.
0681: * @see java.lang.String#valueOf(float)
0682: * @see java.lang.StringBuffer#append(java.lang.String)
0683: */
0684: public AppendingStringBuffer append(float f) {
0685: return append(String.valueOf(f));
0686: }
0687:
0688: /**
0689: * Appends the string representation of the <code>double</code> argument
0690: * to this string buffer.
0691: * <p>
0692: * The argument is converted to a string as if by the method
0693: * <code>String.valueOf</code>, and the characters of that string are
0694: * then appended to this string buffer.
0695: *
0696: * @param d
0697: * a <code>double</code>.
0698: * @return a reference to this <code>AppendingStringBuffer</code> object.
0699: * @see java.lang.String#valueOf(double)
0700: * @see java.lang.StringBuffer#append(java.lang.String)
0701: */
0702: public AppendingStringBuffer append(double d) {
0703: return append(String.valueOf(d));
0704: }
0705:
0706: /**
0707: * Removes the characters in a substring of this
0708: * <code>AppendingStringBuffer</code>. The substring begins at the
0709: * specified <code>start</code> and extends to the character at index
0710: * <code>end - 1</code> or to the end of the
0711: * <code>AppendingStringBuffer</code> if no such character exists. If
0712: * <code>start</code> is equal to <code>end</code>, no changes are
0713: * made.
0714: *
0715: * @param start
0716: * The beginning index, inclusive.
0717: * @param end
0718: * The ending index, exclusive.
0719: * @return This string buffer.
0720: * @exception StringIndexOutOfBoundsException
0721: * if <code>start</code> is negative, greater than
0722: * <code>length()</code>, or greater than <code>end</code>.
0723: * @since 1.2
0724: */
0725: public AppendingStringBuffer delete(int start, int end) {
0726: if (start < 0) {
0727: throw new StringIndexOutOfBoundsException(start);
0728: }
0729: if (end > count) {
0730: end = count;
0731: }
0732: if (start > end) {
0733: throw new StringIndexOutOfBoundsException();
0734: }
0735:
0736: int len = end - start;
0737: if (len > 0) {
0738: System.arraycopy(value, start + len, value, start, count
0739: - end);
0740: count -= len;
0741: }
0742: return this ;
0743: }
0744:
0745: /**
0746: * Removes the character at the specified position in this
0747: * <code>AppendingStringBuffer</code> (shortening the
0748: * <code>AppendingStringBuffer</code> by one character).
0749: *
0750: * @param index
0751: * Index of character to remove
0752: * @return This string buffer.
0753: * @exception StringIndexOutOfBoundsException
0754: * if the <code>index</code> is negative or greater than or
0755: * equal to <code>length()</code>.
0756: * @since 1.2
0757: */
0758: public AppendingStringBuffer deleteCharAt(int index) {
0759: if ((index < 0) || (index >= count)) {
0760: throw new StringIndexOutOfBoundsException();
0761: }
0762: System.arraycopy(value, index + 1, value, index, count - index
0763: - 1);
0764: count--;
0765: return this ;
0766: }
0767:
0768: /**
0769: * Replaces the characters in a substring of this
0770: * <code>AppendingStringBuffer</code> with characters in the specified
0771: * <code>String</code>. The substring begins at the specified
0772: * <code>start</code> and extends to the character at index
0773: * <code>end - 1</code> or to the end of the
0774: * <code>AppendingStringBuffer</code> if no such character exists. First
0775: * the characters in the substring are removed and then the specified
0776: * <code>String</code> is inserted at <code>start</code>. (The
0777: * <code>AppendingStringBuffer</code> will be lengthened to accommodate
0778: * the specified String if necessary.)
0779: *
0780: * @param start
0781: * The beginning index, inclusive.
0782: * @param end
0783: * The ending index, exclusive.
0784: * @param str
0785: * String that will replace previous contents.
0786: * @return This string buffer.
0787: * @exception StringIndexOutOfBoundsException
0788: * if <code>start</code> is negative, greater than
0789: * <code>length()</code>, or greater than <code>end</code>.
0790: * @since 1.2
0791: */
0792: public AppendingStringBuffer replace(int start, int end, String str) {
0793: if (start < 0) {
0794: throw new StringIndexOutOfBoundsException(start);
0795: }
0796: if (end > count) {
0797: end = count;
0798: }
0799: if (start > end) {
0800: throw new StringIndexOutOfBoundsException();
0801: }
0802:
0803: int len = str.length();
0804: int newCount = count + len - (end - start);
0805: if (newCount > value.length) {
0806: expandCapacity(newCount);
0807: }
0808:
0809: System.arraycopy(value, end, value, start + len, count - end);
0810: str.getChars(0, len, value, start);
0811: count = newCount;
0812: return this ;
0813: }
0814:
0815: /**
0816: * Returns a new <code>String</code> that contains a subsequence of
0817: * characters currently contained in this <code>AppendingStringBuffer</code>.The
0818: * substring begins at the specified index and extends to the end of the
0819: * <code>AppendingStringBuffer</code>.
0820: *
0821: * @param start
0822: * The beginning index, inclusive.
0823: * @return The new string.
0824: * @exception StringIndexOutOfBoundsException
0825: * if <code>start</code> is less than zero, or greater than
0826: * the length of this <code>AppendingStringBuffer</code>.
0827: * @since 1.2
0828: */
0829: public String substring(int start) {
0830: return substring(start, count);
0831: }
0832:
0833: /**
0834: * Returns a new character sequence that is a subsequence of this sequence.
0835: *
0836: * <p>
0837: * An invocation of this method of the form
0838: *
0839: * <blockquote>
0840: *
0841: * <pre>
0842: * sb.subSequence(begin, end)
0843: * </pre>
0844: *
0845: * </blockquote>
0846: *
0847: * behaves in exactly the same way as the invocation
0848: *
0849: * <blockquote>
0850: *
0851: * <pre>
0852: * sb.substring(begin, end)
0853: * </pre>
0854: *
0855: * </blockquote>
0856: *
0857: * This method is provided so that the <tt>AppendingStringBuffer</tt>
0858: * class can implement the {@link CharSequence} interface.
0859: * </p>
0860: *
0861: * @param start
0862: * the start index, inclusive.
0863: * @param end
0864: * the end index, exclusive.
0865: * @return the specified subsequence.
0866: *
0867: * @throws IndexOutOfBoundsException
0868: * if <tt>start</tt> or <tt>end</tt> are negative, if
0869: * <tt>end</tt> is greater than <tt>length()</tt>, or if
0870: * <tt>start</tt> is greater than <tt>end</tt>
0871: *
0872: * @since 1.4
0873: * @spec JSR-51
0874: */
0875: public CharSequence subSequence(int start, int end) {
0876: return this .substring(start, end);
0877: }
0878:
0879: /**
0880: * Returns a new <code>String</code> that contains a subsequence of
0881: * characters currently contained in this <code>AppendingStringBuffer</code>.
0882: * The substring begins at the specified <code>start</code> and extends to
0883: * the character at index <code>end - 1</code>. An exception is thrown if
0884: *
0885: * @param start
0886: * The beginning index, inclusive.
0887: * @param end
0888: * The ending index, exclusive.
0889: * @return The new string.
0890: * @exception StringIndexOutOfBoundsException
0891: * if <code>start</code> or <code>end</code> are negative
0892: * or greater than <code>length()</code>, or
0893: * <code>start</code> is greater than <code>end</code>.
0894: * @since 1.2
0895: */
0896: public String substring(int start, int end) {
0897: if (start < 0) {
0898: throw new StringIndexOutOfBoundsException(start);
0899: }
0900: if (end > count) {
0901: throw new StringIndexOutOfBoundsException(end);
0902: }
0903: if (start > end) {
0904: throw new StringIndexOutOfBoundsException(end - start);
0905: }
0906: return new String(value, start, end - start);
0907: }
0908:
0909: /**
0910: * Inserts the string representation of a subarray of the <code>str</code>
0911: * array argument into this string buffer. The subarray begins at the
0912: * specified <code>offset</code> and extends <code>len</code>
0913: * characters. The characters of the subarray are inserted into this string
0914: * buffer at the position indicated by <code>index</code>. The length of
0915: * this <code>AppendingStringBuffer</code> increases by <code>len</code>
0916: * characters.
0917: *
0918: * @param index
0919: * position at which to insert subarray.
0920: * @param str
0921: * A character array.
0922: * @param offset
0923: * the index of the first character in subarray to to be
0924: * inserted.
0925: * @param len
0926: * the number of characters in the subarray to to be inserted.
0927: * @return This string buffer.
0928: * @exception StringIndexOutOfBoundsException
0929: * if <code>index</code> is negative or greater than
0930: * <code>length()</code>, or <code>offset</code> or
0931: * <code>len</code> are negative, or
0932: * <code>(offset+len)</code> is greater than
0933: * <code>str.length</code>.
0934: * @since 1.2
0935: */
0936: public AppendingStringBuffer insert(int index, char str[],
0937: int offset, int len) {
0938: if ((index < 0) || (index > count)) {
0939: throw new StringIndexOutOfBoundsException();
0940: }
0941: if ((offset < 0) || (offset + len < 0)
0942: || (offset + len > str.length)) {
0943: throw new StringIndexOutOfBoundsException(offset);
0944: }
0945: if (len < 0) {
0946: throw new StringIndexOutOfBoundsException(len);
0947: }
0948: int newCount = count + len;
0949: if (newCount > value.length) {
0950: expandCapacity(newCount);
0951: }
0952: System.arraycopy(value, index, value, index + len, count
0953: - index);
0954: System.arraycopy(str, offset, value, index, len);
0955: count = newCount;
0956: return this ;
0957: }
0958:
0959: /**
0960: * Inserts the string representation of the <code>Object</code> argument
0961: * into this string buffer.
0962: * <p>
0963: * The second argument is converted to a string as if by the method
0964: * <code>String.valueOf</code>, and the characters of that string are
0965: * then inserted into this string buffer at the indicated offset.
0966: * <p>
0967: * The offset argument must be greater than or equal to <code>0</code>,
0968: * and less than or equal to the length of this string buffer.
0969: *
0970: * @param offset
0971: * the offset.
0972: * @param obj
0973: * an <code>Object</code>.
0974: * @return a reference to this <code>AppendingStringBuffer</code> object.
0975: * @exception StringIndexOutOfBoundsException
0976: * if the offset is invalid.
0977: * @see java.lang.String#valueOf(java.lang.Object)
0978: * @see AppendingStringBuffer#insert(int, java.lang.String)
0979: * @see AppendingStringBuffer#length()
0980: */
0981: public AppendingStringBuffer insert(int offset, Object obj) {
0982: if (obj instanceof AppendingStringBuffer) {
0983: AppendingStringBuffer asb = (AppendingStringBuffer) obj;
0984: return insert(offset, asb.value, 0, asb.count);
0985: } else if (obj instanceof StringBuffer) {
0986: return insert(offset, (StringBuffer) obj);
0987: }
0988: return insert(offset, String.valueOf(obj));
0989: }
0990:
0991: /**
0992: * Inserts the string into this string buffer.
0993: * <p>
0994: * The characters of the <code>String</code> argument are inserted, in
0995: * order, into this string buffer at the indicated offset, moving up any
0996: * characters originally above that position and increasing the length of
0997: * this string buffer by the length of the argument. If <code>str</code>
0998: * is <code>null</code>, then the four characters <code>"null"</code>
0999: * are inserted into this string buffer.
1000: * <p>
1001: * The character at index <i>k</i> in the new character sequence is equal
1002: * to:
1003: * <ul>
1004: * <li>the character at index <i>k</i> in the old character sequence, if
1005: * <i>k</i> is less than <code>offset</code>
1006: * <li>the character at index <i>k</i><code>-offset</code> in the
1007: * argument <code>str</code>, if <i>k</i> is not less than
1008: * <code>offset</code> but is less than <code>offset+str.length()</code>
1009: * <li>the character at index <i>k</i><code>-str.length()</code> in the
1010: * old character sequence, if <i>k</i> is not less than
1011: * <code>offset+str.length()</code>
1012: * </ul>
1013: * <p>
1014: * The offset argument must be greater than or equal to <code>0</code>,
1015: * and less than or equal to the length of this string buffer.
1016: *
1017: * @param offset
1018: * the offset.
1019: * @param str
1020: * a string.
1021: * @return a reference to this <code>AppendingStringBuffer</code> object.
1022: * @exception StringIndexOutOfBoundsException
1023: * if the offset is invalid.
1024: * @see java.lang.StringBuffer#length()
1025: */
1026: public AppendingStringBuffer insert(int offset, String str) {
1027: if ((offset < 0) || (offset > count)) {
1028: throw new StringIndexOutOfBoundsException();
1029: }
1030:
1031: if (str == null) {
1032: str = String.valueOf(str);
1033: }
1034: int len = str.length();
1035: int newcount = count + len;
1036: if (newcount > value.length) {
1037: expandCapacity(newcount);
1038: }
1039: System.arraycopy(value, offset, value, offset + len, count
1040: - offset);
1041: str.getChars(0, len, value, offset);
1042: count = newcount;
1043: return this ;
1044: }
1045:
1046: /**
1047: * Inserts the string into this string buffer.
1048: * <p>
1049: * The characters of the <code>String</code> argument are inserted, in
1050: * order, into this string buffer at the indicated offset, moving up any
1051: * characters originally above that position and increasing the length of
1052: * this string buffer by the length of the argument. If <code>str</code>
1053: * is <code>null</code>, then the four characters <code>"null"</code>
1054: * are inserted into this string buffer.
1055: * <p>
1056: * The character at index <i>k</i> in the new character sequence is equal
1057: * to:
1058: * <ul>
1059: * <li>the character at index <i>k</i> in the old character sequence, if
1060: * <i>k</i> is less than <code>offset</code>
1061: * <li>the character at index <i>k</i><code>-offset</code> in the
1062: * argument <code>str</code>, if <i>k</i> is not less than
1063: * <code>offset</code> but is less than <code>offset+str.length()</code>
1064: * <li>the character at index <i>k</i><code>-str.length()</code> in the
1065: * old character sequence, if <i>k</i> is not less than
1066: * <code>offset+str.length()</code>
1067: * </ul>
1068: * <p>
1069: * The offset argument must be greater than or equal to <code>0</code>,
1070: * and less than or equal to the length of this string buffer.
1071: *
1072: * @param offset
1073: * the offset.
1074: * @param str
1075: * a string.
1076: * @return a reference to this <code>AppendingStringBuffer</code> object.
1077: * @exception StringIndexOutOfBoundsException
1078: * if the offset is invalid.
1079: * @see java.lang.StringBuffer#length()
1080: */
1081: public AppendingStringBuffer insert(int offset, StringBuffer str) {
1082: if ((offset < 0) || (offset > count)) {
1083: throw new StringIndexOutOfBoundsException();
1084: }
1085:
1086: if (str == null) {
1087: str = SB_NULL;
1088: }
1089: int len = str.length();
1090: int newcount = count + len;
1091: if (newcount > value.length) {
1092: expandCapacity(newcount);
1093: }
1094: System.arraycopy(value, offset, value, offset + len, count
1095: - offset);
1096: str.getChars(0, len, value, offset);
1097: count = newcount;
1098: return this ;
1099: }
1100:
1101: /**
1102: * Inserts the string representation of the <code>char</code> array
1103: * argument into this string buffer.
1104: * <p>
1105: * The characters of the array argument are inserted into the contents of
1106: * this string buffer at the position indicated by <code>offset</code>.
1107: * The length of this string buffer increases by the length of the argument.
1108: * <p>
1109: * The overall effect is exactly as if the argument were converted to a
1110: * string by the method {@link String#valueOf(char[])} and the characters of
1111: * that string were then {@link #insert(int,String) inserted} into this
1112: * <code>AppendingStringBuffer</code> object at the position indicated by
1113: * <code>offset</code>.
1114: *
1115: * @param offset
1116: * the offset.
1117: * @param str
1118: * a character array.
1119: * @return a reference to this <code>AppendingStringBuffer</code> object.
1120: * @exception StringIndexOutOfBoundsException
1121: * if the offset is invalid.
1122: */
1123: public AppendingStringBuffer insert(int offset, char str[]) {
1124: if ((offset < 0) || (offset > count)) {
1125: throw new StringIndexOutOfBoundsException();
1126: }
1127: int len = str.length;
1128: int newcount = count + len;
1129: if (newcount > value.length) {
1130: expandCapacity(newcount);
1131: }
1132: System.arraycopy(value, offset, value, offset + len, count
1133: - offset);
1134: System.arraycopy(str, 0, value, offset, len);
1135: count = newcount;
1136: return this ;
1137: }
1138:
1139: /**
1140: * Inserts the string representation of the <code>boolean</code> argument
1141: * into this string buffer.
1142: * <p>
1143: * The second argument is converted to a string as if by the method
1144: * <code>String.valueOf</code>, and the characters of that string are
1145: * then inserted into this string buffer at the indicated offset.
1146: * <p>
1147: * The offset argument must be greater than or equal to <code>0</code>,
1148: * and less than or equal to the length of this string buffer.
1149: *
1150: * @param offset
1151: * the offset.
1152: * @param b
1153: * a <code>boolean</code>.
1154: * @return a reference to this <code>AppendingStringBuffer</code> object.
1155: * @exception StringIndexOutOfBoundsException
1156: * if the offset is invalid.
1157: * @see java.lang.String#valueOf(boolean)
1158: * @see java.lang.StringBuffer#insert(int, java.lang.String)
1159: * @see java.lang.StringBuffer#length()
1160: */
1161: public AppendingStringBuffer insert(int offset, boolean b) {
1162: return insert(offset, String.valueOf(b));
1163: }
1164:
1165: /**
1166: * Inserts the string representation of the <code>char</code> argument
1167: * into this string buffer.
1168: * <p>
1169: * The second argument is inserted into the contents of this string buffer
1170: * at the position indicated by <code>offset</code>. The length of this
1171: * string buffer increases by one.
1172: * <p>
1173: * The overall effect is exactly as if the argument were converted to a
1174: * string by the method {@link String#valueOf(char)} and the character in
1175: * that string were then {@link #insert(int, String) inserted} into this
1176: * <code>AppendingStringBuffer</code> object at the position indicated by
1177: * <code>offset</code>.
1178: * <p>
1179: * The offset argument must be greater than or equal to <code>0</code>,
1180: * and less than or equal to the length of this string buffer.
1181: *
1182: * @param offset
1183: * the offset.
1184: * @param c
1185: * a <code>char</code>.
1186: * @return a reference to this <code>AppendingStringBuffer</code> object.
1187: * @exception IndexOutOfBoundsException
1188: * if the offset is invalid.
1189: * @see java.lang.StringBuffer#length()
1190: */
1191: public AppendingStringBuffer insert(int offset, char c) {
1192: int newcount = count + 1;
1193: if (newcount > value.length) {
1194: expandCapacity(newcount);
1195: }
1196: System.arraycopy(value, offset, value, offset + 1, count
1197: - offset);
1198: value[offset] = c;
1199: count = newcount;
1200: return this ;
1201: }
1202:
1203: /**
1204: * Inserts the string representation of the second <code>int</code>
1205: * argument into this string buffer.
1206: * <p>
1207: * The second argument is converted to a string as if by the method
1208: * <code>String.valueOf</code>, and the characters of that string are
1209: * then inserted into this string buffer at the indicated offset.
1210: * <p>
1211: * The offset argument must be greater than or equal to <code>0</code>,
1212: * and less than or equal to the length of this string buffer.
1213: *
1214: * @param offset
1215: * the offset.
1216: * @param i
1217: * an <code>int</code>.
1218: * @return a reference to this <code>AppendingStringBuffer</code> object.
1219: * @exception StringIndexOutOfBoundsException
1220: * if the offset is invalid.
1221: * @see java.lang.String#valueOf(int)
1222: * @see java.lang.StringBuffer#insert(int, java.lang.String)
1223: * @see java.lang.StringBuffer#length()
1224: */
1225: public AppendingStringBuffer insert(int offset, int i) {
1226: return insert(offset, String.valueOf(i));
1227: }
1228:
1229: /**
1230: * Inserts the string representation of the <code>long</code> argument
1231: * into this string buffer.
1232: * <p>
1233: * The second argument is converted to a string as if by the method
1234: * <code>String.valueOf</code>, and the characters of that string are
1235: * then inserted into this string buffer at the position indicated by
1236: * <code>offset</code>.
1237: * <p>
1238: * The offset argument must be greater than or equal to <code>0</code>,
1239: * and less than or equal to the length of this string buffer.
1240: *
1241: * @param offset
1242: * the offset.
1243: * @param l
1244: * a <code>long</code>.
1245: * @return a reference to this <code>AppendingStringBuffer</code> object.
1246: * @exception StringIndexOutOfBoundsException
1247: * if the offset is invalid.
1248: * @see java.lang.String#valueOf(long)
1249: * @see java.lang.StringBuffer#insert(int, java.lang.String)
1250: * @see java.lang.StringBuffer#length()
1251: */
1252: public AppendingStringBuffer insert(int offset, long l) {
1253: return insert(offset, String.valueOf(l));
1254: }
1255:
1256: /**
1257: * Inserts the string representation of the <code>float</code> argument
1258: * into this string buffer.
1259: * <p>
1260: * The second argument is converted to a string as if by the method
1261: * <code>String.valueOf</code>, and the characters of that string are
1262: * then inserted into this string buffer at the indicated offset.
1263: * <p>
1264: * The offset argument must be greater than or equal to <code>0</code>,
1265: * and less than or equal to the length of this string buffer.
1266: *
1267: * @param offset
1268: * the offset.
1269: * @param f
1270: * a <code>float</code>.
1271: * @return a reference to this <code>AppendingStringBuffer</code> object.
1272: * @exception StringIndexOutOfBoundsException
1273: * if the offset is invalid.
1274: * @see java.lang.String#valueOf(float)
1275: * @see java.lang.StringBuffer#insert(int, java.lang.String)
1276: * @see java.lang.StringBuffer#length()
1277: */
1278: public AppendingStringBuffer insert(int offset, float f) {
1279: return insert(offset, String.valueOf(f));
1280: }
1281:
1282: /**
1283: * Inserts the string representation of the <code>double</code> argument
1284: * into this string buffer.
1285: * <p>
1286: * The second argument is converted to a string as if by the method
1287: * <code>String.valueOf</code>, and the characters of that string are
1288: * then inserted into this string buffer at the indicated offset.
1289: * <p>
1290: * The offset argument must be greater than or equal to <code>0</code>,
1291: * and less than or equal to the length of this string buffer.
1292: *
1293: * @param offset
1294: * the offset.
1295: * @param d
1296: * a <code>double</code>.
1297: * @return a reference to this <code>AppendingStringBuffer</code> object.
1298: * @exception StringIndexOutOfBoundsException
1299: * if the offset is invalid.
1300: * @see java.lang.String#valueOf(double)
1301: * @see java.lang.StringBuffer#insert(int, java.lang.String)
1302: * @see java.lang.StringBuffer#length()
1303: */
1304: public AppendingStringBuffer insert(int offset, double d) {
1305: return insert(offset, String.valueOf(d));
1306: }
1307:
1308: /**
1309: * Returns the index within this string of the first occurrence of the
1310: * specified substring. The integer returned is the smallest value <i>k</i>
1311: * such that: <blockquote>
1312: *
1313: * <pre>
1314: * this.toString().startsWith(str, <i>k</i>)
1315: * </pre>
1316: *
1317: * </blockquote> is <code>true</code>.
1318: *
1319: * @param str
1320: * any string.
1321: * @return if the string argument occurs as a substring within this object,
1322: * then the index of the first character of the first such substring
1323: * is returned; if it does not occur as a substring, <code>-1</code>
1324: * is returned.
1325: * @exception java.lang.NullPointerException
1326: * if <code>str</code> is <code>null</code>.
1327: * @since 1.4
1328: */
1329: public int indexOf(String str) {
1330: return indexOf(str, 0);
1331: }
1332:
1333: /**
1334: * Returns the index within this string of the first occurrence of the
1335: * specified substring, starting at the specified index. The integer
1336: * returned is the smallest value <tt>k</tt> for which: <blockquote>
1337: *
1338: * <pre>
1339: * k >= Math.min(fromIndex, str.length()) && this.toString().startsWith(str, k)
1340: * </pre>
1341: *
1342: * </blockquote> If no such value of <i>k</i> exists, then -1 is returned.
1343: *
1344: * @param str
1345: * the substring for which to search.
1346: * @param fromIndex
1347: * the index from which to start the search.
1348: * @return the index within this string of the first occurrence of the
1349: * specified substring, starting at the specified index.
1350: * @exception java.lang.NullPointerException
1351: * if <code>str</code> is <code>null</code>.
1352: * @since 1.4
1353: */
1354: public int indexOf(String str, int fromIndex) {
1355: return indexOf(value, 0, count, str.toCharArray(), 0, str
1356: .length(), fromIndex);
1357: }
1358:
1359: static int indexOf(char[] source, int sourceOffset,
1360: int sourceCount, char[] target, int targetOffset,
1361: int targetCount, int fromIndex) {
1362: if (fromIndex >= sourceCount) {
1363: return (targetCount == 0 ? sourceCount : -1);
1364: }
1365: if (fromIndex < 0) {
1366: fromIndex = 0;
1367: }
1368: if (targetCount == 0) {
1369: return fromIndex;
1370: }
1371:
1372: char first = target[targetOffset];
1373: int i = sourceOffset + fromIndex;
1374: int max = sourceOffset + (sourceCount - targetCount);
1375:
1376: startSearchForFirstChar: while (true) {
1377: /* Look for first character. */
1378: while (i <= max && source[i] != first) {
1379: i++;
1380: }
1381: if (i > max) {
1382: return -1;
1383: }
1384:
1385: /* Found first character, now look at the rest of v2 */
1386: int j = i + 1;
1387: int end = j + targetCount - 1;
1388: int k = targetOffset + 1;
1389: while (j < end) {
1390: if (source[j++] != target[k++]) {
1391: i++;
1392: /* Look for str's first char again. */
1393: continue startSearchForFirstChar;
1394: }
1395: }
1396: return i - sourceOffset; /* Found whole string. */
1397: }
1398: }
1399:
1400: /**
1401: * Returns the index within this string of the rightmost occurrence of the
1402: * specified substring. The rightmost empty string "" is considered to occur
1403: * at the index value <code>this.length()</code>. The returned index is
1404: * the largest value <i>k</i> such that <blockquote>
1405: *
1406: * <pre>
1407: * this.toString().startsWith(str, k)
1408: * </pre>
1409: *
1410: * </blockquote> is true.
1411: *
1412: * @param str
1413: * the substring to search for.
1414: * @return if the string argument occurs one or more times as a substring
1415: * within this object, then the index of the first character of the
1416: * last such substring is returned. If it does not occur as a
1417: * substring, <code>-1</code> is returned.
1418: * @exception java.lang.NullPointerException
1419: * if <code>str</code> is <code>null</code>.
1420: * @since 1.4
1421: */
1422: public int lastIndexOf(String str) {
1423: return lastIndexOf(str, count);
1424: }
1425:
1426: /**
1427: * Returns the index within this string of the last occurrence of the
1428: * specified substring. The integer returned is the largest value <i>k</i>
1429: * such that: <blockquote>
1430: *
1431: * <pre>
1432: * k <= Math.min(fromIndex, str.length()) && this.toString().startsWith(str, k)
1433: * </pre>
1434: *
1435: * </blockquote> If no such value of <i>k</i> exists, then -1 is returned.
1436: *
1437: * @param str
1438: * the substring to search for.
1439: * @param fromIndex
1440: * the index to start the search from.
1441: * @return the index within this string of the last occurrence of the
1442: * specified substring.
1443: * @exception java.lang.NullPointerException
1444: * if <code>str</code> is <code>null</code>.
1445: * @since 1.4
1446: */
1447: public int lastIndexOf(String str, int fromIndex) {
1448: return lastIndexOf(value, 0, count, str.toCharArray(), 0, str
1449: .length(), fromIndex);
1450: }
1451:
1452: static int lastIndexOf(char[] source, int sourceOffset,
1453: int sourceCount, char[] target, int targetOffset,
1454: int targetCount, int fromIndex) {
1455: /*
1456: * Check arguments; return immediately where possible. For consistency,
1457: * don't check for null str.
1458: */
1459: int rightIndex = sourceCount - targetCount;
1460: if (fromIndex < 0) {
1461: return -1;
1462: }
1463: if (fromIndex > rightIndex) {
1464: fromIndex = rightIndex;
1465: }
1466: /* Empty string always matches. */
1467: if (targetCount == 0) {
1468: return fromIndex;
1469: }
1470:
1471: int strLastIndex = targetOffset + targetCount - 1;
1472: char strLastChar = target[strLastIndex];
1473: int min = sourceOffset + targetCount - 1;
1474: int i = min + fromIndex;
1475:
1476: startSearchForLastChar: while (true) {
1477: while (i >= min && source[i] != strLastChar) {
1478: i--;
1479: }
1480: if (i < min) {
1481: return -1;
1482: }
1483: int j = i - 1;
1484: int start = j - (targetCount - 1);
1485: int k = strLastIndex - 1;
1486:
1487: while (j > start) {
1488: if (source[j--] != target[k--]) {
1489: i--;
1490: continue startSearchForLastChar;
1491: }
1492: }
1493: return start - sourceOffset + 1;
1494: }
1495: }
1496:
1497: /**
1498: * Tests if this AppendingStringBuffer starts with the specified prefix beginning a
1499: * specified index.
1500: *
1501: * @param prefix
1502: * the prefix.
1503: * @param toffset
1504: * where to begin looking in the string.
1505: * @return <code>true</code> if the character sequence represented by the
1506: * argument is a prefix of the substring of this object starting at
1507: * index <code>toffset</code>; <code>false</code> otherwise.
1508: * The result is <code>false</code> if <code>toffset</code> is
1509: * negative or greater than the length of this <code>String</code>
1510: * object; otherwise the result is the same as the result of the
1511: * expression
1512: *
1513: * <pre>
1514: * this.subString(toffset).startsWith(prefix)
1515: * </pre>
1516: */
1517: public boolean startsWith(CharSequence prefix, int toffset) {
1518: char ta[] = value;
1519: int to = toffset;
1520: int po = 0;
1521: int pc = prefix.length();
1522: // Note: toffset might be near -1>>>1.
1523: if ((toffset < 0) || (toffset > count - pc)) {
1524: return false;
1525: }
1526: while (--pc >= 0) {
1527: if (ta[to++] != prefix.charAt(po++)) {
1528: return false;
1529: }
1530: }
1531: return true;
1532: }
1533:
1534: /**
1535: * Tests if this AppendingStringBuffer starts with the specified prefix.
1536: *
1537: * @param prefix
1538: * the prefix.
1539: * @return <code>true</code> if the character sequence represented by the
1540: * argument is a prefix of the character sequence represented by
1541: * this AppendingStringBuffer; <code>false</code> otherwise. Note also that
1542: * <code>true</code> will be returned if the argument is an empty
1543: * string or is equal to this <code>AppendingStringBuffer</code> object as
1544: * determined by the {@link #equals(Object)} method.
1545: * @since 1. 0
1546: */
1547: public boolean startsWith(CharSequence prefix) {
1548: return startsWith(prefix, 0);
1549: }
1550:
1551: /**
1552: * Tests if this AppendingStringBuffer ends with the specified suffix.
1553: *
1554: * @param suffix
1555: * the suffix.
1556: * @return <code>true</code> if the character sequence represented by the
1557: * argument is a suffix of the character sequence represented by
1558: * this AppendingStringBuffer; <code>false</code> otherwise. Note that the result
1559: * will be <code>true</code> if the argument is the empty string
1560: * or is equal to this <code>AppendingStringBuffer</code> object as determined by
1561: * the {@link #equals(Object)} method.
1562: */
1563: public boolean endsWith(CharSequence suffix) {
1564: return startsWith(suffix, count - suffix.length());
1565: }
1566:
1567: /**
1568: * Converts to a string representing the data in this AppendingStringBuffer. A new
1569: * <code>String</code> object is allocated and initialized to contain the
1570: * character sequence currently represented by this string buffer. This
1571: * <code>String</code> is then returned. Subsequent changes to the string
1572: * buffer do not affect the contents of the <code>String</code>.
1573: * <p>
1574: * Implementation advice: This method can be coded so as to create a new
1575: * <code>String</code> object without allocating new memory to hold a copy
1576: * of the character sequence. Instead, the string can share the memory used
1577: * by the string buffer. Any subsequent operation that alters the content or
1578: * capacity of the string buffer must then make a copy of the internal
1579: * buffer at that time. This strategy is effective for reducing the amount
1580: * of memory allocated by a string concatenation operation when it is
1581: * implemented using a string buffer.
1582: *
1583: * @return a string representation of the string buffer.
1584: */
1585: public String toString() {
1586: return new String(this .value, 0, count);
1587: }
1588:
1589: /**
1590: * This method returns the internal char array. So it is not
1591: *
1592: * @return The internal char array
1593: */
1594: public final char[] getValue() {
1595: return value;
1596: }
1597:
1598: /**
1599: * readObject is called to restore the state of the AppendingStringBuffer
1600: * from a stream.
1601: *
1602: * @param s
1603: * @throws ClassNotFoundException
1604: * @throws IOException
1605: */
1606: private void readObject(java.io.ObjectInputStream s)
1607: throws IOException, ClassNotFoundException {
1608: s.defaultReadObject();
1609: value = (char[]) value.clone();
1610: }
1611:
1612: /**
1613: * Compares this AppendingStringBuffer to the specified object. The result
1614: * is <code>true</code> if and only if the argument is not
1615: * <code>null</code> and is a <code>AppendingStringBuffer</code> object
1616: * or another charsequence object! that represents the same sequence of
1617: * characters as this object.
1618: *
1619: * @param anObject
1620: * the object to compare this <code>AppendingStringBuffer</code>
1621: * against.
1622: * @return <code>true</code> if the <code>AppendingStringBuffer</code>are
1623: * equal; <code>false</code> otherwise.
1624: */
1625: public boolean equals(Object anObject) {
1626: if (this == anObject) {
1627: return true;
1628: }
1629: if (anObject instanceof AppendingStringBuffer) {
1630: AppendingStringBuffer anotherString = (AppendingStringBuffer) anObject;
1631: int n = count;
1632: if (n == anotherString.count) {
1633: char v1[] = value;
1634: char v2[] = anotherString.value;
1635: int i = 0;
1636: while (n-- != 0) {
1637: if (v1[i] != v2[i++]) {
1638: return false;
1639: }
1640: }
1641: return true;
1642: }
1643: } else if (anObject instanceof CharSequence) {
1644: CharSequence sequence = (CharSequence) anObject;
1645: int n = count;
1646: if (sequence.length() == count) {
1647: char v1[] = value;
1648: int i = 0;
1649: while (n-- != 0) {
1650: if (v1[i] != sequence.charAt(i++)) {
1651: return false;
1652: }
1653: }
1654: return true;
1655: }
1656: }
1657: return false;
1658: }
1659:
1660: /**
1661: * Returns a hash code for this AppendingStringBuffer. The hash code for a
1662: * <code>AppendingStringBuffer</code> object is computed as <blockquote>
1663: *
1664: * <pre>
1665: * s[0]*31ˆ(n-1) + s[1]*31ˆ(n-2) + ... + s[n-1]
1666: * </pre>
1667: *
1668: * </blockquote> using <code>int</code> arithmetic, where
1669: * <code>s[i]</code> is the <i>i</i>th character of the
1670: * AppendingStringBuffer, <code>n</code> is the length of the
1671: * AppendingStringBuffer, and <code>^</code> indicates exponentiation.
1672: * (The hash value of the empty AppendingStringBuffer is zero.)
1673: *
1674: * @return a hash code value for this object.
1675: */
1676: public int hashCode() {
1677: int h = 0;
1678: if (h == 0) {
1679: int off = 0;
1680: char val[] = value;
1681: int len = count;
1682:
1683: for (int i = 0; i < len; i++) {
1684: h = 31 * h + val[off++];
1685: }
1686: }
1687: return h;
1688: }
1689:
1690: /**
1691: * Clears the buffer contents, but leaves the allocated size intact
1692: */
1693: public void clear() {
1694: count = 0;
1695: }
1696: }
|