diff options
author | Mark Pulford <mark@kyne.com.au> | 2011-12-31 16:51:18 +1030 |
---|---|---|
committer | Mark Pulford <mark@kyne.com.au> | 2011-12-31 16:51:18 +1030 |
commit | 0637fcaf549ce120efa541c8d7445cb36c30e53f (patch) | |
tree | 5ad33e581d4f886d3903c4b8621ab16e870b8b69 /lua_cjson.c | |
parent | 0a63a3fce3b7f3b58497e43c6c932d4888b51f1d (diff) | |
download | lua-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.c | 70 |
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[] = { | |||
105 | typedef struct { | 105 | typedef 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) | |||
276 | static int json_cfg_encode_keep_buffer(lua_State *l) | 275 | static 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 | ||
428 | static void json_encode_exception(lua_State *l, json_config_t *cfg, int lindex, | 440 | static 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 | */ |
473 | static int lua_array_length(lua_State *l, json_config_t *cfg) | 485 | static 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 | ||
516 | static void json_check_encode_depth(lua_State *l, json_config_t *cfg, int current_depth) | 528 | static 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, | |||
661 | static int json_encode(lua_State *l) | 674 | static 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 | } |