aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lua_cjson.c107
1 files changed, 47 insertions, 60 deletions
diff --git a/lua_cjson.c b/lua_cjson.c
index 9ec69cf..00fa2dd 100644
--- a/lua_cjson.c
+++ b/lua_cjson.c
@@ -200,55 +200,29 @@ static json_config_t *json_fetch_config(lua_State *l)
200 return cfg; 200 return cfg;
201} 201}
202 202
203static void json_verify_arg_count(lua_State *l, int args) 203/* Ensure the correct number of arguments have been provided.
204 * Pad with nil to allow other functions to simply check arg[i]
205 * to find whether an argument was provided */
206static json_config_t *json_arg_init(lua_State *l, int args)
204{ 207{
205 luaL_argcheck(l, lua_gettop(l) <= args, args + 1, 208 luaL_argcheck(l, lua_gettop(l) <= args, args + 1,
206 "found too many arguments"); 209 "found too many arguments");
207}
208
209/* Configures handling of extremely sparse arrays:
210 * convert: Convert extremely sparse arrays into objects? Otherwise error.
211 * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio
212 * safe: Always use an array when the max index <= safe */
213static int json_cfg_encode_sparse_array(lua_State *l)
214{
215 json_config_t *cfg;
216 int val;
217
218 json_verify_arg_count(l, 3);
219 cfg = json_fetch_config(l);
220
221 switch (lua_gettop(l)) {
222 case 3:
223 val = luaL_checkinteger(l, 3);
224 luaL_argcheck(l, val >= 0, 3, "expected integer >= 0");
225 cfg->encode_sparse_safe = val;
226 case 2:
227 val = luaL_checkinteger(l, 2);
228 luaL_argcheck(l, val >= 0, 2, "expected integer >= 0");
229 cfg->encode_sparse_ratio = val;
230 case 1:
231 luaL_argcheck(l, lua_isboolean(l, 1), 1, "expected boolean");
232 cfg->encode_sparse_convert = lua_toboolean(l, 1);
233 }
234 210
235 lua_pushboolean(l, cfg->encode_sparse_convert); 211 while (lua_gettop(l) < args)
236 lua_pushinteger(l, cfg->encode_sparse_ratio); 212 lua_pushnil(l);
237 lua_pushinteger(l, cfg->encode_sparse_safe);
238 213
239 return 3; 214 return json_fetch_config(l);
240} 215}
241 216
242/* Process integer options for configuration functions */ 217/* Process integer options for configuration functions */
243static int json_integer_option(lua_State *l, int *setting, int min, int max) 218static int json_integer_option(lua_State *l, int optindex, int *setting,
219 int min, int max)
244{ 220{
245 char errmsg[64]; 221 char errmsg[64];
246 int value; 222 int value;
247 223
248 json_verify_arg_count(l, 1); 224 if (!lua_isnil(l, optindex)) {
249 225 value = luaL_checkinteger(l, optindex);
250 if (lua_gettop(l)) {
251 value = luaL_checkinteger(l, 1);
252 snprintf(errmsg, sizeof(errmsg), "expected integer between %d and %d", min, max); 226 snprintf(errmsg, sizeof(errmsg), "expected integer between %d and %d", min, max);
253 luaL_argcheck(l, min <= value && value <= max, 1, errmsg); 227 luaL_argcheck(l, min <= value && value <= max, 1, errmsg);
254 *setting = value; 228 *setting = value;
@@ -260,7 +234,7 @@ static int json_integer_option(lua_State *l, int *setting, int min, int max)
260} 234}
261 235
262/* Process enumerated arguments for a configuration function */ 236/* Process enumerated arguments for a configuration function */
263static int json_enum_option(lua_State *l, int *setting, 237static int json_enum_option(lua_State *l, int optindex, int *setting,
264 const char **options, int bool_value) 238 const char **options, int bool_value)
265{ 239{
266 static const char *bool_options[] = { "off", "on", NULL }; 240 static const char *bool_options[] = { "off", "on", NULL };
@@ -270,11 +244,11 @@ static int json_enum_option(lua_State *l, int *setting,
270 bool_value = 1; 244 bool_value = 1;
271 } 245 }
272 246
273 if (lua_gettop(l)) { 247 if (!lua_isnil(l, optindex)) {
274 if (lua_isboolean(l, 1)) 248 if (lua_isboolean(l, optindex))
275 *setting = lua_toboolean(l, 1) * bool_value; 249 *setting = lua_toboolean(l, optindex) * bool_value;
276 else 250 else
277 *setting = luaL_checkoption(l, 1, NULL, options); 251 *setting = luaL_checkoption(l, optindex, NULL, options);
278 } 252 }
279 253
280 lua_pushstring(l, options[*setting]); 254 lua_pushstring(l, options[*setting]);
@@ -282,41 +256,56 @@ static int json_enum_option(lua_State *l, int *setting,
282 return 1; 256 return 1;
283} 257}
284 258
259/* Configures handling of extremely sparse arrays:
260 * convert: Convert extremely sparse arrays into objects? Otherwise error.
261 * ratio: 0: always allow sparse; 1: never allow sparse; >1: use ratio
262 * safe: Always use an array when the max index <= safe */
263static int json_cfg_encode_sparse_array(lua_State *l)
264{
265 json_config_t *cfg = json_arg_init(l, 3);
266
267 json_enum_option(l, 1, &cfg->encode_sparse_convert, NULL, 1);
268 json_integer_option(l, 2, &cfg->encode_sparse_ratio, 0, INT_MAX);
269 json_integer_option(l, 3, &cfg->encode_sparse_safe, 0, INT_MAX);
270
271 return 3;
272}
273
285/* Configures the maximum number of nested arrays/objects allowed when 274/* Configures the maximum number of nested arrays/objects allowed when
286 * encoding */ 275 * encoding */
287static int json_cfg_encode_max_depth(lua_State *l) 276static int json_cfg_encode_max_depth(lua_State *l)
288{ 277{
289 json_config_t *cfg = json_fetch_config(l); 278 json_config_t *cfg = json_arg_init(l, 1);
290 279
291 return json_integer_option(l, &cfg->encode_max_depth, 1, INT_MAX); 280 return json_integer_option(l, 1, &cfg->encode_max_depth, 1, INT_MAX);
292} 281}
293 282
294/* Configures the maximum number of nested arrays/objects allowed when 283/* Configures the maximum number of nested arrays/objects allowed when
295 * encoding */ 284 * encoding */
296static int json_cfg_decode_max_depth(lua_State *l) 285static int json_cfg_decode_max_depth(lua_State *l)
297{ 286{
298 json_config_t *cfg = json_fetch_config(l); 287 json_config_t *cfg = json_arg_init(l, 1);
299 288
300 return json_integer_option(l, &cfg->decode_max_depth, 1, INT_MAX); 289 return json_integer_option(l, 1, &cfg->decode_max_depth, 1, INT_MAX);
301} 290}
302 291
303/* Configures number precision when converting doubles to text */ 292/* Configures number precision when converting doubles to text */
304static int json_cfg_encode_number_precision(lua_State *l) 293static int json_cfg_encode_number_precision(lua_State *l)
305{ 294{
306 json_config_t *cfg = json_fetch_config(l); 295 json_config_t *cfg = json_arg_init(l, 1);
307 296
308 return json_integer_option(l, &cfg->encode_number_precision, 1, 14); 297 return json_integer_option(l, 1, &cfg->encode_number_precision, 1, 14);
309} 298}
310 299
311/* Configures JSON encoding buffer persistence */ 300/* Configures JSON encoding buffer persistence */
312static int json_cfg_encode_keep_buffer(lua_State *l) 301static int json_cfg_encode_keep_buffer(lua_State *l)
313{ 302{
314 json_config_t *cfg = json_fetch_config(l); 303 json_config_t *cfg = json_arg_init(l, 1);
315 int old_value; 304 int old_value;
316 305
317 old_value = cfg->encode_keep_buffer; 306 old_value = cfg->encode_keep_buffer;
318 307
319 json_enum_option(l, &cfg->encode_keep_buffer, NULL, 1); 308 json_enum_option(l, 1, &cfg->encode_keep_buffer, NULL, 1);
320 309
321 /* Init / free the buffer if the setting has changed */ 310 /* Init / free the buffer if the setting has changed */
322 if (old_value ^ cfg->encode_keep_buffer) { 311 if (old_value ^ cfg->encode_keep_buffer) {
@@ -332,9 +321,9 @@ static int json_cfg_encode_keep_buffer(lua_State *l)
332static int json_cfg_encode_invalid_numbers(lua_State *l) 321static int json_cfg_encode_invalid_numbers(lua_State *l)
333{ 322{
334 static const char *options[] = { "off", "on", "null", NULL }; 323 static const char *options[] = { "off", "on", "null", NULL };
335 json_config_t *cfg = json_fetch_config(l); 324 json_config_t *cfg = json_arg_init(l, 1);
336 325
337 json_enum_option(l, &cfg->encode_invalid_numbers, options, 1); 326 json_enum_option(l, 1, &cfg->encode_invalid_numbers, options, 1);
338 327
339#if DISABLE_INVALID_NUMBERS 328#if DISABLE_INVALID_NUMBERS
340 if (cfg->encode_invalid_numbers == 1) { 329 if (cfg->encode_invalid_numbers == 1) {
@@ -348,9 +337,9 @@ static int json_cfg_encode_invalid_numbers(lua_State *l)
348 337
349static int json_cfg_decode_invalid_numbers(lua_State *l) 338static int json_cfg_decode_invalid_numbers(lua_State *l)
350{ 339{
351 json_config_t *cfg = json_fetch_config(l); 340 json_config_t *cfg = json_arg_init(l, 1);
352 341
353 json_enum_option(l, &cfg->decode_invalid_numbers, NULL, 1); 342 json_enum_option(l, 1, &cfg->decode_invalid_numbers, NULL, 1);
354 343
355#if DISABLE_INVALID_NUMBERS 344#if DISABLE_INVALID_NUMBERS
356 if (cfg->decode_invalid_numbers) { 345 if (cfg->decode_invalid_numbers) {
@@ -368,22 +357,20 @@ static int json_cfg_decode_invalid_numbers(lua_State *l)
368static int json_cfg_refuse_invalid_numbers(lua_State *l) 357static int json_cfg_refuse_invalid_numbers(lua_State *l)
369{ 358{
370 static const char *options[] = { "none", "encode", "decode", "both", NULL }; 359 static const char *options[] = { "none", "encode", "decode", "both", NULL };
371 json_config_t *cfg = json_fetch_config(l); 360 json_config_t *cfg = json_arg_init(l, 1);
372 int have_arg, setting; 361 int setting;
373
374 have_arg = lua_gettop(l);
375 362
376 /* Map config variables to options list index */ 363 /* Map config variables to options list index */
377 setting = !cfg->encode_invalid_numbers + /* bit 0 */ 364 setting = !cfg->encode_invalid_numbers + /* bit 0 */
378 (!cfg->decode_invalid_numbers << 1); /* bit 1 */ 365 (!cfg->decode_invalid_numbers << 1); /* bit 1 */
379 366
380 json_enum_option(l, &setting, options, 3); 367 json_enum_option(l, 1, &setting, options, 3);
381 368
382 /* Map options list index to config variables 369 /* Map options list index to config variables
383 * 370 *
384 * Only update the config variables when an argument has been provided. 371 * Only update the config variables when an argument has been provided.
385 * Otherwise a "null" encoding setting may inadvertently be disabled. */ 372 * Otherwise a "null" encoding setting may inadvertently be disabled. */
386 if (have_arg) { 373 if (!lua_isnil(l, 1)) {
387 cfg->encode_invalid_numbers = !(setting & 1); 374 cfg->encode_invalid_numbers = !(setting & 1);
388 cfg->decode_invalid_numbers = !(setting & 2); 375 cfg->decode_invalid_numbers = !(setting & 2);
389 376