diff options
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | lua_cjson.c | 73 | ||||
| -rw-r--r-- | manual.txt | 61 | ||||
| -rwxr-xr-x | tests/bench.lua | 2 | ||||
| -rw-r--r-- | tests/common.lua | 6 | ||||
| -rwxr-xr-x | tests/decode.lua | 4 | ||||
| -rwxr-xr-x | tests/encode.lua | 4 | ||||
| -rwxr-xr-x | tests/test.lua | 16 |
8 files changed, 122 insertions, 47 deletions
| @@ -2,7 +2,8 @@ LUA_VERSION = 5.1 | |||
| 2 | 2 | ||
| 3 | ## Available defines for CJSON_CFLAGS | 3 | ## Available defines for CJSON_CFLAGS |
| 4 | # | 4 | # |
| 5 | # USE_INTERNAL_ISINF: Workaround for Solaris platforms missing isinf(). | 5 | # USE_INTERNAL_ISINF: Workaround for Solaris platforms missing isinf(). |
| 6 | # DISABLE_CJSON_GLOBAL: Do not store module is "cjson" global | ||
| 6 | 7 | ||
| 7 | ## Build defaults | 8 | ## Build defaults |
| 8 | PREFIX = /usr/local | 9 | PREFIX = /usr/local |
diff --git a/lua_cjson.c b/lua_cjson.c index 8e9b237..be5cdc2 100644 --- a/lua_cjson.c +++ b/lua_cjson.c | |||
| @@ -45,6 +45,10 @@ | |||
| 45 | #include "strbuf.h" | 45 | #include "strbuf.h" |
| 46 | #include "fpconv.h" | 46 | #include "fpconv.h" |
| 47 | 47 | ||
| 48 | #ifndef CJSON_MODNAME | ||
| 49 | #define CJSON_MODNAME "cjson" | ||
| 50 | #endif | ||
| 51 | |||
| 48 | #ifndef CJSON_VERSION | 52 | #ifndef CJSON_VERSION |
| 49 | #define CJSON_VERSION "1.0devel" | 53 | #define CJSON_VERSION "1.0devel" |
| 50 | #endif | 54 | #endif |
| @@ -175,22 +179,16 @@ static const char *char2escape[256] = { | |||
| 175 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 179 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| 176 | }; | 180 | }; |
| 177 | 181 | ||
| 178 | static int json_config_key; | ||
| 179 | |||
| 180 | /* ===== CONFIGURATION ===== */ | 182 | /* ===== CONFIGURATION ===== */ |
| 181 | 183 | ||
| 182 | static json_config_t *json_fetch_config(lua_State *l) | 184 | static json_config_t *json_fetch_config(lua_State *l) |
| 183 | { | 185 | { |
| 184 | json_config_t *cfg; | 186 | json_config_t *cfg; |
| 185 | 187 | ||
| 186 | lua_pushlightuserdata(l, &json_config_key); | 188 | cfg = lua_touserdata(l, lua_upvalueindex(1)); |
| 187 | lua_gettable(l, LUA_REGISTRYINDEX); | ||
| 188 | cfg = lua_touserdata(l, -1); | ||
| 189 | if (!cfg) | 189 | if (!cfg) |
| 190 | luaL_error(l, "BUG: Unable to fetch CJSON configuration"); | 190 | luaL_error(l, "BUG: Unable to fetch CJSON configuration"); |
| 191 | 191 | ||
| 192 | lua_pop(l, 1); | ||
| 193 | |||
| 194 | return cfg; | 192 | return cfg; |
| 195 | } | 193 | } |
| 196 | 194 | ||
| @@ -1246,7 +1244,27 @@ static int json_decode(lua_State *l) | |||
| 1246 | 1244 | ||
| 1247 | /* ===== INITIALISATION ===== */ | 1245 | /* ===== INITIALISATION ===== */ |
| 1248 | 1246 | ||
| 1249 | int luaopen_cjson(lua_State *l) | 1247 | #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502 |
| 1248 | /* Compatibility for Lua 5.1. | ||
| 1249 | * | ||
| 1250 | * luaL_setfuncs() is used to create a module table where the functions have | ||
| 1251 | * json_config_t as their first upvalue. Code borrowed from Lua 5.2 source. */ | ||
| 1252 | static void luaL_setfuncs (lua_State *l, const luaL_Reg *reg, int nup) | ||
| 1253 | { | ||
| 1254 | int i; | ||
| 1255 | |||
| 1256 | luaL_checkstack(l, nup, "too many upvalues"); | ||
| 1257 | for (; reg->name != NULL; reg++) { /* fill the table with given functions */ | ||
| 1258 | for (i = 0; i < nup; i++) /* copy upvalues to the top */ | ||
| 1259 | lua_pushvalue(l, -nup); | ||
| 1260 | lua_pushcclosure(l, reg->func, nup); /* closure with those upvalues */ | ||
| 1261 | lua_setfield(l, -(nup + 2), reg->name); | ||
| 1262 | } | ||
| 1263 | lua_pop(l, nup); /* remove upvalues */ | ||
| 1264 | } | ||
| 1265 | #endif | ||
| 1266 | |||
| 1267 | static int lua_cjson_new(lua_State *l) | ||
| 1250 | { | 1268 | { |
| 1251 | luaL_Reg reg[] = { | 1269 | luaL_Reg reg[] = { |
| 1252 | { "encode", json_encode }, | 1270 | { "encode", json_encode }, |
| @@ -1257,28 +1275,51 @@ int luaopen_cjson(lua_State *l) | |||
| 1257 | { "encode_keep_buffer", json_cfg_encode_keep_buffer }, | 1275 | { "encode_keep_buffer", json_cfg_encode_keep_buffer }, |
| 1258 | { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers }, | 1276 | { "refuse_invalid_numbers", json_cfg_refuse_invalid_numbers }, |
| 1259 | { "update_locale", json_update_locale }, | 1277 | { "update_locale", json_update_locale }, |
| 1278 | { "new", lua_cjson_new }, | ||
| 1260 | { NULL, NULL } | 1279 | { NULL, NULL } |
| 1261 | }; | 1280 | }; |
| 1262 | 1281 | ||
| 1263 | /* Update the current locale for g_fmt/strtod */ | 1282 | /* Update the current locale for g_fmt/strtod. |
| 1283 | * Using different locales per-thread is not supported. */ | ||
| 1264 | fpconv_update_locale(); | 1284 | fpconv_update_locale(); |
| 1265 | 1285 | ||
| 1266 | /* Use json_config_key as a pointer. | 1286 | /* cjson module table */ |
| 1267 | * It's faster than using a config string, and more unique */ | 1287 | lua_newtable(l); |
| 1268 | lua_pushlightuserdata(l, &json_config_key); | ||
| 1269 | json_create_config(l); | ||
| 1270 | lua_settable(l, LUA_REGISTRYINDEX); | ||
| 1271 | 1288 | ||
| 1272 | luaL_register(l, "cjson", reg); | 1289 | /* Register functions with config data as upvalue */ |
| 1290 | json_create_config(l); | ||
| 1291 | luaL_setfuncs(l, reg, 1); | ||
| 1273 | 1292 | ||
| 1274 | /* Set cjson.null */ | 1293 | /* Set cjson.null */ |
| 1275 | lua_pushlightuserdata(l, NULL); | 1294 | lua_pushlightuserdata(l, NULL); |
| 1276 | lua_setfield(l, -2, "null"); | 1295 | lua_setfield(l, -2, "null"); |
| 1277 | 1296 | ||
| 1278 | /* Set cjson.version */ | 1297 | /* Set module name / version fields */ |
| 1298 | lua_pushliteral(l, CJSON_MODNAME); | ||
| 1299 | lua_setfield(l, -2, "_NAME"); | ||
| 1300 | lua_pushliteral(l, CJSON_VERSION); | ||
| 1301 | lua_setfield(l, -2, "_VERSION"); | ||
| 1279 | lua_pushliteral(l, CJSON_VERSION); | 1302 | lua_pushliteral(l, CJSON_VERSION); |
| 1280 | lua_setfield(l, -2, "version"); | 1303 | lua_setfield(l, -2, "version"); |
| 1281 | 1304 | ||
| 1305 | return 1; | ||
| 1306 | } | ||
| 1307 | |||
| 1308 | int luaopen_cjson(lua_State *l) | ||
| 1309 | { | ||
| 1310 | lua_cjson_new(l); | ||
| 1311 | |||
| 1312 | #if !defined(DISABLE_CJSON_GLOBAL) && (!defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 502) | ||
| 1313 | /* Register a global "cjson" table to maintain compatibility with earlier | ||
| 1314 | * versions of Lua CJSON which used luaL_register() under Lua 5.1. | ||
| 1315 | * | ||
| 1316 | * From Lua 5.2 onwards, Lua CJSON does not automatically register a global | ||
| 1317 | * table. | ||
| 1318 | */ | ||
| 1319 | lua_pushvalue(l, -1); | ||
| 1320 | lua_setglobal(l, CJSON_MODNAME); | ||
| 1321 | #endif | ||
| 1322 | |||
| 1282 | /* Return cjson table */ | 1323 | /* Return cjson table */ |
| 1283 | return 1; | 1324 | return 1; |
| 1284 | } | 1325 | } |
| @@ -16,8 +16,6 @@ Lua CJSON provides fast JSON parsing and encoding support for Lua. | |||
| 16 | 16 | ||
| 17 | .Caveats | 17 | .Caveats |
| 18 | - UTF-16 and UTF-32 are not supported. | 18 | - UTF-16 and UTF-32 are not supported. |
| 19 | - Multi-threading within a single Lua state is not supported | ||
| 20 | (+lua_lock+ / +lua_unlock+). | ||
| 21 | 19 | ||
| 22 | Lua CJSON is covered by the MIT license. Review the file +LICENSE+ for | 20 | Lua CJSON is covered by the MIT license. Review the file +LICENSE+ for |
| 23 | details. | 21 | details. |
| @@ -32,7 +30,7 @@ comments. | |||
| 32 | Installation Methods | 30 | Installation Methods |
| 33 | -------------------- | 31 | -------------------- |
| 34 | 32 | ||
| 35 | Lua CJSON requires either http://www.lua.org[Lua] or | 33 | Lua CJSON requires either http://www.lua.org[Lua] 5.1, Lua 5.2, or |
| 36 | http://www.luajit.org[LuaJIT] to build. | 34 | http://www.luajit.org[LuaJIT] to build. |
| 37 | 35 | ||
| 38 | There are 4 build methods available: | 36 | There are 4 build methods available: |
| @@ -44,11 +42,13 @@ RPM:: Linux | |||
| 44 | LuaRocks:: Unix, Windows | 42 | LuaRocks:: Unix, Windows |
| 45 | 43 | ||
| 46 | 44 | ||
| 47 | Build options (#define) | 45 | Build Options (#define) |
| 48 | ~~~~~~~~~~~~~~~~~~~~~~~ | 46 | ~~~~~~~~~~~~~~~~~~~~~~~ |
| 49 | 47 | ||
| 50 | [horizontal] | 48 | [horizontal] |
| 51 | USE_INTERNAL_ISINF:: Workaround for Solaris platforms missing isinf(). | 49 | USE_INTERNAL_ISINF:: Workaround for Solaris platforms missing isinf(). |
| 50 | DISABLE_CJSON_GLOBAL:: Do not store module table in global "cjson" | ||
| 51 | variable. | ||
| 52 | 52 | ||
| 53 | 53 | ||
| 54 | Make | 54 | Make |
| @@ -125,9 +125,9 @@ Synopsis | |||
| 125 | 125 | ||
| 126 | [source,lua] | 126 | [source,lua] |
| 127 | ------------ | 127 | ------------ |
| 128 | require "cjson" | 128 | -- Module initalisation methods |
| 129 | -- Or: | ||
| 130 | local cjson = require "cjson" | 129 | local cjson = require "cjson" |
| 130 | local cjson2 = cjson.new() | ||
| 131 | 131 | ||
| 132 | -- Translate Lua value to/from JSON | 132 | -- Translate Lua value to/from JSON |
| 133 | text = cjson.encode(value) | 133 | text = cjson.encode(value) |
| @@ -141,6 +141,34 @@ keep = cjson.encode_keep_buffer([keep]) | |||
| 141 | ------------ | 141 | ------------ |
| 142 | 142 | ||
| 143 | 143 | ||
| 144 | Module Instantiation | ||
| 145 | ~~~~~~~~~~~~~~~~~~~~ | ||
| 146 | |||
| 147 | [source,lua] | ||
| 148 | ------------ | ||
| 149 | local cjson = require "cjson" | ||
| 150 | local cjson2 = cjson.new() | ||
| 151 | ------------ | ||
| 152 | |||
| 153 | Lua CJSON can be loaded via +require+. A global +cjson+ table is | ||
| 154 | registered under Lua 5.1 to maintain backward compatibility. Lua CJSON | ||
| 155 | does not register a global table under Lua 5.2 since this practice is | ||
| 156 | discouraged. | ||
| 157 | |||
| 158 | +cjson.new+ can be used to instantiate an independent copy of the Lua | ||
| 159 | CJSON module. The new module has a separate persistent encoding | ||
| 160 | buffer, and default settings. | ||
| 161 | |||
| 162 | Lua CJSON can support Lua implementations using multiple pre-emptive | ||
| 163 | threads within a single Lua state provided the persistent encoding | ||
| 164 | buffer is not shared. This can be achieved by one of the following | ||
| 165 | methods: | ||
| 166 | |||
| 167 | - Disabling the persistent encoding buffer with +encode_keep_buffer+. | ||
| 168 | - Ensuring only a single thread calls +encode+ at a time. | ||
| 169 | - Using a separate +cjson+ instantiation per pre-emptive thread. | ||
| 170 | |||
| 171 | |||
| 144 | decode | 172 | decode |
| 145 | ~~~~~~ | 173 | ~~~~~~ |
| 146 | 174 | ||
| @@ -423,6 +451,18 @@ Disabled for decoding:: All numbers supported by +strtod+(3) will be parsed. | |||
| 423 | API (Variables) | 451 | API (Variables) |
| 424 | --------------- | 452 | --------------- |
| 425 | 453 | ||
| 454 | _NAME | ||
| 455 | ~~~~~ | ||
| 456 | |||
| 457 | The name of the Lua CJSON module (+"cjson"+). | ||
| 458 | |||
| 459 | |||
| 460 | _VERSION | ||
| 461 | ~~~~~~~~ | ||
| 462 | |||
| 463 | The version number of the Lua CJSON module (Eg, +"1.0devel"+). | ||
| 464 | |||
| 465 | |||
| 426 | null | 466 | null |
| 427 | ~~~~ | 467 | ~~~~ |
| 428 | 468 | ||
| @@ -430,13 +470,6 @@ Lua CJSON decodes JSON +null+ as a Lua +lightuserdata+ NULL pointer. | |||
| 430 | +cjson.null+ is provided for comparison. | 470 | +cjson.null+ is provided for comparison. |
| 431 | 471 | ||
| 432 | 472 | ||
| 433 | version | ||
| 434 | ~~~~~~~ | ||
| 435 | |||
| 436 | The version number of the Lua CJSON module in use can be found in | ||
| 437 | +cjson.version+. | ||
| 438 | |||
| 439 | |||
| 440 | [sect1] | 473 | [sect1] |
| 441 | References | 474 | References |
| 442 | ---------- | 475 | ---------- |
| @@ -445,4 +478,4 @@ References | |||
| 445 | - http://www.json.org/[JSON website] | 478 | - http://www.json.org/[JSON website] |
| 446 | 479 | ||
| 447 | 480 | ||
| 448 | // vi:tw=70: | 481 | // vi:ft=asciidoc tw=70: |
diff --git a/tests/bench.lua b/tests/bench.lua index fdd0bb0..c81213d 100755 --- a/tests/bench.lua +++ b/tests/bench.lua | |||
| @@ -72,7 +72,7 @@ function bench_file(filename) | |||
| 72 | return benchmark(tests, 0.1, 5) | 72 | return benchmark(tests, 0.1, 5) |
| 73 | end | 73 | end |
| 74 | 74 | ||
| 75 | cjson.encode_keep_buffer(true) | 75 | json.encode_keep_buffer(true) |
| 76 | 76 | ||
| 77 | for i = 1, #arg do | 77 | for i = 1, #arg do |
| 78 | local results = bench_file(arg[i]) | 78 | local results = bench_file(arg[i]) |
diff --git a/tests/common.lua b/tests/common.lua index f3dc6f7..7472a10 100644 --- a/tests/common.lua +++ b/tests/common.lua | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | require "cjson" | 1 | local json = require "cjson" |
| 2 | 2 | ||
| 3 | -- Misc routines to assist with CJSON testing | 3 | -- Misc routines to assist with CJSON testing |
| 4 | -- | 4 | -- |
| @@ -77,8 +77,8 @@ function serialise_value(value, indent, depth) | |||
| 77 | if indent == nil then indent = "" end | 77 | if indent == nil then indent = "" end |
| 78 | if depth == nil then depth = 0 end | 78 | if depth == nil then depth = 0 end |
| 79 | 79 | ||
| 80 | if value == cjson.null then | 80 | if value == json.null then |
| 81 | return "cjson.null" | 81 | return "json.null" |
| 82 | elseif type(value) == "string" then | 82 | elseif type(value) == "string" then |
| 83 | return string.format("%q", value) | 83 | return string.format("%q", value) |
| 84 | elseif type(value) == "nil" or type(value) == "number" or | 84 | elseif type(value) == "nil" or type(value) == "number" or |
diff --git a/tests/decode.lua b/tests/decode.lua index cac29e6..89354cd 100755 --- a/tests/decode.lua +++ b/tests/decode.lua | |||
| @@ -7,8 +7,8 @@ | |||
| 7 | -- ./decode.lua test.json | 7 | -- ./decode.lua test.json |
| 8 | 8 | ||
| 9 | require "common" | 9 | require "common" |
| 10 | require "cjson" | 10 | local json = require "cjson" |
| 11 | 11 | ||
| 12 | local json_text = file_load(arg[1]) | 12 | local json_text = file_load(arg[1]) |
| 13 | local t = cjson.decode(json_text) | 13 | local t = json.decode(json_text) |
| 14 | print(serialise_value(t)) | 14 | print(serialise_value(t)) |
diff --git a/tests/encode.lua b/tests/encode.lua index f13787c..a8d749a 100755 --- a/tests/encode.lua +++ b/tests/encode.lua | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | -- ./encode.lua lua_data.lua | 7 | -- ./encode.lua lua_data.lua |
| 8 | 8 | ||
| 9 | require "common" | 9 | require "common" |
| 10 | require "cjson" | 10 | local json = require "cjson" |
| 11 | 11 | ||
| 12 | function get_lua_table(file) | 12 | function get_lua_table(file) |
| 13 | local func = loadstring("data = " .. file_load(file)) | 13 | local func = loadstring("data = " .. file_load(file)) |
| @@ -23,6 +23,6 @@ function get_lua_table(file) | |||
| 23 | end | 23 | end |
| 24 | 24 | ||
| 25 | local t = get_lua_table(arg[1]) | 25 | local t = get_lua_table(arg[1]) |
| 26 | print(cjson.encode(t)) | 26 | print(json.encode(t)) |
| 27 | 27 | ||
| 28 | -- vi:ai et sw=4 ts=4: | 28 | -- vi:ai et sw=4 ts=4: |
diff --git a/tests/test.lua b/tests/test.lua index bdae6ea..99ac73a 100755 --- a/tests/test.lua +++ b/tests/test.lua | |||
| @@ -112,8 +112,8 @@ local decode_numeric_tests = { | |||
| 112 | 112 | ||
| 113 | local encode_table_tests = { | 113 | local encode_table_tests = { |
| 114 | function() | 114 | function() |
| 115 | cjson.encode_sparse_array(true, 2, 3) | 115 | json.encode_sparse_array(true, 2, 3) |
| 116 | cjson.encode_max_depth(5) | 116 | json.encode_max_depth(5) |
| 117 | return "Setting sparse array (true, 2, 3) / max depth (5)" | 117 | return "Setting sparse array (true, 2, 3) / max depth (5)" |
| 118 | end, | 118 | end, |
| 119 | { json.encode, { { [3] = "sparse test" } }, | 119 | { json.encode, { { [3] = "sparse test" } }, |
| @@ -211,19 +211,19 @@ local escape_tests = { | |||
| 211 | local locale_tests = { | 211 | local locale_tests = { |
| 212 | function () | 212 | function () |
| 213 | os.setlocale("cs_CZ") | 213 | os.setlocale("cs_CZ") |
| 214 | cjson.update_locale() | 214 | json.update_locale() |
| 215 | return "Setting locale to cs_CZ (comma separator)" | 215 | return "Setting locale to cs_CZ (comma separator)" |
| 216 | end, | 216 | end, |
| 217 | { json.encode, { 1.5 }, true, { '1.5' } }, | 217 | { json.encode, { 1.5 }, true, { '1.5' } }, |
| 218 | { json.decode, { "[ 10, \"test\" ]" }, true, { { 10, "test" } } }, | 218 | { json.decode, { "[ 10, \"test\" ]" }, true, { { 10, "test" } } }, |
| 219 | function () | 219 | function () |
| 220 | os.setlocale("C") | 220 | os.setlocale("C") |
| 221 | cjson.update_locale() | 221 | json.update_locale() |
| 222 | return "Reverting locale to POSIX" | 222 | return "Reverting locale to POSIX" |
| 223 | end | 223 | end |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | print(string.format("Testing Lua CJSON version %s\n", cjson.version)) | 226 | print(string.format("Testing Lua CJSON version %s\n", json.version)) |
| 227 | 227 | ||
| 228 | run_test_group("decode simple value", decode_simple_tests) | 228 | run_test_group("decode simple value", decode_simple_tests) |
| 229 | run_test_group("encode simple value", encode_simple_tests) | 229 | run_test_group("encode simple value", encode_simple_tests) |
| @@ -232,7 +232,7 @@ run_test_group("decode numeric", decode_numeric_tests) | |||
| 232 | -- INCLUDE: | 232 | -- INCLUDE: |
| 233 | -- - Sparse array exception.. | 233 | -- - Sparse array exception.. |
| 234 | -- - .. | 234 | -- - .. |
| 235 | -- cjson.encode_sparse_array(true, 2, 3) | 235 | -- json.encode_sparse_array(true, 2, 3) |
| 236 | 236 | ||
| 237 | run_test_group("encode table", encode_table_tests) | 237 | run_test_group("encode table", encode_table_tests) |
| 238 | run_test_group("decode error", decode_error_tests) | 238 | run_test_group("decode error", decode_error_tests) |
| @@ -240,8 +240,8 @@ run_test_group("encode error", encode_error_tests) | |||
| 240 | run_test_group("escape", escape_tests) | 240 | run_test_group("escape", escape_tests) |
| 241 | run_test_group("locale", locale_tests) | 241 | run_test_group("locale", locale_tests) |
| 242 | 242 | ||
| 243 | cjson.refuse_invalid_numbers(false) | 243 | json.refuse_invalid_numbers(false) |
| 244 | cjson.encode_max_depth(20) | 244 | json.encode_max_depth(20) |
| 245 | for i = 1, #arg do | 245 | for i = 1, #arg do |
| 246 | run_test("decode cycle " .. arg[i], test_decode_cycle, { arg[i] }, | 246 | run_test("decode cycle " .. arg[i], test_decode_cycle, { arg[i] }, |
| 247 | true, { true }) | 247 | true, { true }) |
