You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by br...@apache.org on 2014/04/26 12:39:03 UTC
svn commit: r1590224 - in /commons/proper/lang/trunk/src:
changes/changes.xml main/java/org/apache/commons/lang3/text/StrBuilder.java
test/java/org/apache/commons/lang3/text/StrBuilderTest.java
Author: britter
Date: Sat Apr 26 10:39:03 2014
New Revision: 1590224
URL: http://svn.apache.org/r1590224
Log:
LANG-993: Add zero copy write method to StrBuilder; LANG-994: Add zero copy read method to StrBuilder. Thanks to Mikhail Mazursky.
Modified:
commons/proper/lang/trunk/src/changes/changes.xml
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/text/StrBuilder.java
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/text/StrBuilderTest.java
Modified: commons/proper/lang/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/changes/changes.xml?rev=1590224&r1=1590223&r2=1590224&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/lang/trunk/src/changes/changes.xml [utf-8] Sat Apr 26 10:39:03 2014
@@ -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>
Modified: commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/text/StrBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/text/StrBuilder.java?rev=1590224&r1=1590223&r2=1590224&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/text/StrBuilder.java (original)
+++ commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/text/StrBuilder.java Sat Apr 26 10:39:03 2014
@@ -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;
@@ -423,6 +425,48 @@ public class StrBuilder implements CharS
//-----------------------------------------------------------------------
/**
+ * 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.
* <p>
* The new line string can be altered using {@link #setNewLineText(String)}.
@@ -2610,6 +2654,32 @@ public class StrBuilder implements CharS
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
Modified: commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/text/StrBuilderTest.java
URL: http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/text/StrBuilderTest.java?rev=1590224&r1=1590223&r2=1590224&view=diff
==============================================================================
--- commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/text/StrBuilderTest.java (original)
+++ commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/text/StrBuilderTest.java Sat Apr 26 10:39:03 2014
@@ -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;
@@ -93,6 +98,84 @@ public class StrBuilderTest {
//-----------------------------------------------------------------------
@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() {
final StrBuilder sb = new StrBuilder();
assertEquals(null, sb.getNewLineText());
@@ -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());
+ }
}