Skip to content

Commit ea618fc

Browse files
committed
Merge pull request msgpack#241 from msgpack/issue_233_2
Issue 233 2
2 parents 8192552 + f2c5f79 commit ea618fc

5 files changed

Lines changed: 97 additions & 19 deletions

File tree

msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackFactory.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,10 @@
2323

2424
public class MessagePackFactory extends JsonFactory {
2525
private static final long serialVersionUID = 2578263992015504347L;
26-
protected int messagePackGeneratorFeature = 0;
27-
protected int messagePackParserFeature = 0;
2826

2927
@Override
3028
public JsonGenerator createGenerator(OutputStream out, JsonEncoding enc) throws IOException {
31-
return new MessagePackGenerator(messagePackGeneratorFeature, _objectCodec, out);
29+
return new MessagePackGenerator(_generatorFeatures, _objectCodec, out);
3230
}
3331

3432
@Override
@@ -55,7 +53,7 @@ public JsonParser createParser(InputStream in) throws IOException, JsonParseExce
5553

5654
@Override
5755
protected MessagePackParser _createParser(InputStream in, IOContext ctxt) throws IOException {
58-
MessagePackParser parser = new MessagePackParser(ctxt, messagePackParserFeature, in);
56+
MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, in);
5957
return parser;
6058
}
6159

@@ -64,7 +62,7 @@ protected JsonParser _createParser(byte[] data, int offset, int len, IOContext c
6462
if (offset != 0 || len != data.length) {
6563
data = Arrays.copyOfRange(data, offset, offset + len);
6664
}
67-
MessagePackParser parser = new MessagePackParser(ctxt, messagePackParserFeature, data);
65+
MessagePackParser parser = new MessagePackParser(ctxt, _parserFeatures, data);
6866
return parser;
6967
}
7068
}

msgpack-jackson/src/main/java/org/msgpack/jackson/dataformat/MessagePackParser.java

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
import java.math.BigDecimal;
2222
import java.math.BigInteger;
2323
import java.util.LinkedList;
24+
import java.util.logging.Logger;
2425

