Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,42 @@ public void writeNumber(BigDecimal dec)
public void writeNumber(String encodedValue)
throws IOException, JsonGenerationException, UnsupportedOperationException
{
throw new UnsupportedOperationException("writeNumber(String encodedValue) isn't supported yet");
// There is a room to improve this API's performance while the implementation is robust.
// If users can use other MessagePackGenerator#writeNumber APIs that accept
// proper numeric types not String, it's better to use the other APIs instead.
try {
long l = Long.parseLong(encodedValue);
addValueToStackTop(l);
return;
}
catch (NumberFormatException e) {
}

try {
double d = Double.parseDouble(encodedValue);
addValueToStackTop(d);
return;
}
catch (NumberFormatException e) {
}

try {
BigInteger bi = new BigInteger(encodedValue);
addValueToStackTop(bi);
return;
}
catch (NumberFormatException e) {
}

try {
BigDecimal bc = new BigDecimal(encodedValue);
addValueToStackTop(bc);
return;
}
catch (NumberFormatException e) {
}

throw new NumberFormatException(encodedValue);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.junit.Test;
import org.msgpack.core.ExtensionTypeHeader;
import org.msgpack.core.MessagePack;
Expand Down Expand Up @@ -732,4 +736,152 @@ public void testComplexTypeKeyWithV06Format()
assertThat(unpacker.unpackString(), is("foo"));
assertThat(unpacker.unpackInt(), is(42));
}

// Test serializers that store a string as a number

public static class IntegerSerializerStoringAsString
extends JsonSerializer<Integer>
{
@Override
public void serialize(Integer value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException
{
gen.writeNumber(String.valueOf(value));
}
}

@Test
public void serializeStringAsInteger()
throws IOException
{
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
objectMapper.registerModule(
new SimpleModule().addSerializer(Integer.class, new IntegerSerializerStoringAsString()));

assertThat(
MessagePack.newDefaultUnpacker(objectMapper.writeValueAsBytes(Integer.MAX_VALUE)).unpackInt(),
is(Integer.MAX_VALUE));
}

public static class LongSerializerStoringAsString
extends JsonSerializer<Long>
{
@Override
public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException
{
gen.writeNumber(String.valueOf(value));
}
}

@Test
public void serializeStringAsLong()
throws IOException
{
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
objectMapper.registerModule(
new SimpleModule().addSerializer(Long.class, new LongSerializerStoringAsString()));

assertThat(
MessagePack.newDefaultUnpacker(objectMapper.writeValueAsBytes(Long.MIN_VALUE)).unpackLong(),
is(Long.MIN_VALUE));
}

public static class FloatSerializerStoringAsString
extends JsonSerializer<Float>
{
@Override
public void serialize(Float value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException
{
gen.writeNumber(String.valueOf(value));
}
}

@Test
public void serializeStringAsFloat()
throws IOException
{
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
objectMapper.registerModule(
new SimpleModule().addSerializer(Float.class, new FloatSerializerStoringAsString()));

assertThat(
MessagePack.newDefaultUnpacker(objectMapper.writeValueAsBytes(Float.MAX_VALUE)).unpackFloat(),
is(Float.MAX_VALUE));
}

public static class DoubleSerializerStoringAsString
extends JsonSerializer<Double>
{
@Override
public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException
{
gen.writeNumber(String.valueOf(value));
}
}

@Test
public void serializeStringAsDouble()
throws IOException
{
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
objectMapper.registerModule(
new SimpleModule().addSerializer(Double.class, new DoubleSerializerStoringAsString()));

assertThat(
MessagePack.newDefaultUnpacker(objectMapper.writeValueAsBytes(Double.MIN_VALUE)).unpackDouble(),
is(Double.MIN_VALUE));
}

public static class BigDecimalSerializerStoringAsString
extends JsonSerializer<BigDecimal>
{
@Override
public void serialize(BigDecimal value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException
{
gen.writeNumber(String.valueOf(value));
}
}

@Test
public void serializeStringAsBigDecimal()
throws IOException
{
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
objectMapper.registerModule(
new SimpleModule().addSerializer(BigDecimal.class, new BigDecimalSerializerStoringAsString()));

BigDecimal bd = BigDecimal.valueOf(Long.MAX_VALUE).add(BigDecimal.ONE);
assertThat(
MessagePack.newDefaultUnpacker(objectMapper.writeValueAsBytes(bd)).unpackDouble(),
is(bd.doubleValue()));
}

public static class BigIntegerSerializerStoringAsString
extends JsonSerializer<BigInteger>
{
@Override
public void serialize(BigInteger value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException
{
gen.writeNumber(String.valueOf(value));
}
}

@Test
public void serializeStringAsBigInteger()
throws IOException
{
ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
objectMapper.registerModule(
new SimpleModule().addSerializer(BigInteger.class, new BigIntegerSerializerStoringAsString()));

BigInteger bi = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE);
assertThat(
MessagePack.newDefaultUnpacker(objectMapper.writeValueAsBytes(bi)).unpackDouble(),
is(bi.doubleValue()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -780,4 +780,75 @@ public void parserShouldReadStrAsBin()
assertEquals("foo", binKeyPojo.s);
assertArrayEquals("bar".getBytes(), binKeyPojo.b);
}

// Test deserializers that parse a string as a number.
// Actually, com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseInteger() takes care of it.

@Test
public void deserializeStringAsInteger()
throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
MessagePack.newDefaultPacker(out).packString(String.valueOf(Integer.MAX_VALUE)).close();

Integer v = objectMapper.readValue(out.toByteArray(), Integer.class);
assertThat(v, is(Integer.MAX_VALUE));
}

@Test
public void deserializeStringAsLong()
throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
MessagePack.newDefaultPacker(out).packString(String.valueOf(Long.MIN_VALUE)).close();

Long v = objectMapper.readValue(out.toByteArray(), Long.class);
assertThat(v, is(Long.MIN_VALUE));
}

@Test
public void deserializeStringAsFloat()
throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
MessagePack.newDefaultPacker(out).packString(String.valueOf(Float.MAX_VALUE)).close();

Float v = objectMapper.readValue(out.toByteArray(), Float.class);
assertThat(v, is(Float.MAX_VALUE));
}

@Test
public void deserializeStringAsDouble()
throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
MessagePack.newDefaultPacker(out).packString(String.valueOf(Double.MIN_VALUE)).close();

Double v = objectMapper.readValue(out.toByteArray(), Double.class);
assertThat(v, is(Double.MIN_VALUE));
}

@Test
public void deserializeStringAsBigInteger()
throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
BigInteger bi = BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE);
MessagePack.newDefaultPacker(out).packString(bi.toString()).close();

BigInteger v = objectMapper.readValue(out.toByteArray(), BigInteger.class);
assertThat(v, is(bi));
}

@Test
public void deserializeStringAsBigDecimal()
throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
BigDecimal bd = BigDecimal.valueOf(Double.MAX_VALUE);
MessagePack.newDefaultPacker(out).packString(bd.toString()).close();

BigDecimal v = objectMapper.readValue(out.toByteArray(), BigDecimal.class);
assertThat(v, is(bd));
}
}