1*572c4311Sfengbojiang #include <math.h>
2*572c4311Sfengbojiang #include <stdlib.h>
3*572c4311Sfengbojiang #include <stdint.h>
4*572c4311Sfengbojiang #include <string.h>
5*572c4311Sfengbojiang #include <assert.h>
6*572c4311Sfengbojiang
7*572c4311Sfengbojiang #include "lua.h"
8*572c4311Sfengbojiang #include "lauxlib.h"
9*572c4311Sfengbojiang
10*572c4311Sfengbojiang #define LUACMSGPACK_NAME "cmsgpack"
11*572c4311Sfengbojiang #define LUACMSGPACK_SAFE_NAME "cmsgpack_safe"
12*572c4311Sfengbojiang #define LUACMSGPACK_VERSION "lua-cmsgpack 0.4.0"
13*572c4311Sfengbojiang #define LUACMSGPACK_COPYRIGHT "Copyright (C) 2012, Salvatore Sanfilippo"
14*572c4311Sfengbojiang #define LUACMSGPACK_DESCRIPTION "MessagePack C implementation for Lua"
15*572c4311Sfengbojiang
16*572c4311Sfengbojiang /* Allows a preprocessor directive to override MAX_NESTING */
17*572c4311Sfengbojiang #ifndef LUACMSGPACK_MAX_NESTING
18*572c4311Sfengbojiang #define LUACMSGPACK_MAX_NESTING 16 /* Max tables nesting. */
19*572c4311Sfengbojiang #endif
20*572c4311Sfengbojiang
21*572c4311Sfengbojiang /* Check if float or double can be an integer without loss of precision */
22*572c4311Sfengbojiang #define IS_INT_TYPE_EQUIVALENT(x, T) (!isinf(x) && (T)(x) == (x))
23*572c4311Sfengbojiang
24*572c4311Sfengbojiang #define IS_INT64_EQUIVALENT(x) IS_INT_TYPE_EQUIVALENT(x, int64_t)
25*572c4311Sfengbojiang #define IS_INT_EQUIVALENT(x) IS_INT_TYPE_EQUIVALENT(x, int)
26*572c4311Sfengbojiang
27*572c4311Sfengbojiang /* If size of pointer is equal to a 4 byte integer, we're on 32 bits. */
28*572c4311Sfengbojiang #if UINTPTR_MAX == UINT_MAX
29*572c4311Sfengbojiang #define BITS_32 1
30*572c4311Sfengbojiang #else
31*572c4311Sfengbojiang #define BITS_32 0
32*572c4311Sfengbojiang #endif
33*572c4311Sfengbojiang
34*572c4311Sfengbojiang #if BITS_32
35*572c4311Sfengbojiang #define lua_pushunsigned(L, n) lua_pushnumber(L, n)
36*572c4311Sfengbojiang #else
37*572c4311Sfengbojiang #define lua_pushunsigned(L, n) lua_pushinteger(L, n)
38*572c4311Sfengbojiang #endif
39*572c4311Sfengbojiang
40*572c4311Sfengbojiang /* =============================================================================
41*572c4311Sfengbojiang * MessagePack implementation and bindings for Lua 5.1/5.2.
42*572c4311Sfengbojiang * Copyright(C) 2012 Salvatore Sanfilippo <[email protected]>
43*572c4311Sfengbojiang *
44*572c4311Sfengbojiang * http://github.com/antirez/lua-cmsgpack
45*572c4311Sfengbojiang *
46*572c4311Sfengbojiang * For MessagePack specification check the following web site:
47*572c4311Sfengbojiang * http://wiki.msgpack.org/display/MSGPACK/Format+specification
48*572c4311Sfengbojiang *
49*572c4311Sfengbojiang * See Copyright Notice at the end of this file.
50*572c4311Sfengbojiang *
51*572c4311Sfengbojiang * CHANGELOG:
52*572c4311Sfengbojiang * 19-Feb-2012 (ver 0.1.0): Initial release.
53*572c4311Sfengbojiang * 20-Feb-2012 (ver 0.2.0): Tables encoding improved.
54*572c4311Sfengbojiang * 20-Feb-2012 (ver 0.2.1): Minor bug fixing.
55*572c4311Sfengbojiang * 20-Feb-2012 (ver 0.3.0): Module renamed lua-cmsgpack (was lua-msgpack).
56*572c4311Sfengbojiang * 04-Apr-2014 (ver 0.3.1): Lua 5.2 support and minor bug fix.
57*572c4311Sfengbojiang * 07-Apr-2014 (ver 0.4.0): Multiple pack/unpack, lua allocator, efficiency.
58*572c4311Sfengbojiang * ========================================================================== */
59*572c4311Sfengbojiang
60*572c4311Sfengbojiang /* -------------------------- Endian conversion --------------------------------
61*572c4311Sfengbojiang * We use it only for floats and doubles, all the other conversions performed
62*572c4311Sfengbojiang * in an endian independent fashion. So the only thing we need is a function
63*572c4311Sfengbojiang * that swaps a binary string if arch is little endian (and left it untouched
64*572c4311Sfengbojiang * otherwise). */
65*572c4311Sfengbojiang
66*572c4311Sfengbojiang /* Reverse memory bytes if arch is little endian. Given the conceptual
67*572c4311Sfengbojiang * simplicity of the Lua build system we prefer check for endianess at runtime.
68*572c4311Sfengbojiang * The performance difference should be acceptable. */
memrevifle(void * ptr,size_t len)69*572c4311Sfengbojiang void memrevifle(void *ptr, size_t len) {
70*572c4311Sfengbojiang unsigned char *p = (unsigned char *)ptr,
71*572c4311Sfengbojiang *e = (unsigned char *)p+len-1,
72*572c4311Sfengbojiang aux;
73*572c4311Sfengbojiang int test = 1;
74*572c4311Sfengbojiang unsigned char *testp = (unsigned char*) &test;
75*572c4311Sfengbojiang
76*572c4311Sfengbojiang if (testp[0] == 0) return; /* Big endian, nothing to do. */
77*572c4311Sfengbojiang len /= 2;
78*572c4311Sfengbojiang while(len--) {
79*572c4311Sfengbojiang aux = *p;
80*572c4311Sfengbojiang *p = *e;
81*572c4311Sfengbojiang *e = aux;
82*572c4311Sfengbojiang p++;
83*572c4311Sfengbojiang e--;
84*572c4311Sfengbojiang }
85*572c4311Sfengbojiang }
86*572c4311Sfengbojiang
87*572c4311Sfengbojiang /* ---------------------------- String buffer ----------------------------------
88*572c4311Sfengbojiang * This is a simple implementation of string buffers. The only operation
89*572c4311Sfengbojiang * supported is creating empty buffers and appending bytes to it.
90*572c4311Sfengbojiang * The string buffer uses 2x preallocation on every realloc for O(N) append
91*572c4311Sfengbojiang * behavior. */
92*572c4311Sfengbojiang
93*572c4311Sfengbojiang typedef struct mp_buf {
94*572c4311Sfengbojiang unsigned char *b;
95*572c4311Sfengbojiang size_t len, free;
96*572c4311Sfengbojiang } mp_buf;
97*572c4311Sfengbojiang
mp_realloc(lua_State * L,void * target,size_t osize,size_t nsize)98*572c4311Sfengbojiang void *mp_realloc(lua_State *L, void *target, size_t osize,size_t nsize) {
99*572c4311Sfengbojiang void *(*local_realloc) (void *, void *, size_t osize, size_t nsize) = NULL;
100*572c4311Sfengbojiang void *ud;
101*572c4311Sfengbojiang
102*572c4311Sfengbojiang local_realloc = lua_getallocf(L, &ud);
103*572c4311Sfengbojiang
104*572c4311Sfengbojiang return local_realloc(ud, target, osize, nsize);
105*572c4311Sfengbojiang }
106*572c4311Sfengbojiang
mp_buf_new(lua_State * L)107*572c4311Sfengbojiang mp_buf *mp_buf_new(lua_State *L) {
108*572c4311Sfengbojiang mp_buf *buf = NULL;
109*572c4311Sfengbojiang
110*572c4311Sfengbojiang /* Old size = 0; new size = sizeof(*buf) */
111*572c4311Sfengbojiang buf = (mp_buf*)mp_realloc(L, NULL, 0, sizeof(*buf));
112*572c4311Sfengbojiang
113*572c4311Sfengbojiang buf->b = NULL;
114*572c4311Sfengbojiang buf->len = buf->free = 0;
115*572c4311Sfengbojiang return buf;
116*572c4311Sfengbojiang }
117*572c4311Sfengbojiang
mp_buf_append(lua_State * L,mp_buf * buf,const unsigned char * s,size_t len)118*572c4311Sfengbojiang void mp_buf_append(lua_State *L, mp_buf *buf, const unsigned char *s, size_t len) {
119*572c4311Sfengbojiang if (buf->free < len) {
120*572c4311Sfengbojiang size_t newsize = (buf->len+len)*2;
121*572c4311Sfengbojiang
122*572c4311Sfengbojiang buf->b = (unsigned char*)mp_realloc(L, buf->b, buf->len + buf->free, newsize);
123*572c4311Sfengbojiang buf->free = newsize - buf->len;
124*572c4311Sfengbojiang }
125*572c4311Sfengbojiang memcpy(buf->b+buf->len,s,len);
126*572c4311Sfengbojiang buf->len += len;
127*572c4311Sfengbojiang buf->free -= len;
128*572c4311Sfengbojiang }
129*572c4311Sfengbojiang
mp_buf_free(lua_State * L,mp_buf * buf)130*572c4311Sfengbojiang void mp_buf_free(lua_State *L, mp_buf *buf) {
131*572c4311Sfengbojiang mp_realloc(L, buf->b, buf->len + buf->free, 0); /* realloc to 0 = free */
132*572c4311Sfengbojiang mp_realloc(L, buf, sizeof(*buf), 0);
133*572c4311Sfengbojiang }
134*572c4311Sfengbojiang
135*572c4311Sfengbojiang /* ---------------------------- String cursor ----------------------------------
136*572c4311Sfengbojiang * This simple data structure is used for parsing. Basically you create a cursor
137*572c4311Sfengbojiang * using a string pointer and a length, then it is possible to access the
138*572c4311Sfengbojiang * current string position with cursor->p, check the remaining length
139*572c4311Sfengbojiang * in cursor->left, and finally consume more string using
140*572c4311Sfengbojiang * mp_cur_consume(cursor,len), to advance 'p' and subtract 'left'.
141*572c4311Sfengbojiang * An additional field cursor->error is set to zero on initialization and can
142*572c4311Sfengbojiang * be used to report errors. */
143*572c4311Sfengbojiang
144*572c4311Sfengbojiang #define MP_CUR_ERROR_NONE 0
145*572c4311Sfengbojiang #define MP_CUR_ERROR_EOF 1 /* Not enough data to complete operation. */
146*572c4311Sfengbojiang #define MP_CUR_ERROR_BADFMT 2 /* Bad data format */
147*572c4311Sfengbojiang
148*572c4311Sfengbojiang typedef struct mp_cur {
149*572c4311Sfengbojiang const unsigned char *p;
150*572c4311Sfengbojiang size_t left;
151*572c4311Sfengbojiang int err;
152*572c4311Sfengbojiang } mp_cur;
153*572c4311Sfengbojiang
mp_cur_init(mp_cur * cursor,const unsigned char * s,size_t len)154*572c4311Sfengbojiang void mp_cur_init(mp_cur *cursor, const unsigned char *s, size_t len) {
155*572c4311Sfengbojiang cursor->p = s;
156*572c4311Sfengbojiang cursor->left = len;
157*572c4311Sfengbojiang cursor->err = MP_CUR_ERROR_NONE;
158*572c4311Sfengbojiang }
159*572c4311Sfengbojiang
160*572c4311Sfengbojiang #define mp_cur_consume(_c,_len) do { _c->p += _len; _c->left -= _len; } while(0)
161*572c4311Sfengbojiang
162*572c4311Sfengbojiang /* When there is not enough room we set an error in the cursor and return. This
163*572c4311Sfengbojiang * is very common across the code so we have a macro to make the code look
164*572c4311Sfengbojiang * a bit simpler. */
165*572c4311Sfengbojiang #define mp_cur_need(_c,_len) do { \
166*572c4311Sfengbojiang if (_c->left < _len) { \
167*572c4311Sfengbojiang _c->err = MP_CUR_ERROR_EOF; \
168*572c4311Sfengbojiang return; \
169*572c4311Sfengbojiang } \
170*572c4311Sfengbojiang } while(0)
171*572c4311Sfengbojiang
172*572c4311Sfengbojiang /* ------------------------- Low level MP encoding -------------------------- */
173*572c4311Sfengbojiang
mp_encode_bytes(lua_State * L,mp_buf * buf,const unsigned char * s,size_t len)174*572c4311Sfengbojiang void mp_encode_bytes(lua_State *L, mp_buf *buf, const unsigned char *s, size_t len) {
175*572c4311Sfengbojiang unsigned char hdr[5];
176*572c4311Sfengbojiang int hdrlen;
177*572c4311Sfengbojiang
178*572c4311Sfengbojiang if (len < 32) {
179*572c4311Sfengbojiang hdr[0] = 0xa0 | (len&0xff); /* fix raw */
180*572c4311Sfengbojiang hdrlen = 1;
181*572c4311Sfengbojiang } else if (len <= 0xff) {
182*572c4311Sfengbojiang hdr[0] = 0xd9;
183*572c4311Sfengbojiang hdr[1] = len;
184*572c4311Sfengbojiang hdrlen = 2;
185*572c4311Sfengbojiang } else if (len <= 0xffff) {
186*572c4311Sfengbojiang hdr[0] = 0xda;
187*572c4311Sfengbojiang hdr[1] = (len&0xff00)>>8;
188*572c4311Sfengbojiang hdr[2] = len&0xff;
189*572c4311Sfengbojiang hdrlen = 3;
190*572c4311Sfengbojiang } else {
191*572c4311Sfengbojiang hdr[0] = 0xdb;
192*572c4311Sfengbojiang hdr[1] = (len&0xff000000)>>24;
193*572c4311Sfengbojiang hdr[2] = (len&0xff0000)>>16;
194*572c4311Sfengbojiang hdr[3] = (len&0xff00)>>8;
195*572c4311Sfengbojiang hdr[4] = len&0xff;
196*572c4311Sfengbojiang hdrlen = 5;
197*572c4311Sfengbojiang }
198*572c4311Sfengbojiang mp_buf_append(L,buf,hdr,hdrlen);
199*572c4311Sfengbojiang mp_buf_append(L,buf,s,len);
200*572c4311Sfengbojiang }
201*572c4311Sfengbojiang
202*572c4311Sfengbojiang /* we assume IEEE 754 internal format for single and double precision floats. */
mp_encode_double(lua_State * L,mp_buf * buf,double d)203*572c4311Sfengbojiang void mp_encode_double(lua_State *L, mp_buf *buf, double d) {
204*572c4311Sfengbojiang unsigned char b[9];
205*572c4311Sfengbojiang float f = d;
206*572c4311Sfengbojiang
207*572c4311Sfengbojiang assert(sizeof(f) == 4 && sizeof(d) == 8);
208*572c4311Sfengbojiang if (d == (double)f) {
209*572c4311Sfengbojiang b[0] = 0xca; /* float IEEE 754 */
210*572c4311Sfengbojiang memcpy(b+1,&f,4);
211*572c4311Sfengbojiang memrevifle(b+1,4);
212*572c4311Sfengbojiang mp_buf_append(L,buf,b,5);
213*572c4311Sfengbojiang } else if (sizeof(d) == 8) {
214*572c4311Sfengbojiang b[0] = 0xcb; /* double IEEE 754 */
215*572c4311Sfengbojiang memcpy(b+1,&d,8);
216*572c4311Sfengbojiang memrevifle(b+1,8);
217*572c4311Sfengbojiang mp_buf_append(L,buf,b,9);
218*572c4311Sfengbojiang }
219*572c4311Sfengbojiang }
220*572c4311Sfengbojiang
mp_encode_int(lua_State * L,mp_buf * buf,int64_t n)221*572c4311Sfengbojiang void mp_encode_int(lua_State *L, mp_buf *buf, int64_t n) {
222*572c4311Sfengbojiang unsigned char b[9];
223*572c4311Sfengbojiang int enclen;
224*572c4311Sfengbojiang
225*572c4311Sfengbojiang if (n >= 0) {
226*572c4311Sfengbojiang if (n <= 127) {
227*572c4311Sfengbojiang b[0] = n & 0x7f; /* positive fixnum */
228*572c4311Sfengbojiang enclen = 1;
229*572c4311Sfengbojiang } else if (n <= 0xff) {
230*572c4311Sfengbojiang b[0] = 0xcc; /* uint 8 */
231*572c4311Sfengbojiang b[1] = n & 0xff;
232*572c4311Sfengbojiang enclen = 2;
233*572c4311Sfengbojiang } else if (n <= 0xffff) {
234*572c4311Sfengbojiang b[0] = 0xcd; /* uint 16 */
235*572c4311Sfengbojiang b[1] = (n & 0xff00) >> 8;
236*572c4311Sfengbojiang b[2] = n & 0xff;
237*572c4311Sfengbojiang enclen = 3;
238*572c4311Sfengbojiang } else if (n <= 0xffffffffLL) {
239*572c4311Sfengbojiang b[0] = 0xce; /* uint 32 */
240*572c4311Sfengbojiang b[1] = (n & 0xff000000) >> 24;
241*572c4311Sfengbojiang b[2] = (n & 0xff0000) >> 16;
242*572c4311Sfengbojiang b[3] = (n & 0xff00) >> 8;
243*572c4311Sfengbojiang b[4] = n & 0xff;
244*572c4311Sfengbojiang enclen = 5;
245*572c4311Sfengbojiang } else {
246*572c4311Sfengbojiang b[0] = 0xcf; /* uint 64 */
247*572c4311Sfengbojiang b[1] = (n & 0xff00000000000000LL) >> 56;
248*572c4311Sfengbojiang b[2] = (n & 0xff000000000000LL) >> 48;
249*572c4311Sfengbojiang b[3] = (n & 0xff0000000000LL) >> 40;
250*572c4311Sfengbojiang b[4] = (n & 0xff00000000LL) >> 32;
251*572c4311Sfengbojiang b[5] = (n & 0xff000000) >> 24;
252*572c4311Sfengbojiang b[6] = (n & 0xff0000) >> 16;
253*572c4311Sfengbojiang b[7] = (n & 0xff00) >> 8;
254*572c4311Sfengbojiang b[8] = n & 0xff;
255*572c4311Sfengbojiang enclen = 9;
256*572c4311Sfengbojiang }
257*572c4311Sfengbojiang } else {
258*572c4311Sfengbojiang if (n >= -32) {
259*572c4311Sfengbojiang b[0] = ((signed char)n); /* negative fixnum */
260*572c4311Sfengbojiang enclen = 1;
261*572c4311Sfengbojiang } else if (n >= -128) {
262*572c4311Sfengbojiang b[0] = 0xd0; /* int 8 */
263*572c4311Sfengbojiang b[1] = n & 0xff;
264*572c4311Sfengbojiang enclen = 2;
265*572c4311Sfengbojiang } else if (n >= -32768) {
266*572c4311Sfengbojiang b[0] = 0xd1; /* int 16 */
267*572c4311Sfengbojiang b[1] = (n & 0xff00) >> 8;
268*572c4311Sfengbojiang b[2] = n & 0xff;
269*572c4311Sfengbojiang enclen = 3;
270*572c4311Sfengbojiang } else if (n >= -2147483648LL) {
271*572c4311Sfengbojiang b[0] = 0xd2; /* int 32 */
272*572c4311Sfengbojiang b[1] = (n & 0xff000000) >> 24;
273*572c4311Sfengbojiang b[2] = (n & 0xff0000) >> 16;
274*572c4311Sfengbojiang b[3] = (n & 0xff00) >> 8;
275*572c4311Sfengbojiang b[4] = n & 0xff;
276*572c4311Sfengbojiang enclen = 5;
277*572c4311Sfengbojiang } else {
278*572c4311Sfengbojiang b[0] = 0xd3; /* int 64 */
279*572c4311Sfengbojiang b[1] = (n & 0xff00000000000000LL) >> 56;
280*572c4311Sfengbojiang b[2] = (n & 0xff000000000000LL) >> 48;
281*572c4311Sfengbojiang b[3] = (n & 0xff0000000000LL) >> 40;
282*572c4311Sfengbojiang b[4] = (n & 0xff00000000LL) >> 32;
283*572c4311Sfengbojiang b[5] = (n & 0xff000000) >> 24;
284*572c4311Sfengbojiang b[6] = (n & 0xff0000) >> 16;
285*572c4311Sfengbojiang b[7] = (n & 0xff00) >> 8;
286*572c4311Sfengbojiang b[8] = n & 0xff;
287*572c4311Sfengbojiang enclen = 9;
288*572c4311Sfengbojiang }
289*572c4311Sfengbojiang }
290*572c4311Sfengbojiang mp_buf_append(L,buf,b,enclen);
291*572c4311Sfengbojiang }
292*572c4311Sfengbojiang
mp_encode_array(lua_State * L,mp_buf * buf,int64_t n)293*572c4311Sfengbojiang void mp_encode_array(lua_State *L, mp_buf *buf, int64_t n) {
294*572c4311Sfengbojiang unsigned char b[5];
295*572c4311Sfengbojiang int enclen;
296*572c4311Sfengbojiang
297*572c4311Sfengbojiang if (n <= 15) {
298*572c4311Sfengbojiang b[0] = 0x90 | (n & 0xf); /* fix array */
299*572c4311Sfengbojiang enclen = 1;
300*572c4311Sfengbojiang } else if (n <= 65535) {
301*572c4311Sfengbojiang b[0] = 0xdc; /* array 16 */
302*572c4311Sfengbojiang b[1] = (n & 0xff00) >> 8;
303*572c4311Sfengbojiang b[2] = n & 0xff;
304*572c4311Sfengbojiang enclen = 3;
305*572c4311Sfengbojiang } else {
306*572c4311Sfengbojiang b[0] = 0xdd; /* array 32 */
307*572c4311Sfengbojiang b[1] = (n & 0xff000000) >> 24;
308*572c4311Sfengbojiang b[2] = (n & 0xff0000) >> 16;
309*572c4311Sfengbojiang b[3] = (n & 0xff00) >> 8;
310*572c4311Sfengbojiang b[4] = n & 0xff;
311*572c4311Sfengbojiang enclen = 5;
312*572c4311Sfengbojiang }
313*572c4311Sfengbojiang mp_buf_append(L,buf,b,enclen);
314*572c4311Sfengbojiang }
315*572c4311Sfengbojiang
mp_encode_map(lua_State * L,mp_buf * buf,int64_t n)316*572c4311Sfengbojiang void mp_encode_map(lua_State *L, mp_buf *buf, int64_t n) {
317*572c4311Sfengbojiang unsigned char b[5];
318*572c4311Sfengbojiang int enclen;
319*572c4311Sfengbojiang
320*572c4311Sfengbojiang if (n <= 15) {
321*572c4311Sfengbojiang b[0] = 0x80 | (n & 0xf); /* fix map */
322*572c4311Sfengbojiang enclen = 1;
323*572c4311Sfengbojiang } else if (n <= 65535) {
324*572c4311Sfengbojiang b[0] = 0xde; /* map 16 */
325*572c4311Sfengbojiang b[1] = (n & 0xff00) >> 8;
326*572c4311Sfengbojiang b[2] = n & 0xff;
327*572c4311Sfengbojiang enclen = 3;
328*572c4311Sfengbojiang } else {
329*572c4311Sfengbojiang b[0] = 0xdf; /* map 32 */
330*572c4311Sfengbojiang b[1] = (n & 0xff000000) >> 24;
331*572c4311Sfengbojiang b[2] = (n & 0xff0000) >> 16;
332*572c4311Sfengbojiang b[3] = (n & 0xff00) >> 8;
333*572c4311Sfengbojiang b[4] = n & 0xff;
334*572c4311Sfengbojiang enclen = 5;
335*572c4311Sfengbojiang }
336*572c4311Sfengbojiang mp_buf_append(L,buf,b,enclen);
337*572c4311Sfengbojiang }
338*572c4311Sfengbojiang
339*572c4311Sfengbojiang /* --------------------------- Lua types encoding --------------------------- */
340*572c4311Sfengbojiang
mp_encode_lua_string(lua_State * L,mp_buf * buf)341*572c4311Sfengbojiang void mp_encode_lua_string(lua_State *L, mp_buf *buf) {
342*572c4311Sfengbojiang size_t len;
343*572c4311Sfengbojiang const char *s;
344*572c4311Sfengbojiang
345*572c4311Sfengbojiang s = lua_tolstring(L,-1,&len);
346*572c4311Sfengbojiang mp_encode_bytes(L,buf,(const unsigned char*)s,len);
347*572c4311Sfengbojiang }
348*572c4311Sfengbojiang
mp_encode_lua_bool(lua_State * L,mp_buf * buf)349*572c4311Sfengbojiang void mp_encode_lua_bool(lua_State *L, mp_buf *buf) {
350*572c4311Sfengbojiang unsigned char b = lua_toboolean(L,-1) ? 0xc3 : 0xc2;
351*572c4311Sfengbojiang mp_buf_append(L,buf,&b,1);
352*572c4311Sfengbojiang }
353*572c4311Sfengbojiang
354*572c4311Sfengbojiang /* Lua 5.3 has a built in 64-bit integer type */
mp_encode_lua_integer(lua_State * L,mp_buf * buf)355*572c4311Sfengbojiang void mp_encode_lua_integer(lua_State *L, mp_buf *buf) {
356*572c4311Sfengbojiang #if (LUA_VERSION_NUM < 503) && BITS_32
357*572c4311Sfengbojiang lua_Number i = lua_tonumber(L,-1);
358*572c4311Sfengbojiang #else
359*572c4311Sfengbojiang lua_Integer i = lua_tointeger(L,-1);
360*572c4311Sfengbojiang #endif
361*572c4311Sfengbojiang mp_encode_int(L, buf, (int64_t)i);
362*572c4311Sfengbojiang }
363*572c4311Sfengbojiang
364*572c4311Sfengbojiang /* Lua 5.2 and lower only has 64-bit doubles, so we need to
365*572c4311Sfengbojiang * detect if the double may be representable as an int
366*572c4311Sfengbojiang * for Lua < 5.3 */
mp_encode_lua_number(lua_State * L,mp_buf * buf)367*572c4311Sfengbojiang void mp_encode_lua_number(lua_State *L, mp_buf *buf) {
368*572c4311Sfengbojiang lua_Number n = lua_tonumber(L,-1);
369*572c4311Sfengbojiang
370*572c4311Sfengbojiang if (IS_INT64_EQUIVALENT(n)) {
371*572c4311Sfengbojiang mp_encode_lua_integer(L, buf);
372*572c4311Sfengbojiang } else {
373*572c4311Sfengbojiang mp_encode_double(L,buf,(double)n);
374*572c4311Sfengbojiang }
375*572c4311Sfengbojiang }
376*572c4311Sfengbojiang
377*572c4311Sfengbojiang void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level);
378*572c4311Sfengbojiang
379*572c4311Sfengbojiang /* Convert a lua table into a message pack list. */
mp_encode_lua_table_as_array(lua_State * L,mp_buf * buf,int level)380*572c4311Sfengbojiang void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) {
381*572c4311Sfengbojiang #if LUA_VERSION_NUM < 502
382*572c4311Sfengbojiang size_t len = lua_objlen(L,-1), j;
383*572c4311Sfengbojiang #else
384*572c4311Sfengbojiang size_t len = lua_rawlen(L,-1), j;
385*572c4311Sfengbojiang #endif
386*572c4311Sfengbojiang
387*572c4311Sfengbojiang mp_encode_array(L,buf,len);
388*572c4311Sfengbojiang luaL_checkstack(L, 1, "in function mp_encode_lua_table_as_array");
389*572c4311Sfengbojiang for (j = 1; j <= len; j++) {
390*572c4311Sfengbojiang lua_pushnumber(L,j);
391*572c4311Sfengbojiang lua_gettable(L,-2);
392*572c4311Sfengbojiang mp_encode_lua_type(L,buf,level+1);
393*572c4311Sfengbojiang }
394*572c4311Sfengbojiang }
395*572c4311Sfengbojiang
396*572c4311Sfengbojiang /* Convert a lua table into a message pack key-value map. */
mp_encode_lua_table_as_map(lua_State * L,mp_buf * buf,int level)397*572c4311Sfengbojiang void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) {
398*572c4311Sfengbojiang size_t len = 0;
399*572c4311Sfengbojiang
400*572c4311Sfengbojiang /* First step: count keys into table. No other way to do it with the
401*572c4311Sfengbojiang * Lua API, we need to iterate a first time. Note that an alternative
402*572c4311Sfengbojiang * would be to do a single run, and then hack the buffer to insert the
403*572c4311Sfengbojiang * map opcodes for message pack. Too hackish for this lib. */
404*572c4311Sfengbojiang luaL_checkstack(L, 3, "in function mp_encode_lua_table_as_map");
405*572c4311Sfengbojiang lua_pushnil(L);
406*572c4311Sfengbojiang while(lua_next(L,-2)) {
407*572c4311Sfengbojiang lua_pop(L,1); /* remove value, keep key for next iteration. */
408*572c4311Sfengbojiang len++;
409*572c4311Sfengbojiang }
410*572c4311Sfengbojiang
411*572c4311Sfengbojiang /* Step two: actually encoding of the map. */
412*572c4311Sfengbojiang mp_encode_map(L,buf,len);
413*572c4311Sfengbojiang lua_pushnil(L);
414*572c4311Sfengbojiang while(lua_next(L,-2)) {
415*572c4311Sfengbojiang /* Stack: ... key value */
416*572c4311Sfengbojiang lua_pushvalue(L,-2); /* Stack: ... key value key */
417*572c4311Sfengbojiang mp_encode_lua_type(L,buf,level+1); /* encode key */
418*572c4311Sfengbojiang mp_encode_lua_type(L,buf,level+1); /* encode val */
419*572c4311Sfengbojiang }
420*572c4311Sfengbojiang }
421*572c4311Sfengbojiang
422*572c4311Sfengbojiang /* Returns true if the Lua table on top of the stack is exclusively composed
423*572c4311Sfengbojiang * of keys from numerical keys from 1 up to N, with N being the total number
424*572c4311Sfengbojiang * of elements, without any hole in the middle. */
table_is_an_array(lua_State * L)425*572c4311Sfengbojiang int table_is_an_array(lua_State *L) {
426*572c4311Sfengbojiang int count = 0, max = 0;
427*572c4311Sfengbojiang #if LUA_VERSION_NUM < 503
428*572c4311Sfengbojiang lua_Number n;
429*572c4311Sfengbojiang #else
430*572c4311Sfengbojiang lua_Integer n;
431*572c4311Sfengbojiang #endif
432*572c4311Sfengbojiang
433*572c4311Sfengbojiang /* Stack top on function entry */
434*572c4311Sfengbojiang int stacktop;
435*572c4311Sfengbojiang
436*572c4311Sfengbojiang stacktop = lua_gettop(L);
437*572c4311Sfengbojiang
438*572c4311Sfengbojiang lua_pushnil(L);
439*572c4311Sfengbojiang while(lua_next(L,-2)) {
440*572c4311Sfengbojiang /* Stack: ... key value */
441*572c4311Sfengbojiang lua_pop(L,1); /* Stack: ... key */
442*572c4311Sfengbojiang /* The <= 0 check is valid here because we're comparing indexes. */
443*572c4311Sfengbojiang #if LUA_VERSION_NUM < 503
444*572c4311Sfengbojiang if ((LUA_TNUMBER != lua_type(L,-1)) || (n = lua_tonumber(L, -1)) <= 0 ||
445*572c4311Sfengbojiang !IS_INT_EQUIVALENT(n))
446*572c4311Sfengbojiang #else
447*572c4311Sfengbojiang if (!lua_isinteger(L,-1) || (n = lua_tointeger(L, -1)) <= 0)
448*572c4311Sfengbojiang #endif
449*572c4311Sfengbojiang {
450*572c4311Sfengbojiang lua_settop(L, stacktop);
451*572c4311Sfengbojiang return 0;
452*572c4311Sfengbojiang }
453*572c4311Sfengbojiang max = (n > max ? n : max);
454*572c4311Sfengbojiang count++;
455*572c4311Sfengbojiang }
456*572c4311Sfengbojiang /* We have the total number of elements in "count". Also we have
457*572c4311Sfengbojiang * the max index encountered in "max". We can't reach this code
458*572c4311Sfengbojiang * if there are indexes <= 0. If you also note that there can not be
459*572c4311Sfengbojiang * repeated keys into a table, you have that if max==count you are sure
460*572c4311Sfengbojiang * that there are all the keys form 1 to count (both included). */
461*572c4311Sfengbojiang lua_settop(L, stacktop);
462*572c4311Sfengbojiang return max == count;
463*572c4311Sfengbojiang }
464*572c4311Sfengbojiang
465*572c4311Sfengbojiang /* If the length operator returns non-zero, that is, there is at least
466*572c4311Sfengbojiang * an object at key '1', we serialize to message pack list. Otherwise
467*572c4311Sfengbojiang * we use a map. */
mp_encode_lua_table(lua_State * L,mp_buf * buf,int level)468*572c4311Sfengbojiang void mp_encode_lua_table(lua_State *L, mp_buf *buf, int level) {
469*572c4311Sfengbojiang if (table_is_an_array(L))
470*572c4311Sfengbojiang mp_encode_lua_table_as_array(L,buf,level);
471*572c4311Sfengbojiang else
472*572c4311Sfengbojiang mp_encode_lua_table_as_map(L,buf,level);
473*572c4311Sfengbojiang }
474*572c4311Sfengbojiang
mp_encode_lua_null(lua_State * L,mp_buf * buf)475*572c4311Sfengbojiang void mp_encode_lua_null(lua_State *L, mp_buf *buf) {
476*572c4311Sfengbojiang unsigned char b[1];
477*572c4311Sfengbojiang
478*572c4311Sfengbojiang b[0] = 0xc0;
479*572c4311Sfengbojiang mp_buf_append(L,buf,b,1);
480*572c4311Sfengbojiang }
481*572c4311Sfengbojiang
mp_encode_lua_type(lua_State * L,mp_buf * buf,int level)482*572c4311Sfengbojiang void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level) {
483*572c4311Sfengbojiang int t = lua_type(L,-1);
484*572c4311Sfengbojiang
485*572c4311Sfengbojiang /* Limit the encoding of nested tables to a specified maximum depth, so that
486*572c4311Sfengbojiang * we survive when called against circular references in tables. */
487*572c4311Sfengbojiang if (t == LUA_TTABLE && level == LUACMSGPACK_MAX_NESTING) t = LUA_TNIL;
488*572c4311Sfengbojiang switch(t) {
489*572c4311Sfengbojiang case LUA_TSTRING: mp_encode_lua_string(L,buf); break;
490*572c4311Sfengbojiang case LUA_TBOOLEAN: mp_encode_lua_bool(L,buf); break;
491*572c4311Sfengbojiang case LUA_TNUMBER:
492*572c4311Sfengbojiang #if LUA_VERSION_NUM < 503
493*572c4311Sfengbojiang mp_encode_lua_number(L,buf); break;
494*572c4311Sfengbojiang #else
495*572c4311Sfengbojiang if (lua_isinteger(L, -1)) {
496*572c4311Sfengbojiang mp_encode_lua_integer(L, buf);
497*572c4311Sfengbojiang } else {
498*572c4311Sfengbojiang mp_encode_lua_number(L, buf);
499*572c4311Sfengbojiang }
500*572c4311Sfengbojiang break;
501*572c4311Sfengbojiang #endif
502*572c4311Sfengbojiang case LUA_TTABLE: mp_encode_lua_table(L,buf,level); break;
503*572c4311Sfengbojiang default: mp_encode_lua_null(L,buf); break;
504*572c4311Sfengbojiang }
505*572c4311Sfengbojiang lua_pop(L,1);
506*572c4311Sfengbojiang }
507*572c4311Sfengbojiang
508*572c4311Sfengbojiang /*
509*572c4311Sfengbojiang * Packs all arguments as a stream for multiple upacking later.
510*572c4311Sfengbojiang * Returns error if no arguments provided.
511*572c4311Sfengbojiang */
mp_pack(lua_State * L)512*572c4311Sfengbojiang int mp_pack(lua_State *L) {
513*572c4311Sfengbojiang int nargs = lua_gettop(L);
514*572c4311Sfengbojiang int i;
515*572c4311Sfengbojiang mp_buf *buf;
516*572c4311Sfengbojiang
517*572c4311Sfengbojiang if (nargs == 0)
518*572c4311Sfengbojiang return luaL_argerror(L, 0, "MessagePack pack needs input.");
519*572c4311Sfengbojiang
520*572c4311Sfengbojiang if (!lua_checkstack(L, nargs))
521*572c4311Sfengbojiang return luaL_argerror(L, 0, "Too many arguments for MessagePack pack.");
522*572c4311Sfengbojiang
523*572c4311Sfengbojiang buf = mp_buf_new(L);
524*572c4311Sfengbojiang for(i = 1; i <= nargs; i++) {
525*572c4311Sfengbojiang /* Copy argument i to top of stack for _encode processing;
526*572c4311Sfengbojiang * the encode function pops it from the stack when complete. */
527*572c4311Sfengbojiang luaL_checkstack(L, 1, "in function mp_check");
528*572c4311Sfengbojiang lua_pushvalue(L, i);
529*572c4311Sfengbojiang
530*572c4311Sfengbojiang mp_encode_lua_type(L,buf,0);
531*572c4311Sfengbojiang
532*572c4311Sfengbojiang lua_pushlstring(L,(char*)buf->b,buf->len);
533*572c4311Sfengbojiang
534*572c4311Sfengbojiang /* Reuse the buffer for the next operation by
535*572c4311Sfengbojiang * setting its free count to the total buffer size
536*572c4311Sfengbojiang * and the current position to zero. */
537*572c4311Sfengbojiang buf->free += buf->len;
538*572c4311Sfengbojiang buf->len = 0;
539*572c4311Sfengbojiang }
540*572c4311Sfengbojiang mp_buf_free(L, buf);
541*572c4311Sfengbojiang
542*572c4311Sfengbojiang /* Concatenate all nargs buffers together */
543*572c4311Sfengbojiang lua_concat(L, nargs);
544*572c4311Sfengbojiang return 1;
545*572c4311Sfengbojiang }
546*572c4311Sfengbojiang
547*572c4311Sfengbojiang /* ------------------------------- Decoding --------------------------------- */
548*572c4311Sfengbojiang
549*572c4311Sfengbojiang void mp_decode_to_lua_type(lua_State *L, mp_cur *c);
550*572c4311Sfengbojiang
mp_decode_to_lua_array(lua_State * L,mp_cur * c,size_t len)551*572c4311Sfengbojiang void mp_decode_to_lua_array(lua_State *L, mp_cur *c, size_t len) {
552*572c4311Sfengbojiang assert(len <= UINT_MAX);
553*572c4311Sfengbojiang int index = 1;
554*572c4311Sfengbojiang
555*572c4311Sfengbojiang lua_newtable(L);
556*572c4311Sfengbojiang luaL_checkstack(L, 1, "in function mp_decode_to_lua_array");
557*572c4311Sfengbojiang while(len--) {
558*572c4311Sfengbojiang lua_pushnumber(L,index++);
559*572c4311Sfengbojiang mp_decode_to_lua_type(L,c);
560*572c4311Sfengbojiang if (c->err) return;
561*572c4311Sfengbojiang lua_settable(L,-3);
562*572c4311Sfengbojiang }
563*572c4311Sfengbojiang }
564*572c4311Sfengbojiang
mp_decode_to_lua_hash(lua_State * L,mp_cur * c,size_t len)565*572c4311Sfengbojiang void mp_decode_to_lua_hash(lua_State *L, mp_cur *c, size_t len) {
566*572c4311Sfengbojiang assert(len <= UINT_MAX);
567*572c4311Sfengbojiang lua_newtable(L);
568*572c4311Sfengbojiang while(len--) {
569*572c4311Sfengbojiang mp_decode_to_lua_type(L,c); /* key */
570*572c4311Sfengbojiang if (c->err) return;
571*572c4311Sfengbojiang mp_decode_to_lua_type(L,c); /* value */
572*572c4311Sfengbojiang if (c->err) return;
573*572c4311Sfengbojiang lua_settable(L,-3);
574*572c4311Sfengbojiang }
575*572c4311Sfengbojiang }
576*572c4311Sfengbojiang
577*572c4311Sfengbojiang /* Decode a Message Pack raw object pointed by the string cursor 'c' to
578*572c4311Sfengbojiang * a Lua type, that is left as the only result on the stack. */
mp_decode_to_lua_type(lua_State * L,mp_cur * c)579*572c4311Sfengbojiang void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
580*572c4311Sfengbojiang mp_cur_need(c,1);
581*572c4311Sfengbojiang
582*572c4311Sfengbojiang /* If we return more than 18 elements, we must resize the stack to
583*572c4311Sfengbojiang * fit all our return values. But, there is no way to
584*572c4311Sfengbojiang * determine how many objects a msgpack will unpack to up front, so
585*572c4311Sfengbojiang * we request a +1 larger stack on each iteration (noop if stack is
586*572c4311Sfengbojiang * big enough, and when stack does require resize it doubles in size) */
587*572c4311Sfengbojiang luaL_checkstack(L, 1,
588*572c4311Sfengbojiang "too many return values at once; "
589*572c4311Sfengbojiang "use unpack_one or unpack_limit instead.");
590*572c4311Sfengbojiang
591*572c4311Sfengbojiang switch(c->p[0]) {
592*572c4311Sfengbojiang case 0xcc: /* uint 8 */
593*572c4311Sfengbojiang mp_cur_need(c,2);
594*572c4311Sfengbojiang lua_pushunsigned(L,c->p[1]);
595*572c4311Sfengbojiang mp_cur_consume(c,2);
596*572c4311Sfengbojiang break;
597*572c4311Sfengbojiang case 0xd0: /* int 8 */
598*572c4311Sfengbojiang mp_cur_need(c,2);
599*572c4311Sfengbojiang lua_pushinteger(L,(signed char)c->p[1]);
600*572c4311Sfengbojiang mp_cur_consume(c,2);
601*572c4311Sfengbojiang break;
602*572c4311Sfengbojiang case 0xcd: /* uint 16 */
603*572c4311Sfengbojiang mp_cur_need(c,3);
604*572c4311Sfengbojiang lua_pushunsigned(L,
605*572c4311Sfengbojiang (c->p[1] << 8) |
606*572c4311Sfengbojiang c->p[2]);
607*572c4311Sfengbojiang mp_cur_consume(c,3);
608*572c4311Sfengbojiang break;
609*572c4311Sfengbojiang case 0xd1: /* int 16 */
610*572c4311Sfengbojiang mp_cur_need(c,3);
611*572c4311Sfengbojiang lua_pushinteger(L,(int16_t)
612*572c4311Sfengbojiang (c->p[1] << 8) |
613*572c4311Sfengbojiang c->p[2]);
614*572c4311Sfengbojiang mp_cur_consume(c,3);
615*572c4311Sfengbojiang break;
616*572c4311Sfengbojiang case 0xce: /* uint 32 */
617*572c4311Sfengbojiang mp_cur_need(c,5);
618*572c4311Sfengbojiang lua_pushunsigned(L,
619*572c4311Sfengbojiang ((uint32_t)c->p[1] << 24) |
620*572c4311Sfengbojiang ((uint32_t)c->p[2] << 16) |
621*572c4311Sfengbojiang ((uint32_t)c->p[3] << 8) |
622*572c4311Sfengbojiang (uint32_t)c->p[4]);
623*572c4311Sfengbojiang mp_cur_consume(c,5);
624*572c4311Sfengbojiang break;
625*572c4311Sfengbojiang case 0xd2: /* int 32 */
626*572c4311Sfengbojiang mp_cur_need(c,5);
627*572c4311Sfengbojiang lua_pushinteger(L,
628*572c4311Sfengbojiang ((int32_t)c->p[1] << 24) |
629*572c4311Sfengbojiang ((int32_t)c->p[2] << 16) |
630*572c4311Sfengbojiang ((int32_t)c->p[3] << 8) |
631*572c4311Sfengbojiang (int32_t)c->p[4]);
632*572c4311Sfengbojiang mp_cur_consume(c,5);
633*572c4311Sfengbojiang break;
634*572c4311Sfengbojiang case 0xcf: /* uint 64 */
635*572c4311Sfengbojiang mp_cur_need(c,9);
636*572c4311Sfengbojiang lua_pushunsigned(L,
637*572c4311Sfengbojiang ((uint64_t)c->p[1] << 56) |
638*572c4311Sfengbojiang ((uint64_t)c->p[2] << 48) |
639*572c4311Sfengbojiang ((uint64_t)c->p[3] << 40) |
640*572c4311Sfengbojiang ((uint64_t)c->p[4] << 32) |
641*572c4311Sfengbojiang ((uint64_t)c->p[5] << 24) |
642*572c4311Sfengbojiang ((uint64_t)c->p[6] << 16) |
643*572c4311Sfengbojiang ((uint64_t)c->p[7] << 8) |
644*572c4311Sfengbojiang (uint64_t)c->p[8]);
645*572c4311Sfengbojiang mp_cur_consume(c,9);
646*572c4311Sfengbojiang break;
647*572c4311Sfengbojiang case 0xd3: /* int 64 */
648*572c4311Sfengbojiang mp_cur_need(c,9);
649*572c4311Sfengbojiang #if LUA_VERSION_NUM < 503
650*572c4311Sfengbojiang lua_pushnumber(L,
651*572c4311Sfengbojiang #else
652*572c4311Sfengbojiang lua_pushinteger(L,
653*572c4311Sfengbojiang #endif
654*572c4311Sfengbojiang ((int64_t)c->p[1] << 56) |
655*572c4311Sfengbojiang ((int64_t)c->p[2] << 48) |
656*572c4311Sfengbojiang ((int64_t)c->p[3] << 40) |
657*572c4311Sfengbojiang ((int64_t)c->p[4] << 32) |
658*572c4311Sfengbojiang ((int64_t)c->p[5] << 24) |
659*572c4311Sfengbojiang ((int64_t)c->p[6] << 16) |
660*572c4311Sfengbojiang ((int64_t)c->p[7] << 8) |
661*572c4311Sfengbojiang (int64_t)c->p[8]);
662*572c4311Sfengbojiang mp_cur_consume(c,9);
663*572c4311Sfengbojiang break;
664*572c4311Sfengbojiang case 0xc0: /* nil */
665*572c4311Sfengbojiang lua_pushnil(L);
666*572c4311Sfengbojiang mp_cur_consume(c,1);
667*572c4311Sfengbojiang break;
668*572c4311Sfengbojiang case 0xc3: /* true */
669*572c4311Sfengbojiang lua_pushboolean(L,1);
670*572c4311Sfengbojiang mp_cur_consume(c,1);
671*572c4311Sfengbojiang break;
672*572c4311Sfengbojiang case 0xc2: /* false */
673*572c4311Sfengbojiang lua_pushboolean(L,0);
674*572c4311Sfengbojiang mp_cur_consume(c,1);
675*572c4311Sfengbojiang break;
676*572c4311Sfengbojiang case 0xca: /* float */
677*572c4311Sfengbojiang mp_cur_need(c,5);
678*572c4311Sfengbojiang assert(sizeof(float) == 4);
679*572c4311Sfengbojiang {
680*572c4311Sfengbojiang float f;
681*572c4311Sfengbojiang memcpy(&f,c->p+1,4);
682*572c4311Sfengbojiang memrevifle(&f,4);
683*572c4311Sfengbojiang lua_pushnumber(L,f);
684*572c4311Sfengbojiang mp_cur_consume(c,5);
685*572c4311Sfengbojiang }
686*572c4311Sfengbojiang break;
687*572c4311Sfengbojiang case 0xcb: /* double */
688*572c4311Sfengbojiang mp_cur_need(c,9);
689*572c4311Sfengbojiang assert(sizeof(double) == 8);
690*572c4311Sfengbojiang {
691*572c4311Sfengbojiang double d;
692*572c4311Sfengbojiang memcpy(&d,c->p+1,8);
693*572c4311Sfengbojiang memrevifle(&d,8);
694*572c4311Sfengbojiang lua_pushnumber(L,d);
695*572c4311Sfengbojiang mp_cur_consume(c,9);
696*572c4311Sfengbojiang }
697*572c4311Sfengbojiang break;
698*572c4311Sfengbojiang case 0xd9: /* raw 8 */
699*572c4311Sfengbojiang mp_cur_need(c,2);
700*572c4311Sfengbojiang {
701*572c4311Sfengbojiang size_t l = c->p[1];
702*572c4311Sfengbojiang mp_cur_need(c,2+l);
703*572c4311Sfengbojiang lua_pushlstring(L,(char*)c->p+2,l);
704*572c4311Sfengbojiang mp_cur_consume(c,2+l);
705*572c4311Sfengbojiang }
706*572c4311Sfengbojiang break;
707*572c4311Sfengbojiang case 0xda: /* raw 16 */
708*572c4311Sfengbojiang mp_cur_need(c,3);
709*572c4311Sfengbojiang {
710*572c4311Sfengbojiang size_t l = (c->p[1] << 8) | c->p[2];
711*572c4311Sfengbojiang mp_cur_need(c,3+l);
712*572c4311Sfengbojiang lua_pushlstring(L,(char*)c->p+3,l);
713*572c4311Sfengbojiang mp_cur_consume(c,3+l);
714*572c4311Sfengbojiang }
715*572c4311Sfengbojiang break;
716*572c4311Sfengbojiang case 0xdb: /* raw 32 */
717*572c4311Sfengbojiang mp_cur_need(c,5);
718*572c4311Sfengbojiang {
719*572c4311Sfengbojiang size_t l = ((size_t)c->p[1] << 24) |
720*572c4311Sfengbojiang ((size_t)c->p[2] << 16) |
721*572c4311Sfengbojiang ((size_t)c->p[3] << 8) |
722*572c4311Sfengbojiang (size_t)c->p[4];
723*572c4311Sfengbojiang mp_cur_consume(c,5);
724*572c4311Sfengbojiang mp_cur_need(c,l);
725*572c4311Sfengbojiang lua_pushlstring(L,(char*)c->p,l);
726*572c4311Sfengbojiang mp_cur_consume(c,l);
727*572c4311Sfengbojiang }
728*572c4311Sfengbojiang break;
729*572c4311Sfengbojiang case 0xdc: /* array 16 */
730*572c4311Sfengbojiang mp_cur_need(c,3);
731*572c4311Sfengbojiang {
732*572c4311Sfengbojiang size_t l = (c->p[1] << 8) | c->p[2];
733*572c4311Sfengbojiang mp_cur_consume(c,3);
734*572c4311Sfengbojiang mp_decode_to_lua_array(L,c,l);
735*572c4311Sfengbojiang }
736*572c4311Sfengbojiang break;
737*572c4311Sfengbojiang case 0xdd: /* array 32 */
738*572c4311Sfengbojiang mp_cur_need(c,5);
739*572c4311Sfengbojiang {
740*572c4311Sfengbojiang size_t l = ((size_t)c->p[1] << 24) |
741*572c4311Sfengbojiang ((size_t)c->p[2] << 16) |
742*572c4311Sfengbojiang ((size_t)c->p[3] << 8) |
743*572c4311Sfengbojiang (size_t)c->p[4];
744*572c4311Sfengbojiang mp_cur_consume(c,5);
745*572c4311Sfengbojiang mp_decode_to_lua_array(L,c,l);
746*572c4311Sfengbojiang }
747*572c4311Sfengbojiang break;
748*572c4311Sfengbojiang case 0xde: /* map 16 */
749*572c4311Sfengbojiang mp_cur_need(c,3);
750*572c4311Sfengbojiang {
751*572c4311Sfengbojiang size_t l = (c->p[1] << 8) | c->p[2];
752*572c4311Sfengbojiang mp_cur_consume(c,3);
753*572c4311Sfengbojiang mp_decode_to_lua_hash(L,c,l);
754*572c4311Sfengbojiang }
755*572c4311Sfengbojiang break;
756*572c4311Sfengbojiang case 0xdf: /* map 32 */
757*572c4311Sfengbojiang mp_cur_need(c,5);
758*572c4311Sfengbojiang {
759*572c4311Sfengbojiang size_t l = ((size_t)c->p[1] << 24) |
760*572c4311Sfengbojiang ((size_t)c->p[2] << 16) |
761*572c4311Sfengbojiang ((size_t)c->p[3] << 8) |
762*572c4311Sfengbojiang (size_t)c->p[4];
763*572c4311Sfengbojiang mp_cur_consume(c,5);
764*572c4311Sfengbojiang mp_decode_to_lua_hash(L,c,l);
765*572c4311Sfengbojiang }
766*572c4311Sfengbojiang break;
767*572c4311Sfengbojiang default: /* types that can't be idenitified by first byte value. */
768*572c4311Sfengbojiang if ((c->p[0] & 0x80) == 0) { /* positive fixnum */
769*572c4311Sfengbojiang lua_pushunsigned(L,c->p[0]);
770*572c4311Sfengbojiang mp_cur_consume(c,1);
771*572c4311Sfengbojiang } else if ((c->p[0] & 0xe0) == 0xe0) { /* negative fixnum */
772*572c4311Sfengbojiang lua_pushinteger(L,(signed char)c->p[0]);
773*572c4311Sfengbojiang mp_cur_consume(c,1);
774*572c4311Sfengbojiang } else if ((c->p[0] & 0xe0) == 0xa0) { /* fix raw */
775*572c4311Sfengbojiang size_t l = c->p[0] & 0x1f;
776*572c4311Sfengbojiang mp_cur_need(c,1+l);
777*572c4311Sfengbojiang lua_pushlstring(L,(char*)c->p+1,l);
778*572c4311Sfengbojiang mp_cur_consume(c,1+l);
779*572c4311Sfengbojiang } else if ((c->p[0] & 0xf0) == 0x90) { /* fix map */
780*572c4311Sfengbojiang size_t l = c->p[0] & 0xf;
781*572c4311Sfengbojiang mp_cur_consume(c,1);
782*572c4311Sfengbojiang mp_decode_to_lua_array(L,c,l);
783*572c4311Sfengbojiang } else if ((c->p[0] & 0xf0) == 0x80) { /* fix map */
784*572c4311Sfengbojiang size_t l = c->p[0] & 0xf;
785*572c4311Sfengbojiang mp_cur_consume(c,1);
786*572c4311Sfengbojiang mp_decode_to_lua_hash(L,c,l);
787*572c4311Sfengbojiang } else {
788*572c4311Sfengbojiang c->err = MP_CUR_ERROR_BADFMT;
789*572c4311Sfengbojiang }
790*572c4311Sfengbojiang }
791*572c4311Sfengbojiang }
792*572c4311Sfengbojiang
mp_unpack_full(lua_State * L,int limit,int offset)793*572c4311Sfengbojiang int mp_unpack_full(lua_State *L, int limit, int offset) {
794*572c4311Sfengbojiang size_t len;
795*572c4311Sfengbojiang const char *s;
796*572c4311Sfengbojiang mp_cur c;
797*572c4311Sfengbojiang int cnt; /* Number of objects unpacked */
798*572c4311Sfengbojiang int decode_all = (!limit && !offset);
799*572c4311Sfengbojiang
800*572c4311Sfengbojiang s = luaL_checklstring(L,1,&len); /* if no match, exits */
801*572c4311Sfengbojiang
802*572c4311Sfengbojiang if (offset < 0 || limit < 0) /* requesting negative off or lim is invalid */
803*572c4311Sfengbojiang return luaL_error(L,
804*572c4311Sfengbojiang "Invalid request to unpack with offset of %d and limit of %d.",
805*572c4311Sfengbojiang offset, len);
806*572c4311Sfengbojiang else if (offset > len)
807*572c4311Sfengbojiang return luaL_error(L,
808*572c4311Sfengbojiang "Start offset %d greater than input length %d.", offset, len);
809*572c4311Sfengbojiang
810*572c4311Sfengbojiang if (decode_all) limit = INT_MAX;
811*572c4311Sfengbojiang
812*572c4311Sfengbojiang mp_cur_init(&c,(const unsigned char *)s+offset,len-offset);
813*572c4311Sfengbojiang
814*572c4311Sfengbojiang /* We loop over the decode because this could be a stream
815*572c4311Sfengbojiang * of multiple top-level values serialized together */
816*572c4311Sfengbojiang for(cnt = 0; c.left > 0 && cnt < limit; cnt++) {
817*572c4311Sfengbojiang mp_decode_to_lua_type(L,&c);
818*572c4311Sfengbojiang
819*572c4311Sfengbojiang if (c.err == MP_CUR_ERROR_EOF) {
820*572c4311Sfengbojiang return luaL_error(L,"Missing bytes in input.");
821*572c4311Sfengbojiang } else if (c.err == MP_CUR_ERROR_BADFMT) {
822*572c4311Sfengbojiang return luaL_error(L,"Bad data format in input.");
823*572c4311Sfengbojiang }
824*572c4311Sfengbojiang }
825*572c4311Sfengbojiang
826*572c4311Sfengbojiang if (!decode_all) {
827*572c4311Sfengbojiang /* c->left is the remaining size of the input buffer.
828*572c4311Sfengbojiang * subtract the entire buffer size from the unprocessed size
829*572c4311Sfengbojiang * to get our next start offset */
830*572c4311Sfengbojiang int offset = len - c.left;
831*572c4311Sfengbojiang
832*572c4311Sfengbojiang luaL_checkstack(L, 1, "in function mp_unpack_full");
833*572c4311Sfengbojiang
834*572c4311Sfengbojiang /* Return offset -1 when we have have processed the entire buffer. */
835*572c4311Sfengbojiang lua_pushinteger(L, c.left == 0 ? -1 : offset);
836*572c4311Sfengbojiang /* Results are returned with the arg elements still
837*572c4311Sfengbojiang * in place. Lua takes care of only returning
838*572c4311Sfengbojiang * elements above the args for us.
839*572c4311Sfengbojiang * In this case, we have one arg on the stack
840*572c4311Sfengbojiang * for this function, so we insert our first return
841*572c4311Sfengbojiang * value at position 2. */
842*572c4311Sfengbojiang lua_insert(L, 2);
843*572c4311Sfengbojiang cnt += 1; /* increase return count by one to make room for offset */
844*572c4311Sfengbojiang }
845*572c4311Sfengbojiang
846*572c4311Sfengbojiang return cnt;
847*572c4311Sfengbojiang }
848*572c4311Sfengbojiang
mp_unpack(lua_State * L)849*572c4311Sfengbojiang int mp_unpack(lua_State *L) {
850*572c4311Sfengbojiang return mp_unpack_full(L, 0, 0);
851*572c4311Sfengbojiang }
852*572c4311Sfengbojiang
mp_unpack_one(lua_State * L)853*572c4311Sfengbojiang int mp_unpack_one(lua_State *L) {
854*572c4311Sfengbojiang int offset = luaL_optinteger(L, 2, 0);
855*572c4311Sfengbojiang /* Variable pop because offset may not exist */
856*572c4311Sfengbojiang lua_pop(L, lua_gettop(L)-1);
857*572c4311Sfengbojiang return mp_unpack_full(L, 1, offset);
858*572c4311Sfengbojiang }
859*572c4311Sfengbojiang
mp_unpack_limit(lua_State * L)860*572c4311Sfengbojiang int mp_unpack_limit(lua_State *L) {
861*572c4311Sfengbojiang int limit = luaL_checkinteger(L, 2);
862*572c4311Sfengbojiang int offset = luaL_optinteger(L, 3, 0);
863*572c4311Sfengbojiang /* Variable pop because offset may not exist */
864*572c4311Sfengbojiang lua_pop(L, lua_gettop(L)-1);
865*572c4311Sfengbojiang
866*572c4311Sfengbojiang return mp_unpack_full(L, limit, offset);
867*572c4311Sfengbojiang }
868*572c4311Sfengbojiang
mp_safe(lua_State * L)869*572c4311Sfengbojiang int mp_safe(lua_State *L) {
870*572c4311Sfengbojiang int argc, err, total_results;
871*572c4311Sfengbojiang
872*572c4311Sfengbojiang argc = lua_gettop(L);
873*572c4311Sfengbojiang
874*572c4311Sfengbojiang /* This adds our function to the bottom of the stack
875*572c4311Sfengbojiang * (the "call this function" position) */
876*572c4311Sfengbojiang lua_pushvalue(L, lua_upvalueindex(1));
877*572c4311Sfengbojiang lua_insert(L, 1);
878*572c4311Sfengbojiang
879*572c4311Sfengbojiang err = lua_pcall(L, argc, LUA_MULTRET, 0);
880*572c4311Sfengbojiang total_results = lua_gettop(L);
881*572c4311Sfengbojiang
882*572c4311Sfengbojiang if (!err) {
883*572c4311Sfengbojiang return total_results;
884*572c4311Sfengbojiang } else {
885*572c4311Sfengbojiang lua_pushnil(L);
886*572c4311Sfengbojiang lua_insert(L,-2);
887*572c4311Sfengbojiang return 2;
888*572c4311Sfengbojiang }
889*572c4311Sfengbojiang }
890*572c4311Sfengbojiang
891*572c4311Sfengbojiang /* -------------------------------------------------------------------------- */
892*572c4311Sfengbojiang const struct luaL_Reg cmds[] = {
893*572c4311Sfengbojiang {"pack", mp_pack},
894*572c4311Sfengbojiang {"unpack", mp_unpack},
895*572c4311Sfengbojiang {"unpack_one", mp_unpack_one},
896*572c4311Sfengbojiang {"unpack_limit", mp_unpack_limit},
897*572c4311Sfengbojiang {0}
898*572c4311Sfengbojiang };
899*572c4311Sfengbojiang
luaopen_create(lua_State * L)900*572c4311Sfengbojiang int luaopen_create(lua_State *L) {
901*572c4311Sfengbojiang int i;
902*572c4311Sfengbojiang /* Manually construct our module table instead of
903*572c4311Sfengbojiang * relying on _register or _newlib */
904*572c4311Sfengbojiang lua_newtable(L);
905*572c4311Sfengbojiang
906*572c4311Sfengbojiang for (i = 0; i < (sizeof(cmds)/sizeof(*cmds) - 1); i++) {
907*572c4311Sfengbojiang lua_pushcfunction(L, cmds[i].func);
908*572c4311Sfengbojiang lua_setfield(L, -2, cmds[i].name);
909*572c4311Sfengbojiang }
910*572c4311Sfengbojiang
911*572c4311Sfengbojiang /* Add metadata */
912*572c4311Sfengbojiang lua_pushliteral(L, LUACMSGPACK_NAME);
913*572c4311Sfengbojiang lua_setfield(L, -2, "_NAME");
914*572c4311Sfengbojiang lua_pushliteral(L, LUACMSGPACK_VERSION);
915*572c4311Sfengbojiang lua_setfield(L, -2, "_VERSION");
916*572c4311Sfengbojiang lua_pushliteral(L, LUACMSGPACK_COPYRIGHT);
917*572c4311Sfengbojiang lua_setfield(L, -2, "_COPYRIGHT");
918*572c4311Sfengbojiang lua_pushliteral(L, LUACMSGPACK_DESCRIPTION);
919*572c4311Sfengbojiang lua_setfield(L, -2, "_DESCRIPTION");
920*572c4311Sfengbojiang return 1;
921*572c4311Sfengbojiang }
922*572c4311Sfengbojiang
luaopen_cmsgpack(lua_State * L)923*572c4311Sfengbojiang LUALIB_API int luaopen_cmsgpack(lua_State *L) {
924*572c4311Sfengbojiang luaopen_create(L);
925*572c4311Sfengbojiang
926*572c4311Sfengbojiang #if LUA_VERSION_NUM < 502
927*572c4311Sfengbojiang /* Register name globally for 5.1 */
928*572c4311Sfengbojiang lua_pushvalue(L, -1);
929*572c4311Sfengbojiang lua_setglobal(L, LUACMSGPACK_NAME);
930*572c4311Sfengbojiang #endif
931*572c4311Sfengbojiang
932*572c4311Sfengbojiang return 1;
933*572c4311Sfengbojiang }
934*572c4311Sfengbojiang
luaopen_cmsgpack_safe(lua_State * L)935*572c4311Sfengbojiang LUALIB_API int luaopen_cmsgpack_safe(lua_State *L) {
936*572c4311Sfengbojiang int i;
937*572c4311Sfengbojiang
938*572c4311Sfengbojiang luaopen_cmsgpack(L);
939*572c4311Sfengbojiang
940*572c4311Sfengbojiang /* Wrap all functions in the safe handler */
941*572c4311Sfengbojiang for (i = 0; i < (sizeof(cmds)/sizeof(*cmds) - 1); i++) {
942*572c4311Sfengbojiang lua_getfield(L, -1, cmds[i].name);
943*572c4311Sfengbojiang lua_pushcclosure(L, mp_safe, 1);
944*572c4311Sfengbojiang lua_setfield(L, -2, cmds[i].name);
945*572c4311Sfengbojiang }
946*572c4311Sfengbojiang
947*572c4311Sfengbojiang #if LUA_VERSION_NUM < 502
948*572c4311Sfengbojiang /* Register name globally for 5.1 */
949*572c4311Sfengbojiang lua_pushvalue(L, -1);
950*572c4311Sfengbojiang lua_setglobal(L, LUACMSGPACK_SAFE_NAME);
951*572c4311Sfengbojiang #endif
952*572c4311Sfengbojiang
953*572c4311Sfengbojiang return 1;
954*572c4311Sfengbojiang }
955*572c4311Sfengbojiang
956*572c4311Sfengbojiang /******************************************************************************
957*572c4311Sfengbojiang * Copyright (C) 2012 Salvatore Sanfilippo. All rights reserved.
958*572c4311Sfengbojiang *
959*572c4311Sfengbojiang * Permission is hereby granted, free of charge, to any person obtaining
960*572c4311Sfengbojiang * a copy of this software and associated documentation files (the
961*572c4311Sfengbojiang * "Software"), to deal in the Software without restriction, including
962*572c4311Sfengbojiang * without limitation the rights to use, copy, modify, merge, publish,
963*572c4311Sfengbojiang * distribute, sublicense, and/or sell copies of the Software, and to
964*572c4311Sfengbojiang * permit persons to whom the Software is furnished to do so, subject to
965*572c4311Sfengbojiang * the following conditions:
966*572c4311Sfengbojiang *
967*572c4311Sfengbojiang * The above copyright notice and this permission notice shall be
968*572c4311Sfengbojiang * included in all copies or substantial portions of the Software.
969*572c4311Sfengbojiang *
970*572c4311Sfengbojiang * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
971*572c4311Sfengbojiang * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
972*572c4311Sfengbojiang * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
973*572c4311Sfengbojiang * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
974*572c4311Sfengbojiang * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
975*572c4311Sfengbojiang * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
976*572c4311Sfengbojiang * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
977*572c4311Sfengbojiang ******************************************************************************/
978