You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
3.9 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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;
}
};