Skip to content
Permalink
Browse files

Add 'minetest.write_json'

  • Loading branch information
ShadowNinja committed Dec 18, 2013
1 parent 49cec3f commit 1ed90c90c304c6cc9cfddb722e4d15a1221d0177
@@ -1530,7 +1530,16 @@ minetest.parse_json(string[, nullvalue]) -> something
^ nullvalue: returned in place of the JSON null; defaults to nil
^ On success returns a table, a string, a number, a boolean or nullvalue
^ On failure outputs an error message and returns nil
^ Example: parse_json("[10, {\"a\":false}]") -> {[1] = 10, [2] = {a = false}}
^ Example: parse_json("[10, {\"a\":false}]") -> {10, {a = false}}
minetest.write_json(data[, styled]) -> string
^ Convert a Lua table into a JSON string
^ styled: Outputs in a human-readable format if this is set, defaults to false
^ Un-serializable things like functions and userdata are saved as null.
^ Warning: JSON is more strict than the Lua table format.
1. You can only use strings and positive integers of at least one as keys.
2. You can not mix string and integer keys.
This is due to the fact that Javascript has two distinct array and object values.
^ Example: write_json({10, {a = false}}) -> "[10, {\"a\": false}]"
minetest.serialize(table) -> string
^ Convert a table containing tables, strings, numbers, booleans and nils
into string form readable by minetest.deserialize
@@ -1081,3 +1081,52 @@ bool push_json_value(lua_State *L, const Json::Value &value, int nullindex)
else
return false;
}

// Converts Lua table --> JSON
void get_json_value(lua_State *L, Json::Value &root, int index)
{
int type = lua_type(L, index);
if (type == LUA_TBOOLEAN) {
root = (bool) lua_toboolean(L, index);
} else if (type == LUA_TNUMBER) {
root = lua_tonumber(L, index);
} else if (type == LUA_TSTRING) {
size_t len;
const char *str = lua_tolstring(L, index, &len);
root = std::string(str, len);
} else if (type == LUA_TTABLE) {
lua_pushnil(L);
while (lua_next(L, index)) {
// Key is at -2 and value is at -1
Json::Value value;
get_json_value(L, value, lua_gettop(L));

Json::ValueType roottype = root.type();
int keytype = lua_type(L, -1);
if (keytype == LUA_TNUMBER) {
lua_Number key = lua_tonumber(L, -1);
if (roottype != Json::nullValue && roottype != Json::arrayValue) {
throw LuaError(NULL, "Can't mix array and object values in JSON");
} else if (key < 1) {
throw LuaError(NULL, "Can't use zero-based or negative indexes in JSON");
} else if (floor(key) != key) {
throw LuaError(NULL, "Can't use indexes with a fractional part in JSON");
}
root[(Json::ArrayIndex) key - 1] = value;
} else if (keytype == LUA_TSTRING) {
if (roottype != Json::nullValue && roottype != Json::objectValue) {
throw LuaError(NULL, "Can't mix array and object values in JSON");
}
root[lua_tostring(L, -1)] = value;
} else {
throw LuaError(NULL, "Lua key to convert to JSON is not a string or number");
}
}
} else if (type == LUA_TNIL) {
root = Json::nullValue;
} else {
throw LuaError(NULL, "Can only store booleans, numbers, strings, objects, arrays, and null in JSON");
}
lua_pop(L, 1); // Pop value
}

@@ -150,6 +150,9 @@ void luaentity_get (lua_State *L,u16 id);
bool push_json_value (lua_State *L,
const Json::Value &value,
int nullindex);
void get_json_value (lua_State *L,
Json::Value &root,
int index);

extern struct EnumString es_TileAnimationType[];

@@ -179,6 +179,32 @@ int ModApiUtil::l_parse_json(lua_State *L)
return 1;
}

// write_json(data[, styled]) -> string
int ModApiUtil::l_write_json(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;

bool styled = false;
if (!lua_isnone(L, 2)) {
styled = lua_toboolean(L, 2);
lua_pop(L, 1);
}

Json::Value root;
get_json_value(L, root, 1);

std::string out;
if (styled) {
Json::StyledWriter writer;
out = writer.write(root);
} else {
Json::FastWriter writer;
out = writer.write(root);
}
lua_pushlstring(L, out.c_str(), out.size());
return 1;
}

// get_dig_params(groups, tool_capabilities[, time_from_last_punch])
int ModApiUtil::l_get_dig_params(lua_State *L)
{
@@ -249,6 +275,7 @@ void ModApiUtil::Initialize(lua_State *L, int top)
API_FCT(setting_save);

API_FCT(parse_json);
API_FCT(write_json);

API_FCT(get_dig_params);
API_FCT(get_hit_params);
@@ -64,6 +64,9 @@ class ModApiUtil : public ModApiBase {
// parse_json(str[, nullvalue])
static int l_parse_json(lua_State *L);

// write_json(data[, styled])
static int l_write_json(lua_State *L);

// get_dig_params(groups, tool_capabilities[, time_from_last_punch])
static int l_get_dig_params(lua_State *L);

0 comments on commit 1ed90c9

Please sign in to comment.
You can’t perform that action at this time.