aboutsummaryrefslogtreecommitdiff
path: root/lua
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lua-cjson-1.0devel-1.rockspec4
-rw-r--r--lua_cjson.c36
2 files changed, 23 insertions, 17 deletions
diff --git a/lua-cjson-1.0devel-1.rockspec b/lua-cjson-1.0devel-1.rockspec
index 3890ec1..fa20c53 100644
--- a/lua-cjson-1.0devel-1.rockspec
+++ b/lua-cjson-1.0devel-1.rockspec
@@ -23,11 +23,11 @@ build = {
23 type = "builtin", 23 type = "builtin",
24 modules = { 24 modules = {
25 cjson = { 25 cjson = {
26 sources = { "lua_cjson.c", "strbuf.c" }, 26 sources = { "lua_cjson.c", "strbuf.c", "fpconv.c" },
27 defines = {
27-- Optional workaround: 28-- Optional workaround:
28-- USE_INTERNAL_ISINF: Provide internal isinf() implementation. Required 29-- USE_INTERNAL_ISINF: Provide internal isinf() implementation. Required
29-- on some Solaris platforms. 30-- on some Solaris platforms.
30 defines = {
31-- LuaRocks does not support platform specific configuration for Solaris. 31-- LuaRocks does not support platform specific configuration for Solaris.
32-- Uncomment the line below on Solaris platforms. 32-- Uncomment the line below on Solaris platforms.
33-- "USE_INTERNAL_ISINF" 33-- "USE_INTERNAL_ISINF"
diff --git a/lua_cjson.c b/lua_cjson.c
index f5ea0dd..8e9b237 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -43,6 +43,7 @@
43#include <lauxlib.h> 43#include <lauxlib.h>
44 44
45#include "strbuf.h" 45#include "strbuf.h"
46#include "fpconv.h"
46 47
47#ifndef CJSON_VERSION 48#ifndef CJSON_VERSION
48#define CJSON_VERSION "1.0devel" 49#define CJSON_VERSION "1.0devel"
@@ -60,6 +61,7 @@
60#define DEFAULT_ENCODE_REFUSE_BADNUM 1 61#define DEFAULT_ENCODE_REFUSE_BADNUM 1
61#define DEFAULT_DECODE_REFUSE_BADNUM 0 62#define DEFAULT_DECODE_REFUSE_BADNUM 0
62#define DEFAULT_ENCODE_KEEP_BUFFER 1 63#define DEFAULT_ENCODE_KEEP_BUFFER 1
64#define DEFAULT_ENCODE_NUMBER_PRECISION 14
63 65
64typedef enum { 66typedef enum {
65 T_OBJ_BEGIN, 67 T_OBJ_BEGIN,
@@ -104,7 +106,6 @@ typedef struct {
104 char *char2escape[256]; /* Encoding */ 106 char *char2escape[256]; /* Encoding */
105#endif 107#endif
106 strbuf_t encode_buf; 108 strbuf_t encode_buf;
107 char number_fmt[8]; /* "%.XXg\0" */
108 int current_depth; 109 int current_depth;
109 110
110 int encode_sparse_convert; 111 int encode_sparse_convert;
@@ -253,12 +254,6 @@ static int json_cfg_encode_max_depth(lua_State *l)
253 return 1; 254 return 1;
254} 255}
255 256
256static void json_set_number_precision(json_config_t *cfg, int prec)
257{
258 cfg->encode_number_precision = prec;
259 sprintf(cfg->number_fmt, "%%.%dg", prec);
260}
261
262/* Configures number precision when converting doubles to text */ 257/* Configures number precision when converting doubles to text */
263static int json_cfg_encode_number_precision(lua_State *l) 258static int json_cfg_encode_number_precision(lua_State *l)
264{ 259{
@@ -272,7 +267,7 @@ static int json_cfg_encode_number_precision(lua_State *l)
272 precision = luaL_checkinteger(l, 1); 267 precision = luaL_checkinteger(l, 1);
273 luaL_argcheck(l, 1 <= precision && precision <= 14, 1, 268 luaL_argcheck(l, 1 <= precision && precision <= 14, 1,
274 "expected integer between 1 and 14"); 269 "expected integer between 1 and 14");
275 json_set_number_precision(cfg, precision); 270 cfg->encode_number_precision = precision;
276 } 271 }
277 272
278 lua_pushinteger(l, cfg->encode_number_precision); 273 lua_pushinteger(l, cfg->encode_number_precision);
@@ -342,6 +337,13 @@ static int json_cfg_refuse_invalid_numbers(lua_State *l)
342 return 1; 337 return 1;
343} 338}
344 339
340static int json_update_locale(lua_State *l)
341{
342 fpconv_update_locale();
343
344 return 0;
345}
346
345static int json_destroy_config(lua_State *l) 347static int json_destroy_config(lua_State *l)
346{ 348{
347 json_config_t *cfg; 349 json_config_t *cfg;
@@ -376,7 +378,7 @@ static void json_create_config(lua_State *l)
376 cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM; 378 cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM;
377 cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM; 379 cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM;
378 cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; 380 cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER;
379 json_set_number_precision(cfg, 14); 381 cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION;
380 382
381 /* Decoding init */ 383 /* Decoding init */
382 384
@@ -562,6 +564,7 @@ static void json_append_number(lua_State *l, strbuf_t *json, int index,
562 json_config_t *cfg) 564 json_config_t *cfg)
563{ 565{
564 double num = lua_tonumber(l, index); 566 double num = lua_tonumber(l, index);
567 int len;
565 568
566 if (cfg->encode_refuse_badnum && (isinf(num) || isnan(num))) 569 if (cfg->encode_refuse_badnum && (isinf(num) || isnan(num)))
567 json_encode_exception(l, cfg, index, "must not be NaN or Inf"); 570 json_encode_exception(l, cfg, index, "must not be NaN or Inf");
@@ -571,11 +574,10 @@ static void json_append_number(lua_State *l, strbuf_t *json, int index,
571 strbuf_append_mem(json, "nan", 3); 574 strbuf_append_mem(json, "nan", 3);
572 } else { 575 } else {
573 /* Longest double printed with %.14g is 21 characters long: 576 /* Longest double printed with %.14g is 21 characters long:
574 * -1.7976931348623e+308 577 * -1.7976931348623e+308 */
575 * 578 strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE);
576 * Use 32 to include the \0, and a few extra just in case.. 579 len = fpconv_g_fmt(strbuf_empty_ptr(json), num, cfg->encode_number_precision);
577 */ 580 strbuf_extend_length(json, len);
578 strbuf_append_fmt(json, 32, cfg->number_fmt, num);
579 } 581 }
580} 582}
581 583
@@ -963,7 +965,7 @@ static void json_next_number_token(json_parse_t *json, json_token_t *token)
963 965
964 token->type = T_NUMBER; 966 token->type = T_NUMBER;
965 startptr = &json->data[json->index]; 967 startptr = &json->data[json->index];
966 token->value.number = strtod(&json->data[json->index], &endptr); 968 token->value.number = fpconv_strtod(&json->data[json->index], &endptr);
967 if (startptr == endptr) 969 if (startptr == endptr)
968 json_set_token_error(token, json, "invalid number"); 970 json_set_token_error(token, json, "invalid number");
969 else 971 else
@@ -1254,9 +1256,13 @@ int luaopen_cjson(lua_State *l)
1254 { "encode_number_precision", json_cfg_encode_number_precision }, 1256 { "encode_number_precision", json_cfg_encode_number_precision },
1255 { "encode_keep_buffer", json_cfg_encode_keep_buffer }, 1257 { "encode_keep_buffer", json_cfg_encode_keep_buffer },
1256 { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers }, 1258 { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers },
1259 { "update_locale", json_update_locale },
1257 { NULL, NULL } 1260 { NULL, NULL }
1258 }; 1261 };
1259 1262
1263 /* Update the current locale for g_fmt/strtod */
1264 fpconv_update_locale();
1265
1260 /* Use json_config_key as a pointer. 1266 /* Use json_config_key as a pointer.
1261 * It's faster than using a config string, and more unique */ 1267 * It's faster than using a config string, and more unique */
1262 lua_pushlightuserdata(l, &json_config_key); 1268 lua_pushlightuserdata(l, &json_config_key);