Skip to content

Commit d6c458f

Browse files
committed
msgpack-value v07 implementation
- Add MessageOverflowException to support integer and float types - Using ChannelBufferInput when FileInputStream is passed to the unpacker - Added test cases for reading various types of MessageBufferInputs - Added ValueHolder of integer/float/raw/ext values - Added unpack method targetted to ValueHolder - Throws MessageTypeException when failed to convert the cursor type - Moved msgpack-value code into msgpack-core - Scala 2.11.1 support - Moved ValueType to value package - Added getTotalReadBytes() method - Added ArrayCursor and MapCursor - Introduced ValueRef as a super type of Value
1 parent cd9cd09 commit d6c458f

File tree

123 files changed

+3787
-4362
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+3787
-4362
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.msgpack.core;
2+
3+
/**
4+
* This error is thrown when the user tries to read a value that has decimal component as byte, short, int and long.
5+
*
6+
*/
7+
public class MessageFloatOverflowException extends MessageOverflowException {
8+
9+
private final double value;
10+
11+
public MessageFloatOverflowException(double value) {
12+
super();
13+
this.value = value;
14+
}
15+
16+
public double getValue() {
17+
return value;
18+
}
19+
20+
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.msgpack.core.MessagePack.Code;
44
import org.msgpack.core.annotations.VisibleForTesting;
5+
import org.msgpack.value.ValueType;
56

67

78
/**
@@ -88,8 +89,13 @@ public static MessageFormat valueOf(final byte b) {
8889
return formatTable[b & 0xFF];
8990
}
9091

92+
/**
93+
* Converting a byte value into MessageFormat. For faster performance, use {@link #valueOf}
94+
* @param b
95+
* @return
96+
*/
9197
@VisibleForTesting
92-
static MessageFormat toMessageFormat(final byte b) {
98+
public static MessageFormat toMessageFormat(final byte b) {
9399
if (Code.isPosFixInt(b)) {
94100
return POSFIXINT;
95101
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919
* Thrown when the input message pack format is invalid
2020
*/
2121
public class MessageFormatException extends MessagePackException {
22+
23+
public MessageFormatException(Throwable e) {
24+
super(e);
25+
}
26+
27+
2228
public MessageFormatException(String message) {
2329
super(message);
2430
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,19 @@
2323
* using a smaller types. For example, calling MessageUnpacker.unpackInt() for an integer value
2424
* that is larger than Integer.MAX_VALUE will cause this exception.
2525
*/
26-
public class MessageIntegerOverflowException extends MessageTypeException {
26+
public class MessageIntegerOverflowException extends MessageOverflowException {
27+
2728
private final BigInteger bigInteger;
2829

2930
public MessageIntegerOverflowException(BigInteger bigInteger) {
3031
super();
3132
this.bigInteger = bigInteger;
3233
}
3334

35+
public MessageIntegerOverflowException(long value) {
36+
this(BigInteger.valueOf(value));
37+
}
38+
3439
public MessageIntegerOverflowException(String message, BigInteger bigInteger) {
3540
super(message);
3641
this.bigInteger = bigInteger;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.msgpack.core;
2+
3+
/**
4+
* Created on 5/28/14.
5+
*/
6+
public class MessageOverflowException extends MessageTypeException {
7+
8+
public MessageOverflowException() {
9+
super();
10+
}
11+
12+
public MessageOverflowException(String message) {
13+
super(message);
14+
}
15+
16+
}

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,11 @@ public MessagePackException(String message, Throwable cause) {
3535
public MessagePackException(Throwable cause) {
3636
super(cause);
3737
}
38+
39+
40+
public static UnsupportedOperationException UNSUPPORTED(String operationName) {
41+
return new UnsupportedOperationException(operationName);
42+
}
43+
44+
public static IllegalStateException UNREACHABLE = new IllegalStateException("Cannot reach here");
3845
}

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.msgpack.core.buffer.MessageBuffer;
1919
import org.msgpack.core.buffer.MessageBufferOutput;
2020
import org.msgpack.core.buffer.OutputStreamBufferOutput;
21+
import org.msgpack.value.Value;
2122

2223
import java.io.Closeable;
2324
import java.io.OutputStream;
@@ -394,6 +395,23 @@ public MessagePacker packMapHeader(int mapSize) throws IOException {
394395
return this;
395396
}
396397

398+
public MessagePacker pack(Value v) throws IOException {
399+
v.writeTo(this);
400+
return this;
401+
}
402+
403+
public MessagePacker packExtendedType(int extType, byte[] src, int offset, int len) throws IOException {
404+
return packExtendedTypeHeader(extType, len).writePayload(src, offset, len);
405+
}
406+
407+
public MessagePacker packExtendedType(int extType, byte[] src) throws IOException {
408+
return packExtendedType(extType, src, 0, src.length);
409+
}
410+
411+
public MessagePacker packExtendedType(int extType, ByteBuffer src) throws IOException {
412+
return packExtendedTypeHeader(extType, src.remaining()).writePayload(src);
413+
}
414+
397415
public MessagePacker packExtendedTypeHeader(int extType, int dataLen) throws IOException {
398416
if(dataLen < (1 << 8)) {
399417
if(dataLen > 0 && (dataLen & (dataLen - 1)) == 0) { // check whether dataLen == 2^x
@@ -424,6 +442,18 @@ public MessagePacker packExtendedTypeHeader(int extType, int dataLen) throws IOE
424442
return this;
425443
}
426444

445+
public MessagePacker packBinary(byte[] src) throws IOException {
446+
return packBinary(src, 0, src.length);
447+
}
448+
449+
public MessagePacker packBinary(byte[] src, int offset, int len) throws IOException {
450+
return packBinaryHeader(len).writePayload(src, offset, len);
451+
}
452+
453+
public MessagePacker packBinary(ByteBuffer src) throws IOException {
454+
return packBinaryHeader(src.remaining()).writePayload(src);
455+
}
456+
427457
public MessagePacker packBinaryHeader(int len) throws IOException {
428458
if(len < (1 << 8)) {
429459
writeByteAndByte(BIN8, (byte) len);
@@ -435,6 +465,10 @@ public MessagePacker packBinaryHeader(int len) throws IOException {
435465
return this;
436466
}
437467

468+
public MessagePacker packRawString(ByteBuffer src) throws IOException {
469+
return packRawStringHeader(src.remaining()).writePayload(src);
470+
}
471+
438472
public MessagePacker packRawStringHeader(int len) throws IOException {
439473
if(len < (1 << 5)) {
440474
writeByte((byte) (FIXSTR_PREFIX | len));

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

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030

3131
import org.msgpack.core.MessagePack.Code;
3232
import org.msgpack.core.buffer.*;
33+
import org.msgpack.value.impl.ArrayCursorImpl;
34+
import org.msgpack.value.Cursor;
35+
import org.msgpack.value.Value;
36+
import org.msgpack.value.ValueType;
37+
import org.msgpack.value.holder.FloatHolder;
38+
import org.msgpack.value.holder.IntegerHolder;
39+
import org.msgpack.value.holder.ValueHolder;
40+
import org.msgpack.value.impl.CursorImpl;
3341

3442
import static org.msgpack.core.Preconditions.*;
3543

@@ -78,6 +86,11 @@ public class MessageUnpacker implements Closeable {
7886
*/
7987
private int position;
8088

89+
/**
90+
* Total read byte size
91+
*/
92+
private long totalReadBytes;
93+
8194
/**
8295
* For preserving the next buffer to use
8396
*/
@@ -103,6 +116,15 @@ public class MessageUnpacker implements Closeable {
103116
*/
104117
private CharBuffer decodeBuffer;
105118

119+
120+
/**
121+
* Get a {@link org.msgpack.value.Cursor} for traversing message-packed values
122+
* @return
123+
*/
124+
public Cursor getCursor() {
125+
return new CursorImpl(this);
126+
}
127+
106128
/**
107129
* Create an MessageUnpacker that reads data from the given byte array.
108130
*
@@ -149,6 +171,11 @@ public MessageUnpacker(MessageBufferInput in, MessagePack.Config config) {
149171
this.config = checkNotNull(config, "Config");
150172
}
151173

174+
175+
public long getTotalReadBytes() {
176+
return totalReadBytes + position;
177+
}
178+
152179
private void prepareDecoder() {
153180
if(decoder == null) {
154181
decodeBuffer = CharBuffer.allocate(config.getStringDecoderBufferSize());
@@ -168,7 +195,9 @@ private void prepareDecoder() {
168195
private boolean ensureBuffer() throws IOException {
169196
while(buffer != null && position >= buffer.size()) {
170197
// Fetch the next buffer
171-
position -= buffer.size();
198+
int bufferSize = buffer.size();
199+
position -= bufferSize;
200+
totalReadBytes += bufferSize;
172201
buffer = takeNextBuffer();
173202
}
174203
return buffer != null;
@@ -248,6 +277,7 @@ private boolean ensure(int byteSizeToRead) throws IOException {
248277
}
249278

250279
// Replace the current buffer with the new buffer
280+
totalReadBytes += position;
251281
buffer = byteSizeToRead == newBuffer.size() ? newBuffer : newBuffer.slice(0, byteSizeToRead);
252282
position = 0;
253283

@@ -515,6 +545,49 @@ private static MessageTypeException unexpected(String expected, byte b)
515545
return new MessageTypeException(String.format("Expected %s, but got %s (%02x)", expected, type.toTypeName(), b));
516546
}
517547

548+
public MessageFormat unpackValue(ValueHolder holder) throws IOException {
549+
MessageFormat mf = getNextFormat();
550+
switch(mf.getValueType()) {
551+
case NIL:
552+
unpackNil();
553+
holder.setNil();
554+
break;
555+
case BOOLEAN:
556+
holder.setBoolean(unpackBoolean());
557+
break;
558+
case INTEGER: {
559+
unpackInteger(holder.getIntegerHolder());
560+
holder.setToInteger();
561+
break;
562+
}
563+
case FLOAT: {
564+
unpackFloat(holder.getFloatHolder());
565+
holder.setToFloat();
566+
break;
567+
}
568+
case STRING:
569+
int strLen = unpackRawStringHeader();
570+
holder.setString(readPayloadAsReference(strLen));
571+
break;
572+
case BINARY: {
573+
int binaryLen = unpackBinaryHeader();
574+
holder.setBinary(readPayloadAsReference(binaryLen));
575+
break;
576+
}
577+
case ARRAY:
578+
holder.prepareArrayCursor(this);
579+
break;
580+
case MAP:
581+
holder.prepareMapCursor(this);
582+
break;
583+
case EXTENDED:
584+
ExtendedTypeHeader extHeader = unpackExtendedTypeHeader();
585+
holder.setExt(extHeader.getType(), readPayloadAsReference(extHeader.getLength()));
586+
break;
587+
}
588+
return mf;
589+
}
590+
518591
public Object unpackNil() throws IOException {
519592
byte b = consume();
520593
if(b == Code.NIL) {
@@ -769,6 +842,73 @@ public BigInteger unpackBigInteger() throws IOException {
769842
throw unexpected("Integer", b);
770843
}
771844

845+
846+
/**
847+
* Unpack an integer, then store the read value to the given holder
848+
* @param holder an integer holder to which the unpacked integer will be set.
849+
* @throws IOException
850+
*/
851+
public void unpackInteger(IntegerHolder holder) throws IOException {
852+
byte b = consume();
853+
854+
if(Code.isFixInt(b)) {
855+
holder.setByte(b);
856+
return;
857+
}
858+
859+
switch(b) {
860+
case Code.INT8: // signed int 8
861+
holder.setByte(readByte());
862+
break;
863+
case Code.INT16:
864+
holder.setShort(readShort());
865+
break;
866+
case Code.INT32:
867+
holder.setInt(readInt());
868+
break;
869+
case Code.INT64: // signed int 64
870+
holder.setLong(readLong());
871+
break;
872+
case Code.UINT8: // unsigned int 8
873+
byte u8 = readByte();
874+
if(u8 < 0) {
875+
holder.setShort((short) (u8 & 0xFF));
876+
}
877+
else {
878+
holder.setByte(u8);
879+
}
880+
break;
881+
case Code.UINT16: // unsigned int 16
882+
short u16 = readShort();
883+
if(u16 < 0) {
884+
holder.setInt(u16 & 0xFFFF);
885+
}
886+
else {
887+
holder.setShort(u16);
888+
}
889+
break;
890+
case Code.UINT32: // unsigned int 32
891+
int u32 = readInt();
892+
if(u32 < 0) {
893+
holder.setLong((long) (u32 & 0x7fffffff) + 0x80000000L);
894+
} else {
895+
holder.setInt(u32);
896+
}
897+
break;
898+
case Code.UINT64: // unsigned int 64
899+
long u64 = readLong();
900+
if(u64 < 0L) {
901+
holder.setBigInteger(BigInteger.valueOf(u64 + Long.MAX_VALUE + 1L).setBit(63));
902+
} else {
903+
holder.setLong(u64);
904+
}
905+
break;
906+
default:
907+
throw unexpected("Integer", b);
908+
}
909+
}
910+
911+
772912
public float unpackFloat() throws IOException {
773913
byte b = consume();
774914
switch(b) {
@@ -795,6 +935,27 @@ public double unpackDouble() throws IOException {
795935
throw unexpected("Float", b);
796936
}
797937

938+
public void unpackFloat(ValueHolder holder) throws IOException {
939+
unpackFloat(holder.getFloatHolder());
940+
}
941+
942+
public void unpackFloat(FloatHolder holder) throws IOException {
943+
byte b = consume();
944+
switch(b) {
945+
case Code.FLOAT32: // float
946+
float fv = readFloat();
947+
holder.setFloat(fv);
948+
break;
949+
case Code.FLOAT64: // double
950+
double dv = readDouble();
951+
holder.setDouble(dv);
952+
break;
953+
default:
954+
throw unexpected("Float", b);
955+
}
956+
}
957+
958+
798959
private final static String EMPTY_STRING = "";
799960

800961
public String unpackString() throws IOException {

0 commit comments

Comments
 (0)