Skip to content

Commit e50747f

Browse files
committed
Support non-string key in jackson-dataformat-msgpack
1 parent 2493c04 commit e50747f

File tree

2 files changed

+156
-3
lines changed

2 files changed

+156
-3
lines changed

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

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,33 @@ public JsonToken nextToken()
190190
case BOOLEAN:
191191
boolean b = messageUnpacker.unpackBoolean();
192192
value = ValueFactory.newNil();
193-
nextToken = b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE;
193+
if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) {
194+
parsingContext.setCurrentName(Boolean.toString(b));
195+
nextToken = JsonToken.FIELD_NAME;
196+
}
197+
else {
198+
nextToken = b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE;
199+
}
194200
break;
195201
case INTEGER:
196202
value = messageUnpacker.unpackValue(var);
197-
nextToken = JsonToken.VALUE_NUMBER_INT;
203+
if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) {
204+
parsingContext.setCurrentName(value.asIntegerValue().toString());
205+
nextToken = JsonToken.FIELD_NAME;
206+
}
207+
else {
208+
nextToken = JsonToken.VALUE_NUMBER_INT;
209+
}
198210
break;
199211
case FLOAT:
200212
value = messageUnpacker.unpackValue(var);
201-
nextToken = JsonToken.VALUE_NUMBER_FLOAT;
213+
if (parsingContext.inObject() && _currToken != JsonToken.FIELD_NAME) {
214+
parsingContext.setCurrentName(value.asFloatValue().toString());
215+
nextToken = JsonToken.FIELD_NAME;
216+
}
217+
else {
218+
nextToken = JsonToken.VALUE_NUMBER_FLOAT;
219+
}
202220
break;
203221
case STRING:
204222
value = messageUnpacker.unpackValue(var);

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

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@
1616
package org.msgpack.jackson.dataformat;
1717

