Fix #318
diff --git a/release-notes/VERSION b/release-notes/VERSION
index f0b2473..170fed2 100644
--- a/release-notes/VERSION
+++ b/release-notes/VERSION
@@ -20,6 +20,8 @@
2.8.3 (not yet released)
+#318: Add support for writing `byte[]` via `JsonGenerator.writeEmbeddedObject()`
+
2.8.2 (30-Aug-2016)
2.8.1 (20-Jul-2016)
diff --git a/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java b/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java
index 92be7cd..da75a61 100644
--- a/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java
+++ b/src/main/java/com/fasterxml/jackson/core/JsonGenerator.java
@@ -1326,7 +1326,17 @@
* @since 2.8
*/
public void writeEmbeddedObject(Object object) throws IOException {
- throw new JsonGenerationException("No native support for writing embedded objects",
+ // 01-Sep-2016, tatu: As per [core#318], handle small number of cases
+ if (object == null) {
+ writeNull();
+ return;
+ }
+ if (object instanceof byte[]) {
+ writeBinary((byte[]) object);
+ return;
+ }
+ throw new JsonGenerationException("No native support for writing embedded objects of type "
+ +object.getClass().getName(),
this);
}
diff --git a/src/test/java/com/fasterxml/jackson/core/base64/Base64BinaryParsingTest.java b/src/test/java/com/fasterxml/jackson/core/base64/Base64BinaryParsingTest.java
new file mode 100644
index 0000000..8693bb9
--- /dev/null
+++ b/src/test/java/com/fasterxml/jackson/core/base64/Base64BinaryParsingTest.java
@@ -0,0 +1,271 @@
+package com.fasterxml.jackson.core.base64;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import java.io.*;
+
+import com.fasterxml.jackson.core.*;
+
+public class Base64BinaryParsingTest
+ extends com.fasterxml.jackson.core.BaseTest
+{
+ public void testBase64UsingInputStream() throws Exception
+ {
+ _testBase64Text(MODE_INPUT_STREAM);
+ _testBase64Text(MODE_INPUT_STREAM_THROTTLED);
+ _testBase64Text(MODE_DATA_INPUT);
+ }
+
+ public void testBase64UsingReader() throws Exception
+ {
+ _testBase64Text(MODE_READER);
+ }
+
+ public void testStreaming() throws IOException
+ {
+ _testStreaming(MODE_INPUT_STREAM);
+ _testStreaming(MODE_INPUT_STREAM_THROTTLED);
+ _testStreaming(MODE_DATA_INPUT);
+ _testStreaming(MODE_READER);
+ }
+
+ public void testSimple() throws IOException
+ {
+ for (int mode : ALL_MODES) {
+ _testSimple(mode);
+ }
+ }
+
+ public void testInArray() throws IOException
+ {
+ for (int mode : ALL_MODES) {
+ _testInArray(mode);
+ }
+ }
+
+ public void testWithEscaped() throws IOException {
+ for (int mode : ALL_MODES) {
+ _testEscaped(mode);
+ }
+ }
+
+ /*
+ /**********************************************************
+ /* Test helper methods
+ /**********************************************************
+ */
+
+ @SuppressWarnings("resource")
+ public void _testBase64Text(int mode) throws Exception
+ {
+ // let's actually iterate over sets of encoding modes, lengths
+
+ final int[] LENS = { 1, 2, 3, 4, 7, 9, 32, 33, 34, 35 };
+ final Base64Variant[] VARIANTS = {
+ Base64Variants.MIME,
+ Base64Variants.MIME_NO_LINEFEEDS,
+ Base64Variants.MODIFIED_FOR_URL,
+ Base64Variants.PEM
+ };
+
+ JsonFactory jsonFactory = new JsonFactory();
+ final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ StringWriter chars = null;
+ for (int len : LENS) {
+ byte[] input = new byte[len];
+ for (int i = 0; i < input.length; ++i) {
+ input[i] = (byte) i;
+ }
+ for (Base64Variant variant : VARIANTS) {
+ JsonGenerator g;
+
+ if (mode == MODE_READER) {
+ chars = new StringWriter();
+ g = jsonFactory.createGenerator(chars);
+ } else {
+ bytes.reset();
+ g = jsonFactory.createGenerator(bytes, JsonEncoding.UTF8);
+ }
+ g.writeBinary(variant, input, 0, input.length);
+ g.close();
+ JsonParser p;
+ if (mode == MODE_READER) {
+ p = jsonFactory.createParser(chars.toString());
+ } else {
+ p = createParser(jsonFactory, mode, bytes.toByteArray());
+ }
+ assertToken(JsonToken.VALUE_STRING, p.nextToken());
+ byte[] data = null;
+ try {
+ data = p.getBinaryValue(variant);
+ } catch (Exception e) {
+ IOException ioException = new IOException("Failed (variant "+variant+", data length "+len+"): "+e.getMessage());
+ ioException.initCause(e);
+ throw ioException;
+ }
+ assertNotNull(data);
+ assertArrayEquals(data, input);
+ if (mode != MODE_DATA_INPUT) { // no look-ahead for DataInput
+ assertNull(p.nextToken());
+ }
+ p.close();
+ }
+ }
+ }
+
+ private byte[] _generateData(int size)
+ {
+ byte[] result = new byte[size];
+ for (int i = 0; i < size; ++i) {
+ result[i] = (byte) (i % 255);
+ }
+ return result;
+ }
+
+ private void _testStreaming(int mode) throws IOException
+ {
+ final int[] SIZES = new int[] {
+ 1, 2, 3, 4, 5, 6,
+ 7, 8, 12,
+ 100, 350, 1900, 6000, 19000, 65000,
+ 139000
+ };
+
+ JsonFactory jsonFactory = new JsonFactory();
+ final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ StringWriter chars = null;
+
+ for (int size : SIZES) {
+ byte[] data = _generateData(size);
+ JsonGenerator g;
+ if (mode == MODE_READER) {
+ chars = new StringWriter();
+ g = jsonFactory.createGenerator(chars);
+ } else {
+ bytes.reset();
+ g = jsonFactory.createGenerator(bytes, JsonEncoding.UTF8);
+ }
+
+ g.writeStartObject();
+ g.writeFieldName("b");
+ g.writeBinary(data);
+ g.writeEndObject();
+ g.close();
+
+ // and verify
+ JsonParser p;
+ if (mode == MODE_READER) {
+ p = jsonFactory.createParser(chars.toString());
+ } else {
+ p = createParser(jsonFactory, mode, bytes.toByteArray());
+ }
+ assertToken(JsonToken.START_OBJECT, p.nextToken());
+
+ assertToken(JsonToken.FIELD_NAME, p.nextToken());
+ assertEquals("b", p.getCurrentName());
+ assertToken(JsonToken.VALUE_STRING, p.nextToken());
+ ByteArrayOutputStream result = new ByteArrayOutputStream(size);
+ int gotten = p.readBinaryValue(result);
+ assertEquals(size, gotten);
+ assertArrayEquals(data, result.toByteArray());
+ assertToken(JsonToken.END_OBJECT, p.nextToken());
+ if (mode != MODE_DATA_INPUT) { // no look-ahead for DataInput
+ assertNull(p.nextToken());
+ }
+ p.close();
+ }
+ }
+
+ private void _testSimple(int mode)
+ throws IOException
+ {
+ /* The usual sample input string, from Thomas Hobbes's "Leviathan"
+ * (via Wikipedia)
+ */
+ final String RESULT = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.";
+ final byte[] RESULT_BYTES = RESULT.getBytes("US-ASCII");
+
+ // And here's what should produce it...
+ final String INPUT_STR =
+ "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"
++"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg"
++"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu"
++"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo"
++"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="
+ ;
+
+ final String DOC = "\""+INPUT_STR+"\"";
+ JsonParser p = createParser(mode, DOC);
+
+ assertToken(JsonToken.VALUE_STRING, p.nextToken());
+ byte[] data = p.getBinaryValue();
+ assertNotNull(data);
+ assertArrayEquals(RESULT_BYTES, data);
+ p.close();
+ }
+
+ private void _testInArray(int mode) throws IOException
+ {
+ JsonFactory f = new JsonFactory();
+
+ final int entryCount = 7;
+
+ StringWriter sw = new StringWriter();
+ JsonGenerator jg = f.createGenerator(sw);
+ jg.writeStartArray();
+
+ byte[][] entries = new byte[entryCount][];
+ for (int i = 0; i < entryCount; ++i) {
+ byte[] b = new byte[200 + i * 100];
+ for (int x = 0; x < b.length; ++x) {
+ b[x] = (byte) (i + x);
+ }
+ entries[i] = b;
+ jg.writeBinary(b);
+ }
+
+ jg.writeEndArray();
+ jg.close();
+
+ JsonParser p = createParser(f, mode, sw.toString());
+
+ assertToken(JsonToken.START_ARRAY, p.nextToken());
+
+ for (int i = 0; i < entryCount; ++i) {
+ assertToken(JsonToken.VALUE_STRING, p.nextToken());
+ byte[] b = p.getBinaryValue();
+ assertArrayEquals(entries[i], b);
+ }
+ assertToken(JsonToken.END_ARRAY, p.nextToken());
+ p.close();
+ }
+
+ private void _testEscaped(int mode) throws IOException
+ {
+ // Input: "Test!" -> "VGVzdCE="
+
+ // First, try with embedded linefeed half-way through:
+
+ String DOC = quote("VGVz\\ndCE="); // note: must double-quote to get linefeed
+ JsonParser p = createParser(mode, DOC);
+ assertToken(JsonToken.VALUE_STRING, p.nextToken());
+ byte[] b = p.getBinaryValue();
+ assertEquals("Test!", new String(b, "US-ASCII"));
+ if (mode != MODE_DATA_INPUT) {
+ assertNull(p.nextToken());
+ }
+ p.close();
+
+ // and then with escaped chars
+// DOC = quote("V\\u0047V\\u007AdCE="); // note: must escape backslash...
+ DOC = quote("V\\u0047V\\u007AdCE="); // note: must escape backslash...
+ p = createParser(mode, DOC);
+ assertToken(JsonToken.VALUE_STRING, p.nextToken());
+ b = p.getBinaryValue();
+ assertEquals("Test!", new String(b, "US-ASCII"));
+ if (mode != MODE_DATA_INPUT) {
+ assertNull(p.nextToken());
+ }
+ p.close();
+ }
+}
diff --git a/src/test/java/com/fasterxml/jackson/core/base64/Base64GenerationTest.java b/src/test/java/com/fasterxml/jackson/core/base64/Base64GenerationTest.java
new file mode 100644
index 0000000..f3b064f
--- /dev/null
+++ b/src/test/java/com/fasterxml/jackson/core/base64/Base64GenerationTest.java
@@ -0,0 +1,207 @@
+package com.fasterxml.jackson.core.base64;
+
+import java.io.*;
+
+import com.fasterxml.jackson.core.*;
+import com.fasterxml.jackson.core.testsupport.ThrottledInputStream;
+
+public class Base64GenerationTest
+ extends com.fasterxml.jackson.core.BaseTest
+{
+ /* The usual sample input string, from Thomas Hobbes's "Leviathan"
+ * (via Wikipedia)
+ */
+ private final static String WIKIPEDIA_BASE64_TEXT = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.";
+ private final static byte[] WIKIPEDIA_BASE64_AS_BYTES;
+ static {
+ try {
+ WIKIPEDIA_BASE64_AS_BYTES = WIKIPEDIA_BASE64_TEXT.getBytes("US-ASCII");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private final String WIKIPEDIA_BASE64_ENCODED =
+"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"
++"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg"
++"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu"
++"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo"
++"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="
+ ;
+
+
+ private final static Base64Variant[] VARIANTS = {
+ Base64Variants.MIME,
+ Base64Variants.MIME_NO_LINEFEEDS,
+ Base64Variants.MODIFIED_FOR_URL,
+ Base64Variants.PEM
+ };
+
+ /*
+ /**********************************************************
+ /* Test methods
+ /**********************************************************
+ */
+
+ private final JsonFactory JSON_F = new JsonFactory();
+
+ public void testStreamingBinaryWrites() throws Exception
+ {
+ _testStreamingWrites(JSON_F, true);
+ _testStreamingWrites(JSON_F, false);
+ }
+
+ // For [core#55]
+ public void testIssue55() throws Exception
+ {
+ final JsonFactory f = new JsonFactory();
+
+ // First, byte-backed:
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+
+ JsonGenerator gen = f.createGenerator(bytes);
+ ByteArrayInputStream data = new ByteArrayInputStream(new byte[2000]);
+ gen.writeBinary(data, 1999);
+ gen.close();
+
+ final int EXP_LEN = 2670;
+
+ assertEquals(EXP_LEN, bytes.size());
+
+ // Then char-backed
+ StringWriter sw = new StringWriter();
+
+ gen = f.createGenerator(sw);
+ data = new ByteArrayInputStream(new byte[2000]);
+ gen.writeBinary(data, 1999);
+ gen.close();
+
+ assertEquals(EXP_LEN, sw.toString().length());
+ }
+
+ /**
+ * This is really inadequate test, all in all, but should serve
+ * as some kind of sanity check. Reader-side should more thoroughly
+ * test things, as it does need writers to construct the data first.
+ */
+ public void testSimpleBinaryWrite() throws Exception
+ {
+ _testSimpleBinaryWrite(false);
+ _testSimpleBinaryWrite(true);
+ }
+
+ // for [core#318]
+ public void testBinaryAsEmbeddedObject() throws Exception
+ {
+ JsonGenerator g;
+
+ StringWriter sw = new StringWriter();
+ g = JSON_F.createGenerator(sw);
+ g.writeEmbeddedObject(WIKIPEDIA_BASE64_AS_BYTES);
+ g.close();
+ assertEquals(quote(WIKIPEDIA_BASE64_ENCODED), sw.toString());
+
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream(100);
+ g = JSON_F.createGenerator(bytes);
+ g.writeEmbeddedObject(WIKIPEDIA_BASE64_AS_BYTES);
+ g.close();
+ assertEquals(quote(WIKIPEDIA_BASE64_ENCODED), bytes.toString("UTF-8"));
+ }
+
+ /*
+ /**********************************************************
+ /* Helper methods
+ /**********************************************************
+ */
+
+ private void _testSimpleBinaryWrite(boolean useCharBased) throws Exception
+ {
+ /* Let's only test the standard base64 variant; but write
+ * values in root, array and object contexts.
+ */
+ Base64Variant b64v = Base64Variants.getDefaultVariant();
+ JsonFactory jf = new JsonFactory();
+
+ for (int i = 0; i < 3; ++i) {
+ JsonGenerator gen;
+ ByteArrayOutputStream bout = new ByteArrayOutputStream(200);
+ if (useCharBased) {
+ gen = jf.createGenerator(new OutputStreamWriter(bout, "UTF-8"));
+ } else {
+ gen = jf.createGenerator(bout, JsonEncoding.UTF8);
+ }
+
+ switch (i) {
+ case 0: // root
+ gen.writeBinary(b64v, WIKIPEDIA_BASE64_AS_BYTES, 0, WIKIPEDIA_BASE64_AS_BYTES.length);
+ break;
+ case 1: // array
+ gen.writeStartArray();
+ gen.writeBinary(b64v, WIKIPEDIA_BASE64_AS_BYTES, 0, WIKIPEDIA_BASE64_AS_BYTES.length);
+ gen.writeEndArray();
+ break;
+ default: // object
+ gen.writeStartObject();
+ gen.writeFieldName("field");
+ gen.writeBinary(b64v, WIKIPEDIA_BASE64_AS_BYTES, 0, WIKIPEDIA_BASE64_AS_BYTES.length);
+ gen.writeEndObject();
+ break;
+ }
+ gen.close();
+
+ JsonParser jp = jf.createParser(new ByteArrayInputStream(bout.toByteArray()));
+
+ // Need to skip other events before binary data:
+ switch (i) {
+ case 0:
+ break;
+ case 1:
+ assertEquals(JsonToken.START_ARRAY, jp.nextToken());
+ break;
+ default:
+ assertEquals(JsonToken.START_OBJECT, jp.nextToken());
+ assertEquals(JsonToken.FIELD_NAME, jp.nextToken());
+ break;
+ }
+ assertEquals(JsonToken.VALUE_STRING, jp.nextToken());
+ String actualValue = jp.getText();
+ jp.close();
+ assertEquals(WIKIPEDIA_BASE64_ENCODED, actualValue);
+ }
+ }
+
+ private final static String TEXT = "Some content so that we can test encoding of base64 data; must"
+ +" be long enough include a line wrap or two...";
+ private final static String TEXT4 = TEXT + TEXT + TEXT + TEXT;
+
+ @SuppressWarnings("resource")
+ private void _testStreamingWrites(JsonFactory jf, boolean useBytes) throws Exception
+ {
+ final byte[] INPUT = TEXT4.getBytes("UTF-8");
+ for (Base64Variant variant : VARIANTS) {
+ final String EXP_OUTPUT = "[" + quote(variant.encode(INPUT))+"]";
+ for (boolean passLength : new boolean[] { true, false }) {
+ for (int chunkSize : new int[] { 1, 2, 3, 4, 7, 11, 29, 5000 }) {
+//System.err.println(""+variant+", length "+passLength+", chunk "+chunkSize);
+
+ JsonGenerator jgen;
+
+ final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ if (useBytes) {
+ jgen = jf.createGenerator(bytes);
+ } else {
+ jgen = jf.createGenerator(new OutputStreamWriter(bytes, "UTF-8"));
+ }
+ jgen.writeStartArray();
+ int length = passLength ? INPUT.length : -1;
+ InputStream data = new ThrottledInputStream(INPUT, chunkSize);
+ jgen.writeBinary(variant, data, length);
+ jgen.writeEndArray();
+ jgen.close();
+ String JSON = bytes.toString("UTF-8");
+ assertEquals(EXP_OUTPUT, JSON);
+ }
+ }
+ }
+ }
+}
diff --git a/src/test/java/com/fasterxml/jackson/core/base64/TestBase64Generation.java b/src/test/java/com/fasterxml/jackson/core/base64/TestBase64Generation.java
deleted file mode 100644
index ef3c673..0000000
--- a/src/test/java/com/fasterxml/jackson/core/base64/TestBase64Generation.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package com.fasterxml.jackson.core.base64;
-
-import java.io.*;
-
-import com.fasterxml.jackson.core.*;
-import com.fasterxml.jackson.core.testsupport.ThrottledInputStream;
-
-public class TestBase64Generation
- extends com.fasterxml.jackson.core.BaseTest
-{
-
-
- /*
- /**********************************************************
- /* Test methods
- /**********************************************************
- */
-
- public void testStreamingWrites() throws Exception
- {
- final JsonFactory f = new JsonFactory();
- _testStreamingWrites(f, true);
- _testStreamingWrites(f, false);
- }
-
- // For [#55]
- public void testIssue55() throws Exception
- {
- final JsonFactory f = new JsonFactory();
-
- // First, byte-backed:
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-
- JsonGenerator gen = f.createGenerator(bytes);
- ByteArrayInputStream data = new ByteArrayInputStream(new byte[2000]);
- gen.writeBinary(data, 1999);
- gen.close();
-
- final int EXP_LEN = 2670;
-
- assertEquals(EXP_LEN, bytes.size());
-
- // Then char-backed
- StringWriter sw = new StringWriter();
-
- gen = f.createGenerator(sw);
- data = new ByteArrayInputStream(new byte[2000]);
- gen.writeBinary(data, 1999);
- gen.close();
-
- assertEquals(EXP_LEN, sw.toString().length());
- }
-
- /*
- /**********************************************************
- /* Helper methods
- /**********************************************************
- */
-
- private final static Base64Variant[] VARIANTS = {
- Base64Variants.MIME,
- Base64Variants.MIME_NO_LINEFEEDS,
- Base64Variants.MODIFIED_FOR_URL,
- Base64Variants.PEM
- };
-
- private final static String TEXT = "Some content so that we can test encoding of base64 data; must"
- +" be long enough include a line wrap or two...";
- private final static String TEXT4 = TEXT + TEXT + TEXT + TEXT;
-
- @SuppressWarnings("resource")
- private void _testStreamingWrites(JsonFactory jf, boolean useBytes) throws Exception
- {
- final byte[] INPUT = TEXT4.getBytes("UTF-8");
- for (Base64Variant variant : VARIANTS) {
- final String EXP_OUTPUT = "[" + quote(variant.encode(INPUT))+"]";
- for (boolean passLength : new boolean[] { true, false }) {
- for (int chunkSize : new int[] { 1, 2, 3, 4, 7, 11, 29, 5000 }) {
-//System.err.println(""+variant+", length "+passLength+", chunk "+chunkSize);
-
- JsonGenerator jgen;
-
- final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- if (useBytes) {
- jgen = jf.createGenerator(bytes);
- } else {
- jgen = jf.createGenerator(new OutputStreamWriter(bytes, "UTF-8"));
- }
- jgen.writeStartArray();
- int length = passLength ? INPUT.length : -1;
- InputStream data = new ThrottledInputStream(INPUT, chunkSize);
- jgen.writeBinary(variant, data, length);
- jgen.writeEndArray();
- jgen.close();
- String JSON = bytes.toString("UTF-8");
- assertEquals(EXP_OUTPUT, JSON);
- }
- }
- }
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/core/main/TestGeneratorMisc.java b/src/test/java/com/fasterxml/jackson/core/main/TestGeneratorMisc.java
index ded2380..8447524 100644
--- a/src/test/java/com/fasterxml/jackson/core/main/TestGeneratorMisc.java
+++ b/src/test/java/com/fasterxml/jackson/core/main/TestGeneratorMisc.java
@@ -15,6 +15,8 @@
public class TestGeneratorMisc
extends com.fasterxml.jackson.core.BaseTest
{
+ private final JsonFactory JSON_F = new JsonFactory();
+
/*
/**********************************************************
/* Tests for closing, status
@@ -23,12 +25,11 @@
public void testIsClosed() throws IOException
{
- JsonFactory jf = new JsonFactory();
for (int i = 0; i < 2; ++i) {
boolean stream = ((i & 1) == 0);
JsonGenerator jg = stream ?
- jf.createGenerator(new StringWriter())
- : jf.createGenerator(new ByteArrayOutputStream(), JsonEncoding.UTF8)
+ JSON_F.createGenerator(new StringWriter())
+ : JSON_F.createGenerator(new ByteArrayOutputStream(), JsonEncoding.UTF8)
;
assertFalse(jg.isClosed());
jg.writeStartArray();
@@ -46,9 +47,8 @@
public void testSimpleWriteObject() throws IOException
{
// note: NOT mapping factory, for this test
- JsonFactory jf = new JsonFactory();
StringWriter sw = new StringWriter();
- JsonGenerator gen = jf.createGenerator(sw);
+ JsonGenerator gen = JSON_F.createGenerator(sw);
gen.writeStartArray();
// simple wrappers first
@@ -65,7 +65,7 @@
// then other basic types
sw = new StringWriter();
- gen = jf.createGenerator(sw);
+ gen = JSON_F.createGenerator(sw);
gen.writeStartArray();
gen.writeObject(BigInteger.valueOf(1234));
gen.writeObject(new BigDecimal(0.5));
@@ -76,7 +76,7 @@
// then Atomic types
sw = new StringWriter();
- gen = jf.createGenerator(sw);
+ gen = JSON_F.createGenerator(sw);
gen.writeStartArray();
gen.writeObject(new AtomicBoolean(false));
gen.writeObject(new AtomicInteger(13));
@@ -95,9 +95,8 @@
public void testRaw() throws IOException
{
- JsonFactory jf = new JsonFactory();
StringWriter sw = new StringWriter();
- JsonGenerator gen = jf.createGenerator(sw);
+ JsonGenerator gen = JSON_F.createGenerator(sw);
gen.writeStartArray();
gen.writeRaw("-123, true");
gen.writeRaw(", \"x\" ");
@@ -118,9 +117,8 @@
public void testRawValue() throws IOException
{
- JsonFactory jf = new JsonFactory();
StringWriter sw = new StringWriter();
- JsonGenerator gen = jf.createGenerator(sw);
+ JsonGenerator gen = JSON_F.createGenerator(sw);
gen.writeStartArray();
gen.writeRawValue("7");
gen.writeRawValue("[ null ]");
@@ -141,93 +139,6 @@
assertToken(JsonToken.END_ARRAY, jp.nextToken());
jp.close();
}
-
- /*
- /**********************************************************
- /* Tests for binary data
- /**********************************************************
- */
-
- /**
- * This is really inadequate test, all in all, but should serve
- * as some kind of sanity check. Reader-side should more thoroughly
- * test things, as it does need writers to construct the data first.
- */
- public void testBinaryWrite() throws Exception
- {
- _testBinaryWrite(false);
- _testBinaryWrite(true);
- }
-
- private void _testBinaryWrite(boolean useCharBased) throws Exception
- {
- /* The usual sample input string, from Thomas Hobbes's "Leviathan"
- * (via Wikipedia)
- */
- final String INPUT = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.";
- final byte[] INPUT_BYTES = INPUT.getBytes("US-ASCII");
- // as per MIME variant, result minus lfs =
- final String OUTPUT =
- "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"
-+"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg"
-+"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu"
-+"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo"
-+"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="
- ;
-
- /* Let's only test the standard base64 variant; but write
- * values in root, array and object contexts.
- */
- Base64Variant b64v = Base64Variants.getDefaultVariant();
- JsonFactory jf = new JsonFactory();
-
- for (int i = 0; i < 3; ++i) {
- JsonGenerator gen;
- ByteArrayOutputStream bout = new ByteArrayOutputStream(200);
- if (useCharBased) {
- gen = jf.createGenerator(new OutputStreamWriter(bout, "UTF-8"));
- } else {
- gen = jf.createGenerator(bout, JsonEncoding.UTF8);
- }
-
- switch (i) {
- case 0: // root
- gen.writeBinary(b64v, INPUT_BYTES, 0, INPUT_BYTES.length);
- break;
- case 1: // array
- gen.writeStartArray();
- gen.writeBinary(b64v, INPUT_BYTES, 0, INPUT_BYTES.length);
- gen.writeEndArray();
- break;
- default: // object
- gen.writeStartObject();
- gen.writeFieldName("field");
- gen.writeBinary(b64v, INPUT_BYTES, 0, INPUT_BYTES.length);
- gen.writeEndObject();
- break;
- }
- gen.close();
-
- JsonParser jp = jf.createParser(new ByteArrayInputStream(bout.toByteArray()));
-
- // Need to skip other events before binary data:
- switch (i) {
- case 0:
- break;
- case 1:
- assertEquals(JsonToken.START_ARRAY, jp.nextToken());
- break;
- default:
- assertEquals(JsonToken.START_OBJECT, jp.nextToken());
- assertEquals(JsonToken.FIELD_NAME, jp.nextToken());
- break;
- }
- assertEquals(JsonToken.VALUE_STRING, jp.nextToken());
- String actualValue = jp.getText();
- jp.close();
- assertEquals(OUTPUT, actualValue);
- }
- }
/*
/**********************************************************
@@ -240,10 +151,9 @@
*/
public void testLongerObjects() throws Exception
{
- final JsonFactory jf = new JsonFactory();
- _testLongerObjects(jf, 0);
- _testLongerObjects(jf, 1);
- _testLongerObjects(jf, 2);
+ _testLongerObjects(JSON_F, 0);
+ _testLongerObjects(JSON_F, 1);
+ _testLongerObjects(JSON_F, 2);
}
public void _testLongerObjects(JsonFactory jf, int mode) throws Exception
@@ -316,4 +226,40 @@
assertToken(JsonToken.END_OBJECT, jp.nextToken());
jp.close();
}
+
+ /*
+ /**********************************************************
+ /* Tests, other
+ /**********************************************************
+ */
+
+ // NOTE: test for binary data under `base64/` tests
+ public void testAsEmbedded() throws Exception
+ {
+ JsonGenerator g;
+
+ StringWriter sw = new StringWriter();
+ g = JSON_F.createGenerator(sw);
+ g.writeEmbeddedObject(null);
+ g.close();
+ assertEquals("null", sw.toString());
+
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream(100);
+ g = JSON_F.createGenerator(bytes);
+ g.writeEmbeddedObject(null);
+ g.close();
+ assertEquals("null", bytes.toString("UTF-8"));
+
+ // also, for fun, try illegal unknown thingy
+
+ try {
+ g = JSON_F.createGenerator(bytes);
+ // try writing a Class object
+ g.writeEmbeddedObject(getClass());
+ fail("Expected an exception");
+ g.close(); // never gets here
+ } catch (JsonGenerationException e) {
+ verifyException(e, "No native support for");
+ }
+ }
}
diff --git a/src/test/java/com/fasterxml/jackson/core/read/Base64BinaryParsingTest.java b/src/test/java/com/fasterxml/jackson/core/read/Base64BinaryParsingTest.java
deleted file mode 100644
index fbd7126..0000000
--- a/src/test/java/com/fasterxml/jackson/core/read/Base64BinaryParsingTest.java
+++ /dev/null
@@ -1,158 +0,0 @@
-package com.fasterxml.jackson.core.read;
-
-import static org.junit.Assert.assertArrayEquals;
-
-import java.io.*;
-
-import com.fasterxml.jackson.core.*;
-
-public class Base64BinaryParsingTest
- extends com.fasterxml.jackson.core.BaseTest
-{
- public void testBase64UsingInputStream() throws Exception
- {
- _testBase64Text(MODE_INPUT_STREAM);
- _testBase64Text(MODE_INPUT_STREAM_THROTTLED);
- _testBase64Text(MODE_DATA_INPUT);
- }
-
- public void testBase64UsingReader() throws Exception
- {
- _testBase64Text(MODE_READER);
- }
-
- public void testStreaming() throws IOException
- {
- _testStreaming(MODE_INPUT_STREAM);
- _testStreaming(MODE_INPUT_STREAM_THROTTLED);
- _testStreaming(MODE_DATA_INPUT);
- _testStreaming(MODE_READER);
- }
-
- /*
- /**********************************************************
- /* Test helper methods
- /**********************************************************
- */
-
- @SuppressWarnings("resource")
- public void _testBase64Text(int mode) throws Exception
- {
- // let's actually iterate over sets of encoding modes, lengths
-
- final int[] LENS = { 1, 2, 3, 4, 7, 9, 32, 33, 34, 35 };
- final Base64Variant[] VARIANTS = {
- Base64Variants.MIME,
- Base64Variants.MIME_NO_LINEFEEDS,
- Base64Variants.MODIFIED_FOR_URL,
- Base64Variants.PEM
- };
-
- JsonFactory jsonFactory = new JsonFactory();
- final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- StringWriter chars = null;
- for (int len : LENS) {
- byte[] input = new byte[len];
- for (int i = 0; i < input.length; ++i) {
- input[i] = (byte) i;
- }
- for (Base64Variant variant : VARIANTS) {
- JsonGenerator g;
-
- if (mode == MODE_READER) {
- chars = new StringWriter();
- g = jsonFactory.createGenerator(chars);
- } else {
- bytes.reset();
- g = jsonFactory.createGenerator(bytes, JsonEncoding.UTF8);
- }
- g.writeBinary(variant, input, 0, input.length);
- g.close();
- JsonParser p;
- if (mode == MODE_READER) {
- p = jsonFactory.createParser(chars.toString());
- } else {
- p = createParser(jsonFactory, mode, bytes.toByteArray());
- }
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- byte[] data = null;
- try {
- data = p.getBinaryValue(variant);
- } catch (Exception e) {
- IOException ioException = new IOException("Failed (variant "+variant+", data length "+len+"): "+e.getMessage());
- ioException.initCause(e);
- throw ioException;
- }
- assertNotNull(data);
- assertArrayEquals(data, input);
- if (mode != MODE_DATA_INPUT) { // no look-ahead for DataInput
- assertNull(p.nextToken());
- }
- p.close();
- }
- }
- }
-
- private byte[] _generateData(int size)
- {
- byte[] result = new byte[size];
- for (int i = 0; i < size; ++i) {
- result[i] = (byte) (i % 255);
- }
- return result;
- }
-
- private void _testStreaming(int mode) throws IOException
- {
- final int[] SIZES = new int[] {
- 1, 2, 3, 4, 5, 6,
- 7, 8, 12,
- 100, 350, 1900, 6000, 19000, 65000,
- 139000
- };
-
- JsonFactory jsonFactory = new JsonFactory();
- final ByteArrayOutputStream bytes = new ByteArrayOutputStream();
- StringWriter chars = null;
-
- for (int size : SIZES) {
- byte[] data = _generateData(size);
- JsonGenerator g;
- if (mode == MODE_READER) {
- chars = new StringWriter();
- g = jsonFactory.createGenerator(chars);
- } else {
- bytes.reset();
- g = jsonFactory.createGenerator(bytes, JsonEncoding.UTF8);
- }
-
- g.writeStartObject();
- g.writeFieldName("b");
- g.writeBinary(data);
- g.writeEndObject();
- g.close();
-
- // and verify
- JsonParser p;
- if (mode == MODE_READER) {
- p = jsonFactory.createParser(chars.toString());
- } else {
- p = createParser(jsonFactory, mode, bytes.toByteArray());
- }
- assertToken(JsonToken.START_OBJECT, p.nextToken());
-
- assertToken(JsonToken.FIELD_NAME, p.nextToken());
- assertEquals("b", p.getCurrentName());
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- ByteArrayOutputStream result = new ByteArrayOutputStream(size);
- int gotten = p.readBinaryValue(result);
- assertEquals(size, gotten);
- assertArrayEquals(data, result.toByteArray());
- assertToken(JsonToken.END_OBJECT, p.nextToken());
- if (mode != MODE_DATA_INPUT) { // no look-ahead for DataInput
- assertNull(p.nextToken());
- }
- p.close();
- }
- }
-}
diff --git a/src/test/java/com/fasterxml/jackson/core/read/TestJsonParserBinary.java b/src/test/java/com/fasterxml/jackson/core/read/TestJsonParserBinary.java
deleted file mode 100644
index 3c5801c..0000000
--- a/src/test/java/com/fasterxml/jackson/core/read/TestJsonParserBinary.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package com.fasterxml.jackson.core.read;
-
-import java.io.*;
-
-import com.fasterxml.jackson.core.*;
-
-import static org.junit.Assert.*;
-
-/**
- * Tests for verifying that accessing base64 encoded content works ok.
- */
-public class TestJsonParserBinary
- extends com.fasterxml.jackson.core.BaseTest
-{
- /*
- /**********************************************************************
- /* Unit tests
- /**********************************************************************
- */
-
- public void testSimple() throws IOException
- {
- for (int mode : ALL_MODES) {
- _testSimple(mode);
- }
- }
-
- public void testInArray() throws IOException
- {
- for (int mode : ALL_MODES) {
- _testInArray(mode);
- }
- }
-
- public void testWithEscaped() throws IOException {
- for (int mode : ALL_MODES) {
- _testEscaped(mode);
- }
- }
-
- /*
- /**********************************************************************
- /* Actual test methods
- /**********************************************************************
- */
-
- private void _testSimple(int mode)
- throws IOException
- {
- /* The usual sample input string, from Thomas Hobbes's "Leviathan"
- * (via Wikipedia)
- */
- final String RESULT = "Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.";
- final byte[] RESULT_BYTES = RESULT.getBytes("US-ASCII");
-
- // And here's what should produce it...
- final String INPUT_STR =
- "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz"
-+"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg"
-+"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu"
-+"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo"
-+"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4="
- ;
-
- final String DOC = "\""+INPUT_STR+"\"";
- JsonParser p = createParser(mode, DOC);
-
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- byte[] data = p.getBinaryValue();
- assertNotNull(data);
- assertArrayEquals(RESULT_BYTES, data);
- p.close();
- }
-
- private void _testInArray(int mode) throws IOException
- {
- JsonFactory f = new JsonFactory();
-
- final int entryCount = 7;
-
- StringWriter sw = new StringWriter();
- JsonGenerator jg = f.createGenerator(sw);
- jg.writeStartArray();
-
- byte[][] entries = new byte[entryCount][];
- for (int i = 0; i < entryCount; ++i) {
- byte[] b = new byte[200 + i * 100];
- for (int x = 0; x < b.length; ++x) {
- b[x] = (byte) (i + x);
- }
- entries[i] = b;
- jg.writeBinary(b);
- }
-
- jg.writeEndArray();
- jg.close();
-
- JsonParser p = createParser(f, mode, sw.toString());
-
- assertToken(JsonToken.START_ARRAY, p.nextToken());
-
- for (int i = 0; i < entryCount; ++i) {
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- byte[] b = p.getBinaryValue();
- assertArrayEquals(entries[i], b);
- }
- assertToken(JsonToken.END_ARRAY, p.nextToken());
- p.close();
- }
-
- private void _testEscaped(int mode) throws IOException
- {
- // Input: "Test!" -> "VGVzdCE="
-
- // First, try with embedded linefeed half-way through:
-
- String DOC = quote("VGVz\\ndCE="); // note: must double-quote to get linefeed
- JsonParser p = createParser(mode, DOC);
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- byte[] b = p.getBinaryValue();
- assertEquals("Test!", new String(b, "US-ASCII"));
- if (mode != MODE_DATA_INPUT) {
- assertNull(p.nextToken());
- }
- p.close();
-
- // and then with escaped chars
-// DOC = quote("V\\u0047V\\u007AdCE="); // note: must escape backslash...
- DOC = quote("V\\u0047V\\u007AdCE="); // note: must escape backslash...
- p = createParser(mode, DOC);
- assertToken(JsonToken.VALUE_STRING, p.nextToken());
- b = p.getBinaryValue();
- assertEquals("Test!", new String(b, "US-ASCII"));
- if (mode != MODE_DATA_INPUT) {
- assertNull(p.nextToken());
- }
- p.close();
- }
-}