# HG changeset patch # User Jaroslav Tulach # Date 1213429987 -7200 # Node ID b029a28df444bf8dd52947a7c2d2dc6968495d2b # Parent 8379bb7c0dff1356ec9c932f4cd0400ff47cb557 As the purpose of buffer is to "buffer", let's modify our example to delegate to appendable methods directly only if the appendable is too big diff -r 8379bb7c0dff -r b029a28df444 samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java --- a/samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java Sat Jun 14 09:53:06 2008 +0200 +++ b/samples/delegatingwriter/src/org/apidesign/delegatingwriter/AltBufferedWriter.java Sat Jun 14 09:53:07 2008 +0200 @@ -66,7 +66,12 @@ // BEGIN: writer.delegateout // efficient, yet dangerous delegation skipping methods unknown to // subclasses that used version 1.4 - out.append(csq); + if (csq != null && csq.length() < 1024) { + write(csq.toString()); + } else { + flush(); + out.append(csq); + } return this; // END: writer.delegateout } @@ -83,13 +88,10 @@ throw new IOException(ex); } - if (isOverriden) { - if (csq == null) { - write("null"); - } else { - write(csq.toString()); - } + if (isOverriden || (csq != null && csq.length() < 1024)) { + write(csq.toString()); } else { + flush(); out.append(csq); } return this; diff -r 8379bb7c0dff -r b029a28df444 samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterCryptoTest.java --- a/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterCryptoTest.java Sat Jun 14 09:53:06 2008 +0200 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterCryptoTest.java Sat Jun 14 09:53:07 2008 +0200 @@ -14,7 +14,8 @@ */ public class BufferedWriterCryptoTest { private StringWriter writer; - + private String fromCode; + private String toCode; public BufferedWriterCryptoTest() { } @@ -22,6 +23,14 @@ @Before public void setUp() { writer = new StringWriter(); + StringBuffer f = new StringBuffer(); + StringBuffer t = new StringBuffer(); + for (int i = 0; i < 500; i++) { + f.append("VMS"); + t.append("WNT"); + } + fromCode = f.toString(); + toCode = t.toString(); } @Test @@ -35,13 +44,21 @@ } @Test + public void testBehaviourOfRealBufferInJDKWorksFineOnLongSentences() throws IOException { + CryptoWriter bufferedWriter = new CryptoWriter(writer); + bufferedWriter.append(fromCode); + bufferedWriter.flush(); + assertEquals("Converted", toCode, writer.toString()); + } + + @Test public void testBehaviourOfBufferThatDelegatesToAppendFails() throws IOException { CryptoWriter bufferedWriter = new CryptoWriter(writer, CryptoWriter.Behaviour.DELEGATE_TO_OUT); - bufferedWriter.append("VMS"); + bufferedWriter.append(fromCode); bufferedWriter.flush(); assertEquals("This will fail, as the direct delegation from append to " + "the underlaying writer will skip all the crypto methods", - "WNT", writer.toString() + toCode, writer.toString() ); } diff -r 8379bb7c0dff -r b029a28df444 samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterThrowingExceptionTest.java --- a/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterThrowingExceptionTest.java Sat Jun 14 09:53:06 2008 +0200 +++ b/samples/delegatingwriter/test/org/apidesign/delegatingwriter/BufferedWriterThrowingExceptionTest.java Sat Jun 14 09:53:07 2008 +0200 @@ -4,8 +4,6 @@ import java.io.BufferedWriter; import java.io.IOException; import java.io.StringWriter; -import java.io.Writer; -import org.junit.After; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; diff -r 8379bb7c0dff -r b029a28df444 samples/delegatingwriterfinal/src-api1.0/api/SimpleBuffer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/delegatingwriterfinal/src-api1.0/api/SimpleBuffer.java Sat Jun 14 09:53:07 2008 +0200 @@ -0,0 +1,36 @@ +package api; + +import java.io.IOException; + +/** + * + * @author Jaroslav Tulach + */ +final class SimpleBuffer implements Writer.Impl { + private final Writer out; + private final StringBuffer sb = new StringBuffer(); + + public SimpleBuffer(Writer out) { + this.out = out; + } + + public void close() throws IOException { + flush(); + out.close(); + } + + public void flush() throws IOException { + out.write(sb.toString()); + sb.setLength(0); + out.flush(); + } + + public void write(String str, int off, int len) throws IOException { + sb.append(str, len, len); + } + + public void write(char[] arr, int off, int len) throws IOException { + sb.append(arr, len, len); + } + +} diff -r 8379bb7c0dff -r b029a28df444 samples/delegatingwriterfinal/src-api1.0/api/Writer.java --- a/samples/delegatingwriterfinal/src-api1.0/api/Writer.java Sat Jun 14 09:53:06 2008 +0200 +++ b/samples/delegatingwriterfinal/src-api1.0/api/Writer.java Sat Jun 14 09:53:07 2008 +0200 @@ -1,6 +1,5 @@ package api; -import java.io.BufferedWriter; import java.io.IOException; /** Fixing the problem caused by mixing subclassing and delegation in @@ -63,24 +62,7 @@ } public static Writer createBuffered(final Writer out) { - class Delegate extends java.io.Writer { - @Override - public void write(char[] cbuf, int off, int len) throws IOException { - out.write(cbuf, off, len); - } - - @Override - public void flush() throws IOException { - out.flush(); - } - - @Override - public void close() throws IOException { - out.close(); - } - - } - return create(new BufferedWriter(new Delegate())); + return create(new SimpleBuffer(out)); } diff -r 8379bb7c0dff -r b029a28df444 samples/delegatingwriterfinal/src-api2.0/api/SimpleBuffer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/delegatingwriterfinal/src-api2.0/api/SimpleBuffer.java Sat Jun 14 09:53:07 2008 +0200 @@ -0,0 +1,39 @@ +package api; + +import java.io.IOException; + +/** + * + * @author Jaroslav Tulach + */ +final class SimpleBuffer implements Writer.ImplSeq { + private final Writer out; + private final StringBuffer sb = new StringBuffer(); + + public SimpleBuffer(Writer out) { + this.out = out; + } + + public void close() throws IOException { + flush(); + out.close(); + } + + public void flush() throws IOException { + if (sb.length() > 0) { + out.write(sb.toString()); + sb.setLength(0); + out.flush(); + } + } + + public void write(CharSequence seq) throws IOException { + if (seq.length() < 1024) { + sb.append(seq); + } else { + flush(); + out.append(seq); + } + } + +} diff -r 8379bb7c0dff -r b029a28df444 samples/delegatingwriterfinal/src-api2.0/api/Writer.java --- a/samples/delegatingwriterfinal/src-api2.0/api/Writer.java Sat Jun 14 09:53:06 2008 +0200 +++ b/samples/delegatingwriterfinal/src-api2.0/api/Writer.java Sat Jun 14 09:53:07 2008 +0200 @@ -8,7 +8,7 @@ * * @author Jaroslav Tulach */ -public final class Writer { +public final class Writer implements Appendable { private final Impl impl; private final ImplSeq seq; @@ -69,6 +69,27 @@ } } + + + public final Writer append(CharSequence csq) throws IOException { + if (impl != null) { + String s = csq == null ? "null" : csq.toString(); + impl.write(s, 0, s.length()); + } else { + seq.write(csq); + } + return this; + } + + public final Writer append(CharSequence csq, int start, int end) throws IOException { + return append(csq.subSequence(start, end)); + } + + public final Writer append(char c) throws IOException { + write(c); + return this; + } + public static Writer create(Impl impl) { return new Writer(impl, null); } @@ -78,13 +99,9 @@ } public static Writer create(final java.io.Writer w) { - return new Writer(new Impl() { - public void write(String str, int off, int len) throws IOException { - w.write(str, off, len); - } - - public void write(char[] arr, int off, int len) throws IOException { - w.write(arr, off, len); + return new Writer(null, new ImplSeq() { + public void write(CharSequence seq) throws IOException { + w.append(seq); } public void close() throws IOException { @@ -94,28 +111,11 @@ public void flush() throws IOException { w.flush(); } - }, null); + }); } public static Writer createBuffered(final Writer out) { - class Delegate extends java.io.Writer { - @Override - public void write(char[] cbuf, int off, int len) throws IOException { - out.write(cbuf, off, len); - } - - @Override - public void flush() throws IOException { - out.flush(); - } - - @Override - public void close() throws IOException { - out.close(); - } - - } - return create(new BufferedWriter(new Delegate())); + return create(new SimpleBuffer(out)); } diff -r 8379bb7c0dff -r b029a28df444 samples/delegatingwriterfinal/src-test1.0/api/usage/CryptoWriter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/delegatingwriterfinal/src-test1.0/api/usage/CryptoWriter.java Sat Jun 14 09:53:07 2008 +0200 @@ -0,0 +1,60 @@ + +package api.usage; + +import api.Writer; +import java.io.IOException; + + +/** Writer alters each char from 'A' to 'Z' range with next one just like + * old Romans did. + * + * @author Jaroslav Tulach + */ +public class CryptoWriter implements Writer.Impl { + private Writer out; + + private CryptoWriter(Writer out) { + this.out = out; + } + + + public static Writer create(Writer out) { + return Writer.create(new CryptoWriter(out)); + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + char[] arr = new char[len]; + for (int i = 0; i < len; i++) { + arr[i] = convertChar(cbuf[off + i]); + } + out.write(arr, 0, len); + } + + @Override + public void write(String str, int off, int len) throws IOException { + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < len; i++) { + sb.append(convertChar(str.charAt(off + i))); + } + out.write(sb.toString(), 0, len); + } + + private char convertChar(int c) { + if (c == 'Z') { + return 'A'; + } + if (c == 'z') { + return 'a'; + } + return (char)(c + 1); + } + + public void close() throws IOException { + out.close(); + } + + public void flush() throws IOException { + out.flush(); + } +}