aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libraries/json.c61
1 files changed, 52 insertions, 9 deletions
diff --git a/libraries/json.c b/libraries/json.c
index 1ee5e85..f725728 100644
--- a/libraries/json.c
+++ b/libraries/json.c
@@ -1,6 +1,10 @@
#include "cJSON.h"
#include "cJSON.c"
+static cJSON* lua_tocjson(lua_State* L, int index) {
+ return *(cJSON*)lua_touserdata(L, index);
+}
+
// Lua binidngs.
static void f_cjson_push(lua_State* L, cJSON* json, int value) {
if (json) {
@@ -11,22 +15,61 @@ static void f_cjson_push(lua_State* L, cJSON* json, int value) {
luaL_setmetatable(L, value ? "cjson_value" : "cjson_object");
*value = *json;
} break;
- case cJSON_NULL: lua_pushnil(L); break;
- case cJSON_Number: lua_pushnumber(L, json->number); break;
- case cJSON_String: lua_pushlstring(L, json_string(json), json->length); break;
+ case cJSON_Number: lua_pushnumber(L, cJSON_GetNumberValue(json)); break;
+ case cJSON_True: lua_pushboolean(L, 1); break;
+ case cJSON_False: lua_pushboolean(L, 0); break;
+ case cJSON_String: lua_pushstring(L, cJSON_GetStringValue(json)); break;
+ default: lua_pushnil(L); break;
}
} else
lua_pushnil(L);
}
+static cJSON* f_cjson_parse(lua_State* L, int index) {
+ switch (lua_type(L, index)) {
+ case LUA_TUSERDATA:
+ return lua_tocjson(L, index);
+ case LUA_TTABLE:
+ lua_len(L, index);
+ int length = lua_tointeger(L, -1);
+ lua_pop(L, 1);
+ if (length > 0) {
+ cJSON* array = cJSON_CreateArray();
+ for (int i = 1; i <= length; ++i) {
+ lua_geti(L, index, i);
+ cJSON_AddItemToArray(array, f_cjson_parse(-1));
+ lua_pop(L, 1);
+ }
+ return array;
+ } else {
+ cJSON* object = cJSON_CreateObject();
+ lua_pushvalue(L, index);
+ lua_pushnil(L);
+ while (lua_next(L, -2)) {
+ lua_pushvalue(L, -2);able
+ const char *key = lua_tostring(L, -1);
+ cJSON_AddItemToObject(object, lua_tostring(L, -1), f_cjson_parse(L, -2));
+ lua_pop(L, 2);
+ }
+ lua_pop(L, 1);
+ return object;
+ }
+ break;
+ case LUA_TBOOLEN: return lua_toboolean(L, index) ? cJSON_CreateTrue() : cJSON_CreateFalse();
+ case LUA_TSTRING: return cJSON_CreateString(lua_tostring(L, index)); break;
+ case LUA_TINTEGER: return cJSON_CreateNumber(lua_tointeger(L, index)); break;
+ case LUA_TNUMBER: return cJSON_CreateNumber(lua_tonumber(L, index)); break;
+ default: return cJSON_CreateNull(); break;
+ }
+}
static int f_cjson_object_gc(lua_State* L) {
- cJSON** data = lua_touserdata(L, 1);
- cJSON_free(*data);
+ cJSON* json = lua_tocjson(L, 1);
+ cJSON_Delete(json);
}
static int f_cjson_object_index(lua_State* L) {
- cJSON* json = *(cJSON**)lua_touserdata(L, 1);
+ cJSON* json = lua_tocjson(L, 1);
switch (json->type) {
case cJSON_Object: f_cjson_push(L, cJSON_GetObjectItem(json, luaL_checkstring(L, 2)), 1); break;
case cJSON_Array: f_cjson_push(L, cJSON_GetArrayItem(json, luaL_checkinteger(L, 2) - 1), 1); break;
@@ -36,7 +79,7 @@ static int f_cjson_object_index(lua_State* L) {
}
static int f_cjson_object_len(lua_State* L) {
- cJSON* json = *(cJSON**)lua_touserdata(L, 1);
+ cJSON* json = lua_tocjson(L, 1);
switch (json->type) {
case cJSON_Array: lua_pushinteger(L, cJSON_GetArraySize(json->length)); break;
default: return luaL_error(L, "length operation invalid");
@@ -64,8 +107,8 @@ static const luaL_Reg cjson_object[] = {
static int f_cjson_encode(lua_State* L) {
- cJSON** data = lua_touserdata(L, 1);
- char* str = cJSON_PrintUnformatted(*data);
+ cJSON* json = lua_tocjson(L, 1);
+ char* str = cJSON_PrintUnformatted(json);
lua_pushstring(L, str);
free(str);
return 1;