147 return visit([](
auto&&
value) -> std::string {
148 using T = std::decay_t<
decltype(
value)>;
150 if constexpr (std::is_same_v<T, std::monostate>) {
153 else if constexpr (std::is_same_v<T, bool>) {
154 return value ?
"true" :
"false";
156 else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
157 std::ostringstream oss;
158 oss << std::hex << std::setfill(
'0');
159 for (
auto byte :
value) {
160 oss << std::setw(2) << static_cast<int>(
byte);
164 else if constexpr (std::is_arithmetic_v<T>) {
165 return std::to_string(
value);
167 else if constexpr (std::is_same_v<T, std::string>) {
170 else if constexpr (std::is_same_v<T, std::shared_ptr<thread_safe_container>>) {
173 else if constexpr (std::is_same_v<T, array_variant>) {
174 std::string result =
"[";
175 for (
size_t i = 0; i <
value.values.size(); ++i) {
176 if (i > 0) result +=
",";
187 auto var_name =
name();
188 auto var_type =
type();
190 return visit([var_name, var_type](
auto&&
value) -> std::string {
191 using T = std::decay_t<
decltype(
value)>;
194 std::string result =
"{\"name\":\"" + std::string(var_name) +
195 "\",\"type\":" + std::to_string(
static_cast<int>(var_type)) +
198 if constexpr (std::is_same_v<T, std::monostate>) {
201 else if constexpr (std::is_same_v<T, bool>) {
202 result +=
value ?
"true" :
"false";
204 else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
206 std::ostringstream oss;
207 oss << std::hex << std::setfill(
'0');
208 for (
auto byte :
value) {
209 oss << std::setw(2) << static_cast<int>(
byte);
214 else if constexpr (std::is_arithmetic_v<T>) {
215 result += std::to_string(
value);
217 else if constexpr (std::is_same_v<T, std::string>) {
220 for (
char c :
value) {
222 case '"': result +=
"\\\"";
break;
223 case '\\': result +=
"\\\\";
break;
224 case '\b': result +=
"\\b";
break;
225 case '\f': result +=
"\\f";
break;
226 case '\n': result +=
"\\n";
break;
227 case '\r': result +=
"\\r";
break;
228 case '\t': result +=
"\\t";
break;
230 if (c >= 0x20 && c <= 0x7E) {
235 std::snprintf(buf,
sizeof(buf),
"\\u%04x",
static_cast<unsigned char>(c));
242 else if constexpr (std::is_same_v<T, std::shared_ptr<thread_safe_container>>) {
245 else if constexpr (std::is_same_v<T, array_variant>) {
247 for (
size_t i = 0; i <
value.values.size(); ++i) {
248 if (i > 0) result +=
",";
260 visit([&result](
auto&& val) {
261 using T = std::decay_t<
decltype(val)>;
263 if constexpr (std::is_same_v<T, std::monostate>) {
266 else if constexpr (std::is_same_v<T, bool>) {
267 result.push_back(val ? 1 : 0);
269 else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
271 uint32_t size =
static_cast<uint32_t
>(val.size());
272 result.insert(result.end(),
273 reinterpret_cast<const uint8_t*
>(&size),
274 reinterpret_cast<const uint8_t*
>(&size) +
sizeof(size));
275 result.insert(result.end(), val.begin(), val.end());
277 else if constexpr (std::is_arithmetic_v<T> && !std::is_same_v<T, bool>) {
279 result.insert(result.end(),
280 reinterpret_cast<const uint8_t*
>(&val),
281 reinterpret_cast<const uint8_t*
>(&val) +
sizeof(T));
283 else if constexpr (std::is_same_v<T, std::string>) {
285 uint32_t size =
static_cast<uint32_t
>(val.size());
286 result.insert(result.end(),
287 reinterpret_cast<const uint8_t*
>(&size),
288 reinterpret_cast<const uint8_t*
>(&size) +
sizeof(size));
289 result.insert(result.end(), val.begin(), val.end());
291 else if constexpr (std::is_same_v<T, std::shared_ptr<thread_safe_container>>) {
299 result.insert(result.end(),
300 reinterpret_cast<const uint8_t*
>(&size),
301 reinterpret_cast<const uint8_t*
>(&size) +
sizeof(size));
303 auto container_data = val->serialize();
304 uint32_t size =
static_cast<uint32_t
>(container_data.size());
305 result.insert(result.end(),
306 reinterpret_cast<const uint8_t*
>(&size),
307 reinterpret_cast<const uint8_t*
>(&size) +
sizeof(size));
308 result.insert(result.end(), container_data.begin(), container_data.end());
312 result.insert(result.end(),
313 reinterpret_cast<const uint8_t*
>(&size),
314 reinterpret_cast<const uint8_t*
>(&size) +
sizeof(size));
317 else if constexpr (std::is_same_v<T, array_variant>) {
319 uint32_t count =
static_cast<uint32_t
>(val.values.size());
320 result.insert(result.end(),
321 reinterpret_cast<const uint8_t*
>(&count),
322 reinterpret_cast<const uint8_t*
>(&count) +
sizeof(count));
324 for (
const auto& elem : val.values) {
326 auto elem_data = elem->serialize();
327 result.insert(result.end(), elem_data.begin(), elem_data.end());
332 result.insert(result.end(), null_data.begin(), null_data.end());
361 const std::vector<uint8_t>& data,
364 case value_types::null_value:
365 result.
data_.emplace<0>();
368 case value_types::bool_value:
369 if (offset >= data.size())
return false;
370 result.
data_ = (data[offset++] != 0);
373 case value_types::short_value: {
374 if (offset +
sizeof(int16_t) > data.size())
return false;
376 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
377 offset +=
sizeof(
value);
382 case value_types::ushort_value: {
383 if (offset +
sizeof(uint16_t) > data.size())
return false;
385 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
386 offset +=
sizeof(
value);
391 case value_types::int_value: {
392 if (offset +
sizeof(int32_t) > data.size())
return false;
394 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
395 offset +=
sizeof(
value);
400 case value_types::uint_value: {
401 if (offset +
sizeof(uint32_t) > data.size())
return false;
403 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
404 offset +=
sizeof(
value);
409 case value_types::long_value: {
410 if (offset +
sizeof(int64_t) > data.size())
return false;
412 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
413 offset +=
sizeof(
value);
418 case value_types::llong_value: {
419 if (offset +
sizeof(int64_t) > data.size())
return false;
420#if defined(_MSC_VER) && _MSC_VER < 1900
423 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
424 offset +=
sizeof(
value);
430 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
431 offset +=
sizeof(
value);
437 case value_types::ulong_value: {
438 if (offset +
sizeof(uint64_t) > data.size())
return false;
440 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
441 offset +=
sizeof(
value);
446 case value_types::ullong_value: {
447 if (offset +
sizeof(uint64_t) > data.size())
return false;
448#if defined(_MSC_VER) && _MSC_VER < 1900
450 unsigned long long value;
451 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
452 offset +=
sizeof(
value);
458 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
459 offset +=
sizeof(
value);
465 case value_types::float_value: {
466 if (offset +
sizeof(
float) > data.size())
return false;
468 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
469 offset +=
sizeof(
value);
474 case value_types::double_value: {
475 if (offset +
sizeof(
double) > data.size())
return false;
477 std::memcpy(&
value, data.data() + offset,
sizeof(
value));
478 offset +=
sizeof(
value);
483 case value_types::bytes_value: {
484 if (offset +
sizeof(uint32_t) > data.size())
return false;
486 std::memcpy(&size, data.data() + offset,
sizeof(size));
487 offset +=
sizeof(size);
488 if (offset + size > data.size())
return false;
489 std::vector<uint8_t> bytes(data.begin() + offset,
490 data.begin() + offset + size);
492 result.
data_ = std::move(bytes);
496 case value_types::string_value: {
497 if (offset +
sizeof(uint32_t) > data.size())
return false;
499 std::memcpy(&size, data.data() + offset,
sizeof(size));
500 offset +=
sizeof(size);
501 if (offset + size > data.size())
return false;
502 std::string str(data.begin() + offset, data.begin() + offset + size);
504 result.
data_ = std::move(str);
508 case value_types::container_value: {
509 if (offset +
sizeof(uint32_t) > data.size())
return false;
511 std::memcpy(&size, data.data() + offset,
sizeof(size));
512 offset +=
sizeof(size);
514 result.
data_ = std::shared_ptr<thread_safe_container>(
nullptr);
517 if (offset + size > data.size())
return false;
518 std::vector<uint8_t> container_data(data.begin() + offset,
519 data.begin() + offset + size);
522 result.
data_ = container;
526 case value_types::array_value: {
527 if (offset +
sizeof(uint32_t) > data.size())
return false;
529 std::memcpy(&count, data.data() + offset,
sizeof(count));
530 offset +=
sizeof(count);
533 arr.
values.reserve(count);
535 for (uint32_t i = 0; i < count; ++i) {
536 auto elem =
deserialize(std::vector<uint8_t>(data.begin() + offset, data.end()));
537 if (!elem)
return false;
540 auto elem_size = elem->serialize().size();
543 arr.
values.push_back(std::make_shared<value>(std::move(*elem)));
546 result.
data_ = std::move(arr);
556 if (data.size() <
sizeof(uint32_t) + 1) {
564 std::memcpy(&name_len, data.data() + offset,
sizeof(name_len));
565 offset +=
sizeof(name_len);
567 if (offset + name_len + 1 > data.size()) {
572 std::string
name(data.begin() + offset, data.begin() + offset + name_len);
576 uint8_t type_byte = data[offset++];
577 value_types
type =
static_cast<value_types
>(type_byte);
580 if (type_byte > 15) {