LANG-990: Avoid String allocation in StrBuilder.append(CharSequence). This fixes #51 from github. Thanks to Mikhail Mazurskiy and Fabian Lange.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1666669 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Benedikt Ritter 2015-03-14 12:25:06 +00:00
parent 1181552e7d
commit 3328387a53
3 changed files with 89 additions and 2 deletions

View File

@ -22,6 +22,7 @@
<body>
<release version="3.4" date="tba" description="tba">
<action issue="LANG-1098" type="update" dev="britter" due-to="Mikhail Mazurskiy, Fabian Lange">Avoid String allocation in StrBuilder.append(CharSequence)</action>
<action issue="LANG-1098" type="update" dev="britter" due-to="Michał Kordas">Update maven-checkstyle-plugin to 2.14</action>
<action issue="LANG-1097" type="update" dev="britter" due-to="Michał Kordas">Update org.easymock:easymock to 3.3.1</action>
<action issue="LANG-1096" type="update" dev="britter" due-to="Michał Kordas">Update maven-pmd-plugin to 3.4</action>

View File

@ -505,7 +505,10 @@ public class StrBuilder implements CharSequence, Appendable, Serializable, Build
public StrBuilder append(final Object obj) {
if (obj == null) {
return appendNull();
}
}
if (obj instanceof CharSequence) {
return append((CharSequence) obj);
}
return append(obj.toString());
}
@ -521,7 +524,19 @@ public class StrBuilder implements CharSequence, Appendable, Serializable, Build
public StrBuilder append(final CharSequence seq) {
if (seq == null) {
return appendNull();
}
}
if (seq instanceof StrBuilder) {
return append((StrBuilder) seq);
}
if (seq instanceof StringBuilder) {
return append((StringBuilder) seq);
}
if (seq instanceof StringBuffer) {
return append((StringBuffer) seq);
}
if (seq instanceof CharBuffer) {
return append((CharBuffer) seq);
}
return append(seq.toString());
}
@ -606,6 +621,62 @@ public class StrBuilder implements CharSequence, Appendable, Serializable, Build
return append(String.format(format, objs));
}
/**
* Appends the contents of a char buffer to this string builder.
* Appending null will call {@link #appendNull()}.
*
* @param buf the char buffer to append
* @return this, to enable chaining
* @since 3.4
*/
public StrBuilder append(final CharBuffer buf) {
if (buf == null) {
return appendNull();
}
if (buf.hasArray()) {
final int length = buf.remaining();
final int len = length();
ensureCapacity(len + length);
System.arraycopy(buf.array(), buf.arrayOffset() + buf.position(), buffer, len, length);
size += length;
} else {
append(buf.toString());
}
return this;
}
/**
* Appends the contents of a char buffer to this string builder.
* Appending null will call {@link #appendNull()}.
*
* @param buf the char buffer 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
* @since 3.4
*/
public StrBuilder append(final CharBuffer buf, final int startIndex, final int length) {
if (buf == null) {
return appendNull();
}
if (buf.hasArray()) {
final int totalLength = buf.remaining();
if (startIndex < 0 || startIndex > totalLength) {
throw new StringIndexOutOfBoundsException("startIndex must be valid");
}
if (length < 0 || (startIndex + length) > totalLength) {
throw new StringIndexOutOfBoundsException("length must be valid");
}
final int len = length();
ensureCapacity(len + length);
System.arraycopy(buf.array(), buf.arrayOffset() + buf.position() + startIndex, buffer, len, length);
size += length;
} else {
append(buf.toString(), startIndex, length);
}
return this;
}
/**
* Appends a string buffer to this string builder.
* Appending null will call {@link #appendNull()}.

View File

@ -1938,6 +1938,21 @@ public class StrBuilderTest {
assertEquals(sb.toString(), sb.build());
}
//-----------------------------------------------------------------------
@Test
public void testAppendCharBuffer() {
final StrBuilder sb1 = new StrBuilder();
final CharBuffer buf = CharBuffer.allocate(10);
buf.append("0123456789");
buf.flip();
sb1.append(buf);
assertEquals("0123456789", sb1.toString());
final StrBuilder sb2 = new StrBuilder();
sb2.append(buf, 1, 8);
assertEquals("12345678", sb2.toString());
}
//-----------------------------------------------------------------------
@Test
public void testAppendToWriter() throws Exception {