Return-Path: Delivered-To: apmail-incubator-harmony-commits-archive@www.apache.org Received: (qmail 62922 invoked from network); 25 Feb 2006 23:03:01 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 25 Feb 2006 23:03:01 -0000 Received: (qmail 11483 invoked by uid 500); 25 Feb 2006 23:03:01 -0000 Delivered-To: apmail-incubator-harmony-commits-archive@incubator.apache.org Received: (qmail 11431 invoked by uid 500); 25 Feb 2006 23:03:00 -0000 Mailing-List: contact harmony-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: harmony-dev@incubator.apache.org Delivered-To: mailing list harmony-commits@incubator.apache.org Received: (qmail 11413 invoked by uid 99); 25 Feb 2006 23:03:00 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 25 Feb 2006 15:03:00 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Sat, 25 Feb 2006 15:02:58 -0800 Received: (qmail 62791 invoked by uid 65534); 25 Feb 2006 23:02:37 -0000 Message-ID: <20060225230237.62790.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r381015 - /incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/StringBuilder.java Date: Sat, 25 Feb 2006 23:02:37 -0000 To: harmony-commits@incubator.apache.org From: tellison@apache.org X-Mailer: svnmailer-1.0.7 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: tellison Date: Sat Feb 25 15:02:35 2006 New Revision: 381015 URL: http://svn.apache.org/viewcvs?rev=381015&view=rev Log: Apply javadoc enhancement for HARMONY-103 (java.lang.StringBuilder Implementation for LUNI) Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/StringBuilder.java Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/StringBuilder.java URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/StringBuilder.java?rev=381015&r1=381014&r2=381015&view=diff ============================================================================== --- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/StringBuilder.java (original) +++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/lang/StringBuilder.java Sat Feb 25 15:02:35 2006 @@ -1,4 +1,4 @@ -/* Copyright 1998, 2006 The Apache Software Foundation or its licensors, as applicable +/* Copyright 2006 The Apache Software Foundation or its licensors, as applicable * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,629 +23,1180 @@ import org.apache.harmony.luni.util.NotYetImplementedException; /** - * TODO javadoc + *

+ * A modifiable {@link CharSequence sequence of characters} for use in creating + * and modifying Strings. This class is intended as a direct replacement of + * {@link java.lang.StringBuffer} for non-concurrent use; unlike + * StringBuffer this class is not synchronized for thread safety. + *

+ * + *

+ * The majority of the modification methods on this class return + * StringBuilder, so that, like StringBuffers, + * they can be used in chaining method calls together. For example, + * new StringBuilder("One should ").append("always strive ").append("to achieve Harmony"). + *