1818
import com.fasterxml.jackson.core.JsonParser;
19+
import com.fasterxml.jackson.core.JsonProcessingException;
1920
import com.fasterxml.jackson.core.JsonToken;
2021
import com.fasterxml.jackson.core.type.TypeReference;
22+
import com.fasterxml.jackson.databind.DeserializationContext;
2123
import com.fasterxml.jackson.databind.DeserializationFeature;
24+
import com.fasterxml.jackson.databind.KeyDeserializer;
2225
import com.fasterxml.jackson.databind.ObjectMapper;
26+
import com.fasterxml.jackson.databind.module.SimpleModule;
2327
import org.junit.Test;
2428
import org.msgpack.core.MessagePack;
2529
import org.msgpack.core.MessagePacker;
@@ -537,4 +541,135 @@ public void testBinaryKeyInNestedObject()
537541
assertEquals(12, map.get("bar"));
538542
assertEquals(1, objects.get(1));
539543
}
544+
545+
@Test
546+
public void testByteArrayKey()
547+
throws IOException
548+
{
549+
ByteArrayOutputStream out = new ByteArrayOutputStream();
550+
MessagePacker messagePacker = MessagePack.newDefaultPacker(out).packMapHeader(2);
551+
byte[] k0 = new byte[] {0};
552+
byte[] k1 = new byte[] {1};
553+
messagePacker.packBinaryHeader(1).writePayload(k0).packInt(2);
554+
messagePacker.packBinaryHeader(1).writePayload(k1).packInt(3);
555+
messagePacker.close();
556+
557+
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
558+
SimpleModule module = new SimpleModule();
559+
module.addKeyDeserializer(byte[].class, new KeyDeserializer()
560+
{
561+
@Override
562+
public Object deserializeKey(String key, DeserializationContext ctxt)
563+
throws IOException, JsonProcessingException
564+
{
565+
return key.getBytes();
566+
}
567+
});
568+
objectMapper.registerModule(module);
569+
570+
Map<byte[], Integer> map = objectMapper.readValue(
571+
out.toByteArray(), new TypeReference<Map<byte[], Integer>>() {});
572+
assertEquals(2, map.size());
573+
for (Map.Entry<byte[], Integer> entry : map.entrySet()) {
574+
if (Arrays.equals(entry.getKey(), k0)) {
575+
assertEquals((Integer) 2, entry.getValue());
576+
}
577+
else if (Arrays.equals(entry.getKey(), k1)) {
578+
assertEquals((Integer) 3, entry.getValue());
579+
}
580+
}
581+
}
582+
583+
@Test
584+
public void testIntegerKey()
585+
throws IOException
586+
{
587+
ByteArrayOutputStream out = new ByteArrayOutputStream();
588+
MessagePacker messagePacker = MessagePack.newDefaultPacker(out).packMapHeader(3);
589+
for (int i = 0; i < 2; i++) {
590+
messagePacker.packInt(i).packInt(i + 2);
591+
}
592+
messagePacker.close();
593+
594+
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
595+
SimpleModule module = new SimpleModule();
596+
module.addKeyDeserializer(Integer.class, new KeyDeserializer()
597+
{
598+
@Override
599+
public Object deserializeKey(String key, DeserializationContext ctxt)
600+
throws IOException, JsonProcessingException
601+
{
602+
return Integer.valueOf(key);
603+
}
604+
});
605+
objectMapper.registerModule(module);
606+
607+
Map<Integer, Integer> map = objectMapper.readValue(
608+
out.toByteArray(), new TypeReference<Map<Integer, Integer>>() {});
609+
assertEquals(2, map.size());
610+
assertEquals((Integer) 2, map.get(0));
611+
assertEquals((Integer) 3, map.get(1));
612+
}
613+
614+
@Test
615+
public void testFloatKey()
616+
throws IOException
617+
{
618+
ByteArrayOutputStream out = new ByteArrayOutputStream();
619+
MessagePacker messagePacker = MessagePack.newDefaultPacker(out).packMapHeader(3);
620+
for (int i = 0; i < 2; i++) {
621+
messagePacker.packFloat(i).packInt(i + 2);
622+
}
623+
messagePacker.close();
624+
625+
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
626+
SimpleModule module = new SimpleModule();
627+
module.addKeyDeserializer(Float.class, new KeyDeserializer()
628+
{
629+
@Override
630+
public Object deserializeKey(String key, DeserializationContext ctxt)
631+
throws IOException, JsonProcessingException
632+
{
633+
return Float.valueOf(key);
634+
}
635+
});
636+
objectMapper.registerModule(module);
637+
638+
Map<Float, Integer> map = objectMapper.readValue(
639+
out.toByteArray(), new TypeReference<Map<Float, Integer>>() {});
640+
assertEquals(2, map.size());
641+
assertEquals((Integer) 2, map.get(0f));
642+
assertEquals((Integer) 3, map.get(1f));
643+
}
644+
645+
@Test
646+
public void testBooleanKey()
647+
throws IOException
648+
{
649+
ByteArrayOutputStream out = new ByteArrayOutputStream();
650+
MessagePacker messagePacker = MessagePack.newDefaultPacker(out).packMapHeader(3);
651+
messagePacker.packBoolean(true).packInt(2);
652+
messagePacker.packBoolean(false).packInt(3);
653+
messagePacker.close();
654+
655+
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
656+
SimpleModule module = new SimpleModule();
657+
module.addKeyDeserializer(Boolean.class, new KeyDeserializer()
658+
{
659+
@Override
660+
public Object deserializeKey(String key, DeserializationContext ctxt)
661+
throws IOException, JsonProcessingException
662+
{
663+
return Boolean.valueOf(key);
664+
}
665+
});
666+
objectMapper.registerModule(module);
667+
668+
Map<Boolean, Integer> map = objectMapper.readValue(
669+
out.toByteArray(), new TypeReference<Map<Boolean, Integer>>() {});
670+
assertEquals(2, map.size());
671+
assertEquals((Integer) 2, map.get(true));
672+
assertEquals((Integer) 3, map.get(false));
673+
}
540674
}
675+

0 commit comments

Comments
 (0)