Skip to content

Commit 0f11bda

Browse files
committed
Fixes msgpack#38: Add IntegerValue.mostSuccinctMessageFormat
1 parent ef2a934 commit 0f11bda

File tree

6 files changed

+100
-1
lines changed

6 files changed

+100
-1
lines changed

msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ else if (bi.bitLength() == 64 && bi.signum() == 1) {
423423
writeByteAndLong(UINT64, bi.longValue());
424424
}
425425
else {
426-
throw new IllegalArgumentException("Messagepack cannot serialize BigInteger larger than 2^64-1");
426+
throw new IllegalArgumentException("MessagePack cannot serialize BigInteger larger than 2^64-1");
427427
}
428428
return this;
429429
}

msgpack-core/src/main/java/org/msgpack/value/IntegerValue.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
//
1616
package org.msgpack.value;
1717

18+
import org.msgpack.core.MessageFormat;
19+
1820
import java.math.BigInteger;
1921

2022
/**
@@ -45,6 +47,12 @@ public interface IntegerValue
4547
*/
4648
boolean isInLongRange();
4749

50+
/**
51+
* Returns the most succinct MessageFormat type to represent this integer value.
52+
* @return
53+
*/
54+
MessageFormat mostSuccinctMessageFormat();
55+
4856
/**
4957
* Returns the value as a {@code byte}, otherwise throws an exception.
5058
*

msgpack-core/src/main/java/org/msgpack/value/Variable.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
//
1616
package org.msgpack.value;
1717

18+
import org.msgpack.core.MessageFormat;
1819
import org.msgpack.core.MessageIntegerOverflowException;
1920
import org.msgpack.core.MessagePack;
2021
import org.msgpack.core.MessagePacker;
2122
import org.msgpack.core.MessageStringCodingException;
2223
import org.msgpack.core.MessageTypeCastException;
24+
import org.msgpack.value.impl.ImmutableBigIntegerValueImpl;
2325

2426
import java.io.IOException;
2527
import java.math.BigDecimal;
@@ -515,6 +517,12 @@ public boolean isInLongRange()
515517
return true;
516518
}
517519

520+
@Override
521+
public MessageFormat mostSuccinctMessageFormat()
522+
{
523+
return ImmutableBigIntegerValueImpl.mostSuccinctMessageFormat(this);
524+
}
525+
518526
@Override
519527
public byte getByte()
520528
{

msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableBigIntegerValueImpl.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//
1616
package org.msgpack.value.impl;
1717

18+
import org.msgpack.core.MessageFormat;
1819
import org.msgpack.core.MessageIntegerOverflowException;
1920
import org.msgpack.core.MessagePacker;
2021
import org.msgpack.value.ImmutableIntegerValue;
@@ -35,6 +36,26 @@ public class ImmutableBigIntegerValueImpl
3536
extends AbstractImmutableValue
3637
implements ImmutableIntegerValue
3738
{
39+
public static MessageFormat mostSuccinctMessageFormat(IntegerValue v)
40+
{
41+
if(v.isInByteRange()) {
42+
return MessageFormat.INT8;
43+
}
44+
else if(v.isInShortRange()) {
45+
return MessageFormat.INT16;
46+
}
47+
else if(v.isInIntRange()) {
48+
return MessageFormat.INT32;
49+
}
50+
else if(v.isInLongRange()) {
51+
return MessageFormat.INT64;
52+
}
53+
else {
54+
return MessageFormat.UINT64;
55+
}
56+
}
57+
58+
3859
private final BigInteger value;
3960

4061
public ImmutableBigIntegerValueImpl(BigInteger value)
@@ -141,6 +162,12 @@ public boolean isInLongRange()
141162
return 0 <= value.compareTo(LONG_MIN) && value.compareTo(LONG_MAX) <= 0;
142163
}
143164

165+
@Override
166+
public MessageFormat mostSuccinctMessageFormat()
167+
{
168+
return mostSuccinctMessageFormat(this);
169+
}
170+
144171
@Override
145172
public byte getByte()
146173
{

msgpack-core/src/main/java/org/msgpack/value/impl/ImmutableLongValueImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//
1616
package org.msgpack.value.impl;
1717

18+
import org.msgpack.core.MessageFormat;
1819
import org.msgpack.core.MessageIntegerOverflowException;
1920
import org.msgpack.core.MessagePacker;
2021
import org.msgpack.value.ImmutableIntegerValue;
@@ -139,6 +140,12 @@ public boolean isInLongRange()
139140
return true;
140141
}
141142

143+
@Override
144+
public MessageFormat mostSuccinctMessageFormat()
145+
{
146+
return ImmutableBigIntegerValueImpl.mostSuccinctMessageFormat(this);
147+
}
148+
142149
@Override
143150
public byte getByte()
144151
{
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//
2+
// MessagePack for Java
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
package org.msgpack.value
17+
18+
import java.math.BigInteger
19+
20+
import org.msgpack.core._
21+
22+
class ValueTest extends MessagePackSpec
23+
{
24+
def checkSuccinctType(pack:MessagePacker => Unit, expectedAtMost:MessageFormat) {
25+
val b = createMessagePackData(pack)
26+
val v1 = MessagePack.newDefaultUnpacker(b).unpackValue()
27+
v1.asIntegerValue().mostSuccinctMessageFormat().ordinal() shouldBe <= (expectedAtMost.ordinal())
28+
29+
val v2 = new Variable
30+
MessagePack.newDefaultUnpacker(b).unpackValue(v2)
31+
v2.asIntegerValue().mostSuccinctMessageFormat().ordinal() shouldBe <= (expectedAtMost.ordinal())
32+
}
33+
34+
"Value" should {
35+
"tell most succinct integer type" in {
36+
forAll { (v: Byte) => checkSuccinctType(_.packByte(v), MessageFormat.INT8) }
37+
forAll { (v: Short) => checkSuccinctType(_.packShort(v), MessageFormat.INT16) }
38+
forAll { (v: Int) => checkSuccinctType(_.packInt(v), MessageFormat.INT32) }
39+
forAll { (v: Long) => checkSuccinctType(_.packLong(v), MessageFormat.INT64) }
40+
forAll { (v: Long) => checkSuccinctType(_.packBigInteger(BigInteger.valueOf(v)), MessageFormat.INT64) }
41+
forAll { (v: Long) =>
42+
whenever(v > 0) {
43+
// Create value between 2^63-1 < v <= 2^64-1
44+
checkSuccinctType(_.packBigInteger(BigInteger.valueOf(Long.MaxValue).add(BigInteger.valueOf(v))), MessageFormat.UINT64)
45+
}
46+
}
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)