classlib: add missing implementation of Appendable interface to PrintStream

This commit is contained in:
pcoperatr 2024-04-26 16:48:09 -04:00 committed by GitHub
parent c066864c68
commit 1a1c534535
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 51 deletions

View File

@ -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;
}
}

View File

@ -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));
}
}