Use type switch in JsonEncode
lua_isnumber and lua_isstring try to coerce the values to their respective type, so a type switch is more reliable. Fixes https://github.com/Simply-Love/Simply-Love-SM5/issues/406
This commit is contained in:
+64
-69
@@ -2532,88 +2532,83 @@ int LuaFunc_JsonEncode(lua_State* L)
|
|||||||
|
|
||||||
std::function<Json::Value(int)> convert = [&L, &convert](int index) -> Json::Value
|
std::function<Json::Value(int)> convert = [&L, &convert](int index) -> Json::Value
|
||||||
{
|
{
|
||||||
if (lua_isboolean(L, index))
|
switch (lua_type(L, index))
|
||||||
{
|
{
|
||||||
return Json::Value(static_cast<bool>(lua_toboolean(L, index)));
|
case LUA_TNIL:
|
||||||
}
|
return Json::Value(Json::nullValue);
|
||||||
else if (lua_isnil(L, index))
|
case LUA_TBOOLEAN:
|
||||||
{
|
return Json::Value(static_cast<bool>(lua_toboolean(L, index)));
|
||||||
return Json::Value(Json::nullValue);
|
case LUA_TNUMBER: {
|
||||||
}
|
double val = lua_tonumber(L, index);
|
||||||
else if (lua_isnumber(L, index))
|
|
||||||
{
|
|
||||||
double val = lua_tonumber(L, index);
|
|
||||||
|
|
||||||
if (val == static_cast<Json::UInt>(val))
|
if (val == static_cast<Json::UInt>(val))
|
||||||
{
|
|
||||||
return Json::Value(static_cast<Json::UInt>(val));
|
|
||||||
}
|
|
||||||
else if (val == static_cast<Json::Int>(val))
|
|
||||||
{
|
|
||||||
return Json::Value(static_cast<Json::Int>(val));
|
|
||||||
}
|
|
||||||
return Json::Value(val);
|
|
||||||
}
|
|
||||||
else if (lua_isstring(L, index))
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
const char *s = lua_tolstring(L, index, &len);
|
|
||||||
|
|
||||||
return Json::Value(std::string(s, len));
|
|
||||||
}
|
|
||||||
else if (lua_istable(L, index))
|
|
||||||
{
|
|
||||||
// if the index is relative to the top of the stack,
|
|
||||||
// then calculate the absolute index, so we have a
|
|
||||||
// stable reference
|
|
||||||
if (index < 0)
|
|
||||||
{
|
|
||||||
index = lua_gettop(L) + index + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t len = lua_objlen(L, index);
|
|
||||||
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
// array
|
|
||||||
Json::Value array(Json::arrayValue);
|
|
||||||
array.resize(len);
|
|
||||||
|
|
||||||
for (int i = 0; i < len; i++)
|
|
||||||
{
|
{
|
||||||
lua_rawgeti(L, index, i + 1);
|
return Json::Value(static_cast<Json::UInt>(val));
|
||||||
array[i] = convert(-1);
|
}
|
||||||
lua_pop(L, 1);
|
else if (val == static_cast<Json::Int>(val))
|
||||||
|
{
|
||||||
|
return Json::Value(static_cast<Json::Int>(val));
|
||||||
|
}
|
||||||
|
return Json::Value(val);
|
||||||
|
}
|
||||||
|
case LUA_TSTRING: {
|
||||||
|
size_t len;
|
||||||
|
const char *s = lua_tolstring(L, index, &len);
|
||||||
|
|
||||||
|
return Json::Value(std::string(s, len));
|
||||||
|
}
|
||||||
|
case LUA_TTABLE: {
|
||||||
|
// if the index is relative to the top of the stack,
|
||||||
|
// then calculate the absolute index, so we have a
|
||||||
|
// stable reference
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
index = lua_gettop(L) + index + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array;
|
size_t len = lua_objlen(L, index);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// object
|
|
||||||
Json::Value obj(Json::objectValue);
|
|
||||||
|
|
||||||
lua_pushnil(L);
|
if (len > 0)
|
||||||
while (lua_next(L, index) != 0)
|
|
||||||
{
|
{
|
||||||
if (!lua_isstring(L, -2))
|
// array
|
||||||
|
Json::Value array(Json::arrayValue);
|
||||||
|
array.resize(len);
|
||||||
|
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
luaL_error(L, "object keys must be strings");
|
lua_rawgeti(L, index, i + 1);
|
||||||
|
array[i] = convert(-1);
|
||||||
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t keylen;
|
return array;
|
||||||
const char *key = lua_tolstring(L, -2, &keylen);
|
|
||||||
obj[std::string(key, keylen)] = convert(-1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (obj.size() < 1)
|
|
||||||
{
|
{
|
||||||
return Json::Value(Json::arrayValue);
|
// object
|
||||||
}
|
Json::Value obj(Json::objectValue);
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
lua_pushnil(L);
|
||||||
|
while (lua_next(L, index) != 0)
|
||||||
|
{
|
||||||
|
if (!lua_isstring(L, -2))
|
||||||
|
{
|
||||||
|
luaL_error(L, "object keys must be strings");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t keylen;
|
||||||
|
const char *key = lua_tolstring(L, -2, &keylen);
|
||||||
|
obj[std::string(key, keylen)] = convert(-1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.size() < 1)
|
||||||
|
{
|
||||||
|
return Json::Value(Json::arrayValue);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int tp = lua_type(L, index);
|
int tp = lua_type(L, index);
|
||||||
|
|||||||
Reference in New Issue
Block a user