Add append(StringBuffer,int,int) and append(StrBuilder,int,int)

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@230911 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/java/org/apache/commons/lang/text/StrBuilder.java b/src/java/org/apache/commons/lang/text/StrBuilder.java
index a0c8fe5..a689c19 100644
--- a/src/java/org/apache/commons/lang/text/StrBuilder.java
+++ b/src/java/org/apache/commons/lang/text/StrBuilder.java
@@ -342,7 +342,7 @@
 
     //-----------------------------------------------------------------------
     /**
-     * Appends the text representing <code>null</code> to the string builder.
+     * Appends the text representing <code>null</code> to this string builder.
      *
      * @return this, to enable chaining
      */
@@ -354,7 +354,7 @@
     }
 
     /**
-     * Appends an object to the string builder.
+     * Appends an object to this string builder.
      * Appending null will call {@link #appendNull()}.
      *
      * @param obj  the object to append
@@ -368,7 +368,7 @@
     }
 
     /**
-     * Appends a string to the string builder.
+     * Appends a string to this string builder.
      * Appending null will call {@link #appendNull()}.
      *
      * @param str  the string to append
@@ -389,7 +389,7 @@
     }
 
     /**
-     * Appends a string to the string builder.
+     * Appends part of a string to this string builder.
      * Appending null will call {@link #appendNull()}.
      *
      * @param str  the string to append
@@ -417,7 +417,7 @@
     }
 
     /**
-     * Appends a string buffer to the string builder.
+     * Appends a string buffer to this string builder.
      * Appending null will call {@link #appendNull()}.
      *
      * @param str  the string buffer to append
@@ -438,7 +438,35 @@
     }
 
     /**
-     * Appends another string builder to the string builder.
+     * Appends part of a string buffer to this string builder.
+     * Appending null will call {@link #appendNull()}.
+     *
+     * @param str  the string to append
+     * @param startIndex  the start index, inclusive, must be valid
+     * @param length  the length to append, must be valid
+     * @return this, to enable chaining
+     */
+    public StrBuilder append(StringBuffer str, int startIndex, int length) {
+        if (str == null) {
+            return appendNull();
+        }
+        if (startIndex < 0 || startIndex > str.length()) {
+            throw new StringIndexOutOfBoundsException("startIndex must be valid");
+        }
+        if (length < 0 || (startIndex + length) > str.length()) {
+            throw new StringIndexOutOfBoundsException("length must be valid");
+        }
+        if (length > 0) {
+            int len = length();
+            ensureCapacity(len + length);
+            str.getChars(startIndex, startIndex + length, buffer, len);
+            size += length;
+        }
+        return this;
+    }
+
+    /**
+     * Appends another string builder to this string builder.
      * Appending null will call {@link #appendNull()}.
      *
      * @param str  the string builder to append
@@ -459,6 +487,34 @@
     }
 
     /**
+     * Appends part of a string builder to this string builder.
+     * Appending null will call {@link #appendNull()}.
+     *
+     * @param str  the string to append
+     * @param startIndex  the start index, inclusive, must be valid
+     * @param length  the length to append, must be valid
+     * @return this, to enable chaining
+     */
+    public StrBuilder append(StrBuilder str, int startIndex, int length) {
+        if (str == null) {
+            return appendNull();
+        }
+        if (startIndex < 0 || startIndex > str.length()) {
+            throw new StringIndexOutOfBoundsException("startIndex must be valid");
+        }
+        if (length < 0 || (startIndex + length) > str.length()) {
+            throw new StringIndexOutOfBoundsException("length must be valid");
+        }
+        if (length > 0) {
+            int len = length();
+            ensureCapacity(len + length);
+            str.getChars(startIndex, startIndex + length, buffer, len);
+            size += length;
+        }
+        return this;
+    }
+
+    /**
      * Appends a char array to the string builder.
      * Appending null has no effect.
      * <p>
diff --git a/src/test/org/apache/commons/lang/text/StrBuilderTest.java b/src/test/org/apache/commons/lang/text/StrBuilderTest.java
index df4c33f..b4545e7 100644
--- a/src/test/org/apache/commons/lang/text/StrBuilderTest.java
+++ b/src/test/org/apache/commons/lang/text/StrBuilderTest.java
@@ -635,6 +635,154 @@
         assertEquals("foobar", sb.toString());
     }
 
+    public void testAppend_StringBuffer() {
+        StrBuilder sb = new StrBuilder();
+
+        sb.append(new StringBuffer("foo"));
+        assertEquals("foo", sb.toString());
+
+        sb.append((StringBuffer) null);
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StringBuffer(""));
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StringBuffer("bar"));
+        assertEquals("foobar", sb.toString());
+    }
+
+    public void testAppend_StringBuffer_int_int() {
+        StrBuilder sb = new StrBuilder();
+        
+        sb.append(new StringBuffer("foo"), 0, 3);
+        assertEquals("foo", sb.toString());
+
+        sb.append((StringBuffer) null, 0, 1);
+        assertEquals("foo", sb.toString());
+
+        try {
+            sb.append(new StringBuffer("bar"), -1, 1);
+            fail("append(char[], -1,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StringBuffer("bar"), 3, 1);
+            fail("append(char[], 3,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StringBuffer("bar"), 1, -1);
+            fail("append(char[],, -1) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StringBuffer("bar"), 1, 3);
+            fail("append(char[], 1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StringBuffer("bar"), -1, 3);
+            fail("append(char[], -1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StringBuffer("bar"), 4, 0);
+            fail("append(char[], 4, 0) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.append(new StringBuffer("bar"), 3, 0);
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StringBuffer("abcbardef"), 3, 3);
+        assertEquals("foobar", sb.toString());
+    }
+
+    public void testAppend_StrBuilder() {
+        StrBuilder sb = new StrBuilder();
+
+        sb.append(new StrBuilder("foo"));
+        assertEquals("foo", sb.toString());
+
+        sb.append((StrBuilder) null);
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StrBuilder(""));
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StrBuilder("bar"));
+        assertEquals("foobar", sb.toString());
+    }
+
+    public void testAppend_StrBuilder_int_int() {
+        StrBuilder sb = new StrBuilder();
+        
+        sb.append(new StrBuilder("foo"), 0, 3);
+        assertEquals("foo", sb.toString());
+
+        sb.append((StrBuilder) null, 0, 1);
+        assertEquals("foo", sb.toString());
+
+        try {
+            sb.append(new StrBuilder("bar"), -1, 1);
+            fail("append(char[], -1,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StrBuilder("bar"), 3, 1);
+            fail("append(char[], 3,) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StrBuilder("bar"), 1, -1);
+            fail("append(char[],, -1) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StrBuilder("bar"), 1, 3);
+            fail("append(char[], 1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StrBuilder("bar"), -1, 3);
+            fail("append(char[], -1, 3) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        try {
+            sb.append(new StrBuilder("bar"), 4, 0);
+            fail("append(char[], 4, 0) expected IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+            // expected
+        }
+
+        sb.append(new StrBuilder("bar"), 3, 0);
+        assertEquals("foo", sb.toString());
+
+        sb.append(new StrBuilder("abcbardef"), 3, 3);
+        assertEquals("foobar", sb.toString());
+    }
+
     public void testAppend_CharArray() {
         StrBuilder sb = new StrBuilder();