Skip to content

Commit

Permalink
Fix #153
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Nov 29, 2018
1 parent 7fc8d59 commit 155ec35
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -274,27 +274,38 @@ public final boolean isEnabled(CBORGenerator.Feature f) {
@SuppressWarnings("resource")
@Override
public CBORParser createParser(File f) throws IOException {
return _createParser(new FileInputStream(f), _createContext(f, true));
IOContext ctxt = _createContext(f, true);
return _createParser(_decorate(new FileInputStream(f), ctxt), ctxt);
}

@Override
public CBORParser createParser(URL url) throws IOException {
return _createParser(_optimizedStreamFromURL(url), _createContext(url, true));
IOContext ctxt = _createContext(url, true);
return _createParser(_decorate(_optimizedStreamFromURL(url), ctxt), ctxt);
}

@Override
public CBORParser createParser(InputStream in) throws IOException {
return _createParser(in, _createContext(in, false));
IOContext ctxt = _createContext(in, false);
return _createParser(_decorate(in, ctxt), ctxt);
}

@Override
public CBORParser createParser(byte[] data) throws IOException {
return _createParser(data, 0, data.length, _createContext(data, true));
return createParser(data, 0, data.length);
}

@SuppressWarnings("resource")
@Override
public CBORParser createParser(byte[] data, int offset, int len) throws IOException {
return _createParser(data, offset, len, _createContext(data, true));
IOContext ctxt = _createContext(data, true);
if (_inputDecorator != null) {
InputStream in = _inputDecorator.decorate(ctxt, data, 0, data.length);
if (in != null) {
return _createParser(in, ctxt);
}
}
return _createParser(data, offset, len, ctxt);
}

/*
Expand All @@ -312,8 +323,10 @@ public CBORParser createParser(byte[] data, int offset, int len) throws IOExcept
*/
@Override
public CBORGenerator createGenerator(OutputStream out, JsonEncoding enc) throws IOException {
return _createCBORGenerator(_createContext(out, false),
_generatorFeatures, _formatGeneratorFeatures, _objectCodec, out);
final IOContext ctxt = _createContext(out, false);
return _createCBORGenerator(ctxt,
_generatorFeatures, _formatGeneratorFeatures, _objectCodec,
_decorate(out, ctxt));
}

/**
Expand All @@ -325,8 +338,10 @@ public CBORGenerator createGenerator(OutputStream out, JsonEncoding enc) throws
*/
@Override
public CBORGenerator createGenerator(OutputStream out) throws IOException {
return _createCBORGenerator(_createContext(out, false),
_generatorFeatures, _formatGeneratorFeatures, _objectCodec, out);
final IOContext ctxt = _createContext(out, false);
return _createCBORGenerator(ctxt,
_generatorFeatures, _formatGeneratorFeatures, _objectCodec,
_decorate(out, ctxt));
}

/*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.fasterxml.jackson.dataformat.cbor.filter;

import java.io.*;

import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.dataformat.cbor.*;
import com.fasterxml.jackson.dataformat.cbor.util.PrefixInputDecorator;
import com.fasterxml.jackson.dataformat.cbor.util.PrefixOutputDecorator;

public class StreamingDecoratorsTest extends CBORTestBase
{
public void testInputDecorators() throws Exception
{
final byte[] DOC = cborDoc("42 37");
final CBORFactory streamF = cborFactory();
streamF.setInputDecorator(new PrefixInputDecorator(DOC));
JsonParser p = streamF.createParser(new byte[0], 0, 0);
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(42, p.getIntValue());
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(37, p.getIntValue());
assertNull(p.nextToken());
p.close();
}

public void testOutputDecorators() throws Exception
{
final byte[] DOC = cborDoc(" 137");
final CBORFactory streamF = cborFactory();
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());
assertNull(p.nextToken());
p.close();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.fasterxml.jackson.dataformat.cbor.util;

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) {
if (in instanceof MySequenceInputStream) {
throw new IllegalStateException("Trying to decorate MySequenceInputStream (double-decoration!)");
}
return new MySequenceInputStream(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 {
if (r instanceof SequenceReader) {
throw new IllegalStateException("Trying to decorate SequenceReader (double-decoration!)");
}
String str = new String(_prefix, StandardCharsets.UTF_8);
return new SequenceReader(new StringReader(str), r);
}

// sub-class only so we can check for "double decoration"
static class MySequenceInputStream extends SequenceInputStream {
public MySequenceInputStream(InputStream in1, InputStream in2) {
super(in1, in2);
}
}

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;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.fasterxml.jackson.dataformat.cbor.util;

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
{
if (out instanceof BufferedOut) {
throw new IllegalStateException("Trying to decorate `Buffered` (double-decoration!)");
}
return new BufferedOut(out, _prefix);
}

@Override
public Writer decorate(IOContext ctxt, Writer w) throws IOException {
for (byte b : _prefix) {
w.write((char) (b & 0xFF));
}
return w;
}

static class BufferedOut extends FilterOutputStream {
protected byte[] _prefix;

public BufferedOut(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);
}
}
}
4 changes: 4 additions & 0 deletions release-notes/CREDITS
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,7 @@ Michael Milkin (mmilkin@github)
* Reported, Contributed fix for #142: (ion) `IonParser.getNumberType()` returns `null`
for `IonType.FLOAT`
(2.9.7)

Guido Medina (guidomedina@github)
* Reported #153: (smile) Unable to set a compression input/output decorator to a `SmileFactory`
(2.9.8)
5 changes: 5 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ Project: jackson-datatypes-binaryModules:
=== Releases ===
------------------------------------------------------------------------

2.9.8 (not yet released)

#153: (smile) Unable to set a compression input/output decorator to a `SmileFactory`
(reported by Guido M)

2.9.7 (19-Sep-2018)

#142: (ion) `IonParser.getNumberType()` returns `null` for `IonType.FLOAT`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,15 @@ public SmileParser createParser(InputStream in) throws IOException {
public SmileParser createParser(byte[] data) throws IOException {
return createParser(data, 0, data.length);
}

@SuppressWarnings("resource")
@Override
public SmileParser createParser(byte[] data, int offset, int len) throws IOException {
IOContext ctxt = _createContext(data, true);
if (_inputDecorator != null) {
InputStream in = _inputDecorator.decorate(ctxt, data, 0, data.length);
if (in != null) {
return _createParser(_decorate(in, ctxt), ctxt);
return _createParser(in, ctxt);
}
}
return _createParser(data, offset, len, ctxt);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.fasterxml.jackson.dataformat.smile.filter;

import java.io.ByteArrayOutputStream;
import java.io.*;

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;
Expand All @@ -12,14 +11,15 @@ public class StreamingDecoratorsTest extends BaseTestForSmile
{
public void testInputDecorators() throws Exception
{
final byte[] DOC = _smileDoc("[ 42 ]");
final byte[] DOC = _smileDoc("42 37");
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());
JsonParser p = streamF.createParser(new byte[0], 0, 0);
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(42, p.getIntValue());
assertToken(JsonToken.END_ARRAY, p.nextToken());
assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken());
assertEquals(37, p.getIntValue());
assertNull(p.nextToken());
p.close();
}

Expand All @@ -40,6 +40,7 @@ public void testOutputDecorators() throws Exception
assertEquals(137, p.getIntValue());
assertToken(JsonToken.VALUE_STRING, p.nextToken());
assertEquals("foo", p.getText());
assertNull(p.nextToken());
p.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ public PrefixInputDecorator(byte[] p) {

@Override
public InputStream decorate(IOContext ctxt, InputStream in) {
return new SequenceInputStream(new ByteArrayInputStream(_prefix), in);
if (in instanceof MySequenceInputStream) {
throw new IllegalStateException("Trying to decorate MySequenceInputStream (double-decoration!)");
}
return new MySequenceInputStream(new ByteArrayInputStream(_prefix), in);
}

@Override
Expand All @@ -32,11 +35,21 @@ public InputStream decorate(IOContext ctxt, byte[] src, int offset, int length)

@Override
public Reader decorate(IOContext ctxt, Reader r) throws IOException {
if (r instanceof SequenceReader) {
throw new IllegalStateException("Trying to decorate SequenceReader (double-decoration!)");
}
String str = new String(_prefix, StandardCharsets.UTF_8);
return new SequenceReader(new StringReader(str), r);
}

private static class SequenceReader extends Reader {
// sub-class only so we can check for "double decoration"
static class MySequenceInputStream extends SequenceInputStream {
public MySequenceInputStream(InputStream in1, InputStream in2) {
super(in1, in2);
}
}

static class SequenceReader extends Reader {
protected Reader _reader1, _reader2;

public SequenceReader(Reader r1, Reader r2) {
Expand Down
Loading

0 comments on commit 155ec35

Please sign in to comment.