aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libraries/json.c141
1 files changed, 79 insertions, 62 deletions
diff --git a/libraries/json.c b/libraries/json.c
index f725728..14b006f 100644
--- a/libraries/json.c
+++ b/libraries/json.c
@@ -1,34 +1,40 @@
#include "cJSON.h"
#include "cJSON.c"
+typedef struct json_t {
+ int allocated;
+ cJSON* json;
+} json_t;
+
static cJSON* lua_tocjson(lua_State* L, int index) {
- return *(cJSON*)lua_touserdata(L, index);
+ json_t* value = luaL_testudata(L, index, "cjson");
+ return value ? value->json : NULL;
}
// Lua binidngs.
-static void f_cjson_push(lua_State* L, cJSON* json, int value) {
- if (json) {
- switch (json->type) {
- case cJSON_Array:
- case cJSON_Object: {
- cJSON** value = lua_newuserdata(L, sizeof(cJSON*));
- luaL_setmetatable(L, value ? "cjson_value" : "cjson_object");
- *value = *json;
- } 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 int f_cjson_push(lua_State* L, cJSON* json, int allocated) {
+ if (json) {
+ switch (json->type) {
+ case cJSON_Array:
+ case cJSON_Object: {
+ json_t* value = lua_newuserdata(L, sizeof(json_t));
+ luaL_setmetatable(L, "cjson");
+ value->json = json;
+ value->allocated = allocated;
+ } 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);
+ return 1;
}
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);
@@ -56,19 +62,24 @@ static cJSON* f_cjson_parse(lua_State* L, int index) {
}
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;
+ case LUA_TSTRING: return cJSON_CreateString(lua_tostring(L, index));
+ case LUA_TINTEGER: return cJSON_CreateNumber(lua_tointeger(L, index));
+ case LUA_TNUMBER: return cJSON_CreateNumber(lua_tonumber(L, index));
+ case LUA_TUSERDATA: {
+ cJSON* json = lua_tocjson(L, index);
+ return json ? json : cJSON_CreateNull();
+ } break;
+ default: return cJSON_CreateNull();
}
}
-static int f_cjson_object_gc(lua_State* L) {
- cJSON* json = lua_tocjson(L, 1);
- cJSON_Delete(json);
+static int f_cjson_gc(lua_State* L) {
+ json_t* value = lua_touserdata(L, 1);
+ if (value->allocated)
+ cJSON_Delete(value->json);
}
-static int f_cjson_object_index(lua_State* L) {
+static int f_cjson_index(lua_State* L) {
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;
@@ -78,7 +89,7 @@ static int f_cjson_object_index(lua_State* L) {
return 1;
}
-static int f_cjson_object_len(lua_State* L) {
+static int f_cjson_len(lua_State* L) {
cJSON* json = lua_tocjson(L, 1);
switch (json->type) {
case cJSON_Array: lua_pushinteger(L, cJSON_GetArraySize(json->length)); break;
@@ -87,56 +98,62 @@ static int f_cjson_object_len(lua_State* L) {
return 1;
}
+static int f_cjson_newindex(lua_State* L) {
+ cJSON* json = lua_tocjson(L, 1);
+
+ switch (json->type) {
+ case cJSON_Array: {
+ int index = luaL_checkinteger(L, 2);
+ cJSON* value = f_cjson_parse(L, 3);
+ cJSON_ReplaceItemInArray(json, index, value);
+ } break;
+ case cJSON_Object: {
+ const char* key = luaL_checkstring(L, 2);
+ cJSON* value = f_cjson_parse(L, 3);
+ cJSON_AddItemToObject(json, key, value);
+ } break;
+ default: return luaL_error(L, "assignment operation invalid");
+ }
+ return 0;
+}
-static const luaL_Reg cjson_value[] = {
- { "__index", f_cjson_object_index },
- { "__newindex", f_cjson_object_newindex },
- { "__pairs", f_cjson_object_pairs },
- { "__len", f_cjson_object_len },
- { NULL, NULL }
-};
-static const luaL_Reg cjson_object[] = {
- { "__gc", f_cjson_object_gc },
- { "__index", f_cjson_object_index },
- { "__newindex", f_cjson_object_newindex },
- { "__pairs", f_cjson_object_pairs },
- { "__len", f_cjson_object_len },
- { NULL, NULL }
+static const luaL_Reg cjson_value[] = {
+ { "__gc", f_cjson_gc },
+ { "__index", f_cjson_index },
+ { "__newindex", f_cjson_newindex },
+ { "__pairs", f_cjson_pairs },
+ { "__len", f_cjson_len },
+ { NULL, NULL }
};
static int f_cjson_encode(lua_State* L) {
- cJSON* json = lua_tocjson(L, 1);
- char* str = cJSON_PrintUnformatted(json);
- lua_pushstring(L, str);
- free(str);
- return 1;
+ cJSON* json = lua_tocjson(L, 1);
+ char* str = cJSON_PrintUnformatted(json);
+ lua_pushstring(L, str);
+ free(str);
+ return 1;
}
static int f_cjson_decode(lua_State* L) {
- size_t len;
- const char* str = luaL_checklstring(L, 1, &len);
- cJSON* value = cJSON_ParseWithLength(str, len);
- cJSON** data = lua_newuserdata(L, sizeof(cJSON*));
- luaL_setmetatable(L, "cjson_object");
- *data = value;
- return 1;
+ size_t len;
+ const char* str = luaL_checklstring(L, 1, &len);
+ return f_cjson_push(L, cJSON_ParseWithLength(str, len), 1);
}
+
#ifndef CJSON_STANDALONE
int luaopen_lite_xl_cjson(lua_State* L, void* XL) {
lite_xl_plugin_init(XL);
#else
int luaopen_cjson(lua_State* L) {
#endif
- luaL_newmetatable(L, "cjson_object");
- luaL_setfuncs(L, cjson_object, 0);
- luaL_newmetatable(L, "cjson_value");
- luaL_setfuncs(L, cjson_value, 0);
- lua_newtable(L);
- luaL_setfuncs(L, cjson_lib, 0);
- return 1;
+ luaL_newmetatable(L, "cjson");
+ luaL_setfuncs(L, cjson_value, 0);
+ lua_newtable(L);
+ luaL_setfuncs(L, cjson_lib, 0);
+ return 1;
}