summaryrefslogtreecommitdiff
path: root/src/script/common/c_content.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/common/c_content.cpp')
-rw-r--r--src/script/common/c_content.cpp82
1 files changed, 82 insertions, 0 deletions
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;
+}