Skip to content

Commit 83b6472

Browse files
committed
Add unit tests for PR msgpack#205 and fix some bugs
1 parent cd43469 commit 83b6472

File tree

4 files changed

+102
-28
lines changed

4 files changed

+102
-28
lines changed

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

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import java.util.ArrayList;
1919
import java.util.LinkedList;
2020
import java.util.List;
21-
import java.math.MathContext;
2221

2322
public class MessagePackGenerator extends GeneratorBase {
2423
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
@@ -171,20 +170,7 @@ else if (v instanceof BigInteger) {
171170
messagePacker.packBigInteger((BigInteger) v);
172171
}
173172
else if (v instanceof BigDecimal) {
174-
BigDecimal decimal = (BigDecimal) v;
175-
try {
176-
//Check to see if this BigDecimal can be converted to BigInteger
177-
BigInteger integer = decimal.toBigIntegerExact();
178-
messagePacker.packBigInteger(integer);
179-
} catch (ArithmeticException e){
180-
//If not an integer, then try converting to double
181-
double doubleValue = decimal.doubleValue();
182-
//Check to make sure this BigDecimal can be represented as a double
183-
if (!new BigDecimal(doubleValue, MathContext.DECIMAL128).equals(decimal)) {
184-
throw new IllegalArgumentException("Messagepack cannot serialize a BigDecimal that can't be represented as double");
185-
}
186-
messagePacker.packDouble(doubleValue);
187-
}
173+
packBigDecimal((BigDecimal) v);
188174
}
189175
else if (v instanceof Boolean) {
190176
messagePacker.packBoolean((Boolean) v);
@@ -194,6 +180,29 @@ else if (v instanceof Boolean) {
194180
}
195181
}
196182

183+
private void packBigDecimal(BigDecimal decimal) throws IOException {
184+
MessagePacker messagePacker = getMessagePacker();
185+
boolean failedToPackAsBI = false;
186+
try {
187+
//Check to see if this BigDecimal can be converted to BigInteger
188+
BigInteger integer = decimal.toBigIntegerExact();
189+
messagePacker.packBigInteger(integer);
190+
} catch (ArithmeticException e) {
191+
failedToPackAsBI = true;
192+
} catch (IllegalArgumentException e) {
193+
failedToPackAsBI = true;
194+
}
195+
196+
if (failedToPackAsBI) {
197+
double doubleValue = decimal.doubleValue();
198+
//Check to make sure this BigDecimal can be represented as a double
199+
if (!decimal.toEngineeringString().equals(BigDecimal.valueOf(doubleValue).toEngineeringString())) {
200+
throw new IllegalArgumentException("MessagePack cannot serialize a BigDecimal that can't be represented as double. " + decimal);
201+
}
202+
messagePacker.packDouble(doubleValue);
203+
}
204+
}
205+
197206
private void packObject(StackItemForObject stackItem) throws IOException {
198207
List<String> keys = stackItem.getKeys();
199208
List<Object> values = stackItem.getValues();
@@ -320,9 +329,6 @@ public void close() throws IOException {
320329
try {
321330
flush();
322331
}
323-
catch (Exception e) {
324-
e.printStackTrace();
325-
}
326332
finally {
327333
MessagePacker messagePacker = getMessagePacker();
328334
messagePacker.close();

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,12 +281,12 @@ public BigDecimal getDecimalValue() throws IOException {
281281
return new BigDecimal(number.asBigInteger());
282282
}
283283
}
284-
285-
if (ref.isFloat()) {
284+
else if (ref.isFloat()) {
286285
return BigDecimal.valueOf(ref.asFloat().toDouble());
287286
}
288-
289-
throw new UnsupportedOperationException("couldn't parse value as BigDecimal");
287+
else {
288+
throw new UnsupportedOperationException("Couldn't parse value as BigDecimal. " + ref);
289+
}
290290
}
291291

292292
@Override

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

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.fasterxml.jackson.core.JsonEncoding;
1919
import com.fasterxml.jackson.core.JsonGenerator;
20+
import com.fasterxml.jackson.databind.ObjectMapper;
2021
import org.junit.Test;
2122
import org.msgpack.core.MessagePack;
2223
import org.msgpack.core.MessageUnpacker;
@@ -25,10 +26,8 @@
2526
import java.io.File;
2627
import java.io.FileInputStream;
2728
import java.io.IOException;
28-
import java.util.ArrayList;
29-
import java.util.HashMap;
30-
import java.util.List;
31-
import java.util.Map;
29+
import java.math.BigDecimal;
30+
import java.util.*;
3231

3332
import static org.junit.Assert.assertEquals;
3433
import static org.junit.Assert.assertFalse;
@@ -221,4 +220,47 @@ public void testMessagePackGeneratorDirectly() throws IOException {
221220
assertEquals(2.0f, unpacker.unpackFloat(), 0.001f);
222221
assertFalse(unpacker.hasNext());
223222
}
223+
224+
@Test
225+
public void testBigDecimal() throws IOException {
226+
ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
227+
228+
{
229+
double d0 = 1.23456789;
230+
double d1 = 1.23450000000000000000006789;
231+
List<BigDecimal> bigDecimals = Arrays.asList(
232+
BigDecimal.valueOf(d0),
233+
BigDecimal.valueOf(d1),
234+
BigDecimal.valueOf(Double.MIN_VALUE),
235+
BigDecimal.valueOf(Double.MAX_VALUE),
236+
BigDecimal.valueOf(Double.MIN_NORMAL)
237+
);
238+
239+
byte[] bytes = mapper.writeValueAsBytes(bigDecimals);
240+
MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(bytes);
241+
242+
assertEquals(5, unpacker.unpackArrayHeader());
243+
assertEquals(d0, unpacker.unpackDouble(), 0.000000000000001);
244+
assertEquals(d1, unpacker.unpackDouble(), 0.000000000000001);
245+
assertEquals(Double.MIN_VALUE, unpacker.unpackDouble(), 0.000000000000001);
246+
assertEquals(Double.MAX_VALUE, unpacker.unpackDouble(), 0.000000000000001);
247+
assertEquals(Double.MIN_NORMAL, unpacker.unpackDouble(), 0.000000000000001);
248+
}
249+
250+
{
251+
252+
BigDecimal decimal = new BigDecimal("1234.567890123456789012345678901234567890");
253+
List<BigDecimal> bigDecimals = Arrays.asList(
254+
decimal
255+
);
256+
257+
try {
258+
mapper.writeValueAsBytes(bigDecimals);
259+
assertTrue(false);
260+
}
261+
catch (IllegalArgumentException e) {
262+
assertTrue(true);
263+
}
264+
}
265+
}
224266
}

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@
33
import com.fasterxml.jackson.core.JsonParser;
44
import com.fasterxml.jackson.core.JsonToken;
55
import com.fasterxml.jackson.core.type.TypeReference;
6+
import com.fasterxml.jackson.databind.DeserializationFeature;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
68
import org.junit.Test;
79
import org.msgpack.core.MessagePack;
810
import org.msgpack.core.MessagePacker;
911
import org.msgpack.core.buffer.OutputStreamBufferOutput;
10-
import org.msgpack.value.ExtendedValue;
1112

1213
import java.io.*;
14+
import java.math.BigDecimal;
1315
import java.math.BigInteger;
1416
import java.nio.ByteBuffer;
1517
import java.util.Arrays;
1618
import java.util.List;
1719
import java.util.Map;
1820

1921
import static org.junit.Assert.assertEquals;
20-
import static org.junit.Assert.assertArrayEquals;
2122
import static org.junit.Assert.assertTrue;
2223
import static org.junit.Assert.assertNull;
2324

@@ -315,4 +316,29 @@ public void testMessagePackParserDirectly() throws IOException {
315316
parser.close();
316317
parser.close(); // Intentional
317318
}
319+
320+
@Test
321+
public void testBigDecimal() throws IOException {
322+
double d0 = 1.23456789;
323+
double d1 = 1.23450000000000000000006789;
324+
MessagePacker packer = new MessagePacker(new OutputStreamBufferOutput(out));
325+
packer.packArrayHeader(5);
326+
packer.packDouble(d0);
327+
packer.packDouble(d1);
328+
packer.packDouble(Double.MIN_VALUE);
329+
packer.packDouble(Double.MAX_VALUE);
330+
packer.packDouble(Double.MIN_NORMAL);
331+
packer.flush();
332+
333+
ObjectMapper mapper = new ObjectMapper(new MessagePackFactory());
334+
mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
335+
List<Object> objects = mapper.readValue(out.toByteArray(), new TypeReference<List<Object>>(){});
336+
assertEquals(5, objects.size());
337+
int idx = 0;
338+
assertEquals(BigDecimal.valueOf(d0), objects.get(idx++));
339+
assertEquals(BigDecimal.valueOf(d1), objects.get(idx++));
340+
assertEquals(BigDecimal.valueOf(Double.MIN_VALUE), objects.get(idx++));
341+
assertEquals(BigDecimal.valueOf(Double.MAX_VALUE), objects.get(idx++));
342+
assertEquals(BigDecimal.valueOf(Double.MIN_NORMAL), objects.get(idx++));
343+
}
318344
}

0 commit comments

Comments
 (0)