|
|
#pragma once
|
|
|
|
|
|
#include <string>
|
|
|
#include <vector>
|
|
|
#include <variant>
|
|
|
#include <sstream>
|
|
|
|
|
|
// Сериализаторы для IPC-сообщений.
|
|
|
// Каждый сериализатор определяет:
|
|
|
// - RawData - тип сырых (сериализованных) данных
|
|
|
// - serialize() - сериализация данных в RawData
|
|
|
// - deserialize() - десериализация из RawData
|
|
|
|
|
|
// ===== Текстовый сериализатор (текущий формат) =====
|
|
|
struct TextIpcSerializer {
|
|
|
// Тип сырых данных - строка (текстовый формат)
|
|
|
using RawData = std::string;
|
|
|
|
|
|
static RawData serialize(const std::vector<std::variant<int, std::string>>& data) {
|
|
|
std::ostringstream out;
|
|
|
for (const auto& v : data) {
|
|
|
std::visit([&out](const auto& val) {
|
|
|
using T = std::decay_t<decltype(val)>;
|
|
|
if constexpr (std::is_same_v<T, int>) {
|
|
|
out << 'i' << ' ' << val << ' ';
|
|
|
} else if constexpr (std::is_same_v<T, std::string>) {
|
|
|
out << 's' << ' ' << val.size() << ' ';
|
|
|
out.write(val.data(), static_cast<std::streamsize>(val.size()));
|
|
|
out << ' ';
|
|
|
}
|
|
|
}, v);
|
|
|
}
|
|
|
return out.str();
|
|
|
}
|
|
|
|
|
|
static std::vector<std::variant<int, std::string>> deserialize(const RawData& raw) {
|
|
|
std::vector<std::variant<int, std::string>> result;
|
|
|
std::istringstream in(raw);
|
|
|
|
|
|
while (in.peek() != EOF) {
|
|
|
char tag{};
|
|
|
in >> tag;
|
|
|
|
|
|
if (tag == 'i') {
|
|
|
int v{};
|
|
|
in >> v;
|
|
|
result.emplace_back(v);
|
|
|
} else if (tag == 's') {
|
|
|
std::size_t len{};
|
|
|
in >> len;
|
|
|
in.get(); // пробел
|
|
|
std::string str(len, '\0');
|
|
|
in.read(&str[0], static_cast<std::streamsize>(len));
|
|
|
in.get(); // завершающий пробел
|
|
|
result.emplace_back(std::move(str));
|
|
|
}
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// ===== JSON сериализатор (пример для будущего использования, например yami4) =====
|
|
|
struct JsonIpcSerializer {
|
|
|
// Тип сырых данных - строка (JSON - текстовый формат)
|
|
|
using RawData = std::string;
|
|
|
|
|
|
static RawData serialize(const std::vector<std::variant<int, std::string>>& data) {
|
|
|
// Упрощенный JSON формат: ["i:42", "s:5:hello"]
|
|
|
// В реальности использовать библиотеку JSON
|
|
|
std::ostringstream out;
|
|
|
out << "[";
|
|
|
bool first = true;
|
|
|
for (const auto& v : data) {
|
|
|
if (!first) out << ",";
|
|
|
first = false;
|
|
|
std::visit([&out](const auto& val) {
|
|
|
using T = std::decay_t<decltype(val)>;
|
|
|
if constexpr (std::is_same_v<T, int>) {
|
|
|
out << "\"i:" << val << "\"";
|
|
|
} else if constexpr (std::is_same_v<T, std::string>) {
|
|
|
// Экранирование для JSON (упрощенно)
|
|
|
out << "\"s:" << val.size() << ":";
|
|
|
for (char c : val) {
|
|
|
if (c == '"' || c == '\\') out << '\\';
|
|
|
out << c;
|
|
|
}
|
|
|
out << "\"";
|
|
|
}
|
|
|
}, v);
|
|
|
}
|
|
|
out << "]";
|
|
|
return out.str();
|
|
|
}
|
|
|
|
|
|
static std::vector<std::variant<int, std::string>> deserialize(const RawData& raw) {
|
|
|
// Упрощенный парсинг JSON (в реальности использовать библиотеку JSON)
|
|
|
std::vector<std::variant<int, std::string>> result;
|
|
|
// TODO: реализовать парсинг JSON
|
|
|
return result;
|
|
|
}
|
|
|
};
|
|
|
|