Skip to content

Commit

Permalink
ajout d'un serialiseur de tableaux pour lua
Browse files Browse the repository at this point in the history
  • Loading branch information
paxo-rch committed Sep 5, 2024
1 parent 1e4e216 commit b4cd394
Showing 1 changed file with 157 additions and 0 deletions.
157 changes: 157 additions & 0 deletions lib/lua/src/lua_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include <libsystem.hpp>
#include <standby.hpp>

#include <fstream>
#include <iostream>


/*
LuaHttpClient::LuaHttpClient(LuaFile* lua)
Expand Down Expand Up @@ -112,6 +115,150 @@ int custom_panic_handler(lua_State* L) {
return 0;
}

template <typename T>
void writeBinaryValue(std::ofstream& file, const T& value) {
file.write(reinterpret_cast<const char*>(&value), sizeof(T));
}

void saveTableToBinaryFile(std::ofstream& file, const sol::table& table) {
// Write the number of key-value pairs
size_t numPairs = table.size();
writeBinaryValue(file, numPairs);

for (const auto& pair : table) {
sol::object key = pair.first;
sol::object value = pair.second;

// Write the key type
if (key.is<std::string>()) {
writeBinaryValue(file, static_cast<uint8_t>(1)); // 1 for string key
std::string keyStr = key.as<std::string>();
size_t keySize = keyStr.size();
writeBinaryValue(file, keySize);
file.write(keyStr.c_str(), keySize);
} else if (key.is<double>() || key.is<int>()) {
writeBinaryValue(file, static_cast<uint8_t>(2)); // 2 for numeric key
double numericKey = key.as<double>();
writeBinaryValue(file, numericKey);
} else {
throw std::runtime_error("Unsupported table key type for binary serialization");
}

// Write the value type and value
if (value.is<std::string>()) {
writeBinaryValue(file, static_cast<uint8_t>(1)); // 1 for string
std::string valueStr = value.as<std::string>();
size_t valueSize = valueStr.size();
writeBinaryValue(file, valueSize);
file.write(valueStr.c_str(), valueSize);
} else if (value.is<double>() || value.is<int>()) {
writeBinaryValue(file, static_cast<uint8_t>(2)); // 2 for number
double numericValue = value.as<double>();
writeBinaryValue(file, numericValue);
} else if (value.is<bool>()) {
writeBinaryValue(file, static_cast<uint8_t>(3)); // 3 for boolean
bool boolValue = value.as<bool>();
writeBinaryValue(file, boolValue);
} else if (value.is<sol::nil_t>()) {
writeBinaryValue(file, static_cast<uint8_t>(4)); // 4 for nil
} else if (value.is<sol::table>()) {
writeBinaryValue(file, static_cast<uint8_t>(5)); // 5 for table
saveTableToBinaryFile(file, value.as<sol::table>()); // Recursively save
} else {
throw std::runtime_error("Unsupported table value type for binary serialization");
}
}
}

void saveTableToBinaryFile(const std::string& filename, const sol::table& table) {
std::ofstream file(filename, std::ios::binary);
if (!file.is_open()) {
throw std::runtime_error("Error opening file for writing: " + filename);
}

try {
saveTableToBinaryFile(file, table);
} catch (const std::exception& e) {
file.close();
throw std::runtime_error(std::string("Error while writing to file: ") + e.what());
}

file.close();
}

template <typename T>
T readBinaryValue(std::ifstream& file) {
T value;
file.read(reinterpret_cast<char*>(&value), sizeof(T));
return value;
}

sol::table loadTableFromBinaryFile(sol::state& lua, std::ifstream& file) {
sol::table table = lua.create_table();

size_t numPairs = readBinaryValue<size_t>(file);

for (size_t i = 0; i < numPairs; ++i) {
// Read key
uint8_t keyType = readBinaryValue<uint8_t>(file);
sol::object key;

if (keyType == 1) { // String key
size_t keySize = readBinaryValue<size_t>(file);
std::vector<char> keyBuffer(keySize);
file.read(keyBuffer.data(), keySize);
key = sol::make_object(lua, std::string(keyBuffer.data(), keySize));
} else if (keyType == 2) { // Numeric key
key = sol::make_object(lua, readBinaryValue<double>(file));
} else {
throw std::runtime_error("Unsupported key type in binary file");
}

// Read value
uint8_t valueType = readBinaryValue<uint8_t>(file);

switch (valueType) {
case 1: { // String
size_t valueSize = readBinaryValue<size_t>(file);
std::vector<char> valueBuffer(valueSize);
file.read(valueBuffer.data(), valueSize);
table[key] = std::string(valueBuffer.data(), valueSize);
break;
}
case 2: // Number
table[key] = readBinaryValue<double>(file);
break;
case 3: // Boolean
table[key] = readBinaryValue<bool>(file);
break;
case 4: // Nil
table[key] = sol::nil;
break;
case 5: // Nested table
table[key] = loadTableFromBinaryFile(lua, file);
break;
default:
throw std::runtime_error("Unsupported value type in binary file");
}
}

return table;
}

sol::table loadTableFromBinaryFile(sol::state& lua, const std::string& filename) {
std::ifstream file(filename, std::ios::binary);
if (!file.is_open()) {
throw std::runtime_error("Error opening file for reading: " + filename);
}

try {
return loadTableFromBinaryFile(lua, file);
} catch (const std::exception& e) {
file.close();
throw std::runtime_error(std::string("Error while reading from file: ") + e.what());
}
}

void LuaFile::load()
{
StandbyMode::triggerPower();
Expand Down Expand Up @@ -169,6 +316,16 @@ void LuaFile::load()
return chunk();
};

lua["saveTable"] = [&](const std::string& filename, const sol::table& table)
{
saveTableToBinaryFile(lua_storage.convertPath(filename).str(), table);
};

lua["loadTable"] = [&](const std::string& filename)
{
return loadTableFromBinaryFile(lua, lua_storage.convertPath(filename).str());
};

if (perms.acces_hardware) // si hardware est autorisé
{
lua.new_usertype<LuaHardware>("hardware",
Expand Down

0 comments on commit b4cd394

Please sign in to comment.