From 516601cb8e909d4c32ef50b10d34e4dd0b467b46 Mon Sep 17 00:00:00 2001 From: MikalaiR Date: Tue, 2 Feb 2016 17:19:46 +0000 Subject: MirLua: libjson-based json parser git-svn-id: http://svn.miranda-ng.org/main/trunk@16215 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/MirLua/Modules/JSON/src/metatable.cpp | 160 ++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 plugins/MirLua/Modules/JSON/src/metatable.cpp (limited to 'plugins/MirLua/Modules/JSON/src/metatable.cpp') diff --git a/plugins/MirLua/Modules/JSON/src/metatable.cpp b/plugins/MirLua/Modules/JSON/src/metatable.cpp new file mode 100644 index 0000000000..2c6ce9b1d6 --- /dev/null +++ b/plugins/MirLua/Modules/JSON/src/metatable.cpp @@ -0,0 +1,160 @@ +#include "stdafx.h" + +void table2json(lua_State *L, int idx, JSONNode &node) +{ + lua_pushnil(L); + while (lua_next(L, idx) != 0) + { + JSONNode &nnode = (lua_type(L, -2) == LUA_TNUMBER ? (node)[(size_t)lua_tonumber(L, -2) - 1] : (node)[lua_tostring(L, -2)]); + + switch (lua_type(L, -1)) + { + case LUA_TSTRING: + nnode = lua_tostring(L, -1); + break; + case LUA_TBOOLEAN: + nnode = lua_toboolean(L, -1) != 0; + break; + case LUA_TNUMBER: + nnode = lua_tonumber(L, -1); + break; + case LUA_TNIL: + nnode.nullify(); + break; + case LUA_TTABLE: + nnode = JSONNode(nnode.name(), NULL); + table2json(L, -1, nnode); + } + + lua_pop(L, 1); + } +} + +int json_pushvalue(lua_State *L, JSONNode &node) +{ + switch (node.type()) + { + case JSON_NULL: + lua_pushnil(L); + break; + case JSON_STRING: + lua_pushstring(L, node.as_string().c_str()); + break; + case JSON_NUMBER: + lua_pushnumber(L, node.as_int()); + break; + case JSON_BOOL: + lua_pushboolean(L, node.as_bool()); + break; + case JSON_ARRAY: + case JSON_NODE: + MT *udata = (MT*)lua_newuserdata(L, sizeof(MT)); + udata->node = &node; + udata->bDelete = false; + luaL_setmetatable(L, MT_JSON); + } + return 1; +} + +int json_setvalue(lua_State *L, JSONNode &node) +{ + switch (lua_type(L, 3)) + { + case LUA_TSTRING: + node = lua_tostring(L, 3); + break; + case LUA_TBOOLEAN: + node = lua_toboolean(L, 3) != 0; + break; + case LUA_TNUMBER: + node = lua_tonumber(L, 3); + break; + case LUA_TNIL: + node.nullify(); + break; + //case LUA_TTABLE: + //node = JSONNode(node.name(), JSONNode()); + //table2json(L, 3, node); + } + + return 0; +} + +static int json__call(lua_State *L) +{ + if (lua_istable(L, 1)) + { +/* MT *udata = (MT*)lua_newuserdata(L, sizeof(MT)); + udata->node = json_new(JSON_NODE); + table2json(L, 1, *udata->node); + udata->bDelete = true; + luaL_setmetatable(L, MT_JSON); + return 1; +*/ + } + return 0; +} + +static int json__index(lua_State *L) +{ + JSONNode *node = ((MT*)luaL_checkudata(L, 1, MT_JSON))->node; + switch (lua_type(L, 2)) + { + case LUA_TNUMBER: + return json_pushvalue(L, (*node)[(size_t)lua_tonumber(L, 2) - 1]); + case LUA_TSTRING: + return json_pushvalue(L, (*node)[lua_tostring(L, 2)]); + } + return 0; +} + +static int json__newindex(lua_State *L) +{ + JSONNode *node = ((MT*)luaL_checkudata(L, 1, MT_JSON))->node; + switch (lua_type(L, 2)) + { + case LUA_TNUMBER: + json_setvalue(L, (*node)[(size_t)lua_tonumber(L, 2) - 1]); + break; + case LUA_TSTRING: + json_setvalue(L, (*node)[lua_tostring(L, 2)]); + break; + } + return 0; +} + +static int json__len(lua_State *L) +{ + JSONNode *node = ((MT*)luaL_checkudata(L, 1, MT_JSON))->node; + lua_pushnumber(L, (*node).size()); + return 1; +} + +static int json__tostring(lua_State *L) +{ + JSONNode *node = ((MT*)luaL_checkudata(L, 1, MT_JSON))->node; + lua_pushstring(L, (*node).write().c_str()); + return 1; +} + +static int json__gc(lua_State *L) +{ + MT *mt = (MT*)luaL_checkudata(L, 1, MT_JSON); + if (mt->bDelete) + { + json_delete(mt->node); + mt->node = nullptr; + } + return 0; +} + +static const struct luaL_Reg jsonApi[] = +{ + { "__call", json__call }, + { "__index", json__index }, + { "__newindex", json__newindex }, + { "__len", json__len }, + { "__tostring", json__tostring }, + { "__gc", json__gc }, + { NULL, NULL } +}; -- cgit v1.2.3