aboutsummaryrefslogtreecommitdiff
path: root/lua_cjson.c
diff options
context:
space:
mode:
authorMark Pulford <mark@kyne.com.au>2011-05-10 22:32:01 +0930
committerMark Pulford <mark@kyne.com.au>2011-05-10 22:32:01 +0930
commit126470cc7b6c2314c02805e4d00afe04b6b00312 (patch)
tree9dd59bcc02307403410ef405b0f02bf39bd57560 /lua_cjson.c
parentc877da6c1f84b19cd2e7e8154b4a0d0e355745a0 (diff)
downloadlua-cjson-126470cc7b6c2314c02805e4d00afe04b6b00312.tar.gz
lua-cjson-126470cc7b6c2314c02805e4d00afe04b6b00312.tar.bz2
lua-cjson-126470cc7b6c2314c02805e4d00afe04b6b00312.zip
Add runtime option for persistent encode buffer
Diffstat (limited to 'lua_cjson.c')
-rw-r--r--lua_cjson.c61
1 files changed, 47 insertions, 14 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index f888644..50f27c2 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -49,6 +49,7 @@
49#define DEFAULT_MAX_DEPTH 20 49#define DEFAULT_MAX_DEPTH 20
50#define DEFAULT_ENCODE_REFUSE_BADNUM 1 50#define DEFAULT_ENCODE_REFUSE_BADNUM 1
51#define DEFAULT_DECODE_REFUSE_BADNUM 0 51#define DEFAULT_DECODE_REFUSE_BADNUM 0
52#define DEFAULT_ENCODE_KEEP_BUFFER 1
52 53
53typedef enum { 54typedef enum {
54 T_OBJ_BEGIN, 55 T_OBJ_BEGIN,
@@ -101,6 +102,7 @@ typedef struct {
101 int encode_max_depth; 102 int encode_max_depth;
102 int encode_refuse_badnum; 103 int encode_refuse_badnum;
103 int decode_refuse_badnum; 104 int decode_refuse_badnum;
105 int encode_keep_buffer;
104} json_config_t; 106} json_config_t;
105 107
106typedef struct { 108typedef struct {
@@ -172,7 +174,7 @@ static json_config_t *json_fetch_config(lua_State *l)
172 lua_gettable(l, LUA_REGISTRYINDEX); 174 lua_gettable(l, LUA_REGISTRYINDEX);
173 cfg = lua_touserdata(l, -1); 175 cfg = lua_touserdata(l, -1);
174 if (!cfg) 176 if (!cfg)
175 luaL_error(l, "BUG: Unable to fetch cjson configuration"); 177 luaL_error(l, "BUG: Unable to fetch CJSON configuration");
176 178
177 lua_pop(l, 1); 179 lua_pop(l, 1);
178 180
@@ -239,6 +241,23 @@ static int json_cfg_encode_max_depth(lua_State *l)
239 return 1; 241 return 1;
240} 242}
241 243
244/* Configures JSON encoding buffer persistence */
245static int json_cfg_encode_keep_buffer(lua_State *l)
246{
247 json_config_t *cfg;
248
249 json_verify_arg_count(l, 1);
250 cfg = json_fetch_config(l);
251
252 if (lua_gettop(l)) {
253 luaL_checktype(l, 1, LUA_TBOOLEAN);
254 cfg->encode_keep_buffer = lua_toboolean(l, 1);
255 }
256
257 lua_pushboolean(l, cfg->encode_keep_buffer);
258
259 return 1;
260}
242 261
243/* On argument: decode enum and set config variables 262/* On argument: decode enum and set config variables
244 * **options must point to a NULL terminated array of 4 enums 263 * **options must point to a NULL terminated array of 4 enums
@@ -317,6 +336,7 @@ static void json_create_config(lua_State *l)
317 cfg->encode_max_depth = DEFAULT_MAX_DEPTH; 336 cfg->encode_max_depth = DEFAULT_MAX_DEPTH;
318 cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM; 337 cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM;
319 cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM; 338 cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM;
339 cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER;
320 340
321 /* Decoding init */ 341 /* Decoding init */
322 342
@@ -392,8 +412,11 @@ static void json_create_config(lua_State *l)
392 412
393/* ===== ENCODING ===== */ 413/* ===== ENCODING ===== */
394 414
395static void json_encode_exception(lua_State *l, int lindex, const char *reason) 415static void json_encode_exception(lua_State *l, json_config_t *cfg, int lindex,
416 const char *reason)
396{ 417{
418 if (!cfg->encode_keep_buffer)
419 strbuf_free(&cfg->encode_buf);
397 luaL_error(l, "Cannot serialise %s: %s", 420 luaL_error(l, "Cannot serialise %s: %s",
398 lua_typename(l, lua_type(l, lindex)), reason); 421 lua_typename(l, lua_type(l, lindex)), reason);
399} 422}
@@ -469,7 +492,7 @@ static int lua_array_length(lua_State *l, json_config_t *cfg)
469 max > items * cfg->encode_sparse_ratio && 492 max > items * cfg->encode_sparse_ratio &&
470 max > cfg->encode_sparse_safe) { 493 max > cfg->encode_sparse_safe) {
471 if (!cfg->encode_sparse_convert) 494 if (!cfg->encode_sparse_convert)
472 json_encode_exception(l, -1, "excessively sparse array"); 495 json_encode_exception(l, cfg, -1, "excessively sparse array");
473 496
474 return -1; 497 return -1;
475 } 498 }
@@ -482,6 +505,8 @@ static void json_encode_descend(lua_State *l, json_config_t *cfg)
482 cfg->current_depth++; 505 cfg->current_depth++;
483 506
484 if (cfg->current_depth > cfg->encode_max_depth) { 507 if (cfg->current_depth > cfg->encode_max_depth) {
508 if (!cfg->encode_keep_buffer)
509 strbuf_free(&cfg->encode_buf);
485 luaL_error(l, "Cannot serialise, excessive nesting (%d)", 510 luaL_error(l, "Cannot serialise, excessive nesting (%d)",
486 cfg->current_depth); 511 cfg->current_depth);
487 } 512 }
@@ -520,12 +545,12 @@ static void json_append_array(lua_State *l, json_config_t *cfg, strbuf_t *json,
520} 545}
521 546
522static void json_append_number(lua_State *l, strbuf_t *json, int index, 547static void json_append_number(lua_State *l, strbuf_t *json, int index,
523 int refuse_badnum) 548 json_config_t *cfg)
524{ 549{
525 double num = lua_tonumber(l, index); 550 double num = lua_tonumber(l, index);
526 551
527 if (refuse_badnum && (isinf(num) || isnan(num))) 552 if (cfg->encode_refuse_badnum && (isinf(num) || isnan(num)))
528 json_encode_exception(l, index, "must not be NaN or Inf"); 553 json_encode_exception(l, cfg, index, "must not be NaN or Inf");
529 554
530 strbuf_append_number(json, num); 555 strbuf_append_number(json, num);
531} 556}
@@ -553,13 +578,13 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
553 keytype = lua_type(l, -2); 578 keytype = lua_type(l, -2);
554 if (keytype == LUA_TNUMBER) { 579 if (keytype == LUA_TNUMBER) {
555 strbuf_append_char(json, '"'); 580 strbuf_append_char(json, '"');
556 json_append_number(l, json, -2, cfg->encode_refuse_badnum); 581 json_append_number(l, json, -2, cfg);
557 strbuf_append_mem(json, "\":", 2); 582 strbuf_append_mem(json, "\":", 2);
558 } else if (keytype == LUA_TSTRING) { 583 } else if (keytype == LUA_TSTRING) {
559 json_append_string(l, json, -2); 584 json_append_string(l, json, -2);
560 strbuf_append_char(json, ':'); 585 strbuf_append_char(json, ':');
561 } else { 586 } else {
562 json_encode_exception(l, -2, 587 json_encode_exception(l, cfg, -2,
563 "table key must be a number or string"); 588 "table key must be a number or string");
564 /* never returns */ 589 /* never returns */
565 } 590 }
@@ -585,7 +610,7 @@ static void json_append_data(lua_State *l, json_config_t *cfg, strbuf_t *json)
585 json_append_string(l, json, -1); 610 json_append_string(l, json, -1);
586 break; 611 break;
587 case LUA_TNUMBER: 612 case LUA_TNUMBER:
588 json_append_number(l, json, -1, cfg->encode_refuse_badnum); 613 json_append_number(l, json, -1, cfg);
589 break; 614 break;
590 case LUA_TBOOLEAN: 615 case LUA_TBOOLEAN:
591 if (lua_toboolean(l, -1)) 616 if (lua_toboolean(l, -1))
@@ -611,7 +636,7 @@ static void json_append_data(lua_State *l, json_config_t *cfg, strbuf_t *json)
611 default: 636 default:
612 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, 637 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
613 * and LUA_TLIGHTUSERDATA) cannot be serialised */ 638 * and LUA_TLIGHTUSERDATA) cannot be serialised */
614 json_encode_exception(l, -1, "type not supported"); 639 json_encode_exception(l, cfg, -1, "type not supported");
615 /* never returns */ 640 /* never returns */
616 } 641 }
617} 642}
@@ -629,14 +654,21 @@ static int json_encode(lua_State *l)
629 cfg = json_fetch_config(l); 654 cfg = json_fetch_config(l);
630 cfg->current_depth = 0; 655 cfg->current_depth = 0;
631 656
632 /* Reset persistent encode_buf. Avoids temporary allocation 657 /* Reset the persistent buffer if it exists.
633 * for a single call. */ 658 * Otherwise allocate a new buffer. */
634 strbuf_reset(&cfg->encode_buf); 659 if (strbuf_allocated(&cfg->encode_buf))
660 strbuf_reset(&cfg->encode_buf);
661 else
662 strbuf_init(&cfg->encode_buf, 0);
663
635 json_append_data(l, cfg, &cfg->encode_buf); 664 json_append_data(l, cfg, &cfg->encode_buf);
636 json = strbuf_string(&cfg->encode_buf, &len); 665 json = strbuf_string(&cfg->encode_buf, &len);
637 666
638 lua_pushlstring(l, json, len); 667 lua_pushlstring(l, json, len);
639 668
669 if (!cfg->encode_keep_buffer)
670 strbuf_free(&cfg->encode_buf);
671
640 return 1; 672 return 1;
641} 673}
642 674
@@ -1176,7 +1208,7 @@ static int json_decode(lua_State *l)
1176 /* Detect Unicode other than UTF-8 (see RFC 4627, Sec 3) 1208 /* Detect Unicode other than UTF-8 (see RFC 4627, Sec 3)
1177 * 1209 *
1178 * CJSON can support any simple data type, hence only the first 1210 * CJSON can support any simple data type, hence only the first
1179 * character is guaranteed to be ASCII (at worst: "). This is 1211 * character is guaranteed to be ASCII (at worst: '"'). This is
1180 * still enough to detect whether the wrong encoding is in use. */ 1212 * still enough to detect whether the wrong encoding is in use. */
1181 if (len >= 2 && (!json[0] || !json[1])) 1213 if (len >= 2 && (!json[0] || !json[1]))
1182 luaL_error(l, "JSON parser does not support UTF-16 or UTF-32"); 1214 luaL_error(l, "JSON parser does not support UTF-16 or UTF-32");
@@ -1195,6 +1227,7 @@ int luaopen_cjson(lua_State *l)
1195 { "decode", json_decode }, 1227 { "decode", json_decode },
1196 { "encode_sparse_array", json_cfg_encode_sparse_array }, 1228 { "encode_sparse_array", json_cfg_encode_sparse_array },
1197 { "encode_max_depth", json_cfg_encode_max_depth }, 1229 { "encode_max_depth", json_cfg_encode_max_depth },
1230 { "encode_keep_buffer", json_cfg_encode_keep_buffer },
1198 { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers }, 1231 { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers },
1199 { NULL, NULL } 1232 { NULL, NULL }
1200 }; 1233 };