From e1963ebc7f61cead5aa558d1a927b173077257fe Mon Sep 17 00:00:00 2001 From: Adam Harrison Date: Fri, 8 Mar 2024 13:35:12 -0500 Subject: cJSON addition. --- .gitmodules | 3 ++ lib/cJSON | 1 + libraries/json.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ libraries/json.lua | 7 ++++ 4 files changed, 110 insertions(+) create mode 160000 lib/cJSON create mode 100644 libraries/json.c diff --git a/.gitmodules b/.gitmodules index b83fa2d..0e514da 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,3 +20,6 @@ url = https://github.com/Mbed-TLS/mbedtls.git tag = mbedtls-2.28.3 shallow = true +[submodule "lib/cJSON"] + path = lib/cJSON + url = https://github.com/DaveGamble/cJSON diff --git a/lib/cJSON b/lib/cJSON new file mode 160000 index 0000000..87d8f09 --- /dev/null +++ b/lib/cJSON @@ -0,0 +1 @@ +Subproject commit 87d8f0961a01bf09bef98ff89bae9fdec42181ee diff --git a/libraries/json.c b/libraries/json.c new file mode 100644 index 0000000..1ee5e85 --- /dev/null +++ b/libraries/json.c @@ -0,0 +1,99 @@ +#include "cJSON.h" +#include "cJSON.c" + +// 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_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; + } + } else + lua_pushnil(L); +} + + +static int f_cjson_object_gc(lua_State* L) { + cJSON** data = lua_touserdata(L, 1); + cJSON_free(*data); +} + +static int f_cjson_object_index(lua_State* L) { + cJSON* json = *(cJSON**)lua_touserdata(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; + default: return luaL_error(L, "invalid index"); + } + return 1; +} + +static int f_cjson_object_len(lua_State* L) { + cJSON* json = *(cJSON**)lua_touserdata(L, 1); + switch (json->type) { + case cJSON_Array: lua_pushinteger(L, cJSON_GetArraySize(json->length)); break; + default: return luaL_error(L, "length operation invalid"); + } + return 1; +} + + +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 int f_cjson_encode(lua_State* L) { + cJSON** data = lua_touserdata(L, 1); + char* str = cJSON_PrintUnformatted(*data); + 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; +} + +#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; +} + diff --git a/libraries/json.lua b/libraries/json.lua index c463440..3499195 100644 --- a/libraries/json.lua +++ b/libraries/json.lua @@ -385,5 +385,12 @@ function json.decode(str) return res end +local status, cjson = pcall(require, "libraries.cjson") +if status then + json.ldecode = json.decode + json.lencode = json.encode + json.decode = cjson.decode + json.encode = cjson.encode +end return json -- cgit v1.2.3