diff options
Diffstat (limited to 'lua_cjson.c')
-rw-r--r-- | lua_cjson.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/lua_cjson.c b/lua_cjson.c index 2228fee..4b1915a 100644 --- a/lua_cjson.c +++ b/lua_cjson.c | |||
@@ -26,9 +26,10 @@ | |||
26 | * - JSON "null" values are represented as lightuserdata since Lua | 26 | * - JSON "null" values are represented as lightuserdata since Lua |
27 | * tables cannot contain "nil". Compare with cjson.null. | 27 | * tables cannot contain "nil". Compare with cjson.null. |
28 | * - Invalid UTF-8 characters are not detected and will be passed | 28 | * - Invalid UTF-8 characters are not detected and will be passed |
29 | * untouched. | 29 | * untouched. If required, UTF-8 error checking should be done |
30 | * outside this library. | ||
30 | * - Javascript comments are not part of the JSON spec, and are not | 31 | * - Javascript comments are not part of the JSON spec, and are not |
31 | * supported. | 32 | * currently supported. |
32 | * | 33 | * |
33 | * Note: Decoding is slower than encoding. Lua spends significant | 34 | * Note: Decoding is slower than encoding. Lua spends significant |
34 | * time (30%) managing tables when parsing JSON since it is | 35 | * time (30%) managing tables when parsing JSON since it is |
@@ -94,6 +95,7 @@ typedef struct { | |||
94 | char *char2escape[256]; /* Encoding */ | 95 | char *char2escape[256]; /* Encoding */ |
95 | #endif | 96 | #endif |
96 | strbuf_t encode_buf; | 97 | strbuf_t encode_buf; |
98 | char number_fmt[8]; /* "%.XXg\0" */ | ||
97 | int current_depth; | 99 | int current_depth; |
98 | 100 | ||
99 | int encode_sparse_convert; | 101 | int encode_sparse_convert; |
@@ -103,6 +105,7 @@ typedef struct { | |||
103 | int encode_refuse_badnum; | 105 | int encode_refuse_badnum; |
104 | int decode_refuse_badnum; | 106 | int decode_refuse_badnum; |
105 | int encode_keep_buffer; | 107 | int encode_keep_buffer; |
108 | int encode_number_precision; | ||
106 | } json_config_t; | 109 | } json_config_t; |
107 | 110 | ||
108 | typedef struct { | 111 | typedef struct { |
@@ -241,6 +244,33 @@ static int json_cfg_encode_max_depth(lua_State *l) | |||
241 | return 1; | 244 | return 1; |
242 | } | 245 | } |
243 | 246 | ||
247 | static void json_set_number_precision(json_config_t *cfg, int prec) | ||
248 | { | ||
249 | cfg->encode_number_precision = prec; | ||
250 | sprintf(cfg->number_fmt, "%%.%dg", prec); | ||
251 | } | ||
252 | |||
253 | /* Configures number precision when converting doubles to text */ | ||
254 | static int json_cfg_encode_number_precision(lua_State *l) | ||
255 | { | ||
256 | json_config_t *cfg; | ||
257 | int precision; | ||
258 | |||
259 | json_verify_arg_count(l, 1); | ||
260 | cfg = json_fetch_config(l); | ||
261 | |||
262 | if (lua_gettop(l)) { | ||
263 | precision = luaL_checkinteger(l, 1); | ||
264 | luaL_argcheck(l, 1 <= precision && precision <= 14, 1, | ||
265 | "expected integer between 1 and 14"); | ||
266 | json_set_number_precision(cfg, precision); | ||
267 | } | ||
268 | |||
269 | lua_pushinteger(l, cfg->encode_number_precision); | ||
270 | |||
271 | return 1; | ||
272 | } | ||
273 | |||
244 | /* Configures JSON encoding buffer persistence */ | 274 | /* Configures JSON encoding buffer persistence */ |
245 | static int json_cfg_encode_keep_buffer(lua_State *l) | 275 | static int json_cfg_encode_keep_buffer(lua_State *l) |
246 | { | 276 | { |
@@ -337,6 +367,7 @@ static void json_create_config(lua_State *l) | |||
337 | cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM; | 367 | cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM; |
338 | cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM; | 368 | cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM; |
339 | cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; | 369 | cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; |
370 | json_set_number_precision(cfg, 14); | ||
340 | 371 | ||
341 | /* Decoding init */ | 372 | /* Decoding init */ |
342 | 373 | ||
@@ -552,7 +583,12 @@ static void json_append_number(lua_State *l, strbuf_t *json, int index, | |||
552 | if (cfg->encode_refuse_badnum && (isinf(num) || isnan(num))) | 583 | if (cfg->encode_refuse_badnum && (isinf(num) || isnan(num))) |
553 | json_encode_exception(l, cfg, index, "must not be NaN or Inf"); | 584 | json_encode_exception(l, cfg, index, "must not be NaN or Inf"); |
554 | 585 | ||
555 | strbuf_append_number(json, num); | 586 | /* Lowest double printed with %.14g is 21 characters long: |
587 | * -1.7976931348623e+308 | ||
588 | * | ||
589 | * Use 32 to include the \0, and a few extra just in case.. | ||
590 | */ | ||
591 | strbuf_append_fmt(json, 32, cfg->number_fmt, num); | ||
556 | } | 592 | } |
557 | 593 | ||
558 | static void json_append_object(lua_State *l, json_config_t *cfg, | 594 | static void json_append_object(lua_State *l, json_config_t *cfg, |
@@ -1227,6 +1263,7 @@ int luaopen_cjson(lua_State *l) | |||
1227 | { "decode", json_decode }, | 1263 | { "decode", json_decode }, |
1228 | { "encode_sparse_array", json_cfg_encode_sparse_array }, | 1264 | { "encode_sparse_array", json_cfg_encode_sparse_array }, |
1229 | { "encode_max_depth", json_cfg_encode_max_depth }, | 1265 | { "encode_max_depth", json_cfg_encode_max_depth }, |
1266 | { "encode_number_precision", json_cfg_encode_number_precision }, | ||
1230 | { "encode_keep_buffer", json_cfg_encode_keep_buffer }, | 1267 | { "encode_keep_buffer", json_cfg_encode_keep_buffer }, |
1231 | { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers }, | 1268 | { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers }, |
1232 | { NULL, NULL } | 1269 | { NULL, NULL } |