]> git.saurik.com Git - redis.git/blob - deps/lua/src/lua_cmsgpack.c
Test SINTER against same integer elements, but different set encoding.
[redis.git] / deps / lua / src / lua_cmsgpack.c
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 ******************************************************************************/