Serialization.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 // std
4 #include <cstddef>
5 #include <cstdint>
6 #include <vector>
7 
8 // libraries
9 #include <nop/serializer.h>
10 #include <nop/structure.h>
11 #include <nop/utility/buffer_reader.h>
12 #include <nop/utility/stream_writer.h>
13 
14 // project
15 #include "NlohmannJsonCompat.hpp"
16 
17 // To not require exceptions for embedded usecases.
18 #ifndef __has_feature // Optional of course.
19  #define __has_feature(x) 0 // Compatibility with non-clang compilers.
20 #endif
21 #if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || (defined(_MSC_VER) && defined(_CPPUNWIND)) || defined(__EXCEPTIONS)
22  #define DEPTHAI_EXCEPTIONS
23 #endif
24 
25 namespace dai {
26 
27 enum class SerializationType {
28  LIBNOP,
29  JSON,
31 };
33 
34 namespace utility {
35 
36 // JSON-msgpack serialization
37 template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON_MSGPACK, bool> = true>
38 inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
39  nlohmann::json j = obj;
40  data = nlohmann::json::to_msgpack(j);
41  return true;
42 }
43 template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON_MSGPACK, bool> = true>
44 inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
45  nlohmann::from_json(nlohmann::json::from_msgpack(data, data + size), obj);
46  return true;
47 }
48 
49 // JSON serialization
50 template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON, bool> = true>
51 inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
52  nlohmann::json j = obj;
53  auto json = j.dump();
54  data = std::vector<std::uint8_t>(reinterpret_cast<const std::uint8_t*>(json.data()), reinterpret_cast<const std::uint8_t*>(json.data()) + json.size());
55  return true;
56 }
57 template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::JSON, bool> = true>
58 inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
59  nlohmann::from_json(nlohmann::json::parse(data, data + size), obj);
60  return true;
61 }
62 
63 // NOLINTBEGIN
64 class VectorWriter {
65  public:
66  template <typename... Args>
67  VectorWriter(Args&&... args) : vector{std::forward<Args>(args)...} {}
68  VectorWriter(const VectorWriter&) = default;
69  VectorWriter& operator=(const VectorWriter&) = default;
70 
71  nop::Status<void> Prepare(std::size_t /*size*/) {
72  return {};
73  }
74 
75  nop::Status<void> Write(std::uint8_t byte) {
76  vector.push_back(byte);
77  return ReturnStatus();
78  }
79 
80  nop::Status<void> Write(const void* begin, const void* end) {
81  vector.insert(vector.end(), static_cast<const std::uint8_t*>(begin), static_cast<const std::uint8_t*>(end));
82  return ReturnStatus();
83  }
84 
85  nop::Status<void> Skip(std::size_t padding_bytes, std::uint8_t padding_value = 0x00) {
86  for(std::size_t i = 0; i < padding_bytes; i++) {
87  vector.push_back(padding_value);
88  auto status = ReturnStatus();
89  if(!status) return status;
90  }
91 
92  return {};
93  }
94 
95  const std::vector<std::uint8_t>& ref() const {
96  return vector;
97  }
98  std::vector<std::uint8_t>& ref() {
99  return vector;
100  }
101  std::vector<std::uint8_t>&& take() {
102  return std::move(vector);
103  }
104 
105  private:
106  nop::Status<void> ReturnStatus() {
107  return {};
108  }
109 
110  std::vector<std::uint8_t> vector;
111 };
112 // NOLINTEND
113 
114 // libnop serialization
115 // If exceptions are available it throws in error cases
116 // Otherwise return value can be checked
117 template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::LIBNOP, bool> = true>
118 inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
119  nop::Serializer<VectorWriter> serializer{std::move(data)};
120  auto status = serializer.Write(obj);
121  if(!status) {
122 #ifdef DEPTHAI_EXCEPTIONS
123  throw std::runtime_error(status.GetErrorMessage());
124 #else
125  return false;
126 #endif
127  }
128  data = std::move(serializer.writer().take());
129  return true;
130 }
131 template <SerializationType TYPE, typename T, std::enable_if_t<TYPE == SerializationType::LIBNOP, bool> = true>
132 inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
133  nop::Deserializer<nop::BufferReader> deserializer{data, size};
134  auto status = deserializer.Read(&obj);
135  if(!status) {
136 #ifdef DEPTHAI_EXCEPTIONS
137  throw std::runtime_error(status.GetErrorMessage());
138 #else
139  return false;
140 #endif
141  }
142  return true;
143 }
144 
145 // Serialization using enum
146 template <typename T>
147 inline bool serialize(const T& obj, std::vector<std::uint8_t>& data, SerializationType type) {
148  switch(type) {
150  return serialize<SerializationType::LIBNOP>(obj, data);
152  return serialize<SerializationType::JSON>(obj, data);
154  return serialize<SerializationType::JSON_MSGPACK>(obj, data);
155  default:
156  throw std::invalid_argument("Unknown serialization type");
157  };
158 }
159 template <typename T>
160 inline std::vector<std::uint8_t> serialize(const T& obj, SerializationType type) {
161  std::vector<std::uint8_t> data;
162  if(serialize(obj, data, type)) {
163  return data;
164  } else {
165  return {};
166  }
167 }
168 
169 template <typename T>
170 inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj, SerializationType type) {
171  switch(type) {
173  return deserialize<SerializationType::LIBNOP>(data, size, obj);
175  return deserialize<SerializationType::JSON>(data, size, obj);
177  return deserialize<SerializationType::JSON_MSGPACK>(data, size, obj);
178  default:
179  throw std::invalid_argument("Unknown serialization type");
180  };
181 }
182 template <typename T>
183 inline bool deserialize(const std::vector<std::uint8_t>& data, T& obj, SerializationType type) {
184  return deserialize(data.data(), data.size(), obj, type);
185 }
186 
187 // Serialization using templates
188 template <SerializationType TYPE, typename T>
189 inline std::vector<std::uint8_t> serialize(const T& obj) {
190  std::vector<std::uint8_t> data;
191  if(serialize<TYPE>(obj, data)) {
192  return data;
193  } else {
194  return {};
195  }
196 }
197 template <SerializationType TYPE, typename T>
198 inline bool deserialize(const std::vector<std::uint8_t>& data, T& obj) {
199  return deserialize<TYPE>(data.data(), data.size(), obj);
200 }
201 
202 // Defaults
203 template <typename T>
204 inline bool serialize(const T& obj, std::vector<std::uint8_t>& data) {
205  return serialize<DEFAULT_SERIALIZATION_TYPE>(obj, data);
206 }
207 template <typename T>
208 inline std::vector<std::uint8_t> serialize(const T& obj) {
209  return serialize<DEFAULT_SERIALIZATION_TYPE>(obj);
210 }
211 template <typename T>
212 inline bool deserialize(const std::uint8_t* data, std::size_t size, T& obj) {
213  return deserialize<DEFAULT_SERIALIZATION_TYPE>(data, size, obj);
214 }
215 template <typename T>
216 inline bool deserialize(const std::vector<std::uint8_t>& data, T& obj) {
217  return deserialize<DEFAULT_SERIALIZATION_TYPE>(data, obj);
218 }
219 
220 } // namespace utility
221 
222 // // In dai scope
223 // template<typename Base, typename Derived>
224 // struct Serializable : Base {
225 // virtual void serialize(std::vector<std::uint8_t>& data) {
226 // utility::serialize(static_cast<const Derived&>(*this), data);
227 // }
228 // };
229 
230 } // namespace dai
231 
232 #define DEPTHAI_DEFERRED_EXPAND(x) x
233 #if defined(_MSC_VER) && (!defined(_MSVC_TRADITIONAL) || _MSVC_TRADITIONAL)
234  // Logic using the traditional preprocessor
235  // This is for suppressing false positive warnings when compiling
236  // without /Zc:preprocessor
237  #pragma warning(disable : 4003)
238 #endif
239 
240 #define DEPTHAI_NLOHMANN_JSON_OPTIONAL_TO(v1) nlohmann::to_json(nlohmann_json_j[#v1], nlohmann_json_t.v1);
241 #define DEPTHAI_NLOHMANN_JSON_OPTIONAL_FROM(v1) \
242  if(nlohmann_json_j.contains(#v1)) nlohmann_json_j[#v1].get_to(nlohmann_json_t.v1);
243 #define DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_NON_INTRUSIVE(Type, ...) \
244  inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { \
245  DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_TO, __VA_ARGS__)) \
246  } \
247  inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { \
248  DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_FROM, __VA_ARGS__)) \
249  }
250 #define DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_INTRUSIVE(Type, ...) \
251  friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { \
252  DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_TO, __VA_ARGS__)) \
253  } \
254  friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { \
255  DEPTHAI_NLOHMANN_JSON_EXPAND(DEPTHAI_NLOHMANN_JSON_PASTE(DEPTHAI_NLOHMANN_JSON_OPTIONAL_FROM, __VA_ARGS__)) \
256  }
257 
258 // Macros
259 #define DEPTHAI_SERIALIZE_OPTIONAL_EXT(...) \
260  DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_NON_INTRUSIVE(__VA_ARGS__)) \
261  DEPTHAI_DEFERRED_EXPAND(NOP_EXTERNAL_STRUCTURE(__VA_ARGS__))
262 
263 #define DEPTHAI_SERIALIZE_OPTIONAL(...) \
264  DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_OPTIONAL_INTRUSIVE(__VA_ARGS__)) \
265  DEPTHAI_DEFERRED_EXPAND(NOP_EXTERNAL_STRUCTURE(__VA_ARGS__))
266 
267 #define DEPTHAI_SERIALIZE_EXT(...) \
268  DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(__VA_ARGS__)) \
269  DEPTHAI_DEFERRED_EXPAND(NOP_EXTERNAL_STRUCTURE(__VA_ARGS__))
270 
271 #define DEPTHAI_SERIALIZE(...) \
272  DEPTHAI_DEFERRED_EXPAND(DEPTHAI_NLOHMANN_DEFINE_TYPE_INTRUSIVE(__VA_ARGS__)) \
273  DEPTHAI_DEFERRED_EXPAND(NOP_STRUCTURE(__VA_ARGS__))
dai::DEFAULT_SERIALIZATION_TYPE
constexpr static auto DEFAULT_SERIALIZATION_TYPE
Definition: Serialization.hpp:32
dai::utility::VectorWriter::operator=
VectorWriter & operator=(const VectorWriter &)=default
dai::utility::VectorWriter::VectorWriter
VectorWriter(Args &&... args)
Definition: Serialization.hpp:67
NlohmannJsonCompat.hpp
dai::utility::VectorWriter::ref
const std::vector< std::uint8_t > & ref() const
Definition: Serialization.hpp:95
dai::SerializationType::JSON_MSGPACK
@ JSON_MSGPACK
dai::utility::serialize
bool serialize(const T &obj, std::vector< std::uint8_t > &data)
Definition: Serialization.hpp:38
DAI_SPAN_NAMESPACE_NAME::detail::data
constexpr auto data(C &c) -> decltype(c.data())
Definition: span.hpp:177
dai::utility::VectorWriter::take
std::vector< std::uint8_t > && take()
Definition: Serialization.hpp:101
dai::SerializationType::JSON
@ JSON
dai::utility::VectorWriter::Skip
nop::Status< void > Skip(std::size_t padding_bytes, std::uint8_t padding_value=0x00)
Definition: Serialization.hpp:85
dai::utility::deserialize
bool deserialize(const std::uint8_t *data, std::size_t size, T &obj)
Definition: Serialization.hpp:44
dai::SerializationType::LIBNOP
@ LIBNOP
dai::utility::VectorWriter::ReturnStatus
nop::Status< void > ReturnStatus()
Definition: Serialization.hpp:106
DAI_SPAN_NAMESPACE_NAME::detail::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: span.hpp:167
dai::utility::VectorWriter::Write
nop::Status< void > Write(std::uint8_t byte)
Definition: Serialization.hpp:75
dai::utility::VectorWriter::Prepare
nop::Status< void > Prepare(std::size_t)
Definition: Serialization.hpp:71
dai::SerializationType
SerializationType
Definition: Serialization.hpp:27
nanorpc::core::detail::pack::meta::type
type
Definition: pack_meta.h:26
nanorpc::core::detail::pack::meta::status
status
Definition: pack_meta.h:33
dai::utility::VectorWriter::Write
nop::Status< void > Write(const void *begin, const void *end)
Definition: Serialization.hpp:80
dai::utility::VectorWriter
Definition: Serialization.hpp:64
dai::utility::VectorWriter::ref
std::vector< std::uint8_t > & ref()
Definition: Serialization.hpp:98
dai::utility::VectorWriter::vector
std::vector< std::uint8_t > vector
Definition: Serialization.hpp:110
dai
Definition: CameraExposureOffset.hpp:6


depthai
Author(s): Martin Peterlin
autogenerated on Sat Mar 22 2025 02:58:19