Container System 0.1.0
High-performance C++20 type-safe container framework with SIMD-accelerated serialization
Loading...
Searching...
No Matches
binary_serializer.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#include "binary_serializer.h"
6#include "../container.h"
9
10namespace kcenon::container
11{
12
13namespace
14{
15 // Header field IDs for binary format
16 inline constexpr int TARGET_ID = 1;
17 inline constexpr int TARGET_SUB_ID = 2;
18 inline constexpr int SOURCE_ID = 3;
19 inline constexpr int SOURCE_SUB_ID = 4;
20 inline constexpr int MESSAGE_TYPE = 5;
21 inline constexpr int MESSAGE_VERSION = 6;
22} // anonymous namespace
23
24#if CONTAINER_HAS_RESULT
25kcenon::common::Result<std::vector<uint8_t>>
26binary_serializer::serialize(const value_container& container) const noexcept
27{
28 try
29 {
30 // Get container data through public accessors
31 auto message_type = container.message_type();
32 auto target_id = container.target_id();
33 auto target_sub_id = container.target_sub_id();
34 auto source_id = container.source_id();
35 auto source_sub_id = container.source_sub_id();
36 auto version = container.version();
37 auto data_section = container.datas();
38
39 // Build header with pre-allocated buffer
40 std::string result;
41 result.reserve(200 + data_section.size());
42
43 // Note: In fmt library, {{}} produces single {}, so {{{{}}}} produces {{}}
44 utility_module::formatter::format_to(std::back_inserter(result), "@header={{{{");
45
46 if (message_type != "data_container")
47 {
48 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
49 TARGET_ID, target_id);
50 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
51 TARGET_SUB_ID, target_sub_id);
52 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
53 SOURCE_ID, source_id);
54 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
55 SOURCE_SUB_ID, source_sub_id);
56 }
57 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
58 MESSAGE_TYPE, message_type);
59 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
60 MESSAGE_VERSION, version);
61 utility_module::formatter::format_to(std::back_inserter(result), "}}}};");
62
63 // Append data section
64 result.append(data_section);
65
66 // Convert to byte array
67 auto [arr, err] = utility_module::convert_string::to_array(result);
68 if (!err.empty())
69 {
70 return kcenon::common::Result<std::vector<uint8_t>>(
71 kcenon::common::error_info{
72 -1,
73 "Failed to convert binary string to bytes: " + err,
74 "binary_serializer"});
75 }
76
77 return kcenon::common::ok(std::move(arr));
78 }
79 catch (const std::bad_alloc&)
80 {
81 return kcenon::common::Result<std::vector<uint8_t>>(
82 kcenon::common::error_info{
83 -2,
84 "Memory allocation failed during binary serialization",
85 "binary_serializer"});
86 }
87 catch (const std::exception& e)
88 {
89 return kcenon::common::Result<std::vector<uint8_t>>(
90 kcenon::common::error_info{
91 -1,
92 std::string("Binary serialization failed: ") + e.what(),
93 "binary_serializer"});
94 }
95}
96
97std::string binary_serializer::serialize_to_string(const value_container& container) const
98{
99 // Get container data through public accessors
100 auto message_type = container.message_type();
101 auto target_id = container.target_id();
102 auto target_sub_id = container.target_sub_id();
103 auto source_id = container.source_id();
104 auto source_sub_id = container.source_sub_id();
105 auto version = container.version();
106 auto data_section = container.datas();
107
108 // Build header with pre-allocated buffer
109 std::string result;
110 result.reserve(200 + data_section.size());
111
112 utility_module::formatter::format_to(std::back_inserter(result), "@header={{{{");
113
114 if (message_type != "data_container")
115 {
116 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
117 TARGET_ID, target_id);
118 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
119 TARGET_SUB_ID, target_sub_id);
120 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
121 SOURCE_ID, source_id);
122 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
123 SOURCE_SUB_ID, source_sub_id);
124 }
125 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
126 MESSAGE_TYPE, message_type);
127 utility_module::formatter::format_to(std::back_inserter(result), "[{},{}];",
128 MESSAGE_VERSION, version);
129 utility_module::formatter::format_to(std::back_inserter(result), "}}}};");
130
131 result.append(data_section);
132
133 return result;
134}
135#endif
136
137} // namespace kcenon::container
static void format_to(OutputIt out, const std::string &format_str, Args &&... args)
Definition formatter.h:62
constexpr int MESSAGE_VERSION
Definition container.cpp:37
constexpr int TARGET_ID
Definition container.cpp:32
constexpr int SOURCE_ID
Definition container.cpp:34
constexpr int MESSAGE_TYPE
Definition container.cpp:36
constexpr int TARGET_SUB_ID
Definition container.cpp:33
constexpr int SOURCE_SUB_ID
Definition container.cpp:35
std::tuple< std::optional< std::vector< uint8_t > >, std::optional< std::string > > to_array(const std::string &str)