Skip to content

Commit 38b3ef1

Browse files
committed
Fix #276
1 parent de8f7a0 commit 38b3ef1

File tree

5 files changed

+133
-41
lines changed

5 files changed

+133
-41
lines changed

release-notes/VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ JSON library.
2626
#257: Add `writeStartObject(Object pojo)` to streamline assignment of current value
2727
#265: `JsonStringEncoder` should allow passing `CharSequence`
2828
(contributed by Mikael S)
29+
#276: Add support for serializing using `java.io.DataOutput`
2930
#280: Add `JsonParser.finishToken()` to force full, non-lazy reading of current token
3031

3132
2.7.4 (29-Apr-2016)

src/main/java/com/fasterxml/jackson/core/JsonFactory.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,28 @@ public JsonGenerator createGenerator(File f, JsonEncoding enc) throws IOExceptio
11481148
return _createGenerator(_decorate(w, ctxt), ctxt);
11491149
}
11501150

1151+
/**
1152+
* Method for constructing generator for writing content using specified
1153+
* {@link DataOutput} instance.
1154+
*
1155+
* @since 2.8
1156+
*/
1157+
public JsonGenerator createGenerator(DataOutput out, JsonEncoding enc) throws IOException {
1158+
return createGenerator(_createDataOutputWrapper(out), enc);
1159+
}
1160+
1161+
/**
1162+
* Convenience method for constructing generator that uses default
1163+
* encoding of the format (UTF-8 for JSON and most other data formats).
1164+
*<p>
1165+
* Note: there are formats that use fixed encoding (like most binary data formats).
1166+
*
1167+
* @since 2.8
1168+
*/
1169+
public JsonGenerator createGenerator(DataOutput out) throws IOException {
1170+
return createGenerator(_createDataOutputWrapper(out), JsonEncoding.UTF8);
1171+
}
1172+
11511173
/*
11521174
/**********************************************************
11531175
/* Generator factories, old (pre-2.2)
@@ -1450,6 +1472,13 @@ protected IOContext _createContext(Object srcRef, boolean resourceManaged) {
14501472
return new IOContext(_getBufferRecycler(), srcRef, resourceManaged);
14511473
}
14521474

1475+
/**
1476+
* @since 2.8
1477+
*/
1478+
protected OutputStream _createDataOutputWrapper(DataOutput out) {
1479+
return new DataOutputAsStream(out);
1480+
}
1481+
14531482
/**
14541483
* Helper methods used for constructing an optimal stream for
14551484
* parsers to use, when input is to be read from an URL.
@@ -1465,7 +1494,7 @@ protected InputStream _optimizedStreamFromURL(URL url) throws IOException {
14651494
*/
14661495
String host = url.getHost();
14671496
if (host == null || host.length() == 0) {
1468-
// [Issue#48]: Let's try to avoid probs with URL encoded stuff
1497+
// [core#48]: Let's try to avoid probs with URL encoded stuff
14691498
String path = url.getPath();
14701499
if (path.indexOf('%') < 0) {
14711500
return new FileInputStream(url.getPath());
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.fasterxml.jackson.core.io;
2+
3+
import java.io.*;
4+
5+
/**
6+
* Helper class to support use of {@link DataOutput} for output, directly,
7+
* without caller having to provide for implementation.
8+
*
9+
* @since 2.8
10+
*/
11+
public class DataOutputAsStream extends OutputStream
12+
{
13+
protected final DataOutput _output;
14+
15+
public DataOutputAsStream(DataOutput out) {
16+
super();
17+
_output = out;
18+
}
19+
20+
@Override
21+
public void write(int b) throws IOException {
22+
_output.write(b);
23+
}
24+
25+
@Override
26+
public void write(byte b[]) throws IOException {
27+
_output.write(b, 0, b.length);
28+
}
29+
30+
@Override
31+
public void write(byte b[], int offset, int length) throws IOException {
32+
_output.write(b, offset, length);
33+
}
34+
35+
// These are no-ops, base class impl works fine
36+
37+
/*
38+
@Override
39+
public void flush() throws IOException { }
40+
41+
@Override
42+
public void close() throws IOException { }
43+
*/
44+
}

src/main/java/com/fasterxml/jackson/core/util/ByteArrayBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public final class ByteArrayBuilder extends OutputStream
4242
private int _pastLen;
4343
private byte[] _currBlock;
4444
private int _currBlockPtr;
45-
45+
4646
public ByteArrayBuilder() { this(null); }
4747
public ByteArrayBuilder(BufferRecycler br) { this(br, INITIAL_BLOCK_SIZE); }
4848
public ByteArrayBuilder(int firstBlockSize) { this(null, firstBlockSize); }

src/test/java/com/fasterxml/jackson/core/main/TestGeneratorMisc.java

Lines changed: 57 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -240,46 +240,41 @@ private void _testBinaryWrite(boolean useCharBased) throws Exception
240240
*/
241241
public void testLongerObjects() throws Exception
242242
{
243-
JsonFactory jf = new JsonFactory();
244-
for (int i = 0; i < 2; ++i) {
245-
boolean useChars = (i == 0);
246-
JsonGenerator jgen;
247-
ByteArrayOutputStream bout = new ByteArrayOutputStream(200);
248-
if (useChars) {
249-
jgen = jf.createGenerator(new OutputStreamWriter(bout, "UTF-8"));
250-
} else {
251-
jgen = jf.createGenerator(bout, JsonEncoding.UTF8);
252-
}
243+
final JsonFactory jf = new JsonFactory();
244+
_testLongerObjects(jf, 0);
245+
_testLongerObjects(jf, 1);
246+
_testLongerObjects(jf, 2);
247+
}
253248

254-
jgen.writeStartObject();
249+
public void _testLongerObjects(JsonFactory jf, int mode) throws Exception
250+
{
251+
JsonGenerator jgen;
252+
ByteArrayOutputStream bout = new ByteArrayOutputStream(200);
255253

256-
for (int rounds = 0; rounds < 1500; ++rounds) {
257-
for (int letter = 'a'; letter <= 'z'; ++letter) {
258-
for (int index = 0; index < 20; ++index) {
259-
String name;
260-
if (letter > 'f') {
261-
name = "X"+letter+index;
262-
} else if (letter > 'p') {
263-
name = ""+letter+index;
264-
} else {
265-
name = "__"+index+letter;
266-
}
267-
jgen.writeFieldName(name);
268-
jgen.writeNumber(index-1);
269-
}
270-
jgen.writeRaw('\n');
271-
}
254+
switch (mode) {
255+
case 0:
256+
jgen = jf.createGenerator(new OutputStreamWriter(bout, "UTF-8"));
257+
break;
258+
case 1:
259+
jgen = jf.createGenerator(bout, JsonEncoding.UTF8);
260+
break;
261+
case 2:
262+
{
263+
DataOutputStream dout = new DataOutputStream(bout);
264+
jgen = jf.createGenerator((DataOutput) dout);
272265
}
273-
jgen.writeEndObject();
274-
jgen.close();
266+
267+
break;
268+
default:
269+
fail("Unknown mode "+mode);
270+
jgen = null;
271+
}
272+
273+
jgen.writeStartObject();
275274

276-
byte[] json = bout.toByteArray();
277-
JsonParser jp = jf.createParser(json);
278-
assertToken(JsonToken.START_OBJECT, jp.nextToken());
279-
for (int rounds = 0; rounds < 1500; ++rounds) {
275+
for (int rounds = 0; rounds < 1500; ++rounds) {
280276
for (int letter = 'a'; letter <= 'z'; ++letter) {
281277
for (int index = 0; index < 20; ++index) {
282-
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
283278
String name;
284279
if (letter > 'f') {
285280
name = "X"+letter+index;
@@ -288,14 +283,37 @@ public void testLongerObjects() throws Exception
288283
} else {
289284
name = "__"+index+letter;
290285
}
291-
assertEquals(name, jp.getCurrentName());
292-
assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
293-
assertEquals(index-1, jp.getIntValue());
286+
jgen.writeFieldName(name);
287+
jgen.writeNumber(index-1);
294288
}
289+
jgen.writeRaw('\n');
295290
}
291+
}
292+
jgen.writeEndObject();
293+
jgen.close();
294+
295+
byte[] json = bout.toByteArray();
296+
JsonParser jp = jf.createParser(json);
297+
assertToken(JsonToken.START_OBJECT, jp.nextToken());
298+
for (int rounds = 0; rounds < 1500; ++rounds) {
299+
for (int letter = 'a'; letter <= 'z'; ++letter) {
300+
for (int index = 0; index < 20; ++index) {
301+
assertToken(JsonToken.FIELD_NAME, jp.nextToken());
302+
String name;
303+
if (letter > 'f') {
304+
name = "X"+letter+index;
305+
} else if (letter > 'p') {
306+
name = ""+letter+index;
307+
} else {
308+
name = "__"+index+letter;
309+
}
310+
assertEquals(name, jp.getCurrentName());
311+
assertToken(JsonToken.VALUE_NUMBER_INT, jp.nextToken());
312+
assertEquals(index-1, jp.getIntValue());
296313
}
297-
assertToken(JsonToken.END_OBJECT, jp.nextToken());
298-
jp.close();
299314
}
315+
}
316+
assertToken(JsonToken.END_OBJECT, jp.nextToken());
317+
jp.close();
300318
}
301319
}

0 commit comments

Comments
 (0)