java: adds Unpacker.unpackBigInteger()

This commit is contained in:
frsyuki 2010-08-19 01:19:34 +09:00
parent 1d17836b7d
commit b4c98584db
3 changed files with 55 additions and 4 deletions

View File

@ -19,7 +19,7 @@ package org.msgpack;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
//import java.math.BigInteger; import java.math.BigInteger;
abstract class BufferedUnpackerImpl extends UnpackerImpl { abstract class BufferedUnpackerImpl extends UnpackerImpl {
int offset = 0; int offset = 0;
@ -198,8 +198,7 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
{ {
long o = castBuffer.getLong(0); long o = castBuffer.getLong(0);
if(o < 0) { if(o < 0) {
// FIXME unpackBigInteger throw new MessageTypeException();
throw new MessageTypeException("uint 64 bigger than 0x7fffffff is not supported");
} }
advance(9); advance(9);
return o; return o;
@ -231,7 +230,25 @@ abstract class BufferedUnpackerImpl extends UnpackerImpl {
} }
} }
// FIXME unpackBigInteger final BigInteger unpackBigInteger() throws IOException, MessageTypeException {
more(1);
int b = buffer[offset];
if((b & 0xff) != 0xcf) {
return BigInteger.valueOf(unpackLong());
}
// unsigned int 64
more(9);
castBuffer.rewind();
castBuffer.put(buffer, offset+1, 8);
advance(9);
long o = castBuffer.getLong(0);
if(o < 0) {
return new BigInteger(1, castBuffer.array());
} else {
return BigInteger.valueOf(o);
}
}
final float unpackFloat() throws IOException, MessageTypeException { final float unpackFloat() throws IOException, MessageTypeException {
more(1); more(1);

View File

@ -22,6 +22,7 @@ import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Iterator; import java.util.Iterator;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.math.BigInteger;
/** /**
* Unpacker enables you to deserialize objects from stream. * Unpacker enables you to deserialize objects from stream.
@ -452,6 +453,15 @@ public class Unpacker implements Iterable<MessagePackObject> {
return impl.unpackLong(); return impl.unpackLong();
} }
/**
* Gets one {@code BigInteger} value from the buffer.
* This method calls {@link fill()} method if needed.
* @throws MessageTypeException the first value of the buffer is not a {@code BigInteger}.
*/
public BigInteger unpackBigInteger() throws IOException, MessageTypeException {
return impl.unpackBigInteger();
}
/** /**
* Gets one {@code float} value from the buffer. * Gets one {@code float} value from the buffer.
* This method calls {@link fill()} method if needed. * This method calls {@link fill()} method if needed.

View File

@ -3,6 +3,7 @@ package org.msgpack;
import org.msgpack.*; import org.msgpack.*;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.math.BigInteger;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -48,6 +49,29 @@ public class TestDirectConversion {
assertEquals(val, pac.unpackLong()); assertEquals(val, pac.unpackLong());
} }
@Test
public void testBigInteger() throws Exception {
testBigInteger(BigInteger.valueOf(0));
testBigInteger(BigInteger.valueOf(-1));
testBigInteger(BigInteger.valueOf(1));
testBigInteger(BigInteger.valueOf(Integer.MIN_VALUE));
testBigInteger(BigInteger.valueOf(Integer.MAX_VALUE));
testBigInteger(BigInteger.valueOf(Long.MIN_VALUE));
testBigInteger(BigInteger.valueOf(Long.MAX_VALUE));
BigInteger max = BigInteger.valueOf(Long.MAX_VALUE).setBit(63);
testBigInteger(max);
Random rand = new Random();
for (int i = 0; i < 1000; i++)
testBigInteger( max.subtract(BigInteger.valueOf( Math.abs(rand.nextLong()) )) );
}
public void testBigInteger(BigInteger val) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
new Packer(out).pack(val);
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
Unpacker pac = new Unpacker(in);
assertEquals(val, pac.unpackBigInteger());
}
@Test @Test
public void testFloat() throws Exception { public void testFloat() throws Exception {
testFloat((float)0.0); testFloat((float)0.0);