LANG-993: Add zero copy write method to StrBuilder; LANG-994: Add zero copy read method to StrBuilder. Thanks to Mikhail Mazursky.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@1590224 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d13a40266f
commit
6125951060
|
@ -22,6 +22,8 @@
|
|||
<body>
|
||||
|
||||
<release version="3.4" date="tba" description="tba">
|
||||
<action issue="LANG-994" type="add" dev="britter" due-to="Mikhail Mazursky">Add zero copy read method to StrBuilder</action>
|
||||
<action issue="LANG-993" type="add" dev="britter" due-to="Mikhail Mazursky">Add zero copy write method to StrBuilder</action>
|
||||
<action issue="LANG-998" type="update" dev="chas">Javadoc is not clear on preferred pattern to instantiate FastDateParser / FastDatePrinter</action>
|
||||
<action issue="LANG-996" type="fix" dev="chas">FastDateParser should be case insensitive</action>
|
||||
<action issue="LANG-995" type="fix" dev="britter" due-to="Andrey Khobnya">Fix bug with stripping spaces on last line in WordUtils.wrap()</action>
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
*/
|
||||
package org.apache.commons.lang3.text;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Serializable;
|
||||
import java.io.Writer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -421,6 +423,48 @@ public class StrBuilder implements CharSequence, Appendable, Serializable, Build
|
|||
System.arraycopy(buffer, startIndex, destination, destinationIndex, endIndex - startIndex);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* If possible, reads chars from the provided {@link Readable} directly into underlying
|
||||
* character buffer without making extra copies.
|
||||
*
|
||||
* @param readable object to read from
|
||||
* @return the number of characters read
|
||||
* @throws IOException if an I/O error occurs
|
||||
*
|
||||
* @since 3.4
|
||||
* @see #appendTo(Appendable)
|
||||
*/
|
||||
public int readFrom(final Readable readable) throws IOException {
|
||||
final int oldSize = size;
|
||||
if (readable instanceof Reader) {
|
||||
final Reader r = (Reader) readable;
|
||||
ensureCapacity(size + 1);
|
||||
int read;
|
||||
while ((read = r.read(buffer, size, buffer.length - size)) != -1) {
|
||||
size += read;
|
||||
ensureCapacity(size + 1);
|
||||
}
|
||||
} else if (readable instanceof CharBuffer) {
|
||||
final CharBuffer cb = (CharBuffer) readable;
|
||||
final int remaining = cb.remaining();
|
||||
ensureCapacity(size + remaining);
|
||||
cb.get(buffer, size, remaining);
|
||||
size += remaining;
|
||||
} else {
|
||||
while (true) {
|
||||
ensureCapacity(size + 1);
|
||||
final CharBuffer buf = CharBuffer.wrap(buffer, size, buffer.length - size);
|
||||
final int read = readable.read(buf);
|
||||
if (read == -1) {
|
||||
break;
|
||||
}
|
||||
size += read;
|
||||
}
|
||||
}
|
||||
return size - oldSize;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
/**
|
||||
* Appends the new line string to this string builder.
|
||||
|
@ -2610,6 +2654,32 @@ public class StrBuilder implements CharSequence, Appendable, Serializable, Build
|
|||
return new StrBuilderWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends current contents of this <code>StrBuilder</code> to the
|
||||
* provided {@link Appendable}.
|
||||
* <p>
|
||||
* This method tries to avoid doing any extra copies of contents.
|
||||
*
|
||||
* @param appendable the appendable to append data to
|
||||
* @throws IOException if an I/O error occurs
|
||||
*
|
||||
* @since 3.4
|
||||
* @see #readFrom(Readable)
|
||||
*/
|
||||
public void appendTo(final Appendable appendable) throws IOException {
|
||||
if (appendable instanceof Writer) {
|
||||
((Writer) appendable).write(buffer, 0, size);
|
||||
} else if (appendable instanceof StringBuilder) {
|
||||
((StringBuilder) appendable).append(buffer, 0, size);
|
||||
} else if (appendable instanceof StringBuffer) {
|
||||
((StringBuffer) appendable).append(buffer, 0, size);
|
||||
} else if (appendable instanceof CharBuffer) {
|
||||
((CharBuffer) appendable).put(buffer, 0, size);
|
||||
} else {
|
||||
appendable.append(this);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// /**
|
||||
// * Gets a String version of the string builder by calling the internal
|
||||
|
|
|
@ -19,8 +19,13 @@ package org.apache.commons.lang3.text;
|
|||
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
@ -91,6 +96,84 @@ public class StrBuilderTest {
|
|||
assertSame(sb, sb.trim());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@Test
|
||||
public void testReadFromReader() throws Exception {
|
||||
String s = "";
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
StrBuilder sb = new StrBuilder();
|
||||
int len = sb.readFrom(new StringReader(s));
|
||||
|
||||
assertEquals(s.length(), len);
|
||||
assertEquals(s, sb.toString());
|
||||
|
||||
s += Integer.toString(i);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFromReaderAppendsToEnd() throws Exception {
|
||||
StrBuilder sb = new StrBuilder("Test");
|
||||
sb.readFrom(new StringReader(" 123"));
|
||||
assertEquals("Test 123", sb.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFromCharBuffer() throws Exception {
|
||||
String s = "";
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
StrBuilder sb = new StrBuilder();
|
||||
int len = sb.readFrom(CharBuffer.wrap(s));
|
||||
|
||||
assertEquals(s.length(), len);
|
||||
assertEquals(s, sb.toString());
|
||||
|
||||
s += Integer.toString(i);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFromCharBufferAppendsToEnd() throws Exception {
|
||||
StrBuilder sb = new StrBuilder("Test");
|
||||
sb.readFrom(CharBuffer.wrap(" 123"));
|
||||
assertEquals("Test 123", sb.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFromReadable() throws Exception {
|
||||
String s = "";
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
StrBuilder sb = new StrBuilder();
|
||||
int len = sb.readFrom(new MockReadable(s));
|
||||
|
||||
assertEquals(s.length(), len);
|
||||
assertEquals(s, sb.toString());
|
||||
|
||||
s += Integer.toString(i);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadFromReadableAppendsToEnd() throws Exception {
|
||||
StrBuilder sb = new StrBuilder("Test");
|
||||
sb.readFrom(new MockReadable(" 123"));
|
||||
assertEquals("Test 123", sb.toString());
|
||||
}
|
||||
|
||||
private static class MockReadable implements Readable {
|
||||
|
||||
private final CharBuffer src;
|
||||
|
||||
public MockReadable(final String src) {
|
||||
this.src = CharBuffer.wrap(src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(final CharBuffer cb) throws IOException {
|
||||
return src.read(cb);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@Test
|
||||
public void testGetSetNewLineText() {
|
||||
|
@ -1855,4 +1938,48 @@ public class StrBuilderTest {
|
|||
assertEquals(sb.toString(), sb.build());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@Test
|
||||
public void testAppendToWriter() throws Exception {
|
||||
final StrBuilder sb = new StrBuilder("1234567890");
|
||||
final StringWriter writer = new StringWriter();
|
||||
writer.append("Test ");
|
||||
|
||||
sb.appendTo(writer);
|
||||
|
||||
assertEquals("Test 1234567890", writer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppendToStringBuilder() throws Exception {
|
||||
final StrBuilder sb = new StrBuilder("1234567890");
|
||||
final StringBuilder builder = new StringBuilder("Test ");
|
||||
|
||||
sb.appendTo(builder);
|
||||
|
||||
assertEquals("Test 1234567890", builder.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppendToStringBuffer() throws Exception {
|
||||
final StrBuilder sb = new StrBuilder("1234567890");
|
||||
final StringBuffer buffer = new StringBuffer("Test ");
|
||||
|
||||
sb.appendTo(buffer);
|
||||
|
||||
assertEquals("Test 1234567890", buffer.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppendToCharBuffer() throws Exception {
|
||||
final StrBuilder sb = new StrBuilder("1234567890");
|
||||
final String text = "Test ";
|
||||
final CharBuffer buffer = CharBuffer.allocate(sb.size() + text.length());
|
||||
buffer.put(text);
|
||||
|
||||
sb.appendTo(buffer);
|
||||
|
||||
buffer.flip();
|
||||
assertEquals("Test 1234567890", buffer.toString());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue