From 7fc8d59a999343ad900b91135cd2e6adf1dcfea2 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 28 Nov 2018 22:12:03 -0800 Subject: [PATCH] Add bit more Smile/stream/decorator testing --- .../dataformat/smile/BaseTestForSmile.java | 6 +- .../smile/filter/StreamingDecoratorsTest.java | 45 ++++++++++++ .../smile/testutil/PrefixInputDecorator.java | 71 +++++++++++++++++++ .../smile/testutil/PrefixOutputDecorator.java | 62 ++++++++++++++++ 4 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 smile/src/test/java/com/fasterxml/jackson/dataformat/smile/filter/StreamingDecoratorsTest.java create mode 100644 smile/src/test/java/com/fasterxml/jackson/dataformat/smile/testutil/PrefixInputDecorator.java create mode 100644 smile/src/test/java/com/fasterxml/jackson/dataformat/smile/testutil/PrefixOutputDecorator.java diff --git a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/BaseTestForSmile.java b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/BaseTestForSmile.java index f1aefb969..2408b9280 100644 --- a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/BaseTestForSmile.java +++ b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/BaseTestForSmile.java @@ -62,13 +62,13 @@ protected SmileParser _smileParser(InputStream in) throws IOException { protected SmileParser _smileParser(byte[] input, boolean requireHeader) throws IOException { SmileFactory f = smileFactory(requireHeader, false, false); - return _smileParser(f, input); + return _smileParser(f, input); } protected SmileParser _smileParser(InputStream in, boolean requireHeader) throws IOException { SmileFactory f = smileFactory(requireHeader, false, false); - return _smileParser(f, in); + return _smileParser(f, in); } protected SmileParser _smileParser(SmileFactory f, byte[] input) throws IOException { @@ -102,7 +102,7 @@ protected SmileFactory smileFactory(boolean requireHeader, f.configure(SmileGenerator.Feature.WRITE_END_MARKER, writeEndMarker); return f; } - + protected byte[] _smileDoc(String json) throws IOException { return _smileDoc(json, true); diff --git a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/filter/StreamingDecoratorsTest.java b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/filter/StreamingDecoratorsTest.java new file mode 100644 index 000000000..f1759ba7f --- /dev/null +++ b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/filter/StreamingDecoratorsTest.java @@ -0,0 +1,45 @@ +package com.fasterxml.jackson.dataformat.smile.filter; + +import java.io.ByteArrayOutputStream; + +import com.fasterxml.jackson.core.*; + +import com.fasterxml.jackson.dataformat.smile.*; +import com.fasterxml.jackson.dataformat.smile.testutil.PrefixInputDecorator; +import com.fasterxml.jackson.dataformat.smile.testutil.PrefixOutputDecorator; + +public class StreamingDecoratorsTest extends BaseTestForSmile +{ + public void testInputDecorators() throws Exception + { + final byte[] DOC = _smileDoc("[ 42 ]"); + final SmileFactory streamF = smileFactory(false, true, false); + streamF.setInputDecorator(new PrefixInputDecorator(DOC)); + JsonParser p = streamF.createParser(new byte[0]); + assertToken(JsonToken.START_ARRAY, p.nextToken()); + assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); + assertEquals(42, p.getIntValue()); + assertToken(JsonToken.END_ARRAY, p.nextToken()); + p.close(); + } + + public void testOutputDecorators() throws Exception + { + final byte[] DOC = _smileDoc(" 137"); + // important! Do not add document header for this test + final SmileFactory streamF = smileFactory(false, false, false); + streamF.setOutputDecorator(new PrefixOutputDecorator(DOC)); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + + JsonGenerator g = streamF.createGenerator(bytes); + g.writeString("foo"); + g.close(); + + JsonParser p = streamF.createParser(bytes.toByteArray()); + assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); + assertEquals(137, p.getIntValue()); + assertToken(JsonToken.VALUE_STRING, p.nextToken()); + assertEquals("foo", p.getText()); + p.close(); + } +} diff --git a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/testutil/PrefixInputDecorator.java b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/testutil/PrefixInputDecorator.java new file mode 100644 index 000000000..96e0297d4 --- /dev/null +++ b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/testutil/PrefixInputDecorator.java @@ -0,0 +1,71 @@ +package com.fasterxml.jackson.dataformat.smile.testutil; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.SequenceInputStream; +import java.io.StringReader; +import java.nio.charset.StandardCharsets; + +import com.fasterxml.jackson.core.io.IOContext; +import com.fasterxml.jackson.core.io.InputDecorator; + +@SuppressWarnings("serial") +public class PrefixInputDecorator extends InputDecorator +{ + protected final byte[] _prefix; + + public PrefixInputDecorator(byte[] p) { + _prefix = p; + } + + @Override + public InputStream decorate(IOContext ctxt, InputStream in) { + return new SequenceInputStream(new ByteArrayInputStream(_prefix), in); + } + + @Override + public InputStream decorate(IOContext ctxt, byte[] src, int offset, int length) { + return decorate(ctxt, new ByteArrayInputStream(src, offset, length)); + } + + @Override + public Reader decorate(IOContext ctxt, Reader r) throws IOException { + String str = new String(_prefix, StandardCharsets.UTF_8); + return new SequenceReader(new StringReader(str), r); + } + + private static class SequenceReader extends Reader { + protected Reader _reader1, _reader2; + + public SequenceReader(Reader r1, Reader r2) { + _reader1 = r1; + _reader2 = r2; + } + + @Override + public int read(char[] cbuf, int off, int len) throws IOException { + if (_reader1 != null) { + int count = _reader1.read(cbuf, off, len); + if (count > 0) { + return count; + } + _reader1 = null; + } + if (_reader2 != null) { + int count = _reader2.read(cbuf, off, len); + if (count > 0) { + return count; + } + _reader2 = null; + } + return -1; + } + + @Override + public void close() throws IOException { + _reader1 = _reader2 = null; + } + } +} diff --git a/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/testutil/PrefixOutputDecorator.java b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/testutil/PrefixOutputDecorator.java new file mode 100644 index 000000000..b1383a502 --- /dev/null +++ b/smile/src/test/java/com/fasterxml/jackson/dataformat/smile/testutil/PrefixOutputDecorator.java @@ -0,0 +1,62 @@ +package com.fasterxml.jackson.dataformat.smile.testutil; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + +import com.fasterxml.jackson.core.io.IOContext; +import com.fasterxml.jackson.core.io.OutputDecorator; + +@SuppressWarnings("serial") +public class PrefixOutputDecorator extends OutputDecorator +{ + protected final byte[] _prefix; + + public PrefixOutputDecorator(byte[] p) { + _prefix = p; + } + + @Override + public OutputStream decorate(IOContext ctxt, OutputStream out) + throws IOException + { + out.write(_prefix); + return out; + } + + @Override + public Writer decorate(IOContext ctxt, Writer w) throws IOException { + for (byte b : _prefix) { + w.write((char) (b & 0xFF)); + } + return w; + } + + static class Buffered extends FilterOutputStream { + protected byte[] _prefix; + + public Buffered(OutputStream b, byte[] prefix) { + super(b); + _prefix = prefix; + } + + @Override + public void write(int b) throws IOException { + if (_prefix != null) { + out.write(_prefix); + _prefix = null; + } + super.write(b); + } + + @Override + public void write(byte[] b, int offset, int len) throws IOException { + if (_prefix != null) { + out.write(_prefix); + _prefix = null; + } + super.write(b, offset, len); + } + } +}