DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
serialization
include
serialization
Serialization.hpp
Go to the documentation of this file.
1
16
17
#ifndef SERIALIZATION_INCLUDE_SERIALIZATION_SERIALIZATION_HPP_
18
#define SERIALIZATION_INCLUDE_SERIALIZATION_SERIALIZATION_HPP_
19
20
#include "
ers/Issue.hpp
"
21
#include "
logging/Logging.hpp
"
// NOTE: if ISSUES ARE DECLARED BEFORE include logging/Logging.hpp, TLOG_DEBUG<<issue wont work.
22
23
#include "boost/preprocessor.hpp"
24
#include "msgpack.hpp"
25
26
#include <algorithm>
27
#include <string>
28
#include <vector>
29
35
// NOLINTBEGIN
36
#define DUNE_DAQ_TYPESTRING(Type, typestring) \
37
template<> \
38
inline std::string dunedaq::datatype_to_string<Type>() \
39
{ \
40
return typestring; \
41
}
42
46
#define DUNE_DAQ_SERIALIZABLE(Type, typestring) \
47
DUNE_DAQ_TYPESTRING(Type, typestring) \
48
template<> \
49
struct dunedaq::serialization::is_serializable<Type> \
50
{ \
51
static constexpr bool value = true; \
52
}
53
71
#define DUNE_DAQ_SERIALIZE(Type, ...) \
72
MSGPACK_DEFINE(__VA_ARGS__) \
73
static_assert(true, "")
74
76
#define OPACK(r, data, elem) o.pack(m.elem);
78
#define OUNPACK(r, data, elem) m.elem = o.via.array.ptr[i++].as<decltype(m.elem)>();
79
100
#define DUNE_DAQ_SERIALIZE_NON_INTRUSIVE(NS, Type, ...) \
101
DUNE_DAQ_SERIALIZABLE(NS::Type, #Type); \
102
namespace msgpack { \
103
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) \
104
{ \
105
namespace adaptor { \
106
template<> \
107
struct pack<NS::Type> \
108
{ \
109
template<typename Stream> \
110
packer<Stream>& operator()(msgpack::packer<Stream>& o, NS::Type const& m) const \
111
{ \
112
o.pack_array(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__)); \
113
BOOST_PP_SEQ_FOR_EACH(OPACK, , BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
114
return o; \
115
} \
116
}; \
117
template<> \
118
struct convert<NS::Type> \
119
{ \
120
msgpack::object const& operator()(msgpack::object const& o, NS::Type& m) const \
121
{ \
122
if (o.type != msgpack::type::ARRAY) \
123
throw msgpack::type_error(); \
124
if (o.via.array.size != BOOST_PP_VARIADIC_SIZE(__VA_ARGS__)) \
125
throw msgpack::type_error(); \
126
int i = 0; \
127
BOOST_PP_SEQ_FOR_EACH(OUNPACK, , BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
128
return o; \
129
} \
130
}; \
131
} \
132
} \
133
}
// namespace msgpack
134
138
#define DUNE_DAQ_SERIALIZE_ENUM(Type) MSGPACK_ADD_ENUM(Type)
139
// NOLINTEND
140
141
namespace
dunedaq
{
142
143
// Disable coverage collection LCOV_EXCL_START
145
ERS_DECLARE_ISSUE
(serialization, UnknownSerializationTypeString,
"Unknown serialization type "
<< t, ((std::string)t))
147
ERS_DECLARE_ISSUE
(serialization, UnknownSerializationTypeEnum,
"Unknown serialization type"
, )
149
ERS_DECLARE_ISSUE
(serialization,
UnknownSerializationTypeByte
,
"Unknown serialization type "
<< t, ((
char
)t))
// NOLINT
151
ERS_DECLARE_ISSUE
(serialization, CannotDeserializeMessage,
"Cannot deserialize message"
, )
152
// Re-enable coverage collection LCOV_EXCL_STOP
153
154
template<typename T>
155
inline
std
::
string
156
datatype_to_string()
157
{
158
return
"Unknown"
;
159
}
160
161
namespace
serialization {
162
163
template
<
typename
T>
164
struct
is_serializable : std::false_type
165
{};
166
170
enum
SerializationType
171
{
172
kMsgPack
173
};
174
178
inline
SerializationType
179
from_string(
const
std::string s)
180
{
181
if
(s ==
"msgpack"
)
182
return
kMsgPack;
183
throw
UnknownSerializationTypeString(
ERS_HERE
, s);
184
}
185
186
constexpr
uint8_t
// NOLINT(build/unsigned)
187
serialization_type_byte(SerializationType stype)
188
{
189
switch
(stype) {
190
case
kMsgPack:
191
return
'M'
;
192
default
:
193
throw
UnknownSerializationTypeEnum(
ERS_HERE
);
194
}
195
}
196
197
constexpr
SerializationType DEFAULT_SERIALIZATION_TYPE = kMsgPack;
198
202
template
<
class
T>
203
std::vector<uint8_t>
// NOLINT(build/unsigned)
204
serialize(
const
T& obj, SerializationType stype = DEFAULT_SERIALIZATION_TYPE)
205
{
206
switch
(stype) {
207
case
kMsgPack: {
208
// Serialize into the sbuffer and then copy to a
209
// std::vector. Seems like it would be more efficient to
210
// write directly to the vector (by creating a class that
211
// implements `void write(char* buf, size_t len)`), but my
212
// tests aren't any faster than this
213
msgpack::sbuffer buf;
214
msgpack::pack(buf, obj);
215
std::vector<uint8_t>
ret
(buf.size() + 1);
// NOLINT(build/unsigned)
216
ret
[0] = serialization_type_byte(stype);
217
std::copy(buf.data(), buf.data() + buf.size(),
ret
.begin() + 1);
// NOLINT
218
return
ret
;
219
}
220
default
:
221
throw
UnknownSerializationTypeEnum(
ERS_HERE
);
222
}
223
}
224
228
template
<
class
T,
typename
CharType =
unsigned
char
>
229
T
230
deserialize(
const
std::vector<CharType>& v)
231
{
232
// The first byte in the array indicates the serialization format;
233
// the rest is the actual message
234
switch
(v[0]) {
235
case
serialization_type_byte(kMsgPack): {
236
try
{
237
// The lambda function here is of type `unpack_reference_func`
238
// as described at
239
// https://github.com/msgpack/msgpack-c/wiki/v2_0_cpp_unpacker#memory-management
240
// . It is called for every STR, BIN and EXT field in the
241
// MsgPack data. If the function returns false, the object is
242
// copied into MsgPack's "zone", otherwise a pointer to the
243
// original buffer is stored. Our input buffer is going to exist
244
// at least until the end of this function, so it's safe to
245
// return true (ie, store a pointer in the MsgPack object; no
246
// copy) everywhere. Doing so results in a factor ~2 speedup in
247
// deserializing Fragment, which is just a large BIN field
248
msgpack::object_handle oh = msgpack::unpack(
249
const_cast<
char
*
>
(
reinterpret_cast<
const
char
*
>
(
v
.data() + 1)),
// NOLINT
250
v
.size() - 1,
251
[](msgpack::type::object_type
/*typ*/
, std::size_t
/*length*/
,
void
*
/*user_data*/
) ->
bool
{ return true; });
252
msgpack::object
obj
= oh.get();
253
return
obj
.as<T>();
254
}
catch
(msgpack::type_error& e) {
255
throw
CannotDeserializeMessage(
ERS_HERE
, e);
256
}
catch
(msgpack::unpack_error& e) {
257
throw
CannotDeserializeMessage(
ERS_HERE
, e);
258
}
259
}
260
default
:
261
throw
UnknownSerializationTypeByte
(
ERS_HERE
, (
char
)
v
[0]);
// NOLINT
262
}
263
}
264
265
}
// namespace serialization
266
}
// namespace dunedaq
267
268
#endif
// SERIALIZATION_INCLUDE_SERIALIZATION_SERIALIZATION_HPP_
Issue.hpp
ERS_HERE
#define ERS_HERE
Definition
LocalContext.hpp:127
Logging.hpp
checkLinks.ret
ret
Definition
checkLinks.py:8
dunedaq
The DUNE-DAQ namespace.
Definition
cib_utilities.cpp:5
dunedaq::obj
msgpack::object obj
Definition
Serialization.hpp:252
dunedaq::UnknownSerializationTypeByte
UnknownSerializationTypeByte
Definition
Serialization.hpp:149
dunedaq::ERS_DECLARE_ISSUE
ERS_DECLARE_ISSUE(cibmodules, CIBCommunicationError, " CIB Hardware Communication Error: "<< descriptor,((std::string) descriptor)) ERS_DECLARE_ISSUE(cibmodules
dunedaq::v
default char v[0]
Definition
Serialization.hpp:261
std
Definition
SchemaUtils.hpp:118
Generated on
for DUNE-DAQ by
1.18.0