Skip to content

Commit ee5d508

Browse files
author
dmitriy.grytsovets
committed
MP_BIN Support
MsgPackLite is not static anymore
1 parent 2ce017f commit ee5d508

File tree

3 files changed

+117
-113
lines changed

3 files changed

+117
-113
lines changed

src/main/java/org/tarantool/MsgPackLite.java

+111-103
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import java.math.BigInteger;
1010
import java.nio.ByteBuffer;
1111
import java.util.ArrayList;
12-
import java.util.LinkedHashMap;
12+
import java.util.HashMap;
1313
import java.util.List;
1414
import java.util.Map;
1515
import java.util.concurrent.Callable;
@@ -19,59 +19,59 @@
1919
*/
2020
public class MsgPackLite {
2121

22-
public static final int OPTION_UNPACK_RAW_AS_STRING = 0x1;
23-
public static final int OPTION_UNPACK_RAW_AS_BYTE_BUFFER = 0x2;
24-
public static final int OPTION_UNPACK_NUMBER_UINT32_AS_INT = 0x4;
25-
public static final int OPTION_UNPACK_NUMBER_AS_LONG = 0x8;
22+
public static final MsgPackLite INSTANCE = new MsgPackLite();
2623

27-
protected static final int MAX_4BIT = 0xf;
28-
protected static final int MAX_5BIT = 0x1f;
29-
protected static final int MAX_7BIT = 0x7f;
30-
protected static final int MAX_8BIT = 0xff;
31-
protected static final int MAX_15BIT = 0x7fff;
32-
protected static final int MAX_16BIT = 0xffff;
33-
protected static final int MAX_31BIT = 0x7fffffff;
34-
protected static final long MAX_32BIT = 0xffffffffL;
24+
protected final int MAX_4BIT = 0xf;
25+
protected final int MAX_5BIT = 0x1f;
26+
protected final int MAX_7BIT = 0x7f;
27+
protected final int MAX_8BIT = 0xff;
28+
protected final int MAX_15BIT = 0x7fff;
29+
protected final int MAX_16BIT = 0xffff;
30+
protected final int MAX_31BIT = 0x7fffffff;
31+
protected final long MAX_32BIT = 0xffffffffL;
3532

3633
//these values are from http://wiki.msgpack.org/display/MSGPACK/Format+specification
37-
protected static final byte MP_NULL = (byte) 0xc0;
38-
protected static final byte MP_FALSE = (byte) 0xc2;
39-
protected static final byte MP_TRUE = (byte) 0xc3;
34+
protected final byte MP_NULL = (byte) 0xc0;
35+
protected final byte MP_FALSE = (byte) 0xc2;
36+
protected final byte MP_TRUE = (byte) 0xc3;
37+
protected final byte MP_BIN8 = (byte) 0xc4;
38+
protected final byte MP_BIN16 = (byte) 0xc5;
39+
protected final byte MP_BIN32 = (byte) 0xc6;
4040

41-
protected static final byte MP_FLOAT = (byte) 0xca;
42-
protected static final byte MP_DOUBLE = (byte) 0xcb;
41+
protected final byte MP_FLOAT = (byte) 0xca;
42+
protected final byte MP_DOUBLE = (byte) 0xcb;
4343

44-
protected static final byte MP_FIXNUM = (byte) 0x00;//last 7 bits is value
45-
protected static final byte MP_UINT8 = (byte) 0xcc;
46-
protected static final byte MP_UINT16 = (byte) 0xcd;
47-
protected static final byte MP_UINT32 = (byte) 0xce;
48-
protected static final byte MP_UINT64 = (byte) 0xcf;
44+
protected final byte MP_FIXNUM = (byte) 0x00;//last 7 bits is value
45+
protected final byte MP_UINT8 = (byte) 0xcc;
46+
protected final byte MP_UINT16 = (byte) 0xcd;
47+
protected final byte MP_UINT32 = (byte) 0xce;
48+
protected final byte MP_UINT64 = (byte) 0xcf;
4949

50-
protected static final byte MP_NEGATIVE_FIXNUM = (byte) 0xe0;//last 5 bits is value
51-
protected static final int MP_NEGATIVE_FIXNUM_INT = 0xe0;// /me wishes for signed numbers.
52-
protected static final byte MP_INT8 = (byte) 0xd0;
53-
protected static final byte MP_INT16 = (byte) 0xd1;
54-
protected static final byte MP_INT32 = (byte) 0xd2;
55-
protected static final byte MP_INT64 = (byte) 0xd3;
50+
protected final byte MP_NEGATIVE_FIXNUM = (byte) 0xe0;//last 5 bits is value
51+
protected final int MP_NEGATIVE_FIXNUM_INT = 0xe0;// /me wishes for signed numbers.
52+
protected final byte MP_INT8 = (byte) 0xd0;
53+
protected final byte MP_INT16 = (byte) 0xd1;
54+
protected final byte MP_INT32 = (byte) 0xd2;
55+
protected final byte MP_INT64 = (byte) 0xd3;
5656

57-
protected static final byte MP_FIXARRAY = (byte) 0x90;//last 4 bits is size
58-
protected static final int MP_FIXARRAY_INT = 0x90;
59-
protected static final byte MP_ARRAY16 = (byte) 0xdc;
60-
protected static final byte MP_ARRAY32 = (byte) 0xdd;
57+
protected final byte MP_FIXARRAY = (byte) 0x90;//last 4 bits is size
58+
protected final int MP_FIXARRAY_INT = 0x90;
59+
protected final byte MP_ARRAY16 = (byte) 0xdc;
60+
protected final byte MP_ARRAY32 = (byte) 0xdd;
6161

62-
protected static final byte MP_FIXMAP = (byte) 0x80;//last 4 bits is size
63-
protected static final int MP_FIXMAP_INT = 0x80;
64-
protected static final byte MP_MAP16 = (byte) 0xde;
65-
protected static final byte MP_MAP32 = (byte) 0xdf;
62+
protected final byte MP_FIXMAP = (byte) 0x80;//last 4 bits is size
63+
protected final int MP_FIXMAP_INT = 0x80;
64+
protected final byte MP_MAP16 = (byte) 0xde;
65+
protected final byte MP_MAP32 = (byte) 0xdf;
6666

67-
protected static final byte MP_FIXRAW = (byte) 0xa0;//last 5 bits is size
68-
protected static final int MP_FIXRAW_INT = 0xa0;
69-
protected static final byte MP_RAW8 = (byte) 0xd9;
70-
protected static final byte MP_RAW16 = (byte) 0xda;
71-
protected static final byte MP_RAW32 = (byte) 0xdb;
67+
protected final byte MP_FIXSTR = (byte) 0xa0;//last 5 bits is size
68+
protected final int MP_FIXSTR_INT = 0xa0;
69+
protected final byte MP_STR8 = (byte) 0xd9;
70+
protected final byte MP_STR16 = (byte) 0xda;
71+
protected final byte MP_STR32 = (byte) 0xdb;
7272

73-
public static void pack(Object item, OutputStream os) throws IOException {
74-
DataOutputStream out = (os instanceof DataOutputStream) ? (DataOutputStream) os : new DataOutputStream(os);
73+
public void pack(Object item, OutputStream os) throws IOException {
74+
DataOutputStream out = new DataOutputStream(os);
7575
if (item instanceof Callable) {
7676
try {
7777
item = ((Callable) item).call();
@@ -126,11 +126,24 @@ public static void pack(Object item, OutputStream os) throws IOException {
126126
}
127127
}
128128
}
129-
} else if (item instanceof String || item instanceof byte[] || item instanceof ByteBuffer) {
129+
} else if (item instanceof String) {
130+
byte[] data = ((String) item).getBytes("UTF-8");
131+
if (data.length <= MAX_5BIT) {
132+
out.write(data.length | MP_FIXSTR);
133+
} else if (data.length <= MAX_8BIT) {
134+
out.write(MP_STR8);
135+
out.writeByte(data.length);
136+
} else if (data.length <= MAX_16BIT) {
137+
out.write(MP_STR16);
138+
out.writeShort(data.length);
139+
} else {
140+
out.write(MP_STR32);
141+
out.writeInt(data.length);
142+
}
143+
out.write(data);
144+
} else if (item instanceof byte[]) {
130145
byte[] data;
131-
if (item instanceof String) {
132-
data = ((String) item).getBytes("UTF-8");
133-
} else if (item instanceof byte[]) {
146+
if (item instanceof byte[]) {
134147
data = (byte[]) item;
135148
} else {
136149
ByteBuffer bb = ((ByteBuffer) item);
@@ -143,17 +156,14 @@ public static void pack(Object item, OutputStream os) throws IOException {
143156
bb.get(data);
144157
}
145158
}
146-
147-
if (data.length <= MAX_5BIT) {
148-
out.write(data.length | MP_FIXRAW);
149-
} else if (data.length <= MAX_8BIT) {
150-
out.write(MP_RAW8);
159+
if (data.length <= MAX_8BIT) {
160+
out.write(MP_BIN8);
151161
out.writeByte(data.length);
152162
} else if (data.length <= MAX_16BIT) {
153-
out.write(MP_RAW16);
163+
out.write(MP_BIN16);
154164
out.writeShort(data.length);
155165
} else {
156-
out.write(MP_RAW32);
166+
out.write(MP_BIN32);
157167
out.writeInt(data.length);
158168
}
159169
out.write(data);
@@ -198,15 +208,8 @@ public static void pack(Object item, OutputStream os) throws IOException {
198208
}
199209
}
200210

201-
private static Number val(Number n, int options) {
202-
if ((options & OPTION_UNPACK_NUMBER_AS_LONG) > 0) {
203-
return n.longValue();
204-
}
205-
return n;
206-
}
207-
208-
public static Object unpack(InputStream is, int options) throws IOException {
209-
DataInputStream in = is instanceof DataInputStream ? (DataInputStream) is : new DataInputStream(is);
211+
public Object unpack(InputStream is) throws IOException {
212+
DataInputStream in = new DataInputStream(is);
210213
int value = in.read();
211214
if (value < 0) {
212215
throw new IllegalArgumentException("No more input available when expecting a value");
@@ -223,12 +226,11 @@ public static Object unpack(InputStream is, int options) throws IOException {
223226
case MP_DOUBLE:
224227
return in.readDouble();
225228
case MP_UINT8:
226-
return val(in.read(), options);//received single byte, return as int
229+
return in.read();//read single byte, return as int
227230
case MP_UINT16:
228-
return val(in.readShort() & MAX_16BIT, options);//received short, trick Java into treating it as unsigned, return int
231+
return in.readShort() & MAX_16BIT;//read short, trick Java into treating it as unsigned, return int
229232
case MP_UINT32:
230-
long n = in.readInt() & MAX_32BIT;
231-
return val((options & OPTION_UNPACK_NUMBER_UINT32_AS_INT) > 0 && n <= Integer.MAX_VALUE ? (int) n : n, options);
233+
return in.readInt() & MAX_32BIT;//read int, trick Java into treating it as unsigned, return long
232234
case MP_UINT64: {
233235
long v = in.readLong();
234236
if (v >= 0) {
@@ -241,89 +243,95 @@ public static Object unpack(InputStream is, int options) throws IOException {
241243
(byte) ((v >> 8) & 0xff),
242244
(byte) (v & 0xff),
243245
};
244-
return val(new BigInteger(1, bytes), options);
246+
return new BigInteger(1, bytes);
245247
}
246248
}
247249
case MP_INT8:
248-
return val((byte) in.read(), options);
250+
return (byte) in.read();
249251
case MP_INT16:
250-
return val(in.readShort(), options);
252+
return in.readShort();
251253
case MP_INT32:
252-
return val(in.readInt(), options);
254+
return in.readInt();
253255
case MP_INT64:
254-
return val(in.readLong(), options);
256+
return in.readLong();
255257
case MP_ARRAY16:
256-
return unpackList(in.readShort() & MAX_16BIT, in, options);
258+
return unpackList(in.readShort() & MAX_16BIT, in);
257259
case MP_ARRAY32:
258-
return unpackList(in.readInt(), in, options);
260+
return unpackList(in.readInt(), in);
259261
case MP_MAP16:
260-
return unpackMap(in.readShort() & MAX_16BIT, in, options);
262+
return unpackMap(in.readShort() & MAX_16BIT, in);
261263
case MP_MAP32:
262-
return unpackMap(in.readInt(), in, options);
263-
case MP_RAW8:
264-
return unpackRaw(in.readByte() & MAX_8BIT, in, options);
265-
case MP_RAW16:
266-
return unpackRaw(in.readShort() & MAX_16BIT, in, options);
267-
case MP_RAW32:
268-
return unpackRaw(in.readInt(), in, options);
264+
return unpackMap(in.readInt(), in);
265+
case MP_STR8:
266+
return unpackStr(in.readByte() & MAX_8BIT, in);
267+
case MP_STR16:
268+
return unpackStr(in.readShort() & MAX_16BIT, in);
269+
case MP_STR32:
270+
return unpackStr(in.readInt(), in);
271+
case MP_BIN8:
272+
return unpackBin(in.readByte() & MAX_8BIT, in);
273+
case MP_BIN16:
274+
return unpackBin(in.readShort() & MAX_16BIT, in);
275+
case MP_BIN32:
276+
return unpackBin(in.readInt(), in);
269277
}
270278

271279
if (value >= MP_NEGATIVE_FIXNUM_INT && value <= MP_NEGATIVE_FIXNUM_INT + MAX_5BIT) {
272280
return (byte) value;
273281
} else if (value >= MP_FIXARRAY_INT && value <= MP_FIXARRAY_INT + MAX_4BIT) {
274-
return unpackList(value - MP_FIXARRAY_INT, in, options);
282+
return unpackList(value - MP_FIXARRAY_INT, in);
275283
} else if (value >= MP_FIXMAP_INT && value <= MP_FIXMAP_INT + MAX_4BIT) {
276-
return unpackMap(value - MP_FIXMAP_INT, in, options);
277-
} else if (value >= MP_FIXRAW_INT && value <= MP_FIXRAW_INT + MAX_5BIT) {
278-
return unpackRaw(value - MP_FIXRAW_INT, in, options);
284+
return unpackMap(value - MP_FIXMAP_INT, in);
285+
} else if (value >= MP_FIXSTR_INT && value <= MP_FIXSTR_INT + MAX_5BIT) {
286+
return unpackStr(value - MP_FIXSTR_INT, in);
279287
} else if (value <= MAX_7BIT) {//MP_FIXNUM - the value is value as an int
280288
return value;
281289
} else {
282290
throw new IllegalArgumentException("Input contains invalid type value " + (byte) value);
283291
}
284292
}
285293

286-
protected static List unpackList(int size, DataInputStream in, int options) throws IOException {
294+
protected List unpackList(int size, DataInputStream in) throws IOException {
287295
if (size < 0) {
288296
throw new IllegalArgumentException("Array to unpack too large for Java (more than 2^31 elements)!");
289297
}
290298
List ret = new ArrayList(size);
291299
for (int i = 0; i < size; ++i) {
292-
ret.add(unpack(in, options));
300+
ret.add(unpack(in));
293301
}
294302
return ret;
295303
}
296304

297-
protected static Map unpackMap(int size, DataInputStream in, int options) throws IOException {
305+
protected Map unpackMap(int size, DataInputStream in) throws IOException {
298306
if (size < 0) {
299307
throw new IllegalArgumentException("Map to unpack too large for Java (more than 2^31 elements)!");
300308
}
301-
Map ret = new LinkedHashMap(size);
309+
Map ret = new HashMap(size);
302310
for (int i = 0; i < size; ++i) {
303-
Object key = unpack(in, options);
304-
Object value = unpack(in, options);
311+
Object key = unpack(in);
312+
Object value = unpack(in);
305313
ret.put(key, value);
306314
}
307315
return ret;
308316
}
309317

310-
protected static Object unpackRaw(int size, DataInputStream in, int options) throws IOException {
318+
protected Object unpackStr(int size, DataInputStream in) throws IOException {
311319
if (size < 0) {
312320
throw new IllegalArgumentException("byte[] to unpack too large for Java (more than 2^31 elements)!");
313321
}
314322

315323
byte[] data = new byte[size];
316324
in.readFully(data);
317-
318-
if ((options & OPTION_UNPACK_RAW_AS_BYTE_BUFFER) != 0) {
319-
return ByteBuffer.wrap(data);
320-
} else if ((options & OPTION_UNPACK_RAW_AS_STRING) != 0) {
321-
return new String(data, "UTF-8");
322-
} else {
323-
return data;
324-
}
325+
return new String(data, "UTF-8");
325326
}
326327

328+
protected Object unpackBin(int size, DataInputStream in) throws IOException {
329+
if (size < 0) {
330+
throw new IllegalArgumentException("byte[] to unpack too large for Java (more than 2^31 elements)!");
331+
}
327332

328-
333+
byte[] data = new byte[size];
334+
in.readFully(data);
335+
return data;
336+
}
329337
}

src/main/java/org/tarantool/TarantoolClientConfig.java

-5
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ public class TarantoolClientConfig {
1515
*/
1616
public int defaultRequestSize = 1024;
1717

18-
/**
19-
* MessagePack options when reading from upstream
20-
*/
21-
public int msgPackOptions = MsgPackLite.OPTION_UNPACK_NUMBER_AS_LONG | MsgPackLite.OPTION_UNPACK_RAW_AS_STRING;
22-
2318
/**
2419
* initial size for map which holds futures of sent request
2520
*/

src/main/java/org/tarantool/TarantoolClientImpl.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class TarantoolClientImpl extends AbstractTarantoolOps<Integer, Object, O
4141
protected AtomicLong syncId = new AtomicLong();
4242
protected Map<Long, FutureImpl<List>> futures;
4343
protected AtomicInteger wait = new AtomicInteger();
44+
protected MsgPackLite msgPackLite = MsgPackLite.INSTANCE;
4445

4546
/**
4647
* Read properties
@@ -282,8 +283,8 @@ protected void write(Code code, Long syncId, Long schemaId, boolean forceDirect,
282283
body.put((Key) args[i], value);
283284
}
284285
}
285-
MsgPackLite.pack(header, ds);
286-
MsgPackLite.pack(body, ds);
286+
msgPackLite.pack(header, ds);
287+
msgPackLite.pack(body, ds);
287288
ds.flush();
288289
ByteBuffer buffer = bos.toByteBuffer();
289290
buffer.put(0, (byte) 0xce);
@@ -355,12 +356,12 @@ protected void readThread() {
355356
}
356357

357358
protected void readPacket() throws IOException {
358-
int size = ((Number) MsgPackLite.unpack(is, config.msgPackOptions)).intValue();
359+
int size = ((Number) msgPackLite.unpack(is)).intValue();
359360
long mark = bytesRead;
360361
is.mark(size);
361-
headers = (Map<Integer, Object>) MsgPackLite.unpack(is, config.msgPackOptions);
362+
headers = (Map<Integer, Object>) msgPackLite.unpack(is);
362363
if (bytesRead - mark < size) {
363-
body = (Map<Integer, Object>) MsgPackLite.unpack(is, config.msgPackOptions);
364+
body = (Map<Integer, Object>) msgPackLite.unpack(is);
364365
}
365366
is.skipBytes((int) (bytesRead - mark - size));
366367
}

0 commit comments

Comments
 (0)