9
9
import java .math .BigInteger ;
10
10
import java .nio .ByteBuffer ;
11
11
import java .util .ArrayList ;
12
- import java .util .LinkedHashMap ;
12
+ import java .util .HashMap ;
13
13
import java .util .List ;
14
14
import java .util .Map ;
15
15
import java .util .concurrent .Callable ;
19
19
*/
20
20
public class MsgPackLite {
21
21
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 ();
26
23
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 ;
35
32
36
33
//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 ;
40
40
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 ;
43
43
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 ;
49
49
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 ;
56
56
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 ;
61
61
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 ;
66
66
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 ;
72
72
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 );
75
75
if (item instanceof Callable ) {
76
76
try {
77
77
item = ((Callable ) item ).call ();
@@ -126,11 +126,24 @@ public static void pack(Object item, OutputStream os) throws IOException {
126
126
}
127
127
}
128
128
}
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 []) {
130
145
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 []) {
134
147
data = (byte []) item ;
135
148
} else {
136
149
ByteBuffer bb = ((ByteBuffer ) item );
@@ -143,17 +156,14 @@ public static void pack(Object item, OutputStream os) throws IOException {
143
156
bb .get (data );
144
157
}
145
158
}
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 );
151
161
out .writeByte (data .length );
152
162
} else if (data .length <= MAX_16BIT ) {
153
- out .write (MP_RAW16 );
163
+ out .write (MP_BIN16 );
154
164
out .writeShort (data .length );
155
165
} else {
156
- out .write (MP_RAW32 );
166
+ out .write (MP_BIN32 );
157
167
out .writeInt (data .length );
158
168
}
159
169
out .write (data );
@@ -198,15 +208,8 @@ public static void pack(Object item, OutputStream os) throws IOException {
198
208
}
199
209
}
200
210
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 );
210
213
int value = in .read ();
211
214
if (value < 0 ) {
212
215
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 {
223
226
case MP_DOUBLE :
224
227
return in .readDouble ();
225
228
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
227
230
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
229
232
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
232
234
case MP_UINT64 : {
233
235
long v = in .readLong ();
234
236
if (v >= 0 ) {
@@ -241,89 +243,95 @@ public static Object unpack(InputStream is, int options) throws IOException {
241
243
(byte ) ((v >> 8 ) & 0xff ),
242
244
(byte ) (v & 0xff ),
243
245
};
244
- return val ( new BigInteger (1 , bytes ), options );
246
+ return new BigInteger (1 , bytes );
245
247
}
246
248
}
247
249
case MP_INT8 :
248
- return val (( byte ) in .read (), options );
250
+ return ( byte ) in .read ();
249
251
case MP_INT16 :
250
- return val ( in .readShort (), options );
252
+ return in .readShort ();
251
253
case MP_INT32 :
252
- return val ( in .readInt (), options );
254
+ return in .readInt ();
253
255
case MP_INT64 :
254
- return val ( in .readLong (), options );
256
+ return in .readLong ();
255
257
case MP_ARRAY16 :
256
- return unpackList (in .readShort () & MAX_16BIT , in , options );
258
+ return unpackList (in .readShort () & MAX_16BIT , in );
257
259
case MP_ARRAY32 :
258
- return unpackList (in .readInt (), in , options );
260
+ return unpackList (in .readInt (), in );
259
261
case MP_MAP16 :
260
- return unpackMap (in .readShort () & MAX_16BIT , in , options );
262
+ return unpackMap (in .readShort () & MAX_16BIT , in );
261
263
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 );
269
277
}
270
278
271
279
if (value >= MP_NEGATIVE_FIXNUM_INT && value <= MP_NEGATIVE_FIXNUM_INT + MAX_5BIT ) {
272
280
return (byte ) value ;
273
281
} 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 );
275
283
} 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 );
279
287
} else if (value <= MAX_7BIT ) {//MP_FIXNUM - the value is value as an int
280
288
return value ;
281
289
} else {
282
290
throw new IllegalArgumentException ("Input contains invalid type value " + (byte ) value );
283
291
}
284
292
}
285
293
286
- protected static List unpackList (int size , DataInputStream in , int options ) throws IOException {
294
+ protected List unpackList (int size , DataInputStream in ) throws IOException {
287
295
if (size < 0 ) {
288
296
throw new IllegalArgumentException ("Array to unpack too large for Java (more than 2^31 elements)!" );
289
297
}
290
298
List ret = new ArrayList (size );
291
299
for (int i = 0 ; i < size ; ++i ) {
292
- ret .add (unpack (in , options ));
300
+ ret .add (unpack (in ));
293
301
}
294
302
return ret ;
295
303
}
296
304
297
- protected static Map unpackMap (int size , DataInputStream in , int options ) throws IOException {
305
+ protected Map unpackMap (int size , DataInputStream in ) throws IOException {
298
306
if (size < 0 ) {
299
307
throw new IllegalArgumentException ("Map to unpack too large for Java (more than 2^31 elements)!" );
300
308
}
301
- Map ret = new LinkedHashMap (size );
309
+ Map ret = new HashMap (size );
302
310
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 );
305
313
ret .put (key , value );
306
314
}
307
315
return ret ;
308
316
}
309
317
310
- protected static Object unpackRaw (int size , DataInputStream in , int options ) throws IOException {
318
+ protected Object unpackStr (int size , DataInputStream in ) throws IOException {
311
319
if (size < 0 ) {
312
320
throw new IllegalArgumentException ("byte[] to unpack too large for Java (more than 2^31 elements)!" );
313
321
}
314
322
315
323
byte [] data = new byte [size ];
316
324
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" );
325
326
}
326
327
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
+ }
327
332
328
-
333
+ byte [] data = new byte [size ];
334
+ in .readFully (data );
335
+ return data ;
336
+ }
329
337
}
0 commit comments