diff --git a/.gitignore b/.gitignore index 948a9ca..0698594 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,11 @@ notes packages tags tests/utf8.dat +*.vcproj +*.sln +CMakeCache.txt +CMakeFiles/* +cjson.def +cjson.exp +*.dll* +cmake_install.cmake \ No newline at end of file diff --git a/fpconv.c b/fpconv.c index 7990831..fc22d67 100644 --- a/fpconv.c +++ b/fpconv.c @@ -35,6 +35,10 @@ #include "fpconv.h" +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + /* Lua CJSON assumes the locale is the same for all threads within a * process and doesn't change after initialisation. * @@ -124,7 +128,7 @@ double fpconv_strtod(const char *nptr, char **endptr) /* Duplicate number into buffer */ if (buflen >= FPCONV_G_FMT_BUFSIZE) { /* Handle unusually large numbers */ - buf = malloc(buflen + 1); + buf = (char *)malloc(buflen + 1); if (!buf) { fprintf(stderr, "Out of memory"); abort(); @@ -196,10 +200,12 @@ int fpconv_g_fmt(char *str, double num, int precision) return len; } +#ifndef USE_INTERNAL_FPCONV void fpconv_init() { fpconv_update_locale(); } +#endif /* vi:ai et sw=4 ts=4: */ diff --git a/fpconv.h b/fpconv.h index 0124908..b3e2c3c 100644 --- a/fpconv.h +++ b/fpconv.h @@ -6,6 +6,10 @@ * -1.7976931348623e+308 */ # define FPCONV_G_FMT_BUFSIZE 32 +#ifdef _MSC_VER +#define inline +#endif + #ifdef USE_INTERNAL_FPCONV static inline void fpconv_init() { diff --git a/lua-cjson-git-1.rockspec b/lua-cjson-git-1.rockspec new file mode 100644 index 0000000..8c9d360 --- /dev/null +++ b/lua-cjson-git-1.rockspec @@ -0,0 +1,62 @@ +package = "lua-cjson" +version = "git-1" + +description = { + summary = "A fast JSON encoding/parsing module", + detailed = [[ + The Lua CJSON module provides JSON support for Lua. It features: + - Fast, standards compliant encoding/parsing routines + - Full support for JSON with UTF-8, including decoding surrogate pairs + - Optional run-time support for common exceptions to the JSON specification + (infinity, NaN,..) + - No dependencies on other libraries + ]], + homepage = "http://www.kyne.com.au/~mark/software/lua-cjson.php", + license = "MIT" +} + +source = { + url = "https://git.inconcert/lua-libraries/lua-cjson", + dir = "lua-cjson" +} + +dependencies = { + "lua >= 5.1" +} + +build = { + type = "builtin", + modules = { + cjson = { + defines = { "MULTIPLE_THREADS" }, + sources = { "lua_cjson.c", "strbuf.c", "fpconv.c" }, + defines = { +-- LuaRocks does not support platform specific configuration for Solaris. +-- Uncomment the line below on Solaris platforms if required. +-- "USE_INTERNAL_ISINF" + } + } + }, + install = { + lua = { + ["cjson.util"] = "lua/cjson/util.lua" + }, + bin = { + json2lua = "lua/json2lua.lua", + lua2json = "lua/lua2json.lua" + } + }, + -- Override default build options (per platform) + platforms = { + win32 = { modules = { cjson = { defines = { + "MULTIPLE_THREADS", "DISABLE_INVALID_NUMBERS" + } } } } + }, + copy_directories = { "tests" } +} + +-- Para compilar lua-cjson en windows: +-- luarocks make CFLAGS="/TP /MD /O2 -DMULTIPLE_THREADS -DUSE_INTERNAL_FPCONV" + + +-- vi:ai et sw=4 ts=4: diff --git a/lua_cjson.c b/lua_cjson.c index c14a1c5..604cbd5 100644 --- a/lua_cjson.c +++ b/lua_cjson.c @@ -40,7 +40,13 @@ #include #include #include + +#ifdef __cplusplus +#include +#else #include +#endif + #include #include "strbuf.h" @@ -59,6 +65,14 @@ #define isinf(x) (!isnan(x) && isnan((x) - (x))) #endif +#ifdef _MSC_VER +#define snprintf _snprintf +#define strncasecmp _strnicmp +#include +#define isnan(x) _isnan(x) +#define isinf(x) (!isnan(x) && isnan((x) - (x))) +#endif + #define DEFAULT_SPARSE_CONVERT 0 #define DEFAULT_SPARSE_RATIO 2 #define DEFAULT_SPARSE_SAFE 10 @@ -68,6 +82,7 @@ #define DEFAULT_DECODE_INVALID_NUMBERS 1 #define DEFAULT_ENCODE_KEEP_BUFFER 1 #define DEFAULT_ENCODE_NUMBER_PRECISION 14 +#define DEFAULT_ENCODE_EMPTY_TABLE_AS_ARRAY 0 /* 0 table, 1 array */ #ifdef DISABLE_INVALID_NUMBERS #undef DEFAULT_DECODE_INVALID_NUMBERS @@ -124,6 +139,7 @@ typedef struct { int encode_invalid_numbers; /* 2 => Encode as "null" */ int encode_number_precision; int encode_keep_buffer; + int encode_empty_table_as_array; int decode_invalid_numbers; int decode_max_depth; @@ -193,7 +209,7 @@ static json_config_t *json_fetch_config(lua_State *l) { json_config_t *cfg; - cfg = lua_touserdata(l, lua_upvalueindex(1)); + cfg = (json_config_t *)lua_touserdata(l, lua_upvalueindex(1)); if (!cfg) luaL_error(l, "BUG: Unable to fetch CJSON configuration"); @@ -321,6 +337,13 @@ static int json_cfg_encode_keep_buffer(lua_State *l) return 1; } +/* Configures whether empty tables will be encoded as an object or an array */ +static int json_cfg_encode_empty_tables_as_array(lua_State *l) +{ + json_config_t *cfg = json_arg_init(l, 1); + return json_enum_option(l, 1, &cfg->encode_empty_table_as_array, NULL, 1); +} + #if defined(DISABLE_INVALID_NUMBERS) && !defined(USE_INTERNAL_FPCONV) void json_verify_invalid_number_setting(lua_State *l, int *setting) { @@ -360,7 +383,7 @@ static int json_destroy_config(lua_State *l) { json_config_t *cfg; - cfg = lua_touserdata(l, 1); + cfg = (json_config_t *)lua_touserdata(l, 1); if (cfg) strbuf_free(&cfg->encode_buf); cfg = NULL; @@ -373,7 +396,7 @@ static void json_create_config(lua_State *l) json_config_t *cfg; int i; - cfg = lua_newuserdata(l, sizeof(*cfg)); + cfg = (json_config_t *)lua_newuserdata(l, sizeof(*cfg)); /* Create GC method to clean up strbuf */ lua_newtable(l); @@ -390,6 +413,7 @@ static void json_create_config(lua_State *l) cfg->decode_invalid_numbers = DEFAULT_DECODE_INVALID_NUMBERS; cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION; + cfg->encode_empty_table_as_array = DEFAULT_ENCODE_EMPTY_TABLE_AS_ARRAY; #if DEFAULT_ENCODE_KEEP_BUFFER > 0 strbuf_init(&cfg->encode_buf, 0); @@ -685,7 +709,7 @@ static void json_append_data(lua_State *l, json_config_t *cfg, current_depth++; json_check_encode_depth(l, cfg, current_depth, json); len = lua_array_length(l, cfg, json); - if (len > 0) + if (len > 0 || (cfg->encode_empty_table_as_array && len == 0)) json_append_array(l, cfg, current_depth, json, len); else json_append_object(l, cfg, current_depth, json); @@ -1359,6 +1383,7 @@ static int lua_cjson_new(lua_State *l) { "encode_keep_buffer", json_cfg_encode_keep_buffer }, { "encode_invalid_numbers", json_cfg_encode_invalid_numbers }, { "decode_invalid_numbers", json_cfg_decode_invalid_numbers }, + { "encode_empty_table_as_array", json_cfg_encode_empty_tables_as_array }, { "new", lua_cjson_new }, { NULL, NULL } }; @@ -1407,7 +1432,13 @@ static int lua_cjson_safe_new(lua_State *l) return 1; } -int luaopen_cjson(lua_State *l) +#ifdef _MSC_VER +#define EXPORT_API __declspec(dllexport) +#else +#define EXPORT_API +#endif + +int EXPORT_API luaopen_cjson(lua_State *l) { lua_cjson_new(l); @@ -1421,7 +1452,7 @@ int luaopen_cjson(lua_State *l) return 1; } -int luaopen_cjson_safe(lua_State *l) +int EXPORT_API luaopen_cjson_safe(lua_State *l) { lua_cjson_safe_new(l); diff --git a/strbuf.c b/strbuf.c index f0f7f4b..147f27a 100644 --- a/strbuf.c +++ b/strbuf.c @@ -58,7 +58,7 @@ void strbuf_init(strbuf_t *s, int len) s->reallocs = 0; s->debug = 0; - s->buf = malloc(size); + s->buf = (char *)malloc(size); if (!s->buf) die("Out of memory"); @@ -69,7 +69,7 @@ strbuf_t *strbuf_new(int len) { strbuf_t *s; - s = malloc(sizeof(strbuf_t)); + s = (strbuf_t *)malloc(sizeof(strbuf_t)); if (!s) die("Out of memory"); @@ -173,7 +173,7 @@ void strbuf_resize(strbuf_t *s, int len) } s->size = newsize; - s->buf = realloc(s->buf, s->size); + s->buf = (char *)realloc(s->buf, s->size); if (!s->buf) die("Out of memory"); s->reallocs++; @@ -221,12 +221,12 @@ void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...) void strbuf_append_fmt_retry(strbuf_t *s, const char *fmt, ...) { va_list arg; - int fmt_len, try; + int fmt_len, attempt; int empty_len; /* If the first attempt to append fails, resize the buffer appropriately * and try again */ - for (try = 0; ; try++) { + for (attempt = 0; ; attempt++) { va_start(arg, fmt); /* Append the new formatted string */ /* fmt_len is the length of the string required, excluding the @@ -238,7 +238,7 @@ void strbuf_append_fmt_retry(strbuf_t *s, const char *fmt, ...) if (fmt_len <= empty_len) break; /* SUCCESS */ - if (try > 0) + if (attempt > 0) die("BUG: length of formatted string changed"); strbuf_resize(s, s->length + fmt_len); diff --git a/strbuf.h b/strbuf.h index d861108..05b4878 100644 --- a/strbuf.h +++ b/strbuf.h @@ -48,6 +48,10 @@ typedef struct { #define STRBUF_DEFAULT_INCREMENT -2 #endif +#ifdef _MSC_VER +#define inline +#endif + /* Initialise */ extern strbuf_t *strbuf_new(int len); extern void strbuf_init(strbuf_t *s, int len);