Files
fs2open.github.com/code/scripting/util/LuaValueDeserializer.cpp
T
asarium cf4fe8accc Add Lua API for serializing values
This can be used by script code for reliably storing Lua values without
having to build a custom serialization format.

The C++ code can also be used by other code modules that want to
serialize data. The new classes simply return a byte array with an
unspecified format.

At the moment this uses a plain JSON encoding but could be extended in
the future to include either compression or BSON encoding if necessary.
The format is future compatible by using a simple header to identify
different kinds of formats.
2020-09-12 14:28:16 +02:00

81 lines
2.1 KiB
C++

#include "LuaValueDeserializer.h"
#include "LuaValueSerializer.h"
namespace scripting {
namespace util {
LuaValueDeserializer::LuaValueDeserializer(lua_State* L) : m_L(L) {}
luacpp::LuaValue LuaValueDeserializer::deserialize(const SCP_vector<uint8_t>& serialized) const
{
if (serialized.empty()) {
throw std::runtime_error("Not enough data");
}
const auto type = static_cast<SerializationType>(serialized.front());
switch (type) {
case SerializationType::PlainJson:
return deserializePlainJson(serialized.data() + 1, serialized.size() - 1);
default:
throw std::runtime_error("Unknown serialization type.");
}
}
luacpp::LuaValue LuaValueDeserializer::deserializePlainJson(const uint8_t* data, size_t size) const
{
json_error_t error;
std::unique_ptr<json_t> json(json_loadb(reinterpret_cast<const char*>(data),
size,
JSON_DECODE_ANY | JSON_DECODE_INT_AS_REAL | JSON_ALLOW_NUL,
&error));
if (!json) {
throw json_exception(error);
}
return jsonToValue(json.get());
}
luacpp::LuaValue LuaValueDeserializer::jsonToValue(json_t* json) const
{
switch (json_typeof(json)) {
case JSON_OBJECT: {
auto objectTbl = luacpp::LuaTable::create(m_L);
for(const auto& pair : json::object_range(json))
{
objectTbl.addValue(std::get<0>(pair), jsonToValue(std::get<1>(pair)));
}
return std::move(objectTbl);
}
case JSON_ARRAY: {
auto arrayTbl = luacpp::LuaTable::create(m_L);
size_t i = 1;
for (const auto& value : json::array_range(json))
{
arrayTbl.addValue(i, jsonToValue(value));
++i;
}
return std::move(arrayTbl);
}
case JSON_STRING: {
const auto val = json_string_value(json);
const auto len = json_string_length(json);
return luacpp::LuaValue::createValue(m_L, SCP_string(val, val + len));
}
case JSON_REAL:
return luacpp::LuaValue::createValue(m_L, json_real_value(json));
case JSON_TRUE:
return luacpp::LuaValue::createValue(m_L, true);
case JSON_FALSE:
return luacpp::LuaValue::createValue(m_L, false);
case JSON_NULL:
return luacpp::LuaValue::createNil(m_L);
default:
return luacpp::LuaValue();
}
}
} // namespace util
} // namespace scripting