mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-08 07:28:22 -10:00
* coverity - using `std::move` instead of copying, and change some parameters from value to reference * coverity - fix or mark potential copy-paste mistakes * coverity - various checking of parameter and return values * coverity - miscellaneous fixes, and change some 'intentional' markers to 'false positive' markers
102 lines
2.8 KiB
C++
102 lines
2.8 KiB
C++
|
|
#include "LuaValueSerializer.h"
|
|
|
|
#include "scripting/lua/LuaTable.h"
|
|
|
|
namespace scripting {
|
|
namespace util {
|
|
|
|
LuaValueSerializer::LuaValueSerializer(luacpp::LuaValue value) : m_value(std::move(value)) {}
|
|
|
|
SCP_vector<uint8_t> LuaValueSerializer::serialize() const
|
|
{
|
|
std::unique_ptr<json_t> serializedJson(toJson());
|
|
|
|
const auto json = json_dump_string(serializedJson.get(), JSON_ENCODE_ANY | JSON_COMPACT);
|
|
|
|
SCP_vector<uint8_t> data;
|
|
data.reserve(json.size() + 1);
|
|
|
|
// Add a tiny header describing the following data for future proofing.
|
|
data.push_back(static_cast<uint8_t>(SerializationType::PlainJson));
|
|
|
|
std::transform(json.cbegin(), json.cend(), std::back_inserter(data), [](char c) {
|
|
return static_cast<uint8_t>(c);
|
|
});
|
|
|
|
return data;
|
|
}
|
|
|
|
json_t* LuaValueSerializer::toJson() const
|
|
{
|
|
switch (m_value.getValueType()) {
|
|
case luacpp::ValueType::NIL:
|
|
return json_null();
|
|
case luacpp::ValueType::BOOLEAN:
|
|
return json_boolean(m_value.getValue<bool>());
|
|
case luacpp::ValueType::STRING: {
|
|
const auto string = m_value.getValue<SCP_string>();
|
|
return json_stringn(string.c_str(), string.size());
|
|
}
|
|
case luacpp::ValueType::NUMBER:
|
|
return json_real(m_value.getValue<double>());
|
|
case luacpp::ValueType::TABLE:
|
|
return tableToJson();
|
|
case luacpp::ValueType::NONE:
|
|
case luacpp::ValueType::USERDATA:
|
|
case luacpp::ValueType::FUNCTION:
|
|
case luacpp::ValueType::LIGHTUSERDATA:
|
|
case luacpp::ValueType::THREAD:
|
|
default:
|
|
throw std::runtime_error("Unsupported value type!");
|
|
}
|
|
}
|
|
json_t* LuaValueSerializer::tableToJson() const
|
|
{
|
|
luacpp::LuaTable tableVal;
|
|
tableVal.setReference(m_value.getReference());
|
|
|
|
auto testVal = tableVal.getValue<luacpp::LuaValue>(1);
|
|
if (testVal.getValueType() == luacpp::ValueType::NIL) {
|
|
// If there is no first array element then we assume it is an object
|
|
return tableToJsonObject(tableVal);
|
|
} else {
|
|
// Assume this is an object
|
|
return tableToJsonArray(tableVal);
|
|
}
|
|
}
|
|
json_t* LuaValueSerializer::tableToJsonArray(const luacpp::LuaTable& table)
|
|
{
|
|
auto size = table.getLength();
|
|
auto jsonArray = json_array();
|
|
for (size_t i = 1; i <= size; ++i) {
|
|
luacpp::LuaValue arrayVal;
|
|
if (!table.getValue(i, arrayVal)) {
|
|
json_array_append_new(jsonArray, json_null());
|
|
} else {
|
|
LuaValueSerializer valueSerializer(std::move(arrayVal));
|
|
json_array_append_new(jsonArray, valueSerializer.toJson());
|
|
}
|
|
}
|
|
return jsonArray;
|
|
}
|
|
json_t* LuaValueSerializer::tableToJsonObject(const luacpp::LuaTable& table)
|
|
{
|
|
auto jsonObj = json_object();
|
|
for (const auto& entry : table) {
|
|
if (entry.first.getValueType() != luacpp::ValueType::STRING) {
|
|
// Ignore non-string indices
|
|
continue;
|
|
}
|
|
|
|
const auto index = entry.first.getValue<SCP_string>();
|
|
|
|
LuaValueSerializer valueSerializer(entry.second);
|
|
json_object_set_new(jsonObj, index.c_str(), valueSerializer.toJson());
|
|
}
|
|
return jsonObj;
|
|
}
|
|
|
|
} // namespace util
|
|
} // namespace scripting
|