+ * + * @see java.lang.CharSequence + * @see java.lang.Appendable + * @see java.lang.StringBuffer + * @see java.lang.String + * + * @since 1.5 + * + * @author Nathan Beyer (Harmony) */ public final class StringBuilder implements CharSequence, Serializable { - // TODO add 'implements Appendable' (see HARMONY-103) + // TODO add 'implements Appendable' (see HARMONY-103) - private static final long serialVersionUID = 4383685877147921099L; + private static final long serialVersionUID = 4383685877147921099L; - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - private static final String NULL_STRING = "null"; //$NON-NLS-1$ + private static final String NULL_STRING = "null"; //$NON-NLS-1$ - private static final char[] NULL_CHAR_ARRAY = NULL_STRING.toCharArray(); - - private static final int INITIAL_CAPACITY = 16; - - private transient char[] buffer; - - private transient int length; - - /** - * TODO javadoc - */ - public StringBuilder() { - super(); - this.buffer = new char[INITIAL_CAPACITY]; - } - - /** - * TODO javadoc - */ - public StringBuilder(int capacity) { - super(); - if (capacity < 0) - throw new NegativeArraySizeException(); - this.buffer = new char[capacity]; - } - - /** - * TODO javadoc - */ - public StringBuilder(CharSequence seq) { - super(); - if (seq == null) - throw new NullPointerException(); - this.length = seq.length(); - this.buffer = new char[length + 16]; - for (int i = 0; i < length; i++) { - this.buffer[i] = seq.charAt(i); - } - } - - /** - * TODO javadoc - */ - public StringBuilder(String str) { - this((CharSequence) str); - } - - /** - * TODO javadoc - */ - public StringBuilder append(boolean b) { - return append(String.valueOf(b)); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Appendable#append(char) - */ - public StringBuilder append(char c) { - return append(String.valueOf(c)); - } - - /** - * TODO javadoc - */ - public StringBuilder append(char[] str) { - return append(String.valueOf(str)); - } - - /** - * TODO javadoc - */ - public StringBuilder append(char[] str, int offset, int len) { - return append(String.valueOf(str, offset, len)); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Appendable#append(java.lang.CharSequence) - */ - public StringBuilder append(CharSequence csq) { - return append((String) (csq == null ? null : csq.toString())); - } - - /* - * (non-Javadoc) - * - * @see java.lang.Appendable#append(java.lang.CharSequence, int, int) - */ - public StringBuilder append(CharSequence csq, int start, int end) { - if (csq == null) - csq = NULL_STRING; - return append(csq.subSequence(start, end)); - } - - /** - * TODO javadoc - */ - public StringBuilder append(double d) { - return append(String.valueOf(d)); - } - - /** - * TODO javadoc - */ - public StringBuilder append(float f) { - return append(String.valueOf(f)); - } - - /** - * TODO javadoc - */ - public StringBuilder append(int i) { - return append(String.valueOf(i)); - } - - /** - * TODO javadoc - */ - public StringBuilder append(long lng) { - return append(String.valueOf(lng)); - } - - /** - * TODO javadoc - */ - public StringBuilder append(Object obj) { - return append(String.valueOf(obj)); - } - - /** - * TODO javadoc - */ - public StringBuilder append(String str) { - // if null or interned "null" string append "null" - if (str == null || str == NULL_STRING) { - ensureCapacity(length + 4); - System.arraycopy(NULL_CHAR_ARRAY, 0, buffer, length, 4); - length += 4; - } else { - int len = str.length(); - ensureCapacity(length + len); - for (int i = 0; i < len; i++) { - buffer[length++] = str.charAt(i); - } - } - return this; - } - - /** - * TODO javadoc - */ - public StringBuilder append(StringBuffer sb) { - return append((CharSequence) sb); - } - - /** - *

- * NOTE - This method is currently not implemented and always throws a - * {@link NotYetImplementedException}. - *

- * TODO javadoc - */ - public StringBuilder appendCodePoint(int codePoint) { - // TODO Implement Java 5 code point functionality. - throw new NotYetImplementedException(); - } - - /** - * TODO javadoc - */ - public int capacity() { - return buffer.length; - } - - /* - * (non-Javadoc) - * - * @see java.lang.CharSequence#charAt(int) - */ - public char charAt(int index) { - if (index < 0 || index >= length) - throw new IndexOutOfBoundsException(); - return buffer[index]; - } - - /** - *

- * NOTE - This method is currently NOT completely implemented and just - * delegates to the {@link #charAt(int)} method. - *

- * TODO javadoc - */ - public int codePointAt(int index) { - // TODO Implement Java 5 code point functionality. - return charAt(index); - } - - /** - *

- * NOTE - This method is currently NOT completely implemented and just - * delegates to the {@link #charAt(int)} method by retrieving the character - * at the preceding index. - *

- * TODO javadoc - */ - public int codePointBefore(int index) { - // TODO Implement Java 5 code point functionality. - return codePointAt(index - 1); - } - - /** - *

- * NOTE - This method is currently NOT completely implemented and just - * return the difference between the index parameters. - *

- * TODO javadoc - */ - public int codePointCount(int beginIndex, int endIndex) { - // TODO Implement Java 5 code point functionality. - if (beginIndex < 0 || endIndex > length || beginIndex > endIndex) - throw new IndexOutOfBoundsException(); - return endIndex - beginIndex; - } - - /** - * TODO javadoc - */ - public StringBuilder delete(int start, int end) { - if (start < 0 || start > length || start > end) - throw new StringIndexOutOfBoundsException(); - if (start != end) { - // massage end if it's too long - if (end > length) - end = length; - // shift chars left - System.arraycopy(buffer, end, buffer, start, length - end); - // adjust length - length -= (end - start); - } - return this; - } - - /** - * TODO javadoc - */ - public StringBuilder deleteCharAt(int index) { - // check for index values past length, as 'delete' will massage them out - if (index >= length) - throw new StringIndexOutOfBoundsException(); - return delete(index, index + 1); - } - - /** - * TODO javadoc - */ - public void ensureCapacity(int minimumCapacity) { - if (minimumCapacity > buffer.length) { - /* - * Create a new buffer that's the greater of the requested capacity - * or the current capacity multiplied by 2 plus 2. - */ - char[] newbuffer = new char[Math.max(minimumCapacity, - (buffer.length * 2) + 2)]; - // copy the original buffer's contents - System.arraycopy(buffer, 0, newbuffer, 0, length); - // assign new buffer to instance field - buffer = newbuffer; - } - } - - /** - * TODO javadoc - */ - public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { - if (dst == null) - throw new NullPointerException(); - if (srcBegin < 0 || dstBegin < 0 || srcBegin > srcEnd - || srcEnd > length - || (dstBegin + srcEnd - srcBegin) > dst.length) - throw new IndexOutOfBoundsException(); - - System.arraycopy(buffer, srcBegin, dst, dstBegin, srcEnd - srcBegin); - } - - /** - * TODO javadoc - */ - public int indexOf(String str) { - if (str == null) - throw new NullPointerException(); - // TODO optimize - return this.toString().indexOf(str); - } - - /** - * TODO javadoc - */ - public int indexOf(String str, int fromIndex) { - if (str == null) - throw new NullPointerException(); - // TODO optimize - return this.toString().indexOf(str, fromIndex); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, boolean b) { - if (offset < 0 || offset > length) - throw new StringIndexOutOfBoundsException(); - - return insert(offset, String.valueOf(b)); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, char c) { - if (offset < 0 || offset > length) - throw new StringIndexOutOfBoundsException(); - - return insert(offset, String.valueOf(c)); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, char[] str) { - if (offset < 0 || offset > length) - throw new StringIndexOutOfBoundsException(); - - return insert(offset, String.valueOf(str)); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int index, char[] str, int offset, int len) { - if (index < 0 || index > length) - throw new StringIndexOutOfBoundsException(); - - return insert(index, String.valueOf(str, offset, len)); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, CharSequence s) { - if (offset < 0 || offset > length) - throw new StringIndexOutOfBoundsException(); - - return insert(offset, (s == null ? (String) null : s.toString())); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, CharSequence s, int start, int end) { - if (offset < 0 || offset > length) - throw new IndexOutOfBoundsException(); - - if (s == null) - s = NULL_STRING; - - return insert(offset, s.subSequence(start, end)); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, double d) { - if (offset < 0 || offset > length) - throw new StringIndexOutOfBoundsException(); - - return insert(offset, String.valueOf(d)); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, float f) { - if (offset < 0 || offset > length) - throw new StringIndexOutOfBoundsException(); - - return insert(offset, String.valueOf(f)); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, int i) { - if (offset < 0 || offset > length) - throw new StringIndexOutOfBoundsException(); - - return insert(offset, String.valueOf(i)); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, long l) { - if (offset < 0 || offset > length) - throw new StringIndexOutOfBoundsException(); - - return insert(offset, String.valueOf(l)); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, Object obj) { - if (offset < 0 || offset > length) - throw new StringIndexOutOfBoundsException(); - - return insert(offset, String.valueOf(obj)); - } - - /** - * TODO javadoc - */ - public StringBuilder insert(int offset, String str) { - if (offset < 0 || offset > length) - throw new StringIndexOutOfBoundsException(); - - if (str == null) - str = NULL_STRING; - - int len = str.length(); - ensureCapacity(length + len); - // shift chars right - System.arraycopy(buffer, offset, buffer, offset + len, length - offset); - // adjust length - length += len; - // copy in new chars - for (int i = 0, j = offset; i < len; i++, j++) - buffer[j] = str.charAt(i); - return this; - } - - /** - * TODO javadoc - */ - public int lastIndexOf(String str) { - if (str == null) - throw new NullPointerException(); - // TODO optimize - return this.toString().lastIndexOf(str); - } - - /** - * TODO javadoc - */ - public int lastIndexOf(String str, int fromIndex) { - if (str == null) - throw new NullPointerException(); - // TODO optimize - return this.toString().lastIndexOf(str, fromIndex); - } - - /* - * (non-Javadoc) - * - * @see java.lang.CharSequence#length() - */ - public int length() { - return length; - } - - /** - * TODO javadoc - */ - public int offsetByCodePoints(int index, int codePointOffset) { - // TODO Implement Java 5 code point functionality. - throw new NotYetImplementedException(); - } - - /** - * TODO javadoc - */ - public StringBuilder replace(int start, int end, String str) { - if (start < 0 || start > length || start > end) - throw new StringIndexOutOfBoundsException(); - - if (str == null) // TODO verify this undocumented NPE - throw new NullPointerException(); - - // if the start is just past last char, then treat it like an append - if (start == length) { - return append(str); - } - - int sbLen = end - start; - int strLen = str.length(); - if (strLen > sbLen) { - // shift chars with an insert of the difference - // this will handle capacity and length management - insert(start, new char[strLen - sbLen]); - } - // copy in new chars - for (int i = 0, j = start; i < strLen; i++, j++) - buffer[j] = str.charAt(i); - return this; - } - - /** - * TODO javadoc - */ - public StringBuilder reverse() { - if (length > 1) { // only reverse if necessary - for (int i = 0, j = length - 1; i <= j - 1; i++, j--) { - char c = buffer[j]; - buffer[j] = buffer[i]; - buffer[i] = c; - } - } - return this; - } - - /** - * TODO javadoc - */ - public void setCharAt(int index, char ch) { - if (index < 0 || index >= length) - throw new IndexOutOfBoundsException(); - buffer[index] = ch; - } - - /** - * TODO javadoc - */ - public void setLength(int newLength) { - if (newLength < 0) - throw new IndexOutOfBoundsException(); - if (newLength > length) { - // expand if necessary - ensureCapacity(newLength); - // null out any new chars at the sequence end - for (int i = length; i < newLength; i++) - buffer[i] = 0; - } - length = newLength; - } - - /* - * (non-Javadoc) - * - * @see java.lang.CharSequence#subSequence(int, int) - */ - public CharSequence subSequence(int start, int end) { - return substring(start, end); - } - - /** - * TODO javadoc - */ - public String substring(int start) { - if (start < 0 || start > length) - throw new StringIndexOutOfBoundsException(); - - int ssCharCnt = length - start; - if (ssCharCnt == 0) - return EMPTY_STRING; - return new String(buffer, start, ssCharCnt); - } - - /** - * TODO javadoc - */ - public String substring(int start, int end) { - if (start < 0 || end > length || start > end) - throw new StringIndexOutOfBoundsException(); - - int ssCharCnt = end - start; - if (ssCharCnt == 0) - return EMPTY_STRING; - return new String(buffer, start, end - start); - } - - /** - * TODO javadoc - */ - public String toString() { - if (length == 0) - return EMPTY_STRING; - return new String(buffer, 0, length); - } - - /** - * TODO javadoc - */ - public void trimToSize() { - if (length < buffer.length) { - char[] newbuffer = new char[length]; - System.arraycopy(buffer, 0, newbuffer, 0, length); - buffer = newbuffer; - } - } - - private void readObject(ObjectInputStream in) throws IOException, - ClassNotFoundException { - in.defaultReadObject(); - length = in.readInt(); - buffer = (char[]) in.readObject(); - } - - private void writeObject(ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - out.writeInt(length); - out.writeObject(buffer); - } + private static final char[] NULL_CHAR_ARRAY = NULL_STRING.toCharArray(); + + private static final int INITIAL_CAPACITY = 16; + + private transient char[] buffer; + + private transient int length; + + /** + *

+ * Constructs an instance with an initial capacity of 16. + *

+ * + * @see #capacity() + */ + public StringBuilder() { + super(); + this.buffer = new char[INITIAL_CAPACITY]; + } + + /** + *

+ * Constructs an instance with a specificed capacity. + *

+ * + * @param capacity The initial capicity to use. + * + * @throws NegativeArraySizeException if the capacity + * parameter is null. + * + * @see #capacity() + */ + public StringBuilder(int capacity) { + super(); + if (capacity < 0) + throw new NegativeArraySizeException(); + this.buffer = new char[capacity]; + } + + /** + *

+ * Constructs an instance that's populated by a {@link CharSequence}. The + * capacity of the new builder will bee the length of the + * CharSequence plus 16. + *

+ * + * @param seq The CharSequence to copy into the builder. + * @throws NullPointerException if the seq parameter is + * null. + */ + public StringBuilder(CharSequence seq) { + super(); + if (seq == null) + throw new NullPointerException(); + this.length = seq.length(); + this.buffer = new char[length + 16]; + for (int i = 0; i < length; i++) { + this.buffer[i] = seq.charAt(i); + } + } + + /** + *

+ * Constructs an instance that's populated by a {@link String}. The + * capacity of the new builder will bee the length of the + * String plus 16. + *

+ * + * @param str The String to copy into the builder. + * @throws NullPointerException if the str parameter is + * null. + */ + public StringBuilder(String str) { + this((CharSequence) str); + } + + /** + *

+ * Appends the String representation of the boolean value + * passed. The boolean value is converted to a String + * according to the rule defined by {@link String#valueOf(boolean)}. + *

+ * + * @param b The boolean value to append to this object. + * @return A reference to this object. + * + * @see String#valueOf(boolean) + */ + public StringBuilder append(boolean b) { + return append(String.valueOf(b)); + } + + /** + *

+ * Appends the String representation of the char value + * passed. The char value is converted to a String according + * to the rule defined by {@link String#valueOf(char)}. + *

+ * + * @param c The char value to append to this object. + * @return A reference to this object. + * + * @see String#valueOf(char) + */ + public StringBuilder append(char c) { + return append(String.valueOf(c)); + } + + /** + *

+ * Appends the String representation of the char[] value + * passed. The char[] value is converted to a String + * according to the rule defined by {@link String#valueOf(char[])}. + *

+ * + * @param str The char[] value to append to this object. + * @return A reference to this object. + * + * @see String#valueOf(char[]) + */ + public StringBuilder append(char[] str) { + return append(String.valueOf(str)); + } + + /** + *

+ * Appends the String representation of the subset of the + * char[] value passed. The char[] value is + * converted to a String according to the rule defined by + * {@link String#valueOf(char[],int,int)}. + *

+ * + * @param str The char[] value to append to this object. + * @param offset The inclusive offset index to begin copying from the + * str parameter. + * @param len The number of character to copy from the str + * parameter. + * @return A reference to this object. + * + * @see String#valueOf(char[],int,int) + */ + public StringBuilder append(char[] str, int offset, int len) { + return append(String.valueOf(str, offset, len)); + } + + /** + *

+ * Appends the String representation of the CharSequence + * value passed. If the CharSequence is null, + * then the String "null" is appended. + *

+ * + * @param csq The CharSequence value to append to this + * object. + * @return A reference to this object. + */ + public StringBuilder append(CharSequence csq) { + return append((String) (csq == null ? null : csq.toString())); + } + + /** + *

+ * Appends the String representation of the subsequence of the + * CharSequence value passed. If the + * CharSequence is null, then the String + * "null" is used to extract the subsequence from. + *

+ * + * @param csq The CharSequence value to append to this + * object. + * @param start The beginning index of the subsequence. + * @param end The ending index of the subsequence. + * @return A reference to this object. + */ + public StringBuilder append(CharSequence csq, int start, int end) { + if (csq == null) + csq = NULL_STRING; + return append(csq.subSequence(start, end)); + } + + /** + *

+ * Appends the String representation of the double value + * passed. The double value is converted to a String + * according to the rule defined by {@link String#valueOf(double)}. + *

+ * + * @param d The double value to append to this object. + * @return A reference to this object. + * + * @see String#valueOf(double) + */ + public StringBuilder append(double d) { + return append(String.valueOf(d)); + } + + /** + *

+ * Appends the String representation of the float value + * passed. The float value is converted to a String according + * to the rule defined by {@link String#valueOf(float)}. + *

+ * + * @param f The float value to append to this object. + * @return A reference to this object. + * + * @see String#valueOf(float) + */ + public StringBuilder append(float f) { + return append(String.valueOf(f)); + } + + /** + *

+ * Appends the String representation of the int value passed. + * The int value is converted to a String according to the + * rule defined by {@link String#valueOf(int)}. + *

+ * + * @param i The int value to append to this object. + * @return A reference to this object. + * + * @see String#valueOf(int) + */ + public StringBuilder append(int i) { + return append(String.valueOf(i)); + } + + /** + *

+ * Appends the String representation of the long value + * passed. The long value is converted to a String according + * to the rule defined by {@link String#valueOf(long)}. + *

+ * + * @param lng The long value to append to this object. + * @return A reference to this object. + * + * @see String#valueOf(long) + */ + public StringBuilder append(long lng) { + return append(String.valueOf(lng)); + } + + /** + *

+ * Appends the String representation of the Object value + * passed. The Object value is converted to a String + * according to the rule defined by {@link String#valueOf(Object)}. + *

+ * + * @param obj The Object value to append to this object. + * @return A reference to this object. + * + * @see String#valueOf(Object) + */ + public StringBuilder append(Object obj) { + return append(String.valueOf(obj)); + } + + /** + *

+ * Appends the contents of the String. If the String passed is + * null, then the String "null" is appended. + *

+ * + * @param str The String to append to this object. + * @return A reference to this object. + */ + public StringBuilder append(String str) { + // if null or interned "null" string append "null" + if (str == null || str == NULL_STRING) { + ensureCapacity(length + 4); + System.arraycopy(NULL_CHAR_ARRAY, 0, buffer, length, 4); + length += 4; + } else { + int len = str.length(); + ensureCapacity(length + len); + for (int i = 0; i < len; i++) { + buffer[length++] = str.charAt(i); + } + } + return this; + } + + /** + *

+ * Appends the contents of the StringBuffer. If the StringBuffer passed is + * null, then the StringBuffer "null" is + * appended. + *

+ * + * @param sb The StringBuffer to append to this object. + * @return A reference to this object. + */ + public StringBuilder append(StringBuffer sb) { + return append((CharSequence) sb); + } + + /** + *

+ * NOTE - This method is currently not implemented and always throws a + * {@link NotYetImplementedException}. + *

+ * TODO javadoc + */ + public StringBuilder appendCodePoint(int codePoint) { + // TODO Implement Java 5 code point functionality. + throw new NotYetImplementedException(); + } + + /** + *

+ * The current capacity of this object. + *

+ * + * @return An int value representing the capacity. + */ + public int capacity() { + return buffer.length; + } + + /** + *

+ * Retrieves the character at the index. + *

+ * + * @param The index of character in this object to retrieve. + * @return The char value. + * @throws IndexOutOfBoundsException if index is negative or + * greater than or equal to the current {@link #length()}. + */ + public char charAt(int index) { + if (index < 0 || index >= length) + throw new IndexOutOfBoundsException(); + return buffer[index]; + } + + /** + *

+ * NOTE - This method is currently NOT completely implemented and just + * delegates to the {@link #charAt(int)} method. + *

+ * TODO javadoc + */ + public int codePointAt(int index) { + // TODO Implement Java 5 code point functionality. + return charAt(index); + } + + /** + *

+ * NOTE - This method is currently NOT completely implemented and just + * delegates to the {@link #charAt(int)} method by retrieving the character + * at the preceding index. + *

+ * TODO javadoc + */ + public int codePointBefore(int index) { + // TODO Implement Java 5 code point functionality. + return codePointAt(index - 1); + } + + /** + *

+ * NOTE - This method is currently NOT completely implemented and just + * return the difference between the index parameters. + *

+ * TODO javadoc + */ + public int codePointCount(int beginIndex, int endIndex) { + // TODO Implement Java 5 code point functionality. + if (beginIndex < 0 || endIndex > length || beginIndex > endIndex) + throw new IndexOutOfBoundsException(); + return endIndex - beginIndex; + } + + /** + *

+ * Deletes a sequence of characters within this object, shifts any remaining + * characters to the left and adjusts the {@link #length()} of this object. + *

+ * + * @param start The inclusive start index to begin deletion. + * @param end The exclusive end index to stop deletion. + * @return A reference to this object. + * @throws StringIndexOutOfBoundsException if start is less + * than zero, greater than the current length or greater than + * end. + */ + public StringBuilder delete(int start, int end) { + if (start < 0 || start > length || start > end) + throw new StringIndexOutOfBoundsException(); + if (start != end) { + // massage end if it's too long + if (end > length) + end = length; + // shift chars left + System.arraycopy(buffer, end, buffer, start, length - end); + // adjust length + length -= (end - start); + } + return this; + } + + /** + *

+ * Deletes a single character within this object, shifts any remaining + * characters to the left and adjusts the {@link #length()} of this object. + *

+ * + * @param index The index of the character to delete. + * @return A reference to this object. + * @throws StringIndexOutOfBoundsException if index is less + * than zero or is greather than or equal to the current length. + */ + public StringBuilder deleteCharAt(int index) { + // check for index values past length, as 'delete' will massage them out + if (index >= length) + throw new StringIndexOutOfBoundsException(); + return delete(index, index + 1); + } + + /** + *

+ * Ensures that this object has a minimum capicity available before + * requiring the internal buffer to be enlarged. The general policy of thi + * method is that if the minimumCapacity is larger than the + * current {@link #capacity()}, then the capacity will be increased to the + * largest value of either the minimumCapacity or the current + * capcity multiplied by two plus two. Although this is the general policy, + * there is no guarantee that the capacity will change. + *

+ * + * @param minimumCapacity The new minimum capacity to set. + */ + public void ensureCapacity(int minimumCapacity) { + if (minimumCapacity > buffer.length) { + /* + * Create a new buffer that's the greater of the requested capacity + * or the current capacity multiplied by 2 plus 2. + */ + char[] newbuffer = new char[Math.max(minimumCapacity, + (buffer.length * 2) + 2)]; + // copy the original buffer's contents + System.arraycopy(buffer, 0, newbuffer, 0, length); + // assign new buffer to instance field + buffer = newbuffer; + } + } + + /** + *

+ * Copies the requested sequence of characters to be copied to the + * char[] passed. + *

+ * + * @param srcBegin The inclusive start index of the characters to copy from + * this object. + * @param srcEnd The exclusive end index of the characters to copy from this + * object. + * @param dst The char[] to copy the characters to. + * @param dstBegin The inclusive start index of the dst + * parameter to begin copying to. + * @throws IndexOutOfBoundsException if the srcBegin is + * negative, the dstBegin is negative, the + * srcBegin is greater than srcEnd, + * the srcEnd is greather than the current + * {@link #length()} or dstBegin + srcEnd - srcBegin + * is greater than dst.lenbth. + */ + public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { + if (dst == null) + throw new NullPointerException(); + if (srcBegin < 0 || dstBegin < 0 || srcBegin > srcEnd + || srcEnd > length + || (dstBegin + srcEnd - srcBegin) > dst.length) + throw new IndexOutOfBoundsException(); + + System.arraycopy(buffer, srcBegin, dst, dstBegin, srcEnd - srcBegin); + } + + /** + *

+ * Searches this object for a match to the String passed and returns the + * index of the first character that matches or -1 if a match + * wasn't found. This method follows the same rules as the + * {@link String#indexOf(java.lang.String)}. + *

+ * + * @param str The pattern to search for. + * @return The beginning index of the matching sequence or -1 + * if no match was found. + * + * @throws NullPointerException if the str parameter is + * null. + * + * @see String#indexOf(java.lang.String) + */ + public int indexOf(String str) { + if (str == null) + throw new NullPointerException(); + // TODO optimize + return this.toString().indexOf(str); + } + + /** + *

+ * Searches this object, starting at the fromIndex, for a + * match to the String passed and returns the index of the first character + * that matches or -1 if a match wasn't found. This method + * follows the same rules as the + * {@link String#indexOf(java.lang.String,int)}. + *

+ * + * @param str The pattern to search for. + * @param fromIndex The index of this object to begin searching at. + * @return The beginning index of the matching sequence or -1 + * if no match was found. + * + * @throws NullPointerException if the str parameter is + * null. + * + * @see String#indexOf(java.lang.String,int) + */ + public int indexOf(String str, int fromIndex) { + if (str == null) + throw new NullPointerException(); + // TODO optimize + return this.toString().indexOf(str, fromIndex); + } + + /** + *

+ * Inserts the String representation of the boolean value + * passed into this object at the offset passed. The + * boolean value is converted to a String according to the + * rule defined by {@link String#valueOf(boolean)}. + *

+ * + * @param offset The index of this object to insert the value. + * @param b The boolean value to insert into this object. + * @return A reference to this object. + * + * @throws StringIndexOutOfBoundsException if offset is + * negative or greater than the current {@link #length()}. + * + * @see String#valueOf(boolean) + */ + public StringBuilder insert(int offset, boolean b) { + if (offset < 0 || offset > length) + throw new StringIndexOutOfBoundsException(); + + return insert(offset, String.valueOf(b)); + } + + /** + *

+ * Inserts the String representation of the char value passed + * into this object at the offset passed. The + * char value is converted to a String according to the rule + * defined by {@link String#valueOf(char)}. + *

+ * + * @param offset The index of this object to insert the value. + * @param c The char value to insert into this object. + * @return A reference to this object. + * + * @throws StringIndexOutOfBoundsException if offset is + * negative or greater than the current {@link #length()}. + * + * @see String#valueOf(char) + */ + public StringBuilder insert(int offset, char c) { + if (offset < 0 || offset > length) + throw new StringIndexOutOfBoundsException(); + + return insert(offset, String.valueOf(c)); + } + + /** + *

+ * Inserts the String representation of the char[] value + * passed into this object at the offset passed. The + * char[] value is converted to a String according to the + * rule defined by {@link String#valueOf(char[])}. + *

+ * + * @param offset The index of this object to insert the value. + * @param str The char[] value to insert into this object. + * @return A reference to this object. + * + * @throws StringIndexOutOfBoundsException if offset is + * negative or greater than the current {@link #length()}. + * + * @see String#valueOf(char[]) + */ + public StringBuilder insert(int offset, char[] str) { + if (offset < 0 || offset > length) + throw new StringIndexOutOfBoundsException(); + + return insert(offset, String.valueOf(str)); + } + + /** + *

+ * Inserts the String representation of the subsequence of the + * char[] value passed into this object at the + * offset passed. The char[] value is + * converted to a String according to the rule defined by + * {@link String#valueOf(char[],int,int)}. + *

+ * + * @param offset The index of this object to insert the value. + * @param str The char[] value to insert into this object. + * @param strOffset The inclusive index of the str parameter + * to start copying from. + * @param strLen The number of characters to copy from the str + * parameter. + * @return A reference to this object. + * + * @throws StringIndexOutOfBoundsException if offset is + * negative or greater than the current {@link #length()}. + * + * @see String#valueOf(char[],int,int) + */ + public StringBuilder insert(int offset, char[] str, int strOffset, + int strLen) { + if (offset < 0 || offset > length) + throw new StringIndexOutOfBoundsException(); + + return insert(offset, String.valueOf(str, strOffset, strLen)); + } + + /** + *

+ * Inserts the String representation of the CharSequence + * value passed into this object at the offset passed. The + * CharSequence value is converted to a String as defined by + * {@link CharSequence#toString()}. If the CharSequence is + * null, then the String "null" is inserted. + *

+ * + * @param offset The index of this object to insert the value. + * @param s The CharSequence value to insert into this + * object. + * @return A reference to this object. + * + * @throws IndexOutOfBoundsException if offset is negative or + * greater than the current {@link #length()}. + * + * @see CharSequence#toString() + */ + public StringBuilder insert(int offset, CharSequence s) { + if (offset < 0 || offset > length) + throw new IndexOutOfBoundsException(); + + return insert(offset, (s == null ? (String) null : s.toString())); + } + + /** + *

+ * Inserts the String representation of the subsequence of the + * CharSequence value passed into this object at the + * offset passed. The CharSequence value is + * converted to a String as defined by + * {@link CharSequence#subSequence(int, int)}. If the + * CharSequence is null, then the String + * "null" is used to determine the subsequence. + *

+ * + * @param offset The index of this object to insert the value. + * @param s The CharSequence value to insert into this + * object. + * @param start The start of the subsequence of the s + * parameter. + * @param end The end of the subsequence of the s parameter. + * @return A reference to this object. + * + * @throws IndexOutOfBoundsException if offset is negative or + * greater than the current {@link #length()}. + * + * @see CharSequence#subSequence(int, int) + */ + public StringBuilder insert(int offset, CharSequence s, int start, int end) { + if (offset < 0 || offset > length) + throw new IndexOutOfBoundsException(); + + if (s == null) + s = NULL_STRING; + + return insert(offset, s.subSequence(start, end)); + } + + /** + *

+ * Inserts the String representation of the double value + * passed into this object at the offset passed. The + * double value is converted to a String according to the + * rule defined by {@link String#valueOf(double)}. + *

+ * + * @param offset The index of this object to insert the value. + * @param d The double value to insert into this object. + * @return A reference to this object. + * + * @throws StringIndexOutOfBoundsException if offset is + * negative or greater than the current {@link #length()}. + * + * @see String#valueOf(double) + */ + public StringBuilder insert(int offset, double d) { + if (offset < 0 || offset > length) + throw new StringIndexOutOfBoundsException(); + + return insert(offset, String.valueOf(d)); + } + + /** + *

+ * Inserts the String representation of the float value + * passed into this object at the offset passed. The + * float value is converted to a String according to the rule + * defined by {@link String#valueOf(float)}. + *

+ * + * @param offset The index of this object to insert the value. + * @param b The float value to insert into this object. + * @return A reference to this object. + * + * @throws StringIndexOutOfBoundsException if offset is + * negative or greater than the current {@link #length()}. + * + * @see String#valueOf(float) + */ + public StringBuilder insert(int offset, float f) { + if (offset < 0 || offset > length) + throw new StringIndexOutOfBoundsException(); + + return insert(offset, String.valueOf(f)); + } + + /** + *

+ * Inserts the String representation of the int value passed + * into this object at the offset passed. The + * int value is converted to a String according to the rule + * defined by {@link String#valueOf(int)}. + *

+ * + * @param offset The index of this object to insert the value. + * @param b The int value to insert into this object. + * @return A reference to this object. + * + * @throws StringIndexOutOfBoundsException if offset is + * negative or greater than the current {@link #length()}. + * + * @see String#valueOf(int) + */ + public StringBuilder insert(int offset, int i) { + if (offset < 0 || offset > length) + throw new StringIndexOutOfBoundsException(); + + return insert(offset, String.valueOf(i)); + } + + /** + *

+ * Inserts the String representation of the long value passed + * into this object at the offset passed. The + * long value is converted to a String according to the rule + * defined by {@link String#valueOf(long)}. + *

+ * + * @param offset The index of this object to insert the value. + * @param b The long value to insert into this object. + * @return A reference to this object. + * + * @throws StringIndexOutOfBoundsException if offset is + * negative or greater than the current {@link #length()}. + * + * @see String#valueOf(long) + */ + public StringBuilder insert(int offset, long l) { + if (offset < 0 || offset > length) + throw new StringIndexOutOfBoundsException(); + + return insert(offset, String.valueOf(l)); + } + + /** + *

+ * Inserts the String representation of the Object value + * passed into this object at the offset passed. The + * Object value is converted to a String according to the + * rule defined by {@link String#valueOf(Object)}. + *

+ * + * @param offset The index of this object to insert the value. + * @param b The Object value to insert into this object. + * @return A reference to this object. + * + * @throws StringIndexOutOfBoundsException if offset is + * negative or greater than the current {@link #length()}. + * + * @see String#valueOf(Object) + */ + public StringBuilder insert(int offset, Object obj) { + if (offset < 0 || offset > length) + throw new StringIndexOutOfBoundsException(); + + return insert(offset, String.valueOf(obj)); + } + + /** + *

+ * Inserts the String value passed into this object at the + * offset passed. If the String parameter is null, then the + * String "null" is inserted. + *

+ * + * @param offset The index of this object to insert the value. + * @param str The String to insert into this object. + * @return A reference to this object. + * + * @throws StringIndexOutOfBoundsException if offset is + * negative or greater than the current {@link #length()}. + */ + public StringBuilder insert(int offset, String str) { + if (offset < 0 || offset > length) + throw new StringIndexOutOfBoundsException(); + + if (str == null) + str = NULL_STRING; + + int len = str.length(); + ensureCapacity(length + len); + // shift chars right + System.arraycopy(buffer, offset, buffer, offset + len, length - offset); + // adjust length + length += len; + // copy in new chars + for (int i = 0, j = offset; i < len; i++, j++) + buffer[j] = str.charAt(i); + return this; + } + + /** + *

+ * Searches this object for the last match to the String passed and returns + * the index of the first character that matches or -1 if a + * match wasn't found. This method follows the same rules as the + * {@link String#lastIndexOf(java.lang.String)}. + *

+ * + * @param str The pattern to search for. + * @return The beginning index of the matching sequence or -1 + * if no match was found. + * + * @throws NullPointerException if the str parameter is + * null. + * + * @see String#lastIndexOf(java.lang.String) + */ + public int lastIndexOf(String str) { + if (str == null) + throw new NullPointerException(); + // TODO optimize + return this.toString().lastIndexOf(str); + } + + /** + *

+ * Searches this object, starting at the fromIndex, for the + * last match to the String passed and returns the index of the first + * character that matches or -1 if a match wasn't found. This + * method follows the same rules as the + * {@link String#lastIndexOf(java.lang.String,int)}. + *

+ * + * @param str The pattern to search for. + * @param fromIndex The index of this object to begin searching at. + * @return The beginning index of the matching sequence or -1 + * if no match was found. + * + * @throws NullPointerException if the str parameter is + * null. + * + * @see String#lastIndexOf(java.lang.String,int) + */ + public int lastIndexOf(String str, int fromIndex) { + if (str == null) + throw new NullPointerException(); + // TODO optimize + return this.toString().lastIndexOf(str, fromIndex); + } + + /** + *

+ * The current length of this object. + *

+ * + * @return The current length. + */ + public int length() { + return length; + } + + /** + *

+ * NOTE - This method is currently not implemented and always throws a + * {@link NotYetImplementedException}. + *

+ * TODO javadoc + */ + public int offsetByCodePoints(int index, int codePointOffset) { + // TODO Implement Java 5 code point functionality. + throw new NotYetImplementedException(); + } + + /** + *

+ * Replaces the indicated subsequence of this object with the String passed. + * If the String passed is longer or shorter than the subsequence, then this + * object will be adjusted appropriately. + *

+ * + * @param start The inclusive start index of the sequence to replace in this + * object. + * @param end The exclusive end index of the sequence to replace in this + * object. + * @param str The String to replace the subsequence. + * @return A reference to this object. + * @throws StringIndexOutOfBoundsException if start is + * negative, greater than the current {@link #length()} or greater + * than end. + * @throws NullPointerException if the str parameter is + * null. + */ + public StringBuilder replace(int start, int end, String str) { + if (start < 0 || start > length || start > end) + throw new StringIndexOutOfBoundsException(); + + if (str == null) // TODO verify this undocumented NPE + throw new NullPointerException(); + + // if the start is just past last char, then treat it like an append + if (start == length) { + return append(str); + } + + int sbLen = end - start; + int strLen = str.length(); + if (strLen > sbLen) { + // shift chars with an insert of the difference + // this will handle capacity and length management + insert(start, new char[strLen - sbLen]); + } + // copy in new chars + for (int i = 0, j = start; i < strLen; i++, j++) + buffer[j] = str.charAt(i); + return this; + } + + /** + *

+ * Reverses the contents of this object. + *

+ * + * @return A reference to this object. + */ + public StringBuilder reverse() { + if (length > 1) { // only reverse if necessary + for (int i = 0, j = length - 1; i <= j - 1; i++, j--) { + char c = buffer[j]; + buffer[j] = buffer[i]; + buffer[i] = c; + } + } + return this; + } + + /** + *

+ * Sets the character at the index in this object. + *

+ * + * @param index The index of the character to replace. + * @param ch The character to set. + * @throws IndexOutOfBoundsException if index is negative or + * greater than or equal to the current {@link #length()}. + */ + public void setCharAt(int index, char ch) { + if (index < 0 || index >= length) + throw new IndexOutOfBoundsException(); + buffer[index] = ch; + } + + /** + *

+ * Sets the current length to a new value. If the new length is larger than + * the current length, then the new characters at the end of this object + * will contain the char value of \u0000. + *

+ * + * @param newLength The new length to set this object to. + * @throws IndexOutOfBoundsException if the newLength + * parameter is negative. + */ + public void setLength(int newLength) { + if (newLength < 0) + throw new IndexOutOfBoundsException(); + if (newLength > length) { + // expand if necessary + ensureCapacity(newLength); + // null out any new chars at the sequence end + for (int i = length; i < newLength; i++) + buffer[i] = 0; + } + length = newLength; + } + + /** + *

+ * Returns a CharSequence of the subsequence of this object + * from the start index to the start index. + *

+ * + * @param start The inclusive start index to begin the subsequence. + * @param end The exclusive end index to end the subsequence. + * @return A CharSequence containing the subsequence. + * @throws IndexOutOfBoundsException if start is negative, + * greater than the current {@link #length()} or greater than + * end. + */ + public CharSequence subSequence(int start, int end) { + return substring(start, end); + } + + /** + *

+ * Returns the String value of the subsequence of this object from the + * start index to the current end. + *

+ * + * @param start The inclusive start index to begin the subsequence. + * @return A String containing the subsequence. + * @throws StringIndexOutOfBoundsException if start is + * negative or greater than the current {@link #length()}. + */ + public String substring(int start) { + if (start < 0 || start > length) + throw new StringIndexOutOfBoundsException(); + + int ssCharCnt = length - start; + if (ssCharCnt == 0) + return EMPTY_STRING; + return new String(buffer, start, ssCharCnt); + } + + /** + *

+ * Returns the String value of the subsequence of this object from the + * start index to the start index. + *

+ * + * @param start The inclusive start index to begin the subsequence. + * @param end The exclusive end index to end the subsequence. + * @return A String containing the subsequence. + * @throws StringIndexOutOfBoundsException if start is + * negative, greater than the current {@link #length()} or greater + * than end. + */ + public String substring(int start, int end) { + if (start < 0 || end > length || start > end) + throw new StringIndexOutOfBoundsException(); + + int ssCharCnt = end - start; + if (ssCharCnt == 0) + return EMPTY_STRING; + return new String(buffer, start, end - start); + } + + /** + *

+ * Returns the current String representation of this object. + *

+ * + * @return The current String representation of this object. + */ + public String toString() { + if (length == 0) + return EMPTY_STRING; + return new String(buffer, 0, length); + } + + /** + *

+ * Trims off any extra capacity beyond the current length. Note, this method + * is NOT guaranteed to change the capacity of this object. + *

+ */ + public void trimToSize() { + if (length < buffer.length) { + char[] newbuffer = new char[length]; + System.arraycopy(buffer, 0, newbuffer, 0, length); + buffer = newbuffer; + } + } + + /** + *

+ * Reads the state of a StringBuilder from the passed stream + * and restores it to this instance. + *

+ * + * @param in The stream to read the state from. + * @throws IOException if the stream throws it during the read. + * @throws ClassNotFoundException if the stream throws it during the read. + */ + private void readObject(ObjectInputStream in) throws IOException, + ClassNotFoundException { + in.defaultReadObject(); + length = in.readInt(); + buffer = (char[]) in.readObject(); + } + + /** + *

+ * Writes the state of this object to the stream passed. + *

+ * + * @param out The stream to write the state to. + * @throws IOException if the stream throws it during the write. + * @serialData int - The length of this object. + * char[] - The buffer from this object, which + * may be larger than the length field. + */ + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + out.writeInt(length); + out.writeObject(buffer); + } }