2526
public class MessagePackParser extends ParserMinimalBase {
26-
private static final ThreadLocal<MessageUnpacker> messageUnpackerHolder = new ThreadLocal<MessageUnpacker>();
27+
private static final ThreadLocal<Tuple<Object, MessageUnpacker>> messageUnpackerHolder =
28+
new ThreadLocal<Tuple<Object, MessageUnpacker>>();
2729

2830
private ObjectCodec codec;
2931
private JsonReadContext parsingContext;
@@ -64,27 +66,37 @@ private static class StackItemForArray extends StackItem {
6466
}
6567

6668
public MessagePackParser(IOContext ctxt, int features, InputStream in) throws IOException {
67-
this(ctxt, features, new InputStreamBufferInput(in));
69+
this(ctxt, features, new InputStreamBufferInput(in), in);
6870
}
6971

7072
public MessagePackParser(IOContext ctxt, int features, byte[] bytes) throws IOException {
71-
this(ctxt, features, new ArrayBufferInput(bytes));
73+
this(ctxt, features, new ArrayBufferInput(bytes), bytes);
7274
}
7375

74-
private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input) throws IOException {
76+
private MessagePackParser(IOContext ctxt, int features, MessageBufferInput input, Object src) throws IOException {
77+
super(features);
78+
7579
ioContext = ctxt;
7680
DupDetector dups = Feature.STRICT_DUPLICATE_DETECTION.enabledIn(features)
7781
? DupDetector.rootDetector(this) : null;
7882
parsingContext = JsonReadContext.createRootContext(dups);
7983

80-
MessageUnpacker messageUnpacker = messageUnpackerHolder.get();
81-
if (messageUnpacker == null) {
84+
MessageUnpacker messageUnpacker;
85+
Tuple<Object, MessageUnpacker> messageUnpackerTuple = messageUnpackerHolder.get();
86+
if (messageUnpackerTuple == null) {
8287
messageUnpacker = new MessageUnpacker(input);
8388
}
8489
else {
85-
messageUnpacker.reset(input);
90+
// Considering to reuse InputStream with JsonParser.Feature.AUTO_CLOSE_SOURCE,
91+
// MessagePackParser needs to use the MessageUnpacker that has the same InputStream
92+
// since it has buffer which has loaded the InputStream data ahead.
93+
// However, it needs to call MessageUnpacker#reset when the source is different from the previous one.
94+
if (isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE) || messageUnpackerTuple.first() != src) {
95+
messageUnpackerTuple.second().reset(input);
96+
}
97+
messageUnpacker = messageUnpackerTuple.second();
8698
}
87-
messageUnpackerHolder.set(messageUnpacker);
99+
messageUnpackerHolder.set(new Tuple<Object, MessageUnpacker>(src, messageUnpacker));
88100
}
89101

90102
@Override
@@ -322,8 +334,10 @@ else if (numberValue.isValidLong()) {
322334
@Override
323335
public void close() throws IOException {
324336
try {
325-
MessageUnpacker messageUnpacker = getMessageUnpacker();
326-
messageUnpacker.close();
337+
if (isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)) {
338+
MessageUnpacker messageUnpacker = getMessageUnpacker();
339+
messageUnpacker.close();
340+
}
327341
}
328342
catch (Exception e) {
329343
e.printStackTrace();
@@ -377,10 +391,10 @@ public void overrideCurrentName(String name) {
377391
}
378392

379393
private MessageUnpacker getMessageUnpacker() {
380-
MessageUnpacker messageUnpacker = messageUnpackerHolder.get();
381-
if (messageUnpacker == null) {
394+
Tuple<Object, MessageUnpacker> messageUnpackerTuple = messageUnpackerHolder.get();
395+
if (messageUnpackerTuple == null) {
382396
throw new IllegalStateException("messageUnpacker is null");
383397
}
384-
return messageUnpacker;
398+
return messageUnpackerTuple.second();
385399
}
386400
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.msgpack.jackson.dataformat;
2+
3+
/**
4+
* Created by komamitsu on 5/28/15.
5+
*/
6+
public class Tuple<F, S> {
7+
private final F first;
8+
private final S second;
9+
10+
public Tuple(F first, S second) {
11+
this.first = first;
12+
this.second = second;
13+
}
14+
15+
public F first() {
16+
return first;
17+
}
18+
19+
public S second() {
20+
return second;
21+
}
22+
}

msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackGeneratorTest.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,26 @@ public void testBigDecimal() throws IOException {
265265
}
266266
}
267267

268+
@Test(expected = IOException.class)
269+
public void testEnableFeatureAutoCloseTarget() throws IOException {
270+
File tempFile = File.createTempFile("test", "msgpack");
271+
tempFile.deleteOnExit();
272+
FileOutputStream out = new FileOutputStream(tempFile);
273+
MessagePackFactory messagePackFactory = new MessagePackFactory();
274+
ObjectMapper objectMapper = new ObjectMapper(messagePackFactory);
275+
List<Integer> integers = Arrays.asList(1);
276+
objectMapper.writeValue(out, integers);
277+
objectMapper.writeValue(out, integers);
278+
}
279+
268280
@Test
269281
public void testDisableFeatureAutoCloseTarget() throws IOException {
270282
File tempFile = File.createTempFile("test", "msgpack");
271283
tempFile.deleteOnExit();
272284
FileOutputStream out = new FileOutputStream(tempFile);
273285
MessagePackFactory messagePackFactory = new MessagePackFactory();
274-
messagePackFactory.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
275286
ObjectMapper objectMapper = new ObjectMapper(messagePackFactory);
287+
objectMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
276288
List<Integer> integers = Arrays.asList(1);
277289
objectMapper.writeValue(out, integers);
278290
objectMapper.writeValue(out, integers);

msgpack-jackson/src/test/java/org/msgpack/jackson/dataformat/MessagePackParserTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,4 +341,36 @@ public void testBigDecimal() throws IOException {
341341
assertEquals(BigDecimal.valueOf(Double.MAX_VALUE), objects.get(idx++));
342342
assertEquals(BigDecimal.valueOf(Double.MIN_NORMAL), objects.get(idx++));
343343
}
344+
345+
private File createTestFile() throws IOException {
346+
File tempFile = File.createTempFile("test", "msgpack");
347+
tempFile.deleteOnExit();
348+
FileOutputStream out = new FileOutputStream(tempFile);
349+
MessagePack.newDefaultPacker(out)
350+
.packArrayHeader(1).packInt(1)
351+
.packArrayHeader(1).packInt(1)
352+
.close();
353+
return tempFile;
354+
}
355+
356+
@Test(expected = IOException.class)
357+
public void testEnableFeatureAutoCloseSource() throws IOException {
358+
File tempFile = createTestFile();
359+
MessagePackFactory messagePackFactory = new MessagePackFactory();
360+
FileInputStream in = new FileInputStream(tempFile);
361+
ObjectMapper objectMapper = new ObjectMapper(messagePackFactory);
362+
objectMapper.readValue(in, new TypeReference<List<Integer>>() {});
363+
objectMapper.readValue(in, new TypeReference<List<Integer>>() {});
364+
}
365+
366+
@Test
367+
public void testDisableFeatureAutoCloseSource() throws IOException {
368+
File tempFile = createTestFile();
369+
MessagePackFactory messagePackFactory = new MessagePackFactory();
370+
FileInputStream in = new FileInputStream(tempFile);
371+
ObjectMapper objectMapper = new ObjectMapper(messagePackFactory);
372+
objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, false);
373+
objectMapper.readValue(in, new TypeReference<List<Integer>>() {});
374+
objectMapper.readValue(in, new TypeReference<List<Integer>>() {});
375+
}
344376
}

0 commit comments

Comments
 (0)