diff options
| -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 | } |
