diff options
Diffstat (limited to 'lua_cjson.c')
-rw-r--r-- | lua_cjson.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/lua_cjson.c b/lua_cjson.c index 498c686..afa5266 100644 --- a/lua_cjson.c +++ b/lua_cjson.c | |||
@@ -1310,6 +1310,35 @@ static void luaL_setfuncs (lua_State *l, const luaL_Reg *reg, int nup) | |||
1310 | } | 1310 | } |
1311 | #endif | 1311 | #endif |
1312 | 1312 | ||
1313 | /* Call target function in protected mode with all supplied args. | ||
1314 | * Assumes target function only returns a single non-nil value. | ||
1315 | * Convert and return thrown errors as: nil, "error message" */ | ||
1316 | static int json_protect_conversion(lua_State *l) | ||
1317 | { | ||
1318 | int err; | ||
1319 | |||
1320 | /* Deliberately throw an error for invalid arguments */ | ||
1321 | luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument"); | ||
1322 | |||
1323 | /* pcall() the function stored as upvalue(1) */ | ||
1324 | lua_pushvalue(l, lua_upvalueindex(1)); | ||
1325 | lua_insert(l, 1); | ||
1326 | err = lua_pcall(l, 1, 1, 0); | ||
1327 | if (!err) | ||
1328 | return 1; | ||
1329 | |||
1330 | if (err == LUA_ERRRUN) { | ||
1331 | lua_pushnil(l); | ||
1332 | lua_insert(l, -2); | ||
1333 | return 2; | ||
1334 | } | ||
1335 | |||
1336 | /* Since we are not using a custom error handler, the only remaining | ||
1337 | * errors are memory related */ | ||
1338 | return luaL_error(l, "Memory allocation error in CJSON protected call"); | ||
1339 | } | ||
1340 | |||
1341 | /* Return cjson module table */ | ||
1313 | static int lua_cjson_new(lua_State *l) | 1342 | static int lua_cjson_new(lua_State *l) |
1314 | { | 1343 | { |
1315 | luaL_Reg reg[] = { | 1344 | luaL_Reg reg[] = { |
@@ -1349,6 +1378,27 @@ static int lua_cjson_new(lua_State *l) | |||
1349 | return 1; | 1378 | return 1; |
1350 | } | 1379 | } |
1351 | 1380 | ||
1381 | /* Return cjson.safe module table */ | ||
1382 | static int lua_cjson_safe_new(lua_State *l) | ||
1383 | { | ||
1384 | const char *func[] = { "decode", "encode", NULL }; | ||
1385 | int i; | ||
1386 | |||
1387 | lua_cjson_new(l); | ||
1388 | |||
1389 | /* Fix new() method */ | ||
1390 | lua_pushcfunction(l, lua_cjson_safe_new); | ||
1391 | lua_setfield(l, -2, "new"); | ||
1392 | |||
1393 | for (i = 0; func[i]; i++) { | ||
1394 | lua_getfield(l, -1, func[i]); | ||
1395 | lua_pushcclosure(l, json_protect_conversion, 1); | ||
1396 | lua_setfield(l, -2, func[i]); | ||
1397 | } | ||
1398 | |||
1399 | return 1; | ||
1400 | } | ||
1401 | |||
1352 | int luaopen_cjson(lua_State *l) | 1402 | int luaopen_cjson(lua_State *l) |
1353 | { | 1403 | { |
1354 | lua_cjson_new(l); | 1404 | lua_cjson_new(l); |
@@ -1363,5 +1413,13 @@ int luaopen_cjson(lua_State *l) | |||
1363 | return 1; | 1413 | return 1; |
1364 | } | 1414 | } |
1365 | 1415 | ||
1416 | int luaopen_cjson_safe(lua_State *l) | ||
1417 | { | ||
1418 | lua_cjson_safe_new(l); | ||
1419 | |||
1420 | /* Return cjson.safe table */ | ||
1421 | return 1; | ||
1422 | } | ||
1423 | |||
1366 | /* vi:ai et sw=4 ts=4: | 1424 | /* vi:ai et sw=4 ts=4: |
1367 | */ | 1425 | */ |