History

add cmsgpack 0.3.0 from https://github.com/antirez/lua-cmsgpack

mischief committed 11 years ago

Commit b4455231 parent dcf74894 files · +734 −1Browse files

Showing the changes to src/lua_cmsgpack.c (1 of 4 files). Show all

Unified · Split

src/lua_cmsgpack.c+729−0
@@ -0,0 +1,729 @@
1+#include <math.h>
2+#include <stdlib.h>
3+#include <stdint.h>
4+#include <string.h>
5+#include <assert.h>
6+
7+#include "lua.h"
8+#include "lauxlib.h"
9+
10+#define LUACMSGPACK_VERSION "lua-cmsgpack 0.3.0"
11+#define LUACMSGPACK_COPYRIGHT "Copyright (C) 2012, Salvatore Sanfilippo"
12+#define LUACMSGPACK_DESCRIPTION "MessagePack C implementation for Lua"
13+
14+#define LUACMSGPACK_MAX_NESTING 16 /* Max tables nesting. */
15+
16+/* ==============================================================================
17+ * MessagePack implementation and bindings for Lua 5.1.
18+ * Copyright(C) 2012 Salvatore Sanfilippo <antirez@gmail.com>
19+ *
20+ * http://github.com/antirez/lua-cmsgpack
21+ *
22+ * For MessagePack specification check the following web site:
23+ * http://wiki.msgpack.org/display/MSGPACK/Format+specification
24+ *
25+ * See Copyright Notice at the end of this file.
26+ *
27+ * CHANGELOG:
28+ * 19-Feb-2012 (ver 0.1.0): Initial release.
29+ * 20-Feb-2012 (ver 0.2.0): Tables encoding improved.
30+ * 20-Feb-2012 (ver 0.2.1): Minor bug fixing.
31+ * 20-Feb-2012 (ver 0.3.0): Module renamed lua-cmsgpack (was lua-msgpack).
32+ * ============================================================================ */
33+
34+/* --------------------------- Endian conversion --------------------------------
35+ * We use it only for floats and doubles, all the other conversions are performed
36+ * in an endian independent fashion. So the only thing we need is a function
37+ * that swaps a binary string if the arch is little endian (and left it untouched
38+ * otherwise). */
39+
40+/* Reverse memory bytes if arch is little endian. Given the conceptual
41+ * simplicity of the Lua build system we prefer to check for endianess at runtime.
42+ * The performance difference should be acceptable. */
43+static void memrevifle(void *ptr, size_t len) {
44+ unsigned char *p = ptr, *e = p+len-1, aux;
45+ int test = 1;
46+ unsigned char *testp = (unsigned char*) &test;
47+
48+ if (testp[0] == 0) return; /* Big endian, nothign to do. */
49+ len /= 2;
50+ while(len--) {
51+ aux = *p;
52+ *p = *e;
53+ *e = aux;
54+ p++;
55+ e--;
56+ }
57+}
58+
59+/* ----------------------------- String buffer ----------------------------------
60+ * This is a simple implementation of string buffers. The only opereation
61+ * supported is creating empty buffers and appending bytes to it.
62+ * The string buffer uses 2x preallocation on every realloc for O(N) append
63+ * behavior. */
64+
65+typedef struct mp_buf {
66+ unsigned char *b;
67+ size_t len, free;
68+} mp_buf;
69+
70+static mp_buf *mp_buf_new(void) {
71+ mp_buf *buf = malloc(sizeof(*buf));
72+
73+ buf->b = NULL;
74+ buf->len = buf->free = 0;
75+ return buf;
76+}
77+
78+void mp_buf_append(mp_buf *buf, const unsigned char *s, size_t len) {
79+ if (buf->free < len) {
80+ size_t newlen = buf->len+len;
81+
82+ buf->b = realloc(buf->b,newlen*2);
83+ buf->free = newlen;
84+ }
85+ memcpy(buf->b+buf->len,s,len);
86+ buf->len += len;
87+ buf->free -= len;
88+}
89+
90+void mp_buf_free(mp_buf *buf) {
91+ free(buf->b);
92+ free(buf);
93+}
94+
95+/* ------------------------------ String cursor ----------------------------------
96+ * This simple data structure is used for parsing. Basically you create a cursor
97+ * using a string pointer and a length, then it is possible to access the
98+ * current string position with cursor->p, check the remaining length
99+ * in cursor->left, and finally consume more string using
100+ * mp_cur_consume(cursor,len), to advance 'p' and subtract 'left'.
101+ * An additional field cursor->error is set to zero on initialization and can
102+ * be used to report errors. */
103+
104+#define MP_CUR_ERROR_NONE 0
105+#define MP_CUR_ERROR_EOF 1 /* Not enough data to complete the opereation. */
106+#define MP_CUR_ERROR_BADFMT 2 /* Bad data format */
107+
108+typedef struct mp_cur {
109+ const unsigned char *p;
110+ size_t left;
111+ int err;
112+} mp_cur;
113+
114+static mp_cur *mp_cur_new(const unsigned char *s, size_t len) {
115+ mp_cur *cursor = malloc(sizeof(*cursor));
116+
117+ cursor->p = s;
118+ cursor->left = len;
119+ cursor->err = MP_CUR_ERROR_NONE;
120+ return cursor;
121+}
122+
123+static void mp_cur_free(mp_cur *cursor) {
124+ free(cursor);
125+}
126+
127+#define mp_cur_consume(_c,_len) do { _c->p += _len; _c->left -= _len; } while(0)
128+
129+/* When there is not enough room we set an error in the cursor and return, this
130+ * is very common across the code so we have a macro to make the code look
131+ * a bit simpler. */
132+#define mp_cur_need(_c,_len) do { \
133+ if (_c->left < _len) { \
134+ _c->err = MP_CUR_ERROR_EOF; \
135+ return; \
136+ } \
137+} while(0)
138+
139+/* --------------------------- Low level MP encoding -------------------------- */
140+
141+static void mp_encode_bytes(mp_buf *buf, const unsigned char *s, size_t len) {
142+ unsigned char hdr[5];
143+ int hdrlen;
144+
145+ if (len < 32) {
146+ hdr[0] = 0xa0 | (len&0xff); /* fix raw */
147+ hdrlen = 1;
148+ } else if (len <= 0xffff) {
149+ hdr[0] = 0xda;
150+ hdr[1] = (len&0xff00)>>8;
151+ hdr[2] = len&0xff;
152+ hdrlen = 3;
153+ } else {
154+ hdr[0] = 0xdb;
155+ hdr[1] = (len&0xff000000)>>24;
156+ hdr[2] = (len&0xff0000)>>16;
157+ hdr[3] = (len&0xff00)>>8;
158+ hdr[4] = len&0xff;
159+ hdrlen = 5;
160+ }
161+ mp_buf_append(buf,hdr,hdrlen);
162+ mp_buf_append(buf,s,len);
163+}
164+
165+/* we assume IEEE 754 internal format for single and double precision floats. */
166+static void mp_encode_double(mp_buf *buf, double d) {
167+ unsigned char b[9];
168+ float f = d;
169+
170+ assert(sizeof(f) == 4 && sizeof(d) == 8);
171+ if (d == (double)f) {
172+ b[0] = 0xca; /* float IEEE 754 */
173+ memcpy(b+1,&f,4);
174+ memrevifle(b+1,4);
175+ mp_buf_append(buf,b,5);
176+ } else if (sizeof(d) == 8) {
177+ b[0] = 0xcb; /* double IEEE 754 */
178+ memcpy(b+1,&d,8);
179+ memrevifle(b+1,8);
180+ mp_buf_append(buf,b,9);
181+ }
182+}
183+
184+static void mp_encode_int(mp_buf *buf, int64_t n) {
185+ unsigned char b[9];
186+ int enclen;
187+
188+ if (n >= 0) {
189+ if (n <= 127) {
190+ b[0] = n & 0x7f; /* positive fixnum */
191+ enclen = 1;
192+ } else if (n <= 0xff) {
193+ b[0] = 0xcc; /* uint 8 */
194+ b[1] = n & 0xff;
195+ enclen = 2;
196+ } else if (n <= 0xffff) {
197+ b[0] = 0xcd; /* uint 16 */
198+ b[1] = (n & 0xff00) >> 8;
199+ b[2] = n & 0xff;
200+ enclen = 3;
201+ } else if (n <= 0xffffffffLL) {
202+ b[0] = 0xce; /* uint 32 */
203+ b[1] = (n & 0xff000000) >> 24;
204+ b[2] = (n & 0xff0000) >> 16;
205+ b[3] = (n & 0xff00) >> 8;
206+ b[4] = n & 0xff;
207+ enclen = 5;
208+ } else {
209+ b[0] = 0xcf; /* uint 64 */
210+ b[1] = (n & 0xff00000000000000LL) >> 56;
211+ b[2] = (n & 0xff000000000000LL) >> 48;
212+ b[3] = (n & 0xff0000000000LL) >> 40;
213+ b[4] = (n & 0xff00000000LL) >> 32;
214+ b[5] = (n & 0xff000000) >> 24;
215+ b[6] = (n & 0xff0000) >> 16;
216+ b[7] = (n & 0xff00) >> 8;
217+ b[8] = n & 0xff;
218+ enclen = 9;
219+ }
220+ } else {
221+ if (n >= -32) {
222+ b[0] = ((char)n); /* negative fixnum */
223+ enclen = 1;
224+ } else if (n >= -128) {
225+ b[0] = 0xd0; /* int 8 */
226+ b[1] = n & 0xff;
227+ enclen = 2;
228+ } else if (n >= -32768) {
229+ b[0] = 0xd1; /* int 16 */
230+ b[1] = (n & 0xff00) >> 8;
231+ b[2] = n & 0xff;
232+ enclen = 3;
233+ } else if (n >= -2147483648LL) {
234+ b[0] = 0xd2; /* int 32 */
235+ b[1] = (n & 0xff000000) >> 24;
236+ b[2] = (n & 0xff0000) >> 16;
237+ b[3] = (n & 0xff00) >> 8;
238+ b[4] = n & 0xff;
239+ enclen = 5;
240+ } else {
241+ b[0] = 0xd3; /* int 64 */
242+ b[1] = (n & 0xff00000000000000LL) >> 56;
243+ b[2] = (n & 0xff000000000000LL) >> 48;
244+ b[3] = (n & 0xff0000000000LL) >> 40;
245+ b[4] = (n & 0xff00000000LL) >> 32;
246+ b[5] = (n & 0xff000000) >> 24;
247+ b[6] = (n & 0xff0000) >> 16;
248+ b[7] = (n & 0xff00) >> 8;
249+ b[8] = n & 0xff;
250+ enclen = 9;
251+ }
252+ }
253+ mp_buf_append(buf,b,enclen);
254+}
255+
256+static void mp_encode_array(mp_buf *buf, int64_t n) {
257+ unsigned char b[5];
258+ int enclen;
259+
260+ if (n <= 15) {
261+ b[0] = 0x90 | (n & 0xf); /* fix array */
262+ enclen = 1;
263+ } else if (n <= 65535) {
264+ b[0] = 0xdc; /* array 16 */
265+ b[1] = (n & 0xff00) >> 8;
266+ b[2] = n & 0xff;
267+ enclen = 3;
268+ } else {
269+ b[0] = 0xdd; /* array 32 */
270+ b[1] = (n & 0xff000000) >> 24;
271+ b[2] = (n & 0xff0000) >> 16;
272+ b[3] = (n & 0xff00) >> 8;
273+ b[4] = n & 0xff;
274+ enclen = 5;
275+ }
276+ mp_buf_append(buf,b,enclen);
277+}
278+
279+static void mp_encode_map(mp_buf *buf, int64_t n) {
280+ unsigned char b[5];
281+ int enclen;
282+
283+ if (n <= 15) {
284+ b[0] = 0x80 | (n & 0xf); /* fix map */
285+ enclen = 1;
286+ } else if (n <= 65535) {
287+ b[0] = 0xde; /* map 16 */
288+ b[1] = (n & 0xff00) >> 8;
289+ b[2] = n & 0xff;
290+ enclen = 3;
291+ } else {
292+ b[0] = 0xdf; /* map 32 */
293+ b[1] = (n & 0xff000000) >> 24;
294+ b[2] = (n & 0xff0000) >> 16;
295+ b[3] = (n & 0xff00) >> 8;
296+ b[4] = n & 0xff;
297+ enclen = 5;
298+ }
299+ mp_buf_append(buf,b,enclen);
300+}
301+
302+/* ----------------------------- Lua types encoding --------------------------- */
303+
304+static void mp_encode_lua_string(lua_State *L, mp_buf *buf) {
305+ size_t len;
306+ const char *s;
307+
308+ s = lua_tolstring(L,-1,&len);
309+ mp_encode_bytes(buf,(const unsigned char*)s,len);
310+}
311+
312+static void mp_encode_lua_bool(lua_State *L, mp_buf *buf) {
313+ unsigned char b = lua_toboolean(L,-1) ? 0xc3 : 0xc2;
314+ mp_buf_append(buf,&b,1);
315+}
316+
317+static void mp_encode_lua_number(lua_State *L, mp_buf *buf) {
318+ lua_Number n = lua_tonumber(L,-1);
319+
320+ if (floor(n) != n) {
321+ mp_encode_double(buf,(double)n);
322+ } else {
323+ mp_encode_int(buf,(int64_t)n);
324+ }
325+}
326+
327+static void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level);
328+
329+/* Convert a lua table into a message pack list. */
330+static void mp_encode_lua_table_as_array(lua_State *L, mp_buf *buf, int level) {
331+ size_t len = lua_objlen(L,-1), j;
332+
333+ mp_encode_array(buf,len);
334+ for (j = 1; j <= len; j++) {
335+ lua_pushnumber(L,j);
336+ lua_gettable(L,-2);
337+ mp_encode_lua_type(L,buf,level+1);
338+ }
339+}
340+
341+/* Convert a lua table into a message pack key-value map. */
342+static void mp_encode_lua_table_as_map(lua_State *L, mp_buf *buf, int level) {
343+ size_t len = 0;
344+
345+ /* First step: count keys into table. No other way to do it with the
346+ * Lua API, we need to iterate a first time. Note that an alternative
347+ * would be to do a single run, and then hack the buffer to insert the
348+ * map opcodes for message pack. Too hachish for this lib. */
349+ lua_pushnil(L);
350+ while(lua_next(L,-2)) {
351+ lua_pop(L,1); /* remove value, keep key for next iteration. */
352+ len++;
353+ }
354+
355+ /* Step two: actually encoding of the map. */
356+ mp_encode_map(buf,len);
357+ lua_pushnil(L);
358+ while(lua_next(L,-2)) {
359+ /* Stack: ... key value */
360+ lua_pushvalue(L,-2); /* Stack: ... key value key */
361+ mp_encode_lua_type(L,buf,level+1); /* encode key */
362+ mp_encode_lua_type(L,buf,level+1); /* encode val */
363+ }
364+}
365+
366+/* Returns true if the Lua table on top of the stack is exclusively composed
367+ * of keys from numerical keys from 1 up to N, with N being the total number
368+ * of elements, without any hole in the middle. */
369+static int table_is_an_array(lua_State *L) {
370+ long count = 0, max = 0, idx = 0;
371+ lua_Number n;
372+
373+ lua_pushnil(L);
374+ while(lua_next(L,-2)) {
375+ /* Stack: ... key value */
376+ lua_pop(L,1); /* Stack: ... key */
377+ if (!lua_isnumber(L,-1)) goto not_array;
378+ n = lua_tonumber(L,-1);
379+ idx = n;
380+ if (idx != n || idx < 1) goto not_array;
381+ count++;
382+ max = idx;
383+ }
384+ /* We have the total number of elements in "count". Also we have
385+ * the max index encountered in "idx". We can't reach this code
386+ * if there are indexes <= 0. If you also note that there can not be
387+ * repeated keys into a table, you have that if idx==count you are sure
388+ * that there are all the keys form 1 to count (both included). */
389+ return idx == count;
390+
391+not_array:
392+ lua_pop(L,1);
393+ return 0;
394+}
395+
396+/* If the length operator returns non-zero, that is, there is at least
397+ * an object at key '1', we serialize to message pack list. Otherwise
398+ * we use a map. */
399+static void mp_encode_lua_table(lua_State *L, mp_buf *buf, int level) {
400+ if (table_is_an_array(L))
401+ mp_encode_lua_table_as_array(L,buf,level);
402+ else
403+ mp_encode_lua_table_as_map(L,buf,level);
404+}
405+
406+static void mp_encode_lua_null(lua_State *L, mp_buf *buf) {
407+ unsigned char b[1];
408+
409+ b[0] = 0xc0;
410+ mp_buf_append(buf,b,1);
411+}
412+
413+static void mp_encode_lua_type(lua_State *L, mp_buf *buf, int level) {
414+ int t = lua_type(L,-1);
415+
416+ /* Limit the encoding of nested tables to a specfiied maximum depth, so that
417+ * we survive when called against circular references in tables. */
418+ if (t == LUA_TTABLE && level == LUACMSGPACK_MAX_NESTING) t = LUA_TNIL;
419+ switch(t) {
420+ case LUA_TSTRING: mp_encode_lua_string(L,buf); break;
421+ case LUA_TBOOLEAN: mp_encode_lua_bool(L,buf); break;
422+ case LUA_TNUMBER: mp_encode_lua_number(L,buf); break;
423+ case LUA_TTABLE: mp_encode_lua_table(L,buf,level); break;
424+ default: mp_encode_lua_null(L,buf); break;
425+ }
426+ lua_pop(L,1);
427+}
428+
429+static int mp_pack(lua_State *L) {
430+ mp_buf *buf = mp_buf_new();
431+
432+ mp_encode_lua_type(L,buf,0);
433+ lua_pushlstring(L,(char*)buf->b,buf->len);
434+ mp_buf_free(buf);
435+ return 1;
436+}
437+
438+/* --------------------------------- Decoding --------------------------------- */
439+
440+void mp_decode_to_lua_type(lua_State *L, mp_cur *c);
441+
442+void mp_decode_to_lua_array(lua_State *L, mp_cur *c, size_t len) {
443+ int index = 1;
444+
445+ lua_newtable(L);
446+ while(len--) {
447+ lua_pushnumber(L,index++);
448+ mp_decode_to_lua_type(L,c);
449+ if (c->err) return;
450+ lua_settable(L,-3);
451+ }
452+}
453+
454+void mp_decode_to_lua_hash(lua_State *L, mp_cur *c, size_t len) {
455+ lua_newtable(L);
456+ while(len--) {
457+ mp_decode_to_lua_type(L,c); /* key */
458+ if (c->err) return;
459+ mp_decode_to_lua_type(L,c); /* value */
460+ if (c->err) return;
461+ lua_settable(L,-3);
462+ }
463+}
464+
465+/* Decode a Message Pack raw object pointed by the string cursor 'c' to
466+ * a Lua type, that is left as the only result on the stack. */
467+void mp_decode_to_lua_type(lua_State *L, mp_cur *c) {
468+ mp_cur_need(c,1);
469+ switch(c->p[0]) {
470+ case 0xcc: /* uint 8 */
471+ mp_cur_need(c,2);
472+ lua_pushnumber(L,c->p[1]);
473+ mp_cur_consume(c,2);
474+ break;
475+ case 0xd0: /* int 8 */
476+ mp_cur_need(c,2);
477+ lua_pushnumber(L,(char)c->p[1]);
478+ mp_cur_consume(c,2);
479+ break;
480+ case 0xcd: /* uint 16 */
481+ mp_cur_need(c,3);
482+ lua_pushnumber(L,
483+ (c->p[1] << 8) |
484+ c->p[2]);
485+ mp_cur_consume(c,3);
486+ break;
487+ case 0xd1: /* int 16 */
488+ mp_cur_need(c,3);
489+ lua_pushnumber(L,(int16_t)
490+ (c->p[1] << 8) |
491+ c->p[2]);
492+ mp_cur_consume(c,3);
493+ break;
494+ case 0xce: /* uint 32 */
495+ mp_cur_need(c,5);
496+ lua_pushnumber(L,
497+ ((uint32_t)c->p[1] << 24) |
498+ ((uint32_t)c->p[2] << 16) |
499+ ((uint32_t)c->p[3] << 8) |
500+ (uint32_t)c->p[4]);
501+ mp_cur_consume(c,5);
502+ break;
503+ case 0xd2: /* int 32 */
504+ mp_cur_need(c,5);
505+ lua_pushnumber(L,
506+ ((int32_t)c->p[1] << 24) |
507+ ((int32_t)c->p[2] << 16) |
508+ ((int32_t)c->p[3] << 8) |
509+ (int32_t)c->p[4]);
510+ mp_cur_consume(c,5);
511+ break;
512+ case 0xcf: /* uint 64 */
513+ mp_cur_need(c,9);
514+ lua_pushnumber(L,
515+ ((uint64_t)c->p[1] << 56) |
516+ ((uint64_t)c->p[2] << 48) |
517+ ((uint64_t)c->p[3] << 40) |
518+ ((uint64_t)c->p[4] << 32) |
519+ ((uint64_t)c->p[5] << 24) |
520+ ((uint64_t)c->p[6] << 16) |
521+ ((uint64_t)c->p[7] << 8) |
522+ (uint64_t)c->p[8]);
523+ mp_cur_consume(c,9);
524+ break;
525+ case 0xd3: /* int 64 */
526+ mp_cur_need(c,9);
527+ lua_pushnumber(L,
528+ ((int64_t)c->p[1] << 56) |
529+ ((int64_t)c->p[2] << 48) |
530+ ((int64_t)c->p[3] << 40) |
531+ ((int64_t)c->p[4] << 32) |
532+ ((int64_t)c->p[5] << 24) |
533+ ((int64_t)c->p[6] << 16) |
534+ ((int64_t)c->p[7] << 8) |
535+ (int64_t)c->p[8]);
536+ mp_cur_consume(c,9);
537+ break;
538+ case 0xc0: /* nil */
539+ lua_pushnil(L);
540+ mp_cur_consume(c,1);
541+ break;
542+ case 0xc3: /* true */
543+ lua_pushboolean(L,1);
544+ mp_cur_consume(c,1);
545+ break;
546+ case 0xc2: /* false */
547+ lua_pushboolean(L,0);
548+ mp_cur_consume(c,1);
549+ break;
550+ case 0xca: /* float */
551+ mp_cur_need(c,5);
552+ assert(sizeof(float) == 4);
553+ {
554+ float f;
555+ memcpy(&f,c->p+1,4);
556+ memrevifle(&f,4);
557+ lua_pushnumber(L,f);
558+ mp_cur_consume(c,5);
559+ }
560+ break;
561+ case 0xcb: /* double */
562+ mp_cur_need(c,9);
563+ assert(sizeof(double) == 8);
564+ {
565+ double d;
566+ memcpy(&d,c->p+1,8);
567+ memrevifle(&d,8);
568+ lua_pushnumber(L,d);
569+ mp_cur_consume(c,9);
570+ }
571+ break;
572+ case 0xda: /* raw 16 */
573+ mp_cur_need(c,3);
574+ {
575+ size_t l = (c->p[1] << 8) | c->p[2];
576+ mp_cur_need(c,3+l);
577+ lua_pushlstring(L,(char*)c->p+3,l);
578+ mp_cur_consume(c,3+l);
579+ }
580+ break;
581+ case 0xdb: /* raw 32 */
582+ mp_cur_need(c,5);
583+ {
584+ size_t l = (c->p[1] << 24) |
585+ (c->p[2] << 16) |
586+ (c->p[3] << 8) |
587+ c->p[4];
588+ mp_cur_need(c,5+l);
589+ lua_pushlstring(L,(char*)c->p+5,l);
590+ mp_cur_consume(c,5+l);
591+ }
592+ break;
593+ case 0xdc: /* array 16 */
594+ mp_cur_need(c,3);
595+ {
596+ size_t l = (c->p[1] << 8) | c->p[2];
597+ mp_cur_consume(c,3);
598+ mp_decode_to_lua_array(L,c,l);
599+ }
600+ break;
601+ case 0xdd: /* array 32 */
602+ mp_cur_need(c,5);
603+ {
604+ size_t l = (c->p[1] << 24) |
605+ (c->p[2] << 16) |
606+ (c->p[3] << 8) |
607+ c->p[4];
608+ mp_cur_consume(c,5);
609+ mp_decode_to_lua_array(L,c,l);
610+ }
611+ break;
612+ case 0xde: /* map 16 */
613+ mp_cur_need(c,3);
614+ {
615+ size_t l = (c->p[1] << 8) | c->p[2];
616+ mp_cur_consume(c,3);
617+ mp_decode_to_lua_hash(L,c,l);
618+ }
619+ break;
620+ case 0xdf: /* map 32 */
621+ mp_cur_need(c,5);
622+ {
623+ size_t l = (c->p[1] << 24) |
624+ (c->p[2] << 16) |
625+ (c->p[3] << 8) |
626+ c->p[4];
627+ mp_cur_consume(c,5);
628+ mp_decode_to_lua_hash(L,c,l);
629+ }
630+ break;
631+ default: /* types that can't be idenitified by first byte value. */
632+ if ((c->p[0] & 0x80) == 0) { /* positive fixnum */
633+ lua_pushnumber(L,c->p[0]);
634+ mp_cur_consume(c,1);
635+ } else if ((c->p[0] & 0xe0) == 0xe0) { /* negative fixnum */
636+ lua_pushnumber(L,(signed char)c->p[0]);
637+ mp_cur_consume(c,1);
638+ } else if ((c->p[0] & 0xe0) == 0xa0) { /* fix raw */
639+ size_t l = c->p[0] & 0x1f;
640+ mp_cur_need(c,1+l);
641+ lua_pushlstring(L,(char*)c->p+1,l);
642+ mp_cur_consume(c,1+l);
643+ } else if ((c->p[0] & 0xf0) == 0x90) { /* fix map */
644+ size_t l = c->p[0] & 0xf;
645+ mp_cur_consume(c,1);
646+ mp_decode_to_lua_array(L,c,l);
647+ } else if ((c->p[0] & 0xf0) == 0x80) { /* fix map */
648+ size_t l = c->p[0] & 0xf;
649+ mp_cur_consume(c,1);
650+ mp_decode_to_lua_hash(L,c,l);
651+ } else {
652+ c->err = MP_CUR_ERROR_BADFMT;
653+ }
654+ }
655+}
656+
657+static int mp_unpack(lua_State *L) {
658+ size_t len;
659+ const unsigned char *s;
660+ mp_cur *c;
661+
662+ if (!lua_isstring(L,-1)) {
663+ lua_pushstring(L,"MessagePack decoding needs a string as input.");
664+ lua_error(L);
665+ }
666+
667+ s = (const unsigned char*) lua_tolstring(L,-1,&len);
668+ c = mp_cur_new(s,len);
669+ mp_decode_to_lua_type(L,c);
670+
671+ if (c->err == MP_CUR_ERROR_EOF) {
672+ mp_cur_free(c);
673+ lua_pushstring(L,"Missing bytes in input.");
674+ lua_error(L);
675+ } else if (c->err == MP_CUR_ERROR_BADFMT) {
676+ mp_cur_free(c);
677+ lua_pushstring(L,"Bad data format in input.");
678+ lua_error(L);
679+ } else if (c->left != 0) {
680+ mp_cur_free(c);
681+ lua_pushstring(L,"Extra bytes in input.");
682+ lua_error(L);
683+ }
684+ mp_cur_free(c);
685+ return 1;
686+}
687+
688+/* ---------------------------------------------------------------------------- */
689+
690+static const struct luaL_Reg thislib[] = {
691+ {"pack", mp_pack},
692+ {"unpack", mp_unpack},
693+ {NULL, NULL}
694+};
695+
696+LUALIB_API int luaopen_cmsgpack (lua_State *L) {
697+ luaL_register(L, "cmsgpack", thislib);
698+
699+ lua_pushliteral(L, LUACMSGPACK_VERSION);
700+ lua_setfield(L, -2, "_VERSION");
701+ lua_pushliteral(L, LUACMSGPACK_COPYRIGHT);
702+ lua_setfield(L, -2, "_COPYRIGHT");
703+ lua_pushliteral(L, LUACMSGPACK_DESCRIPTION);
704+ lua_setfield(L, -2, "_DESCRIPTION");
705+ return 1;
706+}
707+
708+/******************************************************************************
709+* Copyright (C) 2012 Salvatore Sanfilippo. All rights reserved.
710+*
711+* Permission is hereby granted, free of charge, to any person obtaining
712+* a copy of this software and associated documentation files (the
713+* "Software"), to deal in the Software without restriction, including
714+* without limitation the rights to use, copy, modify, merge, publish,
715+* distribute, sublicense, and/or sell copies of the Software, and to
716+* permit persons to whom the Software is furnished to do so, subject to
717+* the following conditions:
718+*
719+* The above copyright notice and this permission notice shall be
720+* included in all copies or substantial portions of the Software.
721+*
722+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
723+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
724+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
725+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
726+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
727+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
728+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
729+******************************************************************************/