aboutsummaryrefslogtreecommitdiff
path: root/lua_cjson.c
diff options
context:
space:
mode:
Diffstat (limited to 'lua_cjson.c')
-rw-r--r--lua_cjson.c104
1 files changed, 79 insertions, 25 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index ae178eb..bbd8eff 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -66,6 +66,13 @@
66 66
67#endif 67#endif
68 68
69#ifdef _MSC_VER
70#define CJSON_EXPORT __declspec(dllexport)
71#define strncasecmp(x,y,z) _strnicmp(x,y,z)
72#else
73#define CJSON_EXPORT extern
74#endif
75
69/* Workaround for Solaris platforms missing isinf() */ 76/* Workaround for Solaris platforms missing isinf() */
70#if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF)) 77#if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF))
71#define isinf(x) (!isnan(x) && isnan((x) - (x))) 78#define isinf(x) (!isnan(x) && isnan((x) - (x)))
@@ -104,8 +111,8 @@
104#define json_lightudata_mask(ludata) (ludata) 111#define json_lightudata_mask(ludata) (ludata)
105#endif 112#endif
106 113
107#if LUA_VERSION_NUM > 501 114#if LUA_VERSION_NUM >= 502
108#define lua_objlen(L,i) lua_rawlen(L, (i)) 115#define lua_objlen(L,i) luaL_len(L, (i))
109#endif 116#endif
110 117
111static const char * const *json_empty_array; 118static const char * const *json_empty_array;
@@ -118,6 +125,7 @@ typedef enum {
118 T_ARR_END, 125 T_ARR_END,
119 T_STRING, 126 T_STRING,
120 T_NUMBER, 127 T_NUMBER,
128 T_INTEGER,
121 T_BOOLEAN, 129 T_BOOLEAN,
122 T_NULL, 130 T_NULL,
123 T_COLON, 131 T_COLON,
@@ -135,6 +143,7 @@ static const char *json_token_type_name[] = {
135 "T_ARR_END", 143 "T_ARR_END",
136 "T_STRING", 144 "T_STRING",
137 "T_NUMBER", 145 "T_NUMBER",
146 "T_INTEGER",
138 "T_BOOLEAN", 147 "T_BOOLEAN",
139 "T_NULL", 148 "T_NULL",
140 "T_COLON", 149 "T_COLON",
@@ -184,6 +193,7 @@ typedef struct {
184 union { 193 union {
185 const char *string; 194 const char *string;
186 double number; 195 double number;
196 lua_Integer integer;
187 int boolean; 197 int boolean;
188 } value; 198 } value;
189 size_t string_len; 199 size_t string_len;
@@ -234,7 +244,7 @@ static json_config_t *json_fetch_config(lua_State *l)
234{ 244{
235 json_config_t *cfg; 245 json_config_t *cfg;
236 246
237 cfg = lua_touserdata(l, lua_upvalueindex(1)); 247 cfg = (json_config_t *)lua_touserdata(l, lua_upvalueindex(1));
238 if (!cfg) 248 if (!cfg)
239 luaL_error(l, "BUG: Unable to fetch CJSON configuration"); 249 luaL_error(l, "BUG: Unable to fetch CJSON configuration");
240 250
@@ -443,7 +453,7 @@ static int json_destroy_config(lua_State *l)
443{ 453{
444 json_config_t *cfg; 454 json_config_t *cfg;
445 455
446 cfg = lua_touserdata(l, 1); 456 cfg = (json_config_t *)lua_touserdata(l, 1);
447 if (cfg) 457 if (cfg)
448 strbuf_free(&cfg->encode_buf); 458 strbuf_free(&cfg->encode_buf);
449 cfg = NULL; 459 cfg = NULL;
@@ -456,7 +466,7 @@ static void json_create_config(lua_State *l)
456 json_config_t *cfg; 466 json_config_t *cfg;
457 int i; 467 int i;
458 468
459 cfg = lua_newuserdata(l, sizeof(*cfg)); 469 cfg = (json_config_t *)lua_newuserdata(l, sizeof(*cfg));
460 if (!cfg) 470 if (!cfg)
461 abort(); 471 abort();
462 472
@@ -552,9 +562,9 @@ static void json_encode_exception(lua_State *l, json_config_t *cfg, strbuf_t *js
552static void json_append_string(lua_State *l, strbuf_t *json, int lindex) 562static void json_append_string(lua_State *l, strbuf_t *json, int lindex)
553{ 563{
554 const char *escstr; 564 const char *escstr;
555 unsigned i;
556 const char *str; 565 const char *str;
557 size_t len; 566 size_t len;
567 size_t i;
558 568
559 str = lua_tolstring(l, lindex, &len); 569 str = lua_tolstring(l, lindex, &len);
560 570
@@ -653,9 +663,9 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
653/* json_append_array args: 663/* json_append_array args:
654 * - lua_State 664 * - lua_State
655 * - JSON strbuf 665 * - JSON strbuf
656 * - Size of passwd Lua array (top of stack) */ 666 * - Size of passed Lua array (top of stack) */
657static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth, 667static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth,
658 strbuf_t *json, int array_length) 668 strbuf_t *json, int array_length, int raw)
659{ 669{
660 int comma, i, json_pos, err; 670 int comma, i, json_pos, err;
661 671
@@ -667,7 +677,17 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept
667 if (comma++ > 0) 677 if (comma++ > 0)
668 strbuf_append_char(json, ','); 678 strbuf_append_char(json, ',');
669 679
670 lua_rawgeti(l, -1, i); 680 if (raw) {
681 lua_rawgeti(l, -1, i);
682 } else {
683#if LUA_VERSION_NUM >= 503
684 lua_geti(l, -1, i);
685#else
686 lua_pushinteger(l, i);
687 lua_gettable(l, -2);
688#endif
689 }
690
671 err = json_append_data(l, cfg, current_depth, json); 691 err = json_append_data(l, cfg, current_depth, json);
672 if (err) { 692 if (err) {
673 strbuf_set_length(json, json_pos); 693 strbuf_set_length(json, json_pos);
@@ -684,8 +704,17 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept
684static void json_append_number(lua_State *l, json_config_t *cfg, 704static void json_append_number(lua_State *l, json_config_t *cfg,
685 strbuf_t *json, int lindex) 705 strbuf_t *json, int lindex)
686{ 706{
687 double num = lua_tonumber(l, lindex);
688 int len; 707 int len;
708#if LUA_VERSION_NUM >= 503
709 if (lua_isinteger(l, lindex)) {
710 lua_Integer num = lua_tointeger(l, lindex);
711 strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); /* max length of int64 is 19 */
712 len = sprintf(strbuf_empty_ptr(json), LUA_INTEGER_FMT, num);
713 strbuf_extend_length(json, len);
714 return;
715 }
716#endif
717 double num = lua_tonumber(l, lindex);
689 718
690 if (cfg->encode_invalid_numbers == 0) { 719 if (cfg->encode_invalid_numbers == 0) {
691 /* Prevent encoding invalid numbers */ 720 /* Prevent encoding invalid numbers */
@@ -773,6 +802,7 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
773 int len; 802 int len;
774 int as_array = 0; 803 int as_array = 0;
775 int has_metatable; 804 int has_metatable;
805 int raw = 1;
776 806
777 switch (lua_type(l, -1)) { 807 switch (lua_type(l, -1)) {
778 case LUA_TSTRING: 808 case LUA_TSTRING:
@@ -797,17 +827,30 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
797 lua_pushlightuserdata(l, json_lightudata_mask(&json_array)); 827 lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
798 lua_rawget(l, LUA_REGISTRYINDEX); 828 lua_rawget(l, LUA_REGISTRYINDEX);
799 as_array = lua_rawequal(l, -1, -2); 829 as_array = lua_rawequal(l, -1, -2);
800 lua_pop(l, 2); 830 if (as_array) {
831 raw = 1;
832 lua_pop(l, 2);
833 len = lua_objlen(l, -1);
834 } else {
835 raw = 0;
836 lua_pop(l, 2);
837 if (luaL_getmetafield(l, -1, "__len")) {
838 lua_pushvalue(l, -2);
839 lua_call(l, 1, 1);
840 len = lua_tonumber(l, -1);
841 lua_pop(l, 1);
842 as_array = 1;
843 }
844 }
801 } 845 }
802 846
803 if (as_array) { 847 if (as_array) {
804 len = lua_objlen(l, -1); 848 json_append_array(l, cfg, current_depth, json, len, raw);
805 json_append_array(l, cfg, current_depth, json, len);
806 } else { 849 } else {
807 len = lua_array_length(l, cfg, json); 850 len = lua_array_length(l, cfg, json);
808 851
809 if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object)) { 852 if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object)) {
810 json_append_array(l, cfg, current_depth, json, len); 853 json_append_array(l, cfg, current_depth, json, len, raw);
811 } else { 854 } else {
812 if (has_metatable) { 855 if (has_metatable) {
813 lua_getmetatable(l, -1); 856 lua_getmetatable(l, -1);
@@ -817,7 +860,9 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
817 as_array = lua_rawequal(l, -1, -2); 860 as_array = lua_rawequal(l, -1, -2);
818 lua_pop(l, 2); /* pop pointer + metatable */ 861 lua_pop(l, 2); /* pop pointer + metatable */
819 if (as_array) { 862 if (as_array) {
820 json_append_array(l, cfg, current_depth, json, 0); 863 len = lua_objlen(l, -1);
864 raw = 1;
865 json_append_array(l, cfg, current_depth, json, len, raw);
821 break; 866 break;
822 } 867 }
823 } 868 }
@@ -832,7 +877,7 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
832 if (lua_touserdata(l, -1) == NULL) { 877 if (lua_touserdata(l, -1) == NULL) {
833 strbuf_append_mem(json, "null", 4); 878 strbuf_append_mem(json, "null", 4);
834 } else if (lua_touserdata(l, -1) == json_lightudata_mask(&json_array)) { 879 } else if (lua_touserdata(l, -1) == json_lightudata_mask(&json_array)) {
835 json_append_array(l, cfg, current_depth, json, 0); 880 json_append_array(l, cfg, current_depth, json, 0, 1);
836 } 881 }
837 break; 882 break;
838 default: 883 default:
@@ -1145,13 +1190,19 @@ static int json_is_invalid_number(json_parse_t *json)
1145static void json_next_number_token(json_parse_t *json, json_token_t *token) 1190static void json_next_number_token(json_parse_t *json, json_token_t *token)
1146{ 1191{
1147 char *endptr; 1192 char *endptr;
1148 1193 token->value.integer = strtoll(json->ptr, &endptr, 10);
1149 token->type = T_NUMBER; 1194 if (json->ptr == endptr || *endptr == '.' || *endptr == 'e' ||
1150 token->value.number = fpconv_strtod(json->ptr, &endptr); 1195 *endptr == 'E' || *endptr == 'x') {
1151 if (json->ptr == endptr) 1196 token->type = T_NUMBER;
1152 json_set_token_error(token, json, "invalid number"); 1197 token->value.number = fpconv_strtod(json->ptr, &endptr);
1153 else 1198 if (json->ptr == endptr) {
1154 json->ptr = endptr; /* Skip the processed number */ 1199 json_set_token_error(token, json, "invalid number");
1200 return;
1201 }
1202 } else {
1203 token->type = T_INTEGER;
1204 }
1205 json->ptr = endptr; /* Skip the processed number */
1155 1206
1156 return; 1207 return;
1157} 1208}
@@ -1387,6 +1438,9 @@ static void json_process_value(lua_State *l, json_parse_t *json,
1387 case T_NUMBER: 1438 case T_NUMBER:
1388 lua_pushnumber(l, token->value.number); 1439 lua_pushnumber(l, token->value.number);
1389 break;; 1440 break;;
1441 case T_INTEGER:
1442 lua_pushinteger(l, token->value.integer);
1443 break;;
1390 case T_BOOLEAN: 1444 case T_BOOLEAN:
1391 lua_pushboolean(l, token->value.boolean); 1445 lua_pushboolean(l, token->value.boolean);
1392 break;; 1446 break;;
@@ -1602,7 +1656,7 @@ static int lua_cjson_safe_new(lua_State *l)
1602 return 1; 1656 return 1;
1603} 1657}
1604 1658
1605int luaopen_cjson(lua_State *l) 1659CJSON_EXPORT int luaopen_cjson(lua_State *l)
1606{ 1660{
1607 lua_cjson_new(l); 1661 lua_cjson_new(l);
1608 1662
@@ -1616,7 +1670,7 @@ int luaopen_cjson(lua_State *l)
1616 return 1; 1670 return 1;
1617} 1671}
1618 1672
1619int luaopen_cjson_safe(lua_State *l) 1673CJSON_EXPORT int luaopen_cjson_safe(lua_State *l)
1620{ 1674{
1621 lua_cjson_safe_new(l); 1675 lua_cjson_safe_new(l);
1622 1676