Index: luni/src/test/java/org/apache/harmony/tests/java/lang/StringBufferTest.java =================================================================== --- luni/src/test/java/org/apache/harmony/tests/java/lang/StringBufferTest.java (revision 382050) +++ luni/src/test/java/org/apache/harmony/tests/java/lang/StringBufferTest.java (working copy) @@ -32,4 +32,186 @@ // expected } } + + /** + * @tests StringBuffer.StringBuffer(CharSequence); + */ + public void test_constructorLjava_lang_CharSequence() { + try { + new StringBuffer((CharSequence) null); + fail("Assert 0: NPE must be thrown."); + } catch (NullPointerException e) {} + + assertEquals("Assert 1: must equal 'abc'.", "abc", new StringBuffer((CharSequence)"abc").toString()); + } + + public void test_trimToSize() { + StringBuffer buffer = new StringBuffer(25); + buffer.append("abc"); + int origCapacity = buffer.capacity(); + buffer.trimToSize(); + int trimCapacity = buffer.capacity(); + assertTrue("Assert 0: capacity must be smaller.", trimCapacity < origCapacity); + assertEquals("Assert 1: length must still be 3", 3, buffer.length()); + assertEquals("Assert 2: value must still be 'abc'.", "abc", buffer.toString()); + } + + /** + * @tests java.lang.StringBuffer.append(CharSequence) + */ + public void test_appendLjava_lang_CharSequence() { + StringBuffer sb = new StringBuffer(); + assertSame(sb, sb.append((CharSequence) "ab")); + assertEquals("ab", sb.toString()); + sb.setLength(0); + assertSame(sb, sb.append((CharSequence) "cd")); + assertEquals("cd", sb.toString()); + sb.setLength(0); + assertSame(sb, sb.append((CharSequence) null)); + assertEquals("null", sb.toString()); + } + + /** + * @tests java.lang.StringBuffer.append(CharSequence, int, int) + */ + public void test_appendLjava_lang_CharSequenceII() { + StringBuffer sb = new StringBuffer(); + assertSame(sb, sb.append((CharSequence) "ab", 0, 2)); + assertEquals("ab", sb.toString()); + sb.setLength(0); + assertSame(sb, sb.append((CharSequence) "cd", 0, 2)); + assertEquals("cd", sb.toString()); + sb.setLength(0); + assertSame(sb, sb.append((CharSequence) "abcd", 0, 2)); + assertEquals("ab", sb.toString()); + sb.setLength(0); + assertSame(sb, sb.append((CharSequence) "abcd", 2, 4)); + assertEquals("cd", sb.toString()); + sb.setLength(0); + assertSame(sb, sb.append((CharSequence) null, 0, 2)); + assertEquals("nu", sb.toString()); + } + + /** + * @tests java.lang.StringBuffer.insert(int, CharSequence) + */ + public void test_insertILjava_lang_CharSequence() { + final String fixture = "0000"; + StringBuffer sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(0, (CharSequence) "ab")); + assertEquals("ab0000", sb.toString()); + assertEquals(6, sb.length()); + + sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(2, (CharSequence) "ab")); + assertEquals("00ab00", sb.toString()); + assertEquals(6, sb.length()); + + sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(4, (CharSequence) "ab")); + assertEquals("0000ab", sb.toString()); + assertEquals(6, sb.length()); + + sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(4, (CharSequence) null)); + assertEquals("0000null", sb.toString()); + assertEquals(8, sb.length()); + + try { + sb = new StringBuffer(fixture); + sb.insert(-1, (CharSequence) "ab"); + fail("no IOOBE, negative index"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + sb = new StringBuffer(fixture); + sb.insert(5, (CharSequence) "ab"); + fail("no IOOBE, index too large index"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + } + + /** + * @tests java.lang.StringBuffer.insert(int, CharSequence, int, int) + */ + public void test_insertILjava_lang_CharSequenceII() { + final String fixture = "0000"; + StringBuffer sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 2)); + assertEquals("ab0000", sb.toString()); + assertEquals(6, sb.length()); + + sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(0, (CharSequence) "ab", 0, 1)); + assertEquals("a0000", sb.toString()); + assertEquals(5, sb.length()); + + sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 2)); + assertEquals("00ab00", sb.toString()); + assertEquals(6, sb.length()); + + sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(2, (CharSequence) "ab", 0, 1)); + assertEquals("00a00", sb.toString()); + assertEquals(5, sb.length()); + + sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 2)); + assertEquals("0000ab", sb.toString()); + assertEquals(6, sb.length()); + + sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(4, (CharSequence) "ab", 0, 1)); + assertEquals("0000a", sb.toString()); + assertEquals(5, sb.length()); + + sb = new StringBuffer(fixture); + assertSame(sb, sb.insert(4, (CharSequence) null, 0, 2)); + assertEquals("0000nu", sb.toString()); + assertEquals(6, sb.length()); + + try { + sb = new StringBuffer(fixture); + sb.insert(-1, (CharSequence) "ab", 0, 2); + fail("no IOOBE, negative index"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + sb = new StringBuffer(fixture); + sb.insert(5, (CharSequence) "ab", 0, 2); + fail("no IOOBE, index too large index"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + sb = new StringBuffer(fixture); + sb.insert(5, (CharSequence) "ab", -1, 2); + fail("no IOOBE, negative offset"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + sb = new StringBuffer(fixture); + sb.insert(5, new char[] { 'a', 'b' }, 0, -1); + fail("no IOOBE, negative length"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + + try { + sb = new StringBuffer(fixture); + sb.insert(5, new char[] { 'a', 'b' }, 0, 3); + fail("no IOOBE, too long"); + } catch (IndexOutOfBoundsException e) { + // Expected + } + } } Index: luni/src/main/java/java/lang/StringBuffer.java =================================================================== --- luni/src/main/java/java/lang/StringBuffer.java (revision 382050) +++ luni/src/main/java/java/lang/StringBuffer.java (working copy) @@ -23,6 +23,8 @@ import java.io.Serializable; import java.util.Arrays; +import org.apache.harmony.luni.util.NotYetImplementedException; + /** * StringBuffer is a variable size contiguous indexable array of characters. The * length of the StringBuffer is the number of characters it contains. The @@ -38,8 +40,11 @@ * increased. * * @see String + * @see StringBuilder + * @since 1.0 */ public final class StringBuffer implements Serializable, CharSequence { + //TODO: Add 'Appendable' to implements when return type covariance is supported. private static final long serialVersionUID = 3388685877147921107L; @@ -87,6 +92,27 @@ value = new char[count + INITIAL_SIZE]; string.getChars(0, count, value, 0); } + + /** + *
+ * Constructs a StringBuffer and initializes it with the characters in the
+ * CharSequence.
+ *
CharSequence to initialize the instance.
+ * @throws NullPointerException if the cs parameter is
+ * null.
+ * @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);
+ }
+ }
/**
* Adds the character array to the end of this StringBuffer.
@@ -1081,4 +1107,178 @@
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 + * returned by the {@link #capacity()} method, but this is not required. + *
+ * + * @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; + } + } + + /** + *+ * NOTE - This method is currently NOT completely implemented and just + * delegates to the {@link #charAt(int)} method. + *
+ * TODO javadoc + * @since 1.5 + */ + public int codePointAt(int index) { + // TODO Implement Java 5 code point functionality. + //Note: synchronization is handled by 'charAt' method + 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 + * @since 1.5 + */ + public int codePointBefore(int index) { + // TODO Implement Java 5 code point functionality. + //Note: synchronization is handled by 'codePointAt' method + return codePointAt(index - 1); + } + + /** + *+ * NOTE - This method is currently NOT completely implemented and just + * return the difference between the index parameters. + *
+ * TODO javadoc + * @since 1.5 + */ + public synchronized int codePointCount(int beginIndex, int endIndex) { + // TODO Implement Java 5 code point functionality. + if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) + throw new IndexOutOfBoundsException(); + return endIndex - beginIndex; + } + + /** + *+ * NOTE - This method is currently not implemented and always throws a + * {@link NotYetImplementedException}. + *
+ * TODO javadoc + * @since 1.5 + */ + public synchronized int offsetByCodePoints(int index, int codePointOffset) { + // TODO Implement Java 5 code point functionality. + throw new NotYetImplementedException(); + } + + /** + *Appends the CharSequence to this buffer. If the
+ * CharSequence is null, then the string
+ * "null" is appended.
CharSequence to append.
+ * @return A reference to this object.
+ * @since 1.5
+ */
+ public StringBuffer append(CharSequence s) {
+ if (s == null)
+ s = "null";
+ append(s.toString());
+ return this;
+ }
+
+ /**
+ * Appends the subsequence of the CharSequence to this buffer. If the
+ * CharSequence is null, then the string
+ * "null" is used to extract a subsequence.
CharSequence to append.
+ * @param start The inclusive start index of the subsequence of the CharSequence.
+ * @param end The exclusive end index of the subsequence of the CharSequence.
+ * @return A reference to this object.
+ * @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));
+ return this;
+ }
+
+ /**
+ *
+ * NOTE - This method is currently NOT completely implemented and just
+ * casts the codePoint to a char and appends it.
+ *
Inserts the CharSequence into this buffer at the index. If
+ * CharSequence is null, then the string "null" is
+ * inserted.
CharSequence to insert.
+ * @return A reference to this object.
+ * @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());
+ return this;
+ }
+
+ /**
+ *
+ * Inserts the CharSequence into this buffer at the
+ * index. If CharSequence is
+ * null, then the string "null" is inserted.
+ *
CharSequence to insert.
+ * @param start The inclusive start index of the subsequence of the
+ * CharSequence.
+ * @param end The exclusive end index of the subsequence of the
+ * CharSequence.
+ * @return A reference to this object.
+ * @since 1.5
+ * @throws IndexOutOfBoundsException if index is negative or
+ * greater than the current length, start or
+ * end are negative, start is greater
+ * 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));
+ return this;
+ }
}