From 1a1c534535f962c7325ca1dee3ebaa46578f2320 Mon Sep 17 00:00:00 2001 From: pcoperatr <31451926+pcoperatr@users.noreply.github.com> Date: Fri, 26 Apr 2024 16:48:09 -0400 Subject: [PATCH] classlib: add missing implementation of Appendable interface to PrintStream --- .../teavm/classlib/java/io/TPrintStream.java | 79 +++++++------------ .../classlib/java/io/PrintStreamTest.java | 24 ++++++ 2 files changed, 52 insertions(+), 51 deletions(-) diff --git a/classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java b/classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java index bda2e9af8..cd63b38e5 100644 --- a/classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java +++ b/classlib/src/main/java/org/teavm/classlib/java/io/TPrintStream.java @@ -31,7 +31,7 @@ import org.teavm.classlib.java.nio.charset.TUnsupportedCharsetException; import org.teavm.classlib.java.nio.charset.impl.TUTF8Charset; import org.teavm.classlib.java.util.TFormatter; -public class TPrintStream extends TFilterOutputStream { +public class TPrintStream extends TFilterOutputStream implements Appendable { private boolean autoFlush; private boolean errorState; private TStringBuilder sb = new TStringBuilder(); @@ -145,33 +145,15 @@ public class TPrintStream extends TFilterOutputStream { print(s, 0, s.length); } - private void print(char[] s, int begin, int end) { - TCharBuffer src = TCharBuffer.wrap(s, begin, end - begin); - byte[] destBytes = new byte[TMath.max(16, TMath.min(end - begin, 1024))]; - TByteBuffer dest = TByteBuffer.wrap(destBytes); - TCharsetEncoder encoder = charset.newEncoder() - .onMalformedInput(TCodingErrorAction.REPLACE) - .onUnmappableCharacter(TCodingErrorAction.REPLACE); - while (true) { - boolean overflow = encoder.encode(src, dest, true).isOverflow(); - write(destBytes, 0, dest.position()); - dest.clear(); - if (!overflow) { - break; - } - } - while (true) { - boolean overflow = encoder.flush(dest).isOverflow(); - write(destBytes, 0, dest.position()); - dest.clear(); - if (!overflow) { - break; - } - } + private void print(CharSequence s, int begin, int end) { + printCharBuffer(TCharBuffer.wrap(s, begin, end), begin, end); } - private void print(CharSequence s, int begin, int end) { - TCharBuffer src = TCharBuffer.wrap(s, begin, end - begin); + private void print(char[] s, int begin, int end) { + printCharBuffer(TCharBuffer.wrap(s, begin, end - begin), begin, end); + } + + private void printCharBuffer(TCharBuffer src, int begin, int end) { byte[] destBytes = new byte[TMath.max(16, TMath.min(end - begin, 1024))]; TByteBuffer dest = TByteBuffer.wrap(destBytes); TCharsetEncoder encoder = charset.newEncoder() @@ -285,7 +267,7 @@ public class TPrintStream extends TFilterOutputStream { if (args == null) { args = new Object[1]; } - try (var formatter = new TFormatter(getAppendable(), locale)) { + try (var formatter = new TFormatter(this, locale)) { formatter.format(format, args); if (formatter.ioException() != null) { errorState = true; @@ -301,30 +283,25 @@ public class TPrintStream extends TFilterOutputStream { sb.setLength(0); } - private Appendable appendable; - - private Appendable getAppendable() { - if (appendable == null) { - appendable = new Appendable() { - @Override - public Appendable append(CharSequence csq) { - print(csq, 0, csq.length()); - return this; - } - - @Override - public Appendable append(CharSequence csq, int start, int end) { - print(csq, start, end); - return this; - } - - @Override - public Appendable append(char c) { - print(c); - return this; - } - }; + @Override + public TPrintStream append(CharSequence csq) { + if (csq != null) { + print(csq, 0, csq.length()); + } else { + print("null"); } - return appendable; + return this; + } + + @Override + public TPrintStream append(CharSequence csq, int start, int end) { + print(csq == null ? "null" : csq, start, end); + return this; + } + + @Override + public TPrintStream append(char c) { + print(c); + return this; } } diff --git a/tests/src/test/java/org/teavm/classlib/java/io/PrintStreamTest.java b/tests/src/test/java/org/teavm/classlib/java/io/PrintStreamTest.java index 4262db9d5..8247f1bc3 100644 --- a/tests/src/test/java/org/teavm/classlib/java/io/PrintStreamTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/io/PrintStreamTest.java @@ -34,4 +34,28 @@ public class PrintStreamTest { stream.flush(); assertEquals("n=23; s=null", bytes.toString(StandardCharsets.UTF_8)); } + + @Test + public void append() { + var bytes = new ByteArrayOutputStream(); + var stream = new PrintStream(bytes, false, StandardCharsets.UTF_8); + + stream.append('H'); + stream.append("el"); + stream.append("Hello", 3, 5); + stream.flush(); + assertEquals("Hello", bytes.toString(StandardCharsets.UTF_8)); + } + + @Test + public void append_null() { + var bytes = new ByteArrayOutputStream(); + var stream = new PrintStream(bytes, false, StandardCharsets.UTF_8); + + stream.append(null); + stream.append(null, 1, 2); + stream.flush(); + assertEquals("nullu", bytes.toString(StandardCharsets.UTF_8)); + } + }