From 1ecf51a13f434f5cbc0f6ccc1b9a2ac6402a895f Mon Sep 17 00:00:00 2001 From: Kahrl Date: Mon, 2 Sep 2013 02:01:49 +0200 Subject: Add minetest.parse_json, engine.parse_json --- src/script/common/c_content.cpp | 82 +++++++++++++++++++++++++++++++++++++++++ src/script/common/c_content.h | 6 +++ 2 files changed, 88 insertions(+) (limited to 'src/script/common') diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 2e26adb76..3a3a70860 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -31,6 +31,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tool.h" #include "serverobject.h" #include "mapgen.h" +#include "json/json.h" struct EnumString es_TileAnimationType[] = { @@ -998,3 +999,84 @@ bool read_schematic(lua_State *L, int index, DecoSchematic *dschem, Server *serv return true; } + +/******************************************************************************/ +// Returns depth of json value tree +static int push_json_value_getdepth(const Json::Value &value) +{ + if (!value.isArray() && !value.isObject()) + return 1; + + int maxdepth = 0; + for (Json::Value::const_iterator it = value.begin(); + it != value.end(); ++it) { + int elemdepth = push_json_value_getdepth(*it); + if (elemdepth > maxdepth) + maxdepth = elemdepth; + } + return maxdepth + 1; +} +// Recursive function to convert JSON --> Lua table +static bool push_json_value_helper(lua_State *L, const Json::Value &value, + int nullindex) +{ + switch(value.type()) { + case Json::nullValue: + default: + lua_pushvalue(L, nullindex); + break; + case Json::intValue: + lua_pushinteger(L, value.asInt()); + break; + case Json::uintValue: + lua_pushinteger(L, value.asUInt()); + break; + case Json::realValue: + lua_pushnumber(L, value.asDouble()); + break; + case Json::stringValue: + { + const char *str = value.asCString(); + lua_pushstring(L, str ? str : ""); + } + break; + case Json::booleanValue: + lua_pushboolean(L, value.asInt()); + break; + case Json::arrayValue: + lua_newtable(L); + for (Json::Value::const_iterator it = value.begin(); + it != value.end(); ++it) { + push_json_value_helper(L, *it, nullindex); + lua_rawseti(L, -2, it.index() + 1); + } + break; + case Json::objectValue: + lua_newtable(L); + for (Json::Value::const_iterator it = value.begin(); + it != value.end(); ++it) { + const char *str = it.memberName(); + lua_pushstring(L, str ? str : ""); + push_json_value_helper(L, *it, nullindex); + lua_rawset(L, -3); + } + break; + } + return true; +} +// converts JSON --> Lua table; returns false if lua stack limit exceeded +// nullindex: Lua stack index of value to use in place of JSON null +bool push_json_value(lua_State *L, const Json::Value &value, int nullindex) +{ + if(nullindex < 0) + nullindex = lua_gettop(L) + 1 + nullindex; + + int depth = push_json_value_getdepth(value); + + // The maximum number of Lua stack slots used at each recursion level + // of push_json_value_helper is 2, so make sure there a depth * 2 slots + if (lua_checkstack(L, depth * 2)) + return push_json_value_helper(L, value, nullindex); + else + return false; +} diff --git a/src/script/common/c_content.h b/src/script/common/c_content.h index 6d1dfe1d5..27019e29e 100644 --- a/src/script/common/c_content.h +++ b/src/script/common/c_content.h @@ -39,6 +39,8 @@ extern "C" { #include "irrlichttypes_bloated.h" #include "util/string.h" +namespace Json { class Value; } + struct MapNode; class INodeDefManager; struct PointedThing; @@ -145,6 +147,10 @@ bool read_schematic (lua_State *L, int index, void luaentity_get (lua_State *L,u16 id); +bool push_json_value (lua_State *L, + const Json::Value &value, + int nullindex); + extern struct EnumString es_TileAnimationType[]; #endif /* C_CONTENT_H_ */ -- cgit v1.2.3