Index: src/main/java/java/lang/StringBuffer.java
===================================================================
--- src/main/java/java/lang/StringBuffer.java (revision 412006)
+++ src/main/java/java/lang/StringBuffer.java (working copy)
@@ -16,11 +16,10 @@
package java.lang;
import java.io.IOException;
-import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
import java.io.Serializable;
-import java.util.Arrays;
/**
* StringBuffer is a variable size contiguous indexable array of characters. The
@@ -40,23 +39,16 @@
* @see StringBuilder
* @since 1.0
*/
-public final class StringBuffer implements Appendable, Serializable, CharSequence {
+public final class StringBuffer extends AbstractStringBuilder
+implements Appendable, Serializable, CharSequence {
private static final long serialVersionUID = 3388685877147921107L;
- private static final int INITIAL_SIZE = 16;
-
- private int count;
-
- private boolean shared;
-
- private char[] value;
-
/**
* Constructs a new StringBuffer using the default capacity.
*/
public StringBuffer() {
- this(INITIAL_SIZE);
+ super();
}
/**
@@ -66,9 +58,7 @@
* the initial capacity
*/
public StringBuffer(int capacity) {
- count = 0;
- shared = false;
- value = new char[capacity];
+ super(capacity);
}
/**
@@ -83,10 +73,7 @@
* string
*/
public StringBuffer(String string) {
- count = string.length();
- shared = false;
- value = new char[count + INITIAL_SIZE];
- string.getChars(0, count, value, 0);
+ super(string);
}
/**
@@ -101,13 +88,7 @@
* @since 1.5
*/
public StringBuffer(CharSequence cs) {
- super();
- count = cs.length();
- shared = false;
- value = new char[count + INITIAL_SIZE];
- for (int i = 0; i < count; i++) {
- value[i] = cs.charAt(i);
- }
+ super(cs.toString());
}
/**
@@ -121,15 +102,7 @@
* when chars is null
*/
public synchronized StringBuffer append(char chars[]) {
- int newSize = count + chars.length;
- if (newSize > value.length) {
- ensureCapacityImpl(newSize);
- } else if (shared) {
- value = (char[]) value.clone();
- shared = false;
- }
- System.arraycopy(chars, 0, value, count, chars.length);
- count = newSize;
+ append0(chars);
return this;
}
@@ -152,23 +125,8 @@
* when chars is null
*/
public synchronized StringBuffer append(char chars[], int start, int length) {
- if (chars == null) {
- throw new NullPointerException();
- }
- // start + length could overflow, start/length maybe MaxInt
- if (start >= 0 && 0 <= length && length <= chars.length - start) {
- int newSize = count + length;
- if (newSize > value.length) {
- ensureCapacityImpl(newSize);
- } else if (shared) {
- value = (char[]) value.clone();
- shared = false;
- }
- System.arraycopy(chars, start, value, count, length);
- count = newSize;
- return this;
- }
- throw new ArrayIndexOutOfBoundsException();
+ append0(chars, start, length);
+ return this;
}
/**
@@ -179,16 +137,8 @@
* @return this StringBuffer
*/
public synchronized StringBuffer append(char ch) {
- if (count >= value.length) {
- ensureCapacityImpl(count + 1);
- }
- if (shared) {
- value = (char[]) value.clone();
- shared = false;
- }
- value[count] = ch;
- count++;
- return this;
+ append0(ch);
+ return this;
}
/**
@@ -200,7 +150,7 @@
* @return this StringBuffer
*/
public StringBuffer append(double d) {
- return append(String.valueOf(d));
+ return append(Double.toString(d));
}
/**
@@ -212,7 +162,7 @@
* @return this StringBuffer
*/
public StringBuffer append(float f) {
- return append(String.valueOf(f));
+ return append(Float.toString(f));
}
/**
@@ -247,8 +197,12 @@
* the object
* @return this StringBuffer
*/
- public StringBuffer append(Object obj) {
- return append(String.valueOf(obj));
+ public synchronized StringBuffer append(Object obj) {
+ if (obj == null)
+ appendNull();
+ else
+ append0(obj.toString());
+ return this;
}
/**
@@ -259,19 +213,8 @@
* @return this StringBuffer
*/
public synchronized StringBuffer append(String string) {
- if (string == null)
- string = String.valueOf(string);
- int adding = string.length();
- int newSize = count + adding;
- if (newSize > value.length) {
- ensureCapacityImpl(newSize);
- } else if (shared) {
- value = (char[]) value.clone();
- shared = false;
- }
- string.getChars(0, adding, value, count);
- count = newSize;
- return this;
+ append0(string);
+ return this;
}
/**
@@ -283,23 +226,10 @@
* @return this StringBuffer
*/
public StringBuffer append(boolean b) {
- return append(String.valueOf(b));
+ return append(b ? "true" : "false");
}
/**
- * Answers the number of characters this StringBuffer can hold without
- * growing.
- *
- * @return the capacity of this StringBuffer
- *
- * @see #ensureCapacity
- * @see #length
- */
- public int capacity() {
- return value.length;
- }
-
- /**
* Answers the character at the specified offset in this StringBuffer.
*
* @param index
@@ -311,12 +241,7 @@
* index >= length()
*/
public synchronized char charAt(int index) {
- try {
- if (index < count)
- return value[index];
- } catch (IndexOutOfBoundsException e) {
- }
- throw new StringIndexOutOfBoundsException(index);
+ return super.charAt(index);
}
/**
@@ -333,35 +258,8 @@
* end > length()
*/
public synchronized StringBuffer delete(int start, int end) {
- if (start >= 0) {
- if (end > count)
- end = count;
- if (end > start) {
- int length = count - end;
- if (length > 0) {
- try {
- if (!shared) {
- System.arraycopy(value, end, value, start, length);
- } else {
- char[] newData = new char[value.length];
- System.arraycopy(value, 0, newData, 0, start);
- System
- .arraycopy(value, end, newData, start,
- length);
- value = newData;
- shared = false;
- }
- } catch (IndexOutOfBoundsException e) {
- throw new StringIndexOutOfBoundsException();
- }
- }
- count -= end - start;
- return this;
- }
- if (start == end)
- return this;
- }
- throw new StringIndexOutOfBoundsException();
+ delete0(start, end);
+ return this;
}
/**
@@ -376,29 +274,8 @@
* location >= length()
*/
public synchronized StringBuffer deleteCharAt(int location) {
- if (0 <= location && location < count) {
- int length = count - location - 1;
- if (length > 0) {
- try {
- if (!shared) {
- System.arraycopy(value, location + 1, value, location,
- length);
- } else {
- char[] newData = new char[value.length];
- System.arraycopy(value, 0, newData, 0, location);
- System.arraycopy(value, location + 1, newData,
- location, length);
- value = newData;
- shared = false;
- }
- } catch (IndexOutOfBoundsException e) {
- throw new StringIndexOutOfBoundsException(location);
- }
- }
- count--;
- return this;
- }
- throw new StringIndexOutOfBoundsException(location);
+ deleteCharAt0(location);
+ return this;
}
/**
@@ -410,18 +287,9 @@
* hold before growing
*/
public synchronized void ensureCapacity(int min) {
- if (min > value.length)
- ensureCapacityImpl(min);
+ super.ensureCapacity(min);
}
- private void ensureCapacityImpl(int min) {
- int twice = (value.length << 1) + 2;
- char[] newData = new char[min > twice ? min : twice];
- System.arraycopy(value, 0, newData, 0, count);
- value = newData;
- shared = false;
- }
-
/**
* Copies the specified characters in this StringBuffer to the character
* array starting at the specified offset in the character array.
@@ -441,17 +309,8 @@
* @exception NullPointerException
* when buffer is null
*/
- public synchronized void getChars(int start, int end, char[] buffer,
- int index) {
- // NOTE last character not copied!
- try {
- if (start <= count && end <= count) {
- System.arraycopy(value, start, buffer, index, end - start);
- return;
- }
- } catch (IndexOutOfBoundsException e) {
- }
- throw new ArrayIndexOutOfBoundsException();
+ public synchronized void getChars(int start, int end, char[] buffer, int idx) {
+ super.getChars(start, end, buffer, idx);
}
/**
@@ -470,13 +329,8 @@
* when chars is null
*/
public synchronized StringBuffer insert(int index, char[] chars) {
- if (0 <= index && index <= count) {
- move(chars.length, index);
- System.arraycopy(chars, 0, value, index, chars.length);
- count += chars.length;
- return this;
- }
- throw new StringIndexOutOfBoundsException(index);
+ insert0(index, chars);
+ return this;
}
/**
@@ -502,17 +356,8 @@
*/
public synchronized StringBuffer insert(int index, char chars[], int start,
int length) {
- if (0 <= index && index <= count) {
- // start + length could overflow, start/length maybe MaxInt
- if (start >= 0 && 0 <= length && length <= chars.length - start) {
- move(length, index);
- System.arraycopy(chars, start, value, index, length);
- count += length;
- return this;
- }
- throw new StringIndexOutOfBoundsException();
- }
- throw new StringIndexOutOfBoundsException(index);
+ insert0(index, chars, start, length);
+ return this;
}
/**
@@ -529,13 +374,8 @@
* index > length()
*/
public synchronized StringBuffer insert(int index, char ch) {
- if (0 <= index && index <= count) {
- move(1, index);
- value[index] = ch;
- count++;
- return this;
- }
- throw new ArrayIndexOutOfBoundsException(index);
+ insert0(index, ch);
+ return this;
}
/**
@@ -553,7 +393,7 @@
* index > length()
*/
public StringBuffer insert(int index, double d) {
- return insert(index, String.valueOf(d));
+ return insert(index, Double.toString(d));
}
/**
@@ -571,7 +411,7 @@
* index > length()
*/
public StringBuffer insert(int index, float f) {
- return insert(index, String.valueOf(f));
+ return insert(index, Float.toString(f));
}
/**
@@ -625,7 +465,7 @@
* index > length()
*/
public StringBuffer insert(int index, Object obj) {
- return insert(index, String.valueOf(obj));
+ return insert(index, obj == null ? "null" : obj.toString());
}
/**
@@ -642,16 +482,8 @@
* index > length()
*/
public synchronized StringBuffer insert(int index, String string) {
- if (0 <= index && index <= count) {
- if (string == null)
- string = String.valueOf(string);
- int min = string.length();
- move(min, index);
- string.getChars(0, min, value, index);
- count += min;
- return this;
- }
- throw new StringIndexOutOfBoundsException(index);
+ insert0(index, string);
+ return this;
}
/**
@@ -669,41 +501,10 @@
* index > length()
*/
public StringBuffer insert(int index, boolean b) {
- return insert(index, String.valueOf(b));
+ return insert(index, b ? "true" : "false");
}
/**
- * Answers the size of this StringBuffer.
- *
- * @return the number of characters in this StringBuffer
- */
- public int length() {
- return count;
- }
-
- private void move(int size, int index) {
- int newSize;
- if (value.length - count >= size) {
- if (!shared) {
- System.arraycopy(value, index, value, index + size, count
- - index); // index == count case is no-op
- return;
- }
- newSize = value.length;
- } else {
- int a = count + size, b = (value.length << 1) + 2;
- newSize = a > b ? a : b;
- }
-
- char[] newData = new char[newSize];
- System.arraycopy(value, 0, newData, 0, index);
- // index == count case is no-op
- System.arraycopy(value, index, newData, index + size, count - index);
- value = newData;
- shared = false;
- }
-
- /**
* Replace a range of characters with the characters in the specified
* String.
*
@@ -719,44 +520,8 @@
* when start < 0 or start > end
*/
public synchronized StringBuffer replace(int start, int end, String string) {
- if (start >= 0) {
- if (end > count)
- end = count;
- if (end > start) {
- int stringLength = string.length();
- int diff = end - start - stringLength;
- if (diff > 0) { // replacing with fewer characters
- if (!shared) {
- // index == count case is no-op
- System.arraycopy(value, end, value, start
- + stringLength, count - end);
- } else {
- char[] newData = new char[value.length];
- System.arraycopy(value, 0, newData, 0, start);
- // index == count case is no-op
- System.arraycopy(value, end, newData, start
- + stringLength, count - end);
- value = newData;
- shared = false;
- }
- } else if (diff < 0) {
- // replacing with more characters...need some room
- move(-diff, end);
- } else if (shared) {
- value = (char[]) value.clone();
- shared = false;
- }
- string.getChars(0, stringLength, value, start);
- count -= diff;
- return this;
- }
- if (start == end) {
- if (string == null)
- throw new NullPointerException();
- return insert(start, string);
- }
- }
- throw new StringIndexOutOfBoundsException();
+ replace0(start, end, string);
+ return this;
}
/**
@@ -765,24 +530,8 @@
* @return this StringBuffer
*/
public synchronized StringBuffer reverse() {
- if (count < 2) {
- return this;
- }
- if (!shared) {
- for (int i = 0, end = count, mid = count / 2; i < mid; i++) {
- char temp = value[--end];
- value[end] = value[i];
- value[i] = temp;
- }
- } else {
- char[] newData = new char[value.length];
- for (int i = 0, end = count; i < count; i++) {
- newData[--end] = value[i];
- }
- value = newData;
- shared = false;
- }
- return this;
+ reverse0();
+ return this;
}
/**
@@ -798,14 +547,7 @@
* index >= length()
*/
public synchronized void setCharAt(int index, char ch) {
- if (shared) {
- value = (char[]) value.clone();
- shared = false;
- }
- if (0 <= index && index < count)
- value[index] = ch;
- else
- throw new StringIndexOutOfBoundsException(index);
+ super.setCharAt(index, ch);
}
/**
@@ -823,27 +565,7 @@
* @see #length
*/
public synchronized void setLength(int length) {
- if (length > value.length)
- ensureCapacityImpl(length);
- if (count > length) {
- if (!shared) {
- // NOTE: delete & replace do not void characters orphaned at the
- // end
- try {
- Arrays.fill(value, length, count, (char) 0);
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new IndexOutOfBoundsException();
- }
- } else {
- char[] newData = new char[value.length];
- if (length > 0) {
- System.arraycopy(value, 0, newData, 0, length);
- }
- value = newData;
- shared = false;
- }
- }
- count = length;
+ super.setLength(length);
}
/**
@@ -859,11 +581,7 @@
* start > length()
*/
public synchronized String substring(int start) {
- if (0 <= start && start <= count) {
- shared = true;
- return new String(start, count - start, value);
- }
- throw new StringIndexOutOfBoundsException(start);
+ return super.substring(start);
}
/**
@@ -880,11 +598,7 @@
* end > length()
*/
public synchronized String substring(int start, int end) {
- if (0 <= start && start <= end && end <= count) {
- shared = true;
- return new String(value, start, end - start);
- }
- throw new StringIndexOutOfBoundsException();
+ return super.substring(start, end);
}
/**
@@ -893,35 +607,9 @@
* @return a String containing the characters in this StringBuffer
*/
public synchronized String toString() {
- if (count >= 256 && count <= (value.length >> 1))
- return new String(value, 0, count);
- shared = true;
- return new String(0, count, value);
+ return super.toString();
}
- /*
- * Return the underlying buffer and set the shared flag.
- *
- */
- char[] shareValue() {
- shared = true;
- return value;
- }
-
- private synchronized void writeObject(ObjectOutputStream stream)
- throws IOException {
- stream.defaultWriteObject();
- }
-
- private void readObject(ObjectInputStream stream) throws IOException,
- ClassNotFoundException {
- stream.defaultReadObject();
- if (count > value.length)
- throw new InvalidObjectException(org.apache.harmony.luni.util.Msg
- .getString("K0199"));
- shared = false;
- }
-
/**
* Adds the specified StringBuffer to the end of this StringBuffer.
*
@@ -931,21 +619,14 @@
*
* @since 1.4
*/
- public synchronized StringBuffer append(StringBuffer sbuffer) {
- if (sbuffer == null)
- return append((String) null);
- synchronized (sbuffer) {
- int adding = sbuffer.count;
- int newSize = count + adding;
- if (newSize > value.length) {
- ensureCapacityImpl(newSize);
- } else if (shared) {
- value = (char[]) value.clone();
- shared = false;
- }
- System.arraycopy(sbuffer.value, 0, value, count, adding);
- count = newSize;
- }
+ public synchronized StringBuffer append(StringBuffer sb) {
+ if (sb == null) {
+ appendNull();
+ } else {
+ synchronized (sb) {
+ append0(sb.getValue(), 0, sb.length());
+ }
+ }
return this;
}
@@ -964,30 +645,11 @@
*
* @since 1.4
*/
- public CharSequence subSequence(int start, int end) {
- return substring(start, end);
+ public synchronized CharSequence subSequence(int start, int end) {
+ return super.substring(start, end);
}
/**
- * Searches in this StringBuffer for the first index of the specified
- * character. The search for the character starts at the beginning and moves
- * towards the end.
- *
- *
- * @param string
- * the string to find
- * @return the index in this StringBuffer of the specified character, -1 if
- * the character isn't found
- *
- * @see #lastIndexOf(String)
- *
- * @since 1.4
- */
- public int indexOf(String string) {
- return indexOf(string, 0);
- }
-
- /**
* Searches in this StringBuffer for the index of the specified character.
* The search for the character starts at the specified offset and moves
* towards the end.
@@ -1004,54 +666,10 @@
* @since 1.4
*/
public synchronized int indexOf(String subString, int start) {
- if (start < 0)
- start = 0;
- int subCount = subString.length();
- if (subCount > 0) {
- if (subCount + start > count)
- return -1;
- char firstChar = subString.charAt(0);
- while (true) {
- int i = start;
- boolean found = false;
- for (; i < count; i++)
- if (value[i] == firstChar) {
- found = true;
- break;
- }
- if (!found || subCount + i > count)
- return -1; // handles subCount > count || start >= count
- int o1 = i, o2 = 0;
- while (++o2 < subCount && value[++o1] == subString.charAt(o2)) {
- // Intentionally empty
- }
- if (o2 == subCount)
- return i;
- start = i + 1;
- }
- }
- return (start < count || start == 0) ? start : count;
+ return super.indexOf(subString, start);
}
/**
- * Searches in this StringBuffer for the last index of the specified
- * character. The search for the character starts at the end and moves
- * towards the beginning.
- *
- * @param string
- * the string to find
- * @return the index in this StringBuffer of the specified character, -1 if
- * the character isn't found
- *
- * @see #indexOf(String)
- *
- * @since 1.4
- */
- public synchronized int lastIndexOf(String string) {
- return lastIndexOf(string, count);
- }
-
- /**
* Searches in this StringBuffer for the index of the specified character.
* The search for the character starts at the specified offset and moves
* towards the beginning.
@@ -1068,46 +686,10 @@
* @since 1.4
*/
public synchronized int lastIndexOf(String subString, int start) {
- int subCount = subString.length();
- if (subCount <= count && start >= 0) {
- if (subCount > 0) {
- if (start > count - subCount)
- start = count - subCount; // count and subCount are both
- // >= 1
- char firstChar = subString.charAt(0);
- while (true) {
- int i = start;
- boolean found = false;
- for (; i >= 0; --i)
- if (value[i] == firstChar) {
- found = true;
- break;
- }
- if (!found)
- return -1;
- int o1 = i, o2 = 0;
- while (++o2 < subCount
- && value[++o1] == subString.charAt(o2)) {
- // Intentionally empty
- }
- if (o2 == subCount)
- return i;
- start = i - 1;
- }
- }
- return start < count ? start : count;
- }
- return -1;
- }
+ return super.lastIndexOf(subString, start);
+ }
- /*
- * Returns the character array for this StringBuffer.
- */
- char[] getValue() {
- return value;
- }
-
- /**
+ /**
*
* Trims the storage capacity of this buffer down to the size of the current
* character sequence. Execution of this method may change the results
@@ -1117,12 +699,7 @@
* @since 1.5
*/
public synchronized void trimToSize() {
- if (count < value.length) {
- char[] newValue = new char[count];
- System.arraycopy(value, 0, newValue, 0, count);
- value = newValue;
- shared = false;
- }
+ super.trimToSize();
}
/**
@@ -1140,9 +717,7 @@
* @since 1.5
*/
public synchronized int codePointAt(int index) {
- if (index < 0 || index >= count)
- throw new IndexOutOfBoundsException();
- return Character.codePointAt(value, index, count);
+ return super.codePointAt(index);
}
/**
@@ -1161,9 +736,7 @@
* @since 1.5
*/
public synchronized int codePointBefore(int index) {
- if (index < 1 || index > count)
- throw new IndexOutOfBoundsException();
- return Character.codePointBefore(value, index);
+ return super.codePointBefore(index);
}
/**
@@ -1181,10 +754,7 @@
* @since 1.5
*/
public synchronized int codePointCount(int beginIndex, int endIndex) {
- if (beginIndex < 0 || endIndex > count || beginIndex > endIndex)
- throw new IndexOutOfBoundsException();
- return Character.codePointCount(value, beginIndex, endIndex
- - beginIndex);
+ return super.codePointCount(beginIndex, endIndex);
}
/**
@@ -1203,8 +773,7 @@
* @since 1.5
*/
public synchronized int offsetByCodePoints(int index, int codePointOffset) {
- return Character.offsetByCodePoints(value, 0, count, index,
- codePointOffset);
+ return super.offsetByCodePoints(index, codePointOffset);
}
/**
@@ -1215,10 +784,11 @@
* @return A reference to this object.
* @since 1.5
*/
- public StringBuffer append(CharSequence s) {
+ public synchronized StringBuffer append(CharSequence s) {
if (s == null)
- s = "null";
- append(s.toString());
+ appendNull();
+ else
+ append0(s.toString());
return this;
}
@@ -1233,13 +803,8 @@
* @since 1.5
* @throws IndexOutOfBoundsException if start or end are negative, start is greater than end or end is greater than the length of s.
*/
- public StringBuffer append(CharSequence s, int start, int end) {
- if (s == null)
- s = "null";
- if (start < 0 || end < 0 || start > end || end > s.length())
- throw new IndexOutOfBoundsException();
-
- append(s.subSequence(start, end));
+ public synchronized StringBuffer append(CharSequence s, int start, int end) {
+ append0(s, start, end);
return this;
}
@@ -1269,10 +834,8 @@
* @since 1.5
* @throws IndexOutOfBoundsException if the index is invalid.
*/
- public StringBuffer insert(int index, CharSequence s) {
- if (s == null)
- s = "null";
- insert(index, s.toString());
+ public synchronized StringBuffer insert(int index, CharSequence s) {
+ insert0(index, s == null ? "null" : s.toString());
return this;
}
@@ -1297,13 +860,31 @@
* than end or end is greater than the
* length of s.
*/
- public StringBuffer insert(int index, CharSequence s, int start, int end) {
- if (s == null)
- s = "null";
- if (index < 0 || index > count || start < 0 || end < 0 || start > end
- || end > s.length())
- throw new IndexOutOfBoundsException();
- insert(index, s.subSequence(start, end));
+ public synchronized StringBuffer insert(int index, CharSequence s, int start, int end) {
+ insert0(index, s, start, end);
return this;
}
+
+ private static final ObjectStreamField serialPersistentFields[] = {
+ new ObjectStreamField("count", int.class),
+ new ObjectStreamField("shared", boolean.class),
+ new ObjectStreamField("value", char[].class),
+ };
+
+ private synchronized void writeObject(ObjectOutputStream out)
+ throws IOException {
+ ObjectOutputStream.PutField fields = out.putFields();
+ fields.put("count", length());
+ fields.put("shared", false);
+ fields.put("value", getValue());
+ out.writeFields();
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException,
+ ClassNotFoundException {
+ ObjectInputStream.GetField fields = in.readFields();
+ int count = fields.get("count", 0);
+ char[] value = (char[])fields.get("value", null);
+ set(value, count);
+ }
}
Index: src/main/java/java/lang/StringBuilder.java
===================================================================
--- src/main/java/java/lang/StringBuilder.java (revision 412006)
+++ src/main/java/java/lang/StringBuilder.java (working copy)
@@ -44,22 +44,11 @@
*
* @author Nathan Beyer (Harmony)
*/
-public final class StringBuilder implements Appendable, CharSequence, Serializable {
+public final class StringBuilder extends AbstractStringBuilder
+implements Appendable, CharSequence, Serializable {
private static final long serialVersionUID = 4383685877147921099L;
- private static final String EMPTY_STRING = ""; //$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;
-
/**
*
* Constructs an instance with an initial capacity of 16.
@@ -69,7 +58,6 @@
*/
public StringBuilder() {
super();
- this.buffer = new char[INITIAL_CAPACITY];
}
/**
@@ -85,10 +73,7 @@
* @see #capacity()
*/
public StringBuilder(int capacity) {
- super();
- if (capacity < 0)
- throw new NegativeArraySizeException();
- this.buffer = new char[capacity];
+ super(capacity);
}
/**
@@ -103,14 +88,7 @@
* 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);
- }
+ super(seq.toString());
}
/**
@@ -125,7 +103,7 @@
* null.
*/
public StringBuilder(String str) {
- this((CharSequence) str);
+ super(str);
}
/**
@@ -141,7 +119,8 @@
* @see String#valueOf(boolean)
*/
public StringBuilder append(boolean b) {
- return append(String.valueOf(b));
+ append0(b ? "true" : "false");
+ return this;
}
/**
@@ -157,7 +136,8 @@
* @see String#valueOf(char)
*/
public StringBuilder append(char c) {
- return append(String.valueOf(c));
+ append0(c);
+ return this;
}
/**
@@ -172,8 +152,9 @@
*
* @see String#valueOf(char[])
*/
- public StringBuilder append(char[] str) {
- return append(String.valueOf(str));
+ public StringBuilder append(char[] ch) {
+ append0(ch);
+ return this;
}
/**
@@ -194,7 +175,8 @@
* @see String#valueOf(char[],int,int)
*/
public StringBuilder append(char[] str, int offset, int len) {
- return append(String.valueOf(str, offset, len));
+ append0(str, offset, len);
+ return this;
}
/**
@@ -209,7 +191,11 @@
* @return A reference to this object.
*/
public StringBuilder append(CharSequence csq) {
- return append((String) (csq == null ? null : csq.toString()));
+ if (csq == null)
+ appendNull();
+ else
+ append0(csq.toString());
+ return this;
}
/**
@@ -227,9 +213,8 @@
* @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));
+ append0(csq, start, end);
+ return this;
}
/**
@@ -245,7 +230,8 @@
* @see String#valueOf(double)
*/
public StringBuilder append(double d) {
- return append(String.valueOf(d));
+ append0(Double.toString(d));
+ return this;
}
/**
@@ -261,7 +247,8 @@
* @see String#valueOf(float)
*/
public StringBuilder append(float f) {
- return append(String.valueOf(f));
+ append0(Float.toString(f));
+ return this;
}
/**
@@ -277,7 +264,8 @@
* @see String#valueOf(int)
*/
public StringBuilder append(int i) {
- return append(String.valueOf(i));
+ append0(Integer.toString(i));
+ return this;
}
/**
@@ -293,7 +281,8 @@
* @see String#valueOf(long)
*/
public StringBuilder append(long lng) {
- return append(String.valueOf(lng));
+ append0(Long.toString(lng));
+ return this;
}
/**
@@ -309,7 +298,11 @@
* @see String#valueOf(Object)
*/
public StringBuilder append(Object obj) {
- return append(String.valueOf(obj));
+ if (obj == null)
+ appendNull();
+ else
+ append0(obj.toString());
+ return this;
}
/**
@@ -322,18 +315,7 @@
* @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);
- }
- }
+ append0(str);
return this;
}
@@ -348,7 +330,12 @@
* @return A reference to this object.
*/
public StringBuilder append(StringBuffer sb) {
- return append((CharSequence) sb);
+ if (sb == null) {
+ appendNull();
+ } else {
+ append0(sb.getValue(), 0, sb.length());
+ }
+ return this;
}
/**
@@ -363,97 +350,12 @@
* @see Character#toChars(int)
*/
public StringBuilder appendCodePoint(int codePoint) {
- return append(Character.toChars(codePoint));
+ append0(Character.toChars(codePoint));
+ return this;
}
/**
*
- * 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.
- *
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];
- }
-
- /**
- *
- * Retrieves the Unicode code point value at the index.
- *
char code unit within this
- * object.
- * @return The Unicode code point value.
- * @throws IndexOutOfBoundsException if index is negative or
- * greater than or equal to {@link #length()}.
- * @see Character
- * @see Character#codePointAt(char[], int, int)
- */
- public int codePointAt(int index) {
- if (index < 0 || index >= length)
- throw new IndexOutOfBoundsException();
- return Character.codePointAt(buffer, index, length);
- }
-
- /**
- *
- * Retrieves the Unicode code point value that precedes the
- * index.
- *
char code unit within this
- * object.
- * @return The Unicode code point value.
- * @throws IndexOutOfBoundsException if index is less than 1
- * or greater than {@link #length()}.
- * @see Character
- * @see Character#codePointBefore(char[], int, int)
- */
- public int codePointBefore(int index) {
- if (index < 1 || index > length)
- throw new IndexOutOfBoundsException();
- return Character.codePointBefore(buffer, index);
- }
-
- /**
- *
- * Calculates the number of Unicode code points between
- * beginIndex and endIndex.
- *
beginIndex is
- * negative or greater than endIndex or
- * endIndex is greater than {@link #length()}.
- */
- public int codePointCount(int beginIndex, int endIndex) {
- if (beginIndex < 0 || endIndex > length || beginIndex > endIndex)
- throw new IndexOutOfBoundsException();
- return Character.codePointCount(buffer, beginIndex, 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. *
@@ -466,17 +368,7 @@ *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);
- }
+ delete0(start, end);
return this;
}
@@ -492,122 +384,12 @@
* than zero or is greater 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);
+ deleteCharAt0(index);
+ return this;
}
/**
*
- * Ensures that this object has a minimum capacity available before
- * requiring the internal buffer to be enlarged. The general policy of this
- * 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
- * capacity multiplied by two plus two. Although this is the general policy,
- * there is no guarantee that the capacity will change.
- *
- * Copies the requested sequence of characters to be copied to the
- * char[] passed.
- *
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 greater 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)}.
- *
-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();
- return indexOf(str, 0);
- }
-
- /**
- *
- * 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)}.
- *
-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
@@ -624,10 +406,8 @@
* @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));
+ insert0(offset, b ? "true" : "false");
+ return this;
}
/**
@@ -648,10 +428,8 @@
* @see String#valueOf(char)
*/
public StringBuilder insert(int offset, char c) {
- if (offset < 0 || offset > length)
- throw new ArrayIndexOutOfBoundsException();
-
- return insert(offset, String.valueOf(c));
+ insert0(offset, c);
+ return this;
}
/**
@@ -663,7 +441,7 @@
*
char[] value to insert into this object.
+ * @param ch The char[] value to insert into this object.
* @return A reference to this object.
*
* @throws StringIndexOutOfBoundsException if offset is
@@ -671,11 +449,9 @@
*
* @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));
+ public StringBuilder insert(int offset, char[] ch) {
+ insert0(offset, ch);
+ return this;
}
/**
@@ -702,10 +478,8 @@
*/
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));
+ insert0(offset, str, strOffset, strLen);
+ return this;
}
/**
@@ -728,10 +502,8 @@
* @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()));
+ insert0(offset, s == null ? "null" : s.toString());
+ return this;
}
/**
@@ -759,13 +531,8 @@
* @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));
+ insert0(offset, s, start, end);
+ return this;
}
/**
@@ -786,10 +553,8 @@
* @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));
+ insert0(offset, Double.toString(d));
+ return this;
}
/**
@@ -810,10 +575,8 @@
* @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));
+ insert0(offset, Float.toString(f));
+ return this;
}
/**
@@ -834,10 +597,8 @@
* @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));
+ insert0(offset, Integer.toString(i));
+ return this;
}
/**
@@ -858,10 +619,8 @@
* @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));
+ insert0(offset, Long.toString(l));
+ return this;
}
/**
@@ -882,10 +641,8 @@
* @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));
+ insert0(offset, obj == null ? "null" : obj.toString());
+ return this;
}
/**
@@ -903,105 +660,13 @@
* 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);
+ insert0(offset, str);
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)}.
- *
-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();
- return lastIndexOf(str, length);
- }
/**
*
- * 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)}.
- *
-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; - } - - /** - *
- * Returns the index within this object that is offset from
- * index by codePointOffset code points.
- *
index is negative or
- * greater than {@link #length()} or if there aren't enough code
- * points before or after index to match
- * codePointOffset.
- */
- public int offsetByCodePoints(int index, int codePointOffset) {
- return Character.offsetByCodePoints(buffer, 0, length, index,
- codePointOffset);
- }
-
- /**
- *
* 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.
@@ -1020,32 +685,7 @@
* 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);
- }
- if(end > length) {
- end = length;
- }
- 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]);
- }
- if(strLen < sbLen) {
- delete(start, start + sbLen-strLen);
- }
- // copy in new chars
- for (int i = 0, j = start; i < strLen; i++, j++)
- buffer[j] = str.charAt(i);
+ replace0(start, end, str);
return this;
}
@@ -1057,146 +697,12 @@
* @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;
- }
- }
+ reverse0();
return this;
}
/**
*
- * Sets the character at the index in this object.
- *
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.
- *
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.
- *
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.
- *
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.
- *
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.
*