DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
AvailableParserOperations.hpp
Go to the documentation of this file.
1
9#ifndef FLXLIBS_INCLUDE_FLXLIBS_AVAILABLEPARSEROPERATIONS_HPP_
10#define FLXLIBS_INCLUDE_FLXLIBS_AVAILABLEPARSEROPERATIONS_HPP_
11
12#include "FelixIssues.hpp"
13
14#include "iomanager/Sender.hpp"
15
17
18#include "packetformat/block_format.hpp"
19
20#include <algorithm>
21#include <cstdlib>
22#include <memory>
23#include <sstream>
24#include <utility>
25
26namespace dunedaq {
27namespace flxlibs {
28namespace parsers {
29
30inline void
31print_bytes(std::ostream& ostr, const char* title, const unsigned char* data, std::size_t length, bool format = true)
32{
33 ostr << title << std::endl;
34 ostr << std::setfill('0');
35 for (size_t i = 0; i < length; ++i) {
36 ostr << std::hex << std::setw(2) << static_cast<int>(data[i]);
37 if (format) {
38 ostr << (((i + 1) % 16 == 0) ? "\n" : " ");
39 }
40 }
41 ostr << std::endl;
42}
43
44inline void
45dump_to_buffer(const char* data,
46 std::size_t size,
47 void* buffer,
48 uint32_t buffer_pos, // NOLINT
49 const std::size_t& buffer_size)
50{
51 auto bytes_to_copy = size; // NOLINT
52 while (bytes_to_copy > 0) {
53 auto n = std::min(bytes_to_copy, buffer_size - buffer_pos); // NOLINT
54 std::memcpy(static_cast<char*>(buffer) + buffer_pos, data, n);
55 buffer_pos += n;
56 bytes_to_copy -= n;
57 if (buffer_pos == buffer_size) {
58 buffer_pos = 0;
59 }
60 }
61}
62
63template<class TargetStruct>
64inline std::function<void(const felix::packetformat::chunk& chunk)>
65fixsizedChunkInto(std::shared_ptr<std::function<void(TargetStruct&&)>>& cb,
66 std::chrono::milliseconds timeout = std::chrono::milliseconds(100))
67{
68 return [&](const felix::packetformat::chunk& chunk) {
69 // Chunk info
70 auto subchunk_data = chunk.subchunks();
71 auto subchunk_sizes = chunk.subchunk_lengths();
72 auto n_subchunks = chunk.subchunk_number();
73 std::size_t target_size = sizeof(TargetStruct);
74
75 // Only dump to buffer if possible
76 if (chunk.length() != target_size) {
77 ers::error(UnexpectedChunk(ERS_HERE, chunk.length(), target_size));
78 } else {
79 TargetStruct payload;
80 uint32_t bytes_copied_chunk = 0; // NOLINT
81 for (unsigned i = 0; i < n_subchunks; i++) {
83 subchunk_data[i], subchunk_sizes[i], static_cast<void*>(&payload.data), bytes_copied_chunk, target_size);
84 bytes_copied_chunk += subchunk_sizes[i];
85 }
86 try {
87 (*cb)(std::move(payload));
88 } catch (const std::exception& e) {
89 TLOG() << "Caught " << e.what();
90 }
91 }
92 };
93}
94
95template<class TargetStruct>
96inline std::function<void(const felix::packetformat::shortchunk& shortchunk)>
97fixsizedShortchunkInto(std::shared_ptr<std::function<void(TargetStruct&&)>>& cb,
98 std::chrono::milliseconds timeout = std::chrono::milliseconds(100))
99{
100 return [&](const felix::packetformat::shortchunk& shortchunk) {
101 // Only dump to buffer if possible
102 std::size_t target_size = sizeof(TargetStruct);
103 if (shortchunk.length != target_size) {
104 // report? Add custom way of handling unexpected user payloads.
105 // In this case -> not fixed size shortchunk -> shortchunk-to-userbuff not possible
106 // Can't throw, and can't print as it may flood output
107 } else {
108 TargetStruct payload;
109 std::memcpy(static_cast<char*>(payload), shortchunk.data, target_size);
110 try {
111 (*cb)(std::move(payload));
112 } catch (const std::exception& e) {
113 TLOG() << "Caught " << e.what();
114 }
115 }
116 };
117}
118
119template<class TargetStruct>
120inline std::function<void(const felix::packetformat::chunk& chunk)>
121fixsizedChunkViaHeap(std::shared_ptr<std::function<void(TargetStruct&&)>>& cb,
122 std::chrono::milliseconds timeout = std::chrono::milliseconds(100))
123{
124 return [&](const felix::packetformat::chunk& chunk) {
125 // Chunk info
126 auto subchunk_data = chunk.subchunks();
127 auto subchunk_sizes = chunk.subchunk_lengths();
128 auto n_subchunks = chunk.subchunk_number();
129 auto target_size = sizeof(TargetStruct);
130
131 // Only dump to buffer if possible
132 if (chunk.length() != target_size) {
133 // report? Add custom way of handling unexpected user payloads.
134 // In this case -> not fixed size chunk -> chunk-to-userbuff not possible
135 } else {
136 TargetStruct* payload = new TargetStruct[sizeof(TargetStruct)];
137 // std::unique_ptr<TargetStruct> payload = std::make_unique<TargetStruct>();
138 uint_fast32_t bytes_copied_chunk = 0; // NOLINT
139 for (unsigned i = 0; i < n_subchunks; i++) {
140 dump_to_buffer(subchunk_data[i],
141 subchunk_sizes[i],
142 static_cast<void*>(payload), // static_cast<void*>(&payload_ptr->data),
143 bytes_copied_chunk,
144 target_size);
145 bytes_copied_chunk += subchunk_sizes[i];
146 }
147 try {
148 (*cb)(std::move(payload));
149 } catch (const std::exception& e) {
150 TLOG() << "Caught " << e.what();
151 }
152 }
153 };
154}
155
156template<class TargetWithDatafield>
157inline std::function<void(const felix::packetformat::chunk&)>
158varsizedChunkIntoWithDatafield(std::shared_ptr<std::function<void(TargetWithDatafield&&)>>& cb,
159 std::chrono::milliseconds timeout = std::chrono::milliseconds(100))
160{
161 return [&](const felix::packetformat::chunk& chunk) {
162 auto subchunk_data = chunk.subchunks();
163 auto subchunk_sizes = chunk.subchunk_lengths();
164 auto n_subchunks = chunk.subchunk_number();
165 TargetWithDatafield twd;
166 twd.get_data().reserve(chunk.length());
167 uint32_t bytes_copied_chunk = 0;
168 for (unsigned i = 0; i < n_subchunks; ++i) {
169 dump_to_buffer(subchunk_data[i],
170 subchunk_sizes[i],
171 static_cast<void*>(twd.get_data().data()),
172 bytes_copied_chunk,
173 chunk.length());
174 bytes_copied_chunk += subchunk_sizes[i];
175 }
176 twd.set_data_size(bytes_copied_chunk);
177 try {
178 (*cb)(std::move(twd));
179 } catch (const std::exception& e) {
180 TLOG() << "Caught " << e.what();
181 }
182 };
183}
184
185template<class TargetWithDatafield>
186inline std::function<void(const felix::packetformat::shortchunk&)>
187varsizedShortchunkIntoWithDatafield(std::shared_ptr<std::function<void(TargetWithDatafield&&)>>& cb,
188 std::chrono::milliseconds timeout = std::chrono::milliseconds(100))
189{
190 return [&](const felix::packetformat::shortchunk& shortchunk) {
191 TargetWithDatafield twd;
192 twd.get_data().reserve(shortchunk.length);
193 std::memcpy(static_cast<void*>(twd.get_data().data()), shortchunk.data, shortchunk.length);
194 twd.set_data_size(shortchunk.length);
195 try {
196 (*cb)(std::move(twd));
197 } catch (const std::exception& e) {
198 TLOG() << "Caught " << e.what();
199 }
200 };
201}
202
203inline std::function<void(const felix::packetformat::chunk& chunk)>
205 std::shared_ptr<std::function<void(fdreadoutlibs::types::VariableSizePayloadTypeAdapter&&)>>& cb,
206 std::chrono::milliseconds timeout = std::chrono::milliseconds(100))
207{
208 return [&](const felix::packetformat::chunk& chunk) {
209 auto subchunk_data = chunk.subchunks();
210 auto subchunk_sizes = chunk.subchunk_lengths();
211 auto n_subchunks = chunk.subchunk_number();
212 auto chunk_length = chunk.length();
213
214 char* payload = static_cast<char*>(malloc(chunk_length * sizeof(char)));
215 uint32_t bytes_copied_chunk = 0; // NOLINT(build/unsigned)
216 for (unsigned i = 0; i < n_subchunks; ++i) {
218 subchunk_data[i], subchunk_sizes[i], static_cast<void*>(payload), bytes_copied_chunk, chunk_length);
219 bytes_copied_chunk += subchunk_sizes[i];
220 }
221 fdreadoutlibs::types::VariableSizePayloadTypeAdapter payload_wrapper(chunk_length, payload);
222 try {
223 (*cb)(std::move(payload_wrapper));
224 } catch (const std::exception& e) {
225 TLOG() << "Caught " << e.what();
226 }
227 };
228}
229
230inline std::function<void(const felix::packetformat::shortchunk& shortchunk)>
232 std::shared_ptr<std::function<void(fdreadoutlibs::types::VariableSizePayloadTypeAdapter&&)>>& cb,
233 std::chrono::milliseconds timeout = std::chrono::milliseconds(100))
234{
235 return [&](const felix::packetformat::shortchunk& shortchunk) {
236 auto shortchunk_length = shortchunk.length;
237 char* payload = static_cast<char*>(malloc(shortchunk_length * sizeof(char)));
238 std::memcpy(payload, shortchunk.data, shortchunk_length);
239 fdreadoutlibs::types::VariableSizePayloadTypeAdapter payload_wrapper(shortchunk_length, payload);
240 try {
241 (*cb)(std::move(payload_wrapper));
242 } catch (const std::exception& e) {
243 TLOG() << "Caught " << e.what();
244 }
245 };
246}
247
248inline std::function<void(const felix::packetformat::chunk& chunk)>
249errorChunkIntoSink(std::shared_ptr<std::function<void(felix::packetformat::chunk&&)>>& cb,
250 std::chrono::milliseconds timeout = std::chrono::milliseconds(100))
251{
252 return [&](const felix::packetformat::chunk& chunk) {
253 try {
254 auto payload = chunk;
255 (*cb)(std::move(payload));
256 } catch (const std::exception& e) {
257 TLOG() << "Caught " << e.what();
258 }
259 };
260}
261
263
264} // namespace parsers
265} // namespace flxlibs
266} // namespace dunedaq
267
268#endif // FLXLIBS_INCLUDE_FLXLIBS_AVAILABLEPARSEROPERATIONS_HPP_
#define ERS_HERE
#define TLOG(...)
Definition macro.hpp:21
std::function< void(const felix::packetformat::chunk &chunk)> varsizedChunkIntoWrapper(std::shared_ptr< std::function< void(fdreadoutlibs::types::VariableSizePayloadTypeAdapter &&)> > &cb, std::chrono::milliseconds timeout=std::chrono::milliseconds(100))
std::function< void(const felix::packetformat::chunk &chunk)> errorChunkIntoSink(std::shared_ptr< std::function< void(felix::packetformat::chunk &&)> > &cb, std::chrono::milliseconds timeout=std::chrono::milliseconds(100))
void print_bytes(std::ostream &ostr, const char *title, const unsigned char *data, std::size_t length, bool format=true)
std::function< void(const felix::packetformat::chunk &chunk)> fixsizedChunkInto(std::shared_ptr< std::function< void(TargetStruct &&)> > &cb, std::chrono::milliseconds timeout=std::chrono::milliseconds(100))
void dump_to_buffer(const char *data, std::size_t size, void *buffer, uint32_t buffer_pos, const std::size_t &buffer_size)
std::function< void(const felix::packetformat::shortchunk &shortchunk)> varsizedShortchunkIntoWrapper(std::shared_ptr< std::function< void(fdreadoutlibs::types::VariableSizePayloadTypeAdapter &&)> > &cb, std::chrono::milliseconds timeout=std::chrono::milliseconds(100))
std::function< void(const felix::packetformat::shortchunk &shortchunk)> fixsizedShortchunkInto(std::shared_ptr< std::function< void(TargetStruct &&)> > &cb, std::chrono::milliseconds timeout=std::chrono::milliseconds(100))
std::function< void(const felix::packetformat::chunk &chunk)> fixsizedChunkViaHeap(std::shared_ptr< std::function< void(TargetStruct &&)> > &cb, std::chrono::milliseconds timeout=std::chrono::milliseconds(100))
std::function< void(const felix::packetformat::shortchunk &)> varsizedShortchunkIntoWithDatafield(std::shared_ptr< std::function< void(TargetWithDatafield &&)> > &cb, std::chrono::milliseconds timeout=std::chrono::milliseconds(100))
std::function< void(const felix::packetformat::chunk &)> varsizedChunkIntoWithDatafield(std::shared_ptr< std::function< void(TargetWithDatafield &&)> > &cb, std::chrono::milliseconds timeout=std::chrono::milliseconds(100))
The DUNE-DAQ namespace.
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk int ParserOps couldn t push to queue !Failed chunk
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk size
FELIX Initialization std::string initerror FELIX queue timed std::string queuename UnexpectedChunk
void error(const Issue &issue)
Definition ers.hpp:101
Convencience wrapper to take ownership over char pointers with corresponding allocated memory size.