aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Pulford <mark@kyne.com.au>2011-04-16 03:25:47 +0930
committerMark Pulford <mark@kyne.com.au>2011-04-16 03:25:47 +0930
commitb8cf41c24626ecf184c15575412d1914b54a3db8 (patch)
tree7086cbb1508283433842f89a974218f8e4177f67
parent9f3d6b59c5f097d66e94f987c7731d7a4113057f (diff)
downloadlua-cjson-b8cf41c24626ecf184c15575412d1914b54a3db8.tar.gz
lua-cjson-b8cf41c24626ecf184c15575412d1914b54a3db8.tar.bz2
lua-cjson-b8cf41c24626ecf184c15575412d1914b54a3db8.zip
Improve exception handling in lua_json
- Add json_encode_exception() - Update to throw exceptions during encoding
-rw-r--r--lua_json.c81
1 files changed, 60 insertions, 21 deletions
diff --git a/lua_json.c b/lua_json.c
index ab72dd5..9b7e4e2 100644
--- a/lua_json.c
+++ b/lua_json.c
@@ -35,11 +35,21 @@
35#include <lauxlib.h> 35#include <lauxlib.h>
36 36
37#include "lua_json.h" 37#include "lua_json.h"
38#include "lua_misc.h"
38#include "utils.h" 39#include "utils.h"
39#include "strbuf.h" 40#include "strbuf.h"
40 41
41/* ===== ENCODING ===== */ 42/* ===== ENCODING ===== */
42 43
44static void json_encode_exception(lua_State *l, strbuf_t *json,
45 char *location, int lindex)
46
47{
48 strbuf_free(json);
49
50 luaL_error(l, "Cannot serialise %s: %s", location,
51 lua_typename(l, lua_type(l, lindex)));
52}
43 53
44/* JSON escape a character if required, or return NULL */ 54/* JSON escape a character if required, or return NULL */
45static inline char *json_escape_char(int c) 55static inline char *json_escape_char(int c)
@@ -177,7 +187,8 @@ static void json_append_object(lua_State *l, strbuf_t *json)
177 json_append_string(l, json, -2); 187 json_append_string(l, json, -2);
178 strbuf_append_string(json, ": "); 188 strbuf_append_string(json, ": ");
179 } else { 189 } else {
180 die("Cannot serialise table key %s", lua_typename(l, lua_type(l, -2))); 190 json_encode_exception(l, json, "table key", -2);
191 /* never returns */
181 } 192 }
182 193
183 /* table, key, value */ 194 /* table, key, value */
@@ -189,11 +200,7 @@ static void json_append_object(lua_State *l, strbuf_t *json)
189 strbuf_append_string(json, " }"); 200 strbuf_append_string(json, " }");
190} 201}
191 202
192/* Serialise Lua data into JSON string. 203/* Serialise Lua data into JSON string. */
193 *
194 * FIXME:
195 * - Error handling when cannot serialise key or value (return to script)
196 */
197static void json_append_data(lua_State *l, strbuf_t *json) 204static void json_append_data(lua_State *l, strbuf_t *json)
198{ 205{
199 int len; 206 int len;
@@ -227,13 +234,14 @@ static void json_append_data(lua_State *l, strbuf_t *json)
227 break; 234 break;
228 } 235 }
229 default: 236 default:
230 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD, and LUA_TLIGHTUSERDATA) 237 /* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
231 * cannot be serialised */ 238 * and LUA_TLIGHTUSERDATA) cannot be serialised */
232 /* FIXME: return error */ 239 json_encode_exception(l, json, "value", -1);
233 die("Cannot serialise %s", lua_typename(l, lua_type(l, -1))); 240 /* never returns */
234 } 241 }
235} 242}
236 243
244/* lua_json_encode can throw an exception */
237char *lua_json_encode(lua_State *l, int *len) 245char *lua_json_encode(lua_State *l, int *len)
238{ 246{
239 strbuf_t buf; 247 strbuf_t buf;
@@ -247,6 +255,23 @@ char *lua_json_encode(lua_State *l, int *len)
247 return json; 255 return json;
248} 256}
249 257
258/* lua_c_json_encode(object) must be called via lua_pcall().
259 * It can be used to catch any encoder exceptions */
260int lua_c_json_encode(lua_State *l)
261{
262 char *json;
263 int len;
264
265 lua_ensure_arg_count(l, "lua_c_json_encode", 1);
266
267 json = lua_json_encode(l, &len);
268
269 lua_pushlightuserdata(l, json);
270 lua_pushnumber(l, len);
271
272 return 2;
273}
274
250int lua_api_json_encode(lua_State *l) 275int lua_api_json_encode(lua_State *l)
251{ 276{
252 char *json; 277 char *json;
@@ -493,7 +518,7 @@ static void json_next_token(json_parse_t *json, json_token_t *token)
493 518
494/* This function does not return. 519/* This function does not return.
495 * DO NOT CALL WITH DYNAMIC MEMORY ALLOCATED. 520 * DO NOT CALL WITH DYNAMIC MEMORY ALLOCATED.
496 * The only allowed exception is the temporary parser string 521 * The only supported exception is the temporary parser string
497 * json->tmp struct. 522 * json->tmp struct.
498 * json and token should exist on the stack somewhere. 523 * json and token should exist on the stack somewhere.
499 * luaL_error() will long_jmp and release the stack */ 524 * luaL_error() will long_jmp and release the stack */
@@ -627,21 +652,35 @@ void lua_json_decode(lua_State *l, const char *json_text)
627 strbuf_free(json.tmp); 652 strbuf_free(json.tmp);
628} 653}
629 654
655/* lua_c_json_decode(string) must be called from C with lua_pcall() */
656int lua_c_json_decode(lua_State *l)
657{
658 const char *json;
659
660 lua_ensure_arg_count(l, "json_c_json_decode", 1);
661 luaL_argcheck(l, lua_islightuserdata(l, 1), 1,
662 "missing lightuserdata");
663
664 json = lua_touserdata(l, 1);
665 lua_pop(l, 1);
666
667 lua_json_decode(l, json);
668
669 return 1;
670}
671
630static int lua_api_json_decode(lua_State *l) 672static int lua_api_json_decode(lua_State *l)
631{ 673{
632 int i, n; 674 const char *json;
633 675
634 n = lua_gettop(l); 676 lua_ensure_arg_count(l, "json.decode", 1);
677 json = luaL_checkstring(l, 1);
635 678
636 for (i = 1; i <= n; i++) { 679 lua_json_decode(l, json);
637 if (lua_isstring(l, i)) {
638 lua_json_decode(l, lua_tostring(l, i));
639 } else {
640 lua_pushnil(l);
641 }
642 }
643 680
644 return n; /* Number of results */ 681 lua_remove(l, 1);
682
683 return 1;
645} 684}
646 685
647/* ===== INITIALISATION ===== */ 686/* ===== INITIALISATION ===== */