summaryrefslogtreecommitdiff
path: root/lua_cjson.c
diff options
context:
space:
mode:
authorMark Pulford <mark@kyne.com.au>2011-12-31 16:51:18 +1030
committerMark Pulford <mark@kyne.com.au>2011-12-31 16:51:18 +1030
commit0637fcaf549ce120efa541c8d7445cb36c30e53f (patch)
tree5ad33e581d4f886d3903c4b8621ab16e870b8b69 /lua_cjson.c
parent0a63a3fce3b7f3b58497e43c6c932d4888b51f1d (diff)
downloadlua-cjson-0637fcaf549ce120efa541c8d7445cb36c30e53f.tar.gz
lua-cjson-0637fcaf549ce120efa541c8d7445cb36c30e53f.tar.bz2
lua-cjson-0637fcaf549ce120efa541c8d7445cb36c30e53f.zip
Add option for private buffer
When encode_keep_buffer is false, a private buffer will be used. This will allow multiple encoders to run within a single Lua state.
Diffstat (limited to 'lua_cjson.c')
-rw-r--r--lua_cjson.c70
1 files changed, 44 insertions, 26 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index f1c54ec..3a40e9a 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -105,10 +105,9 @@ static const char *json_token_type_name[] = {
105typedef struct { 105typedef struct {
106 json_token_type_t ch2token[256]; 106 json_token_type_t ch2token[256];
107 char escape2char[256]; /* Decoding */ 107 char escape2char[256]; /* Decoding */
108#if 0 108
109 char escapes[35][8]; /* Pre-generated escape string buffer */ 109 /* encode_buf is only allocated and used when
110 char *char2escape[256]; /* Encoding */ 110 * encode_keep_buffer is set */
111#endif
112 strbuf_t encode_buf; 111 strbuf_t encode_buf;
113 112
114 int encode_sparse_convert; 113 int encode_sparse_convert;
@@ -276,15 +275,26 @@ static int json_cfg_encode_number_precision(lua_State *l)
276static int json_cfg_encode_keep_buffer(lua_State *l) 275static int json_cfg_encode_keep_buffer(lua_State *l)
277{ 276{
278 json_config_t *cfg; 277 json_config_t *cfg;
278 int old_value;
279 279
280 json_verify_arg_count(l, 1); 280 json_verify_arg_count(l, 1);
281 cfg = json_fetch_config(l); 281 cfg = json_fetch_config(l);
282 282
283 old_value = cfg->encode_keep_buffer;
284
283 if (lua_gettop(l)) { 285 if (lua_gettop(l)) {
284 luaL_checktype(l, 1, LUA_TBOOLEAN); 286 luaL_checktype(l, 1, LUA_TBOOLEAN);
285 cfg->encode_keep_buffer = lua_toboolean(l, 1); 287 cfg->encode_keep_buffer = lua_toboolean(l, 1);
286 } 288 }
287 289
290 /* Init / free the buffer if the setting has changed */
291 if (old_value ^ cfg->encode_keep_buffer) {
292 if (cfg->encode_keep_buffer)
293 strbuf_init(&cfg->encode_buf, 0);
294 else
295 strbuf_free(&cfg->encode_buf);
296 }
297
288 lua_pushboolean(l, cfg->encode_keep_buffer); 298 lua_pushboolean(l, cfg->encode_keep_buffer);
289 299
290 return 1; 300 return 1;
@@ -366,8 +376,6 @@ static void json_create_config(lua_State *l)
366 lua_setfield(l, -2, "__gc"); 376 lua_setfield(l, -2, "__gc");
367 lua_setmetatable(l, -2); 377 lua_setmetatable(l, -2);
368 378
369 strbuf_init(&cfg->encode_buf, 0);
370
371 cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT; 379 cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT;
372 cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO; 380 cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO;
373 cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE; 381 cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE;
@@ -377,6 +385,10 @@ static void json_create_config(lua_State *l)
377 cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; 385 cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER;
378 cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION; 386 cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION;
379 387
388#if DEFAULT_ENCODE_KEEP_BUFFER > 0
389 strbuf_init(&cfg->encode_buf, 0);
390#endif
391
380 /* Decoding init */ 392 /* Decoding init */
381 393
382 /* Tag all characters as an error */ 394 /* Tag all characters as an error */
@@ -425,11 +437,11 @@ static void json_create_config(lua_State *l)
425 437
426/* ===== ENCODING ===== */ 438/* ===== ENCODING ===== */
427 439
428static void json_encode_exception(lua_State *l, json_config_t *cfg, int lindex, 440static void json_encode_exception(lua_State *l, json_config_t *cfg, strbuf_t *json, int lindex,
429 const char *reason) 441 const char *reason)
430{ 442{
431 if (!cfg->encode_keep_buffer) 443 if (!cfg->encode_keep_buffer)
432 strbuf_free(&cfg->encode_buf); 444 strbuf_free(json);
433 luaL_error(l, "Cannot serialise %s: %s", 445 luaL_error(l, "Cannot serialise %s: %s",
434 lua_typename(l, lua_type(l, lindex)), reason); 446 lua_typename(l, lua_type(l, lindex)), reason);
435} 447}
@@ -470,7 +482,7 @@ static void json_append_string(lua_State *l, strbuf_t *json, int lindex)
470 * -1 object (not a pure array) 482 * -1 object (not a pure array)
471 * >=0 elements in array 483 * >=0 elements in array
472 */ 484 */
473static int lua_array_length(lua_State *l, json_config_t *cfg) 485static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json)
474{ 486{
475 double k; 487 double k;
476 int max; 488 int max;
@@ -505,7 +517,7 @@ static int lua_array_length(lua_State *l, json_config_t *cfg)
505 max > items * cfg->encode_sparse_ratio && 517 max > items * cfg->encode_sparse_ratio &&
506 max > cfg->encode_sparse_safe) { 518 max > cfg->encode_sparse_safe) {
507 if (!cfg->encode_sparse_convert) 519 if (!cfg->encode_sparse_convert)
508 json_encode_exception(l, cfg, -1, "excessively sparse array"); 520 json_encode_exception(l, cfg, json, -1, "excessively sparse array");
509 521
510 return -1; 522 return -1;
511 } 523 }
@@ -513,11 +525,12 @@ static int lua_array_length(lua_State *l, json_config_t *cfg)
513 return max; 525 return max;
514} 526}
515 527
516static void json_check_encode_depth(lua_State *l, json_config_t *cfg, int current_depth) 528static void json_check_encode_depth(lua_State *l, json_config_t *cfg,
529 strbuf_t *json, int current_depth)
517{ 530{
518 if (current_depth > cfg->encode_max_depth) { 531 if (current_depth > cfg->encode_max_depth) {
519 if (!cfg->encode_keep_buffer) 532 if (!cfg->encode_keep_buffer)
520 strbuf_free(&cfg->encode_buf); 533 strbuf_free(json);
521 luaL_error(l, "Cannot serialise, excessive nesting (%d)", 534 luaL_error(l, "Cannot serialise, excessive nesting (%d)",
522 current_depth); 535 current_depth);
523 } 536 }
@@ -559,7 +572,7 @@ static void json_append_number(lua_State *l, strbuf_t *json, int index,
559 int len; 572 int len;
560 573
561 if (cfg->encode_refuse_badnum && (isinf(num) || isnan(num))) 574 if (cfg->encode_refuse_badnum && (isinf(num) || isnan(num)))
562 json_encode_exception(l, cfg, index, "must not be NaN or Inf"); 575 json_encode_exception(l, cfg, json, index, "must not be NaN or Inf");
563 576
564 if (isnan(num)) { 577 if (isnan(num)) {
565 /* Some platforms may print -nan, just hard code it */ 578 /* Some platforms may print -nan, just hard code it */
@@ -600,7 +613,7 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
600 json_append_string(l, json, -2); 613 json_append_string(l, json, -2);
601 strbuf_append_char(json, ':'); 614 strbuf_append_char(json, ':');
602 } else { 615 } else {
603 json_encode_exception(l, cfg, -2, 616 json_encode_exception(l, cfg, json, -2,
604 "table key must be a number or string"); 617 "table key must be a number or string");
605 /* never returns */ 618 /* never returns */
606 } 619 }
@@ -634,9 +647,9 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
634 strbuf_append_mem(json, "false", 5); 647 strbuf_append_mem(json, "false", 5);
635 break; 648 break;
636 case LUA_TTABLE: 649 case LUA_TTABLE:
637 len = lua_array_length(l, cfg); 650 len = lua_array_length(l, cfg, json);
638 current_depth++; 651 current_depth++;
639 json_check_encode_depth(l, cfg, current_depth); 652 json_check_encode_depth(l, cfg, json, current_depth);
640 if (len > 0) 653 if (len > 0)
641 json_append_array(l, cfg, current_depth, json, len); 654 json_append_array(l, cfg, current_depth, json, len);
642 else 655 else
@@ -653,7 +666,7 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
653 default: 666 default:
654 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, 667 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
655 * and LUA_TLIGHTUSERDATA) cannot be serialised */ 668 * and LUA_TLIGHTUSERDATA) cannot be serialised */
656 json_encode_exception(l, cfg, -1, "type not supported"); 669 json_encode_exception(l, cfg, json, -1, "type not supported");
657 /* never returns */ 670 /* never returns */
658 } 671 }
659} 672}
@@ -661,6 +674,8 @@ static void json_append_data(lua_State *l, json_config_t *cfg,
661static int json_encode(lua_State *l) 674static int json_encode(lua_State *l)
662{ 675{
663 json_config_t *cfg; 676 json_config_t *cfg;
677 strbuf_t local_encode_buf;
678 strbuf_t *encode_buf;
664 char *json; 679 char *json;
665 int len; 680 int len;
666 681
@@ -670,20 +685,23 @@ static int json_encode(lua_State *l)
670 685
671 cfg = json_fetch_config(l); 686 cfg = json_fetch_config(l);
672 687
673 /* Reset the persistent buffer if it exists. 688 if (!cfg->encode_keep_buffer) {
674 * Otherwise allocate a new buffer. */ 689 /* Use private buffer */
675 if (strbuf_allocated(&cfg->encode_buf)) 690 encode_buf = &local_encode_buf;
676 strbuf_reset(&cfg->encode_buf); 691 strbuf_init(encode_buf, 0);
677 else 692 } else {
678 strbuf_init(&cfg->encode_buf, 0); 693 /* Reuse existing buffer */
694 encode_buf = &cfg->encode_buf;
695 strbuf_reset(encode_buf);
696 }
679 697
680 json_append_data(l, cfg, 0, &cfg->encode_buf); 698 json_append_data(l, cfg, 0, encode_buf);
681 json = strbuf_string(&cfg->encode_buf, &len); 699 json = strbuf_string(encode_buf, &len);
682 700
683 lua_pushlstring(l, json, len); 701 lua_pushlstring(l, json, len);
684 702
685 if (!cfg->encode_keep_buffer) 703 if (!cfg->encode_keep_buffer)
686 strbuf_free(&cfg->encode_buf); 704 strbuf_free(encode_buf);
687 705
688 return 1; 706 return 1;
689} 707}