pyxcp 0.25.5__cp312-cp312-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyxcp/__init__.py +20 -0
- pyxcp/aml/EtasCANMonitoring.a2l +82 -0
- pyxcp/aml/EtasCANMonitoring.aml +67 -0
- pyxcp/aml/XCP_Common.aml +408 -0
- pyxcp/aml/XCPonCAN.aml +78 -0
- pyxcp/aml/XCPonEth.aml +33 -0
- pyxcp/aml/XCPonFlx.aml +113 -0
- pyxcp/aml/XCPonSxI.aml +66 -0
- pyxcp/aml/XCPonUSB.aml +106 -0
- pyxcp/aml/ifdata_CAN.a2l +20 -0
- pyxcp/aml/ifdata_Eth.a2l +11 -0
- pyxcp/aml/ifdata_Flx.a2l +94 -0
- pyxcp/aml/ifdata_SxI.a2l +13 -0
- pyxcp/aml/ifdata_USB.a2l +81 -0
- pyxcp/asam/__init__.py +0 -0
- pyxcp/asam/types.py +131 -0
- pyxcp/asamkeydll +0 -0
- pyxcp/asamkeydll.c +116 -0
- pyxcp/asamkeydll.sh +2 -0
- pyxcp/checksum.py +732 -0
- pyxcp/cmdline.py +71 -0
- pyxcp/config/__init__.py +1257 -0
- pyxcp/config/legacy.py +120 -0
- pyxcp/constants.py +47 -0
- pyxcp/cpp_ext/__init__.py +0 -0
- pyxcp/cpp_ext/aligned_buffer.hpp +168 -0
- pyxcp/cpp_ext/bin.hpp +105 -0
- pyxcp/cpp_ext/blockmem.hpp +58 -0
- pyxcp/cpp_ext/cpp_ext.cpython-310-darwin.so +0 -0
- pyxcp/cpp_ext/cpp_ext.cpython-311-darwin.so +0 -0
- pyxcp/cpp_ext/cpp_ext.cpython-312-darwin.so +0 -0
- pyxcp/cpp_ext/daqlist.hpp +374 -0
- pyxcp/cpp_ext/event.hpp +67 -0
- pyxcp/cpp_ext/extension_wrapper.cpp +208 -0
- pyxcp/cpp_ext/framing.hpp +360 -0
- pyxcp/cpp_ext/helper.hpp +280 -0
- pyxcp/cpp_ext/mcobject.hpp +248 -0
- pyxcp/cpp_ext/sxi_framing.hpp +332 -0
- pyxcp/cpp_ext/tsqueue.hpp +46 -0
- pyxcp/daq_stim/__init__.py +291 -0
- pyxcp/daq_stim/optimize/__init__.py +67 -0
- pyxcp/daq_stim/optimize/binpacking.py +41 -0
- pyxcp/daq_stim/scheduler.cpp +62 -0
- pyxcp/daq_stim/scheduler.hpp +75 -0
- pyxcp/daq_stim/stim.cpp +13 -0
- pyxcp/daq_stim/stim.cpython-310-darwin.so +0 -0
- pyxcp/daq_stim/stim.cpython-311-darwin.so +0 -0
- pyxcp/daq_stim/stim.cpython-312-darwin.so +0 -0
- pyxcp/daq_stim/stim.hpp +604 -0
- pyxcp/daq_stim/stim_wrapper.cpp +50 -0
- pyxcp/dllif.py +100 -0
- pyxcp/errormatrix.py +878 -0
- pyxcp/examples/conf_can.toml +19 -0
- pyxcp/examples/conf_can_user.toml +16 -0
- pyxcp/examples/conf_can_vector.json +11 -0
- pyxcp/examples/conf_can_vector.toml +11 -0
- pyxcp/examples/conf_eth.toml +9 -0
- pyxcp/examples/conf_nixnet.json +20 -0
- pyxcp/examples/conf_socket_can.toml +12 -0
- pyxcp/examples/run_daq.py +165 -0
- pyxcp/examples/xcp_policy.py +60 -0
- pyxcp/examples/xcp_read_benchmark.py +38 -0
- pyxcp/examples/xcp_skel.py +48 -0
- pyxcp/examples/xcp_unlock.py +36 -0
- pyxcp/examples/xcp_user_supplied_driver.py +43 -0
- pyxcp/examples/xcphello.py +65 -0
- pyxcp/examples/xcphello_recorder.py +107 -0
- pyxcp/master/__init__.py +10 -0
- pyxcp/master/errorhandler.py +677 -0
- pyxcp/master/master.py +2641 -0
- pyxcp/py.typed +0 -0
- pyxcp/recorder/.idea/.gitignore +8 -0
- pyxcp/recorder/.idea/misc.xml +4 -0
- pyxcp/recorder/.idea/modules.xml +8 -0
- pyxcp/recorder/.idea/recorder.iml +6 -0
- pyxcp/recorder/.idea/sonarlint/issuestore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +7 -0
- pyxcp/recorder/.idea/sonarlint/issuestore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
- pyxcp/recorder/.idea/sonarlint/issuestore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
- pyxcp/recorder/.idea/sonarlint/issuestore/index.pb +7 -0
- pyxcp/recorder/.idea/sonarlint/securityhotspotstore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +0 -0
- pyxcp/recorder/.idea/sonarlint/securityhotspotstore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
- pyxcp/recorder/.idea/sonarlint/securityhotspotstore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
- pyxcp/recorder/.idea/sonarlint/securityhotspotstore/index.pb +7 -0
- pyxcp/recorder/.idea/vcs.xml +10 -0
- pyxcp/recorder/__init__.py +96 -0
- pyxcp/recorder/build_clang.cmd +1 -0
- pyxcp/recorder/build_clang.sh +2 -0
- pyxcp/recorder/build_gcc.cmd +1 -0
- pyxcp/recorder/build_gcc.sh +2 -0
- pyxcp/recorder/build_gcc_arm.sh +2 -0
- pyxcp/recorder/converter/__init__.py +444 -0
- pyxcp/recorder/lz4.c +2829 -0
- pyxcp/recorder/lz4.h +879 -0
- pyxcp/recorder/lz4hc.c +2041 -0
- pyxcp/recorder/lz4hc.h +413 -0
- pyxcp/recorder/mio.hpp +1714 -0
- pyxcp/recorder/reader.hpp +138 -0
- pyxcp/recorder/reco.py +278 -0
- pyxcp/recorder/recorder.rst +0 -0
- pyxcp/recorder/rekorder.cpp +59 -0
- pyxcp/recorder/rekorder.cpython-310-darwin.so +0 -0
- pyxcp/recorder/rekorder.cpython-311-darwin.so +0 -0
- pyxcp/recorder/rekorder.cpython-312-darwin.so +0 -0
- pyxcp/recorder/rekorder.hpp +274 -0
- pyxcp/recorder/setup.py +41 -0
- pyxcp/recorder/test_reko.py +34 -0
- pyxcp/recorder/unfolder.hpp +1354 -0
- pyxcp/recorder/wrap.cpp +184 -0
- pyxcp/recorder/writer.hpp +302 -0
- pyxcp/scripts/__init__.py +0 -0
- pyxcp/scripts/pyxcp_probe_can_drivers.py +20 -0
- pyxcp/scripts/xcp_examples.py +64 -0
- pyxcp/scripts/xcp_fetch_a2l.py +40 -0
- pyxcp/scripts/xcp_id_scanner.py +18 -0
- pyxcp/scripts/xcp_info.py +159 -0
- pyxcp/scripts/xcp_profile.py +26 -0
- pyxcp/scripts/xmraw_converter.py +31 -0
- pyxcp/stim/__init__.py +0 -0
- pyxcp/tests/test_asam_types.py +24 -0
- pyxcp/tests/test_binpacking.py +186 -0
- pyxcp/tests/test_can.py +1324 -0
- pyxcp/tests/test_checksum.py +95 -0
- pyxcp/tests/test_daq.py +193 -0
- pyxcp/tests/test_daq_opt.py +426 -0
- pyxcp/tests/test_frame_padding.py +156 -0
- pyxcp/tests/test_framing.py +262 -0
- pyxcp/tests/test_master.py +2116 -0
- pyxcp/tests/test_transport.py +177 -0
- pyxcp/tests/test_utils.py +30 -0
- pyxcp/timing.py +60 -0
- pyxcp/transport/__init__.py +13 -0
- pyxcp/transport/base.py +484 -0
- pyxcp/transport/base_transport.hpp +0 -0
- pyxcp/transport/can.py +660 -0
- pyxcp/transport/eth.py +254 -0
- pyxcp/transport/hdf5_policy.py +167 -0
- pyxcp/transport/sxi.py +209 -0
- pyxcp/transport/transport_ext.cpython-310-darwin.so +0 -0
- pyxcp/transport/transport_ext.cpython-311-darwin.so +0 -0
- pyxcp/transport/transport_ext.cpython-312-darwin.so +0 -0
- pyxcp/transport/transport_ext.hpp +214 -0
- pyxcp/transport/transport_wrapper.cpp +249 -0
- pyxcp/transport/usb_transport.py +229 -0
- pyxcp/types.py +987 -0
- pyxcp/utils/__init__.py +127 -0
- pyxcp/utils/cli.py +78 -0
- pyxcp/vector/__init__.py +0 -0
- pyxcp/vector/map.py +82 -0
- pyxcp-0.25.5.dist-info/METADATA +341 -0
- pyxcp-0.25.5.dist-info/RECORD +153 -0
- pyxcp-0.25.5.dist-info/WHEEL +6 -0
- pyxcp-0.25.5.dist-info/entry_points.txt +9 -0
- pyxcp-0.25.5.dist-info/licenses/LICENSE +165 -0
|
@@ -0,0 +1,1354 @@
|
|
|
1
|
+
|
|
2
|
+
#ifndef RECORDER_UNFOLDER_HPP
|
|
3
|
+
#define RECORDER_UNFOLDER_HPP
|
|
4
|
+
|
|
5
|
+
#include <any>
|
|
6
|
+
#include <bit>
|
|
7
|
+
#include <charconv>
|
|
8
|
+
#include <cstring>
|
|
9
|
+
#include <iostream>
|
|
10
|
+
#include <limits>
|
|
11
|
+
#include <map>
|
|
12
|
+
#if __has_include(<stdfloat>)
|
|
13
|
+
#include <stdfloat>
|
|
14
|
+
#endif
|
|
15
|
+
#include <variant>
|
|
16
|
+
#include <memory>
|
|
17
|
+
|
|
18
|
+
#include "daqlist.hpp"
|
|
19
|
+
#include "helper.hpp"
|
|
20
|
+
#include "mcobject.hpp"
|
|
21
|
+
#include "writer.hpp"
|
|
22
|
+
|
|
23
|
+
using measurement_value_t = std::variant<std::int64_t, std::uint64_t, long double, std::string>;
|
|
24
|
+
using measurement_tuple_t = std::tuple<std::uint16_t, std::uint64_t, std::uint64_t, std::vector<measurement_value_t>>;
|
|
25
|
+
using measurement_callback_t = std::function<void(std::uint16_t, std::uint64_t, std::uint64_t, std::vector<measurement_value_t>)>;
|
|
26
|
+
|
|
27
|
+
template<typename Ty>
|
|
28
|
+
auto get_value(blob_t const * buf, std::uint64_t offset) -> Ty {
|
|
29
|
+
return *reinterpret_cast<Ty const *>(&buf[offset]);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
template<typename Ty>
|
|
33
|
+
auto get_value_swapped(blob_t const * buf, std::uint64_t offset) -> Ty {
|
|
34
|
+
return _bswap(get_value<Ty>(buf, offset));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
#if HAS_FLOAT16 == 1
|
|
38
|
+
template<>
|
|
39
|
+
auto get_value<std::float16_t>(blob_t const * buf, std::uint64_t offset) -> std::float16_t {
|
|
40
|
+
auto tmp = get_value<std::uint16_t>(buf, offset);
|
|
41
|
+
|
|
42
|
+
return std::bit_cast<std::float16_t>(tmp);
|
|
43
|
+
}
|
|
44
|
+
#endif
|
|
45
|
+
|
|
46
|
+
#if HAS_BFLOAT16 == 1
|
|
47
|
+
template<>
|
|
48
|
+
auto get_value<std::bfloat16_t>(blob_t const * buf, std::uint64_t offset) -> std::bfloat16_t {
|
|
49
|
+
auto tmp = get_value<std::uint16_t>(buf, offset);
|
|
50
|
+
|
|
51
|
+
return std::bit_cast<std::bfloat16_t>(tmp);
|
|
52
|
+
}
|
|
53
|
+
#endif
|
|
54
|
+
|
|
55
|
+
template<>
|
|
56
|
+
auto get_value<float>(blob_t const * buf, std::uint64_t offset) -> float {
|
|
57
|
+
auto tmp = get_value<std::uint32_t>(buf, offset);
|
|
58
|
+
|
|
59
|
+
return std::bit_cast<float>(tmp);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
template<>
|
|
63
|
+
auto get_value<double>(blob_t const * buf, std::uint64_t offset) -> double {
|
|
64
|
+
auto tmp = get_value<std::uint64_t>(buf, offset);
|
|
65
|
+
|
|
66
|
+
return std::bit_cast<double>(tmp);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
#if HAS_FLOAT16 == 1
|
|
70
|
+
template<>
|
|
71
|
+
auto get_value_swapped<std::float16_t>(blob_t const * buf, std::uint64_t offset) -> std::float16_t {
|
|
72
|
+
auto tmp = get_value_swapped<std::uint16_t>(buf, offset);
|
|
73
|
+
|
|
74
|
+
return std::bit_cast<std::float16_t>(tmp);
|
|
75
|
+
}
|
|
76
|
+
#endif
|
|
77
|
+
|
|
78
|
+
#if HAS_BFLOAT16 == 1
|
|
79
|
+
template<>
|
|
80
|
+
auto get_value_swapped<std::bfloat16_t>(blob_t const * buf, std::uint64_t offset) -> std::bfloat16_t {
|
|
81
|
+
auto tmp = get_value_swapped<std::uint16_t>(buf, offset);
|
|
82
|
+
|
|
83
|
+
return std::bit_cast<std::bfloat16_t>(tmp);
|
|
84
|
+
}
|
|
85
|
+
#endif
|
|
86
|
+
|
|
87
|
+
template<>
|
|
88
|
+
auto get_value_swapped<float>(blob_t const * buf, std::uint64_t offset) -> float {
|
|
89
|
+
auto tmp = get_value_swapped<std::uint32_t>(buf, offset);
|
|
90
|
+
|
|
91
|
+
return std::bit_cast<float>(tmp);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
template<>
|
|
95
|
+
auto get_value_swapped<double>(blob_t const * buf, std::uint64_t offset) -> double {
|
|
96
|
+
auto tmp = get_value_swapped<std::uint64_t>(buf, offset);
|
|
97
|
+
|
|
98
|
+
return std::bit_cast<double>(tmp);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
template<>
|
|
102
|
+
auto get_value<std::int16_t>(blob_t const * buf, std::uint64_t offset) -> std::int16_t {
|
|
103
|
+
return static_cast<std::int16_t>(get_value<uint16_t>(buf, offset));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
template<>
|
|
107
|
+
auto get_value_swapped<std::int16_t>(blob_t const * buf, std::uint64_t offset) -> std::int16_t {
|
|
108
|
+
return static_cast<std::int16_t>(get_value_swapped<uint16_t>(buf, offset));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
template<>
|
|
112
|
+
auto get_value<std::int32_t>(blob_t const * buf, std::uint64_t offset) -> std::int32_t {
|
|
113
|
+
return static_cast<std::int32_t>(get_value<uint32_t>(buf, offset));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
template<>
|
|
117
|
+
auto get_value_swapped<std::int32_t>(blob_t const * buf, std::uint64_t offset) -> std::int32_t {
|
|
118
|
+
return static_cast<std::int32_t>(get_value_swapped<uint32_t>(buf, offset));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
template<>
|
|
122
|
+
auto get_value<std::int64_t>(blob_t const * buf, std::uint64_t offset) -> std::int64_t {
|
|
123
|
+
return static_cast<std::int64_t>(get_value<uint64_t>(buf, offset));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
template<>
|
|
127
|
+
auto get_value_swapped<std::int64_t>(blob_t const * buf, std::uint64_t offset) -> std::int64_t {
|
|
128
|
+
return static_cast<std::int64_t>(get_value_swapped<uint64_t>(buf, offset));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/////////////////////////////////////////////////////
|
|
132
|
+
/////////////////////////////////////////////////////
|
|
133
|
+
template<typename Ty>
|
|
134
|
+
void set_value(blob_t* buf, std::uint64_t offset, Ty value) {
|
|
135
|
+
::memcpy(&buf[offset], &value, sizeof(Ty));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
template<typename Ty>
|
|
139
|
+
void set_value_swapped(blob_t* buf, std::uint64_t offset, Ty value) {
|
|
140
|
+
set_value<Ty>(buf, offset, _bswap(value));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
template<>
|
|
144
|
+
void set_value<std::int8_t>(blob_t* buf, std::uint64_t offset, std::int8_t value) {
|
|
145
|
+
buf[offset] = static_cast<blob_t>(value);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
template<>
|
|
149
|
+
void set_value<std::uint8_t>(blob_t* buf, std::uint64_t offset, std::uint8_t value) {
|
|
150
|
+
buf[offset] = static_cast<blob_t>(value);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
template<>
|
|
154
|
+
void set_value<std::int16_t>(blob_t* buf, std::uint64_t offset, std::int16_t value) {
|
|
155
|
+
set_value<std::uint16_t>(buf, offset, static_cast<std::uint16_t>(value));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
template<>
|
|
159
|
+
void set_value_swapped<std::int16_t>(blob_t* buf, std::uint64_t offset, std::int16_t value) {
|
|
160
|
+
set_value_swapped<std::uint16_t>(buf, offset, static_cast<std::uint16_t>(value));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
template<>
|
|
164
|
+
void set_value<std::int32_t>(blob_t* buf, std::uint64_t offset, std::int32_t value) {
|
|
165
|
+
set_value<std::uint32_t>(buf, offset, static_cast<std::uint32_t>(value));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
template<>
|
|
169
|
+
void set_value_swapped<std::int32_t>(blob_t* buf, std::uint64_t offset, std::int32_t value) {
|
|
170
|
+
set_value_swapped<std::uint32_t>(buf, offset, static_cast<std::uint32_t>(value));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
template<>
|
|
174
|
+
void set_value<std::int64_t>(blob_t* buf, std::uint64_t offset, std::int64_t value) {
|
|
175
|
+
set_value<std::uint64_t>(buf, offset, static_cast<std::uint64_t>(value));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
template<>
|
|
179
|
+
void set_value_swapped<std::int64_t>(blob_t* buf, std::uint64_t offset, std::int64_t value) {
|
|
180
|
+
set_value_swapped<std::uint64_t>(buf, offset, static_cast<std::uint64_t>(value));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
#if HAS_FLOAT16 == 1
|
|
184
|
+
template<>
|
|
185
|
+
void set_value<std::float16_t>(blob_t* buf, std::uint64_t offset, std::float16_t value) {
|
|
186
|
+
// set_value<std::uint16_t>(buf, offset, *reinterpret_cast<std::uint16_t*>(&value));
|
|
187
|
+
set_value<std::uint16_t>(buf, offset, std::bit_cast<std::uint16_t>(value));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
template<>
|
|
191
|
+
void set_value_swapped<std::float16_t>(blob_t* buf, std::uint64_t offset, std::float16_t value) {
|
|
192
|
+
// set_value_swapped<std::uint16_t>(buf, offset, *reinterpret_cast<std::uint16_t*>(&value));
|
|
193
|
+
set_value_swapped<std::uint16_t>(buf, offset, std::bit_cast<std::uint16_t>(value));
|
|
194
|
+
}
|
|
195
|
+
#endif
|
|
196
|
+
|
|
197
|
+
#if HAS_BFLOAT16 == 1
|
|
198
|
+
template<>
|
|
199
|
+
void set_value<std::bfloat16_t>(blob_t* buf, std::uint64_t offset, std::bfloat16_t value) {
|
|
200
|
+
// set_value<std::uint16_t>(buf, offset, *reinterpret_cast<std::uint16_t*>(&value));
|
|
201
|
+
set_value<std::uint16_t>(buf, offset, std::bit_cast<std::uint16_t>(value));
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
template<>
|
|
205
|
+
void set_value_swapped<std::bfloat16_t>(blob_t* buf, std::uint64_t offset, std::bfloat16_t value) {
|
|
206
|
+
// set_value_swapped<std::uint16_t>(buf, offset, *reinterpret_cast<std::uint16_t*>(&value));
|
|
207
|
+
set_value_swapped<std::uint16_t>(buf, offset, std::bit_cast<std::uint16_t>(value));
|
|
208
|
+
}
|
|
209
|
+
#endif
|
|
210
|
+
|
|
211
|
+
template<>
|
|
212
|
+
void set_value<float>(blob_t* buf, std::uint64_t offset, float value) {
|
|
213
|
+
// set_value<std::uint32_t>(buf, offset, *reinterpret_cast<std::uint32_t*>(&value));
|
|
214
|
+
set_value<std::uint32_t>(buf, offset, std::bit_cast<std::uint32_t>(value));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
template<>
|
|
218
|
+
void set_value_swapped<float>(blob_t* buf, std::uint64_t offset, float value) {
|
|
219
|
+
// set_value_swapped<std::uint32_t>(buf, offset, *reinterpret_cast<std::uint32_t*>(&value));
|
|
220
|
+
set_value_swapped<std::uint32_t>(buf, offset, std::bit_cast<std::uint32_t>(value));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
template<>
|
|
224
|
+
void set_value<double>(blob_t* buf, std::uint64_t offset, double value) {
|
|
225
|
+
// set_value<std::uint64_t>(buf, offset, *reinterpret_cast<std::uint64_t*>(&value));
|
|
226
|
+
set_value<std::uint64_t>(buf, offset, std::bit_cast<std::uint64_t>(value));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
template<>
|
|
230
|
+
void set_value_swapped<double>(blob_t* buf, std::uint64_t offset, double value) {
|
|
231
|
+
// set_value_swapped<std::uint64_t>(buf, offset, *reinterpret_cast<std::uint64_t*>(&value));
|
|
232
|
+
set_value_swapped<std::uint64_t>(buf, offset, std::bit_cast<std::uint64_t>(value));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/*
|
|
236
|
+
** Get primitive datatypes, consider byte-order.
|
|
237
|
+
*/
|
|
238
|
+
struct Getter {
|
|
239
|
+
Getter() = default;
|
|
240
|
+
|
|
241
|
+
explicit Getter(bool requires_swap, std::uint8_t id_size, std::uint8_t ts_size) : m_id_size(id_size), m_ts_size(ts_size) {
|
|
242
|
+
int8 = get_value<std::int8_t>;
|
|
243
|
+
uint8 = get_value<std::uint8_t>;
|
|
244
|
+
|
|
245
|
+
if (requires_swap) {
|
|
246
|
+
int16 = get_value_swapped<std::int16_t>;
|
|
247
|
+
int32 = get_value_swapped<std::int32_t>;
|
|
248
|
+
int64 = get_value_swapped<std::int64_t>;
|
|
249
|
+
uint16 = get_value_swapped<std::uint16_t>;
|
|
250
|
+
uint32 = get_value_swapped<std::uint32_t>;
|
|
251
|
+
uint64 = get_value_swapped<std::uint64_t>;
|
|
252
|
+
float_ = get_value_swapped<float>;
|
|
253
|
+
double_ = get_value_swapped<double>;
|
|
254
|
+
#if HAS_FLOAT16 == 1
|
|
255
|
+
float16 = get_value_swapped<std::float16_t>;
|
|
256
|
+
#endif
|
|
257
|
+
#if HAS_BFLOAT16 == 1
|
|
258
|
+
bfloat16 = get_value_swapped<std::bfloat16_t>;
|
|
259
|
+
#endif
|
|
260
|
+
} else {
|
|
261
|
+
int16 = get_value<std::int16_t>;
|
|
262
|
+
int32 = get_value<std::int32_t>;
|
|
263
|
+
int64 = get_value<std::int64_t>;
|
|
264
|
+
uint16 = get_value<std::uint16_t>;
|
|
265
|
+
uint32 = get_value<std::uint32_t>;
|
|
266
|
+
uint64 = get_value<std::uint64_t>;
|
|
267
|
+
float_ = get_value<float>;
|
|
268
|
+
double_ = get_value<double>;
|
|
269
|
+
#if HAS_FLOAT16 == 1
|
|
270
|
+
float16 = get_value<std::float16_t>;
|
|
271
|
+
#endif
|
|
272
|
+
#if HAS_BFLOAT16 == 1
|
|
273
|
+
bfloat16 = get_value<std::bfloat16_t>;
|
|
274
|
+
#endif
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
std::uint32_t get_timestamp(blob_t const * buf) {
|
|
279
|
+
switch (m_ts_size) {
|
|
280
|
+
case 0:
|
|
281
|
+
return 0;
|
|
282
|
+
case 1:
|
|
283
|
+
return uint8(buf, m_id_size);
|
|
284
|
+
case 2:
|
|
285
|
+
return uint16(buf, m_id_size);
|
|
286
|
+
case 4:
|
|
287
|
+
return uint32(buf, m_id_size);
|
|
288
|
+
default:
|
|
289
|
+
throw std::runtime_error("Unsupported timestamp size: " + std::to_string(m_ts_size));
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
measurement_value_t reader(std::uint16_t tp, blob_t const * buf, std::uint16_t offset) const {
|
|
294
|
+
switch (tp) {
|
|
295
|
+
case 0:
|
|
296
|
+
return static_cast<std::uint64_t >(uint8(buf, offset));
|
|
297
|
+
case 1:
|
|
298
|
+
return int8(buf, offset);
|
|
299
|
+
case 2:
|
|
300
|
+
return static_cast<std::uint64_t >(uint16(buf, offset));
|
|
301
|
+
case 3:
|
|
302
|
+
return int16(buf, offset);
|
|
303
|
+
case 4:
|
|
304
|
+
return static_cast<std::uint64_t >(uint32(buf, offset));
|
|
305
|
+
case 5:
|
|
306
|
+
return int32(buf, offset);
|
|
307
|
+
case 6:
|
|
308
|
+
return uint64(buf, offset);
|
|
309
|
+
case 7:
|
|
310
|
+
return int64(buf, offset);
|
|
311
|
+
case 8:
|
|
312
|
+
return float_(buf, offset);
|
|
313
|
+
case 9:
|
|
314
|
+
return double_(buf, offset);
|
|
315
|
+
#if HAS_FLOAT16 == 1
|
|
316
|
+
case 10:
|
|
317
|
+
return float16(buf, offset);
|
|
318
|
+
#endif
|
|
319
|
+
#if HAS_BFLOAT16 == 1
|
|
320
|
+
case 11:
|
|
321
|
+
return bfloat16(buf, offset);
|
|
322
|
+
#endif
|
|
323
|
+
default:
|
|
324
|
+
throw std::runtime_error("Unsupported data type: " + std::to_string(tp));
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
void set_first_pids(const std::vector<std::shared_ptr<DaqListBase>>& daq_lists, const std::vector<std::uint16_t>& first_pids) {
|
|
329
|
+
m_first_pids = first_pids;
|
|
330
|
+
|
|
331
|
+
if (m_id_size == 1) {
|
|
332
|
+
// In case of 1-byte ID field (absolute ODT number) we need a mapping.
|
|
333
|
+
std::uint16_t daq_list_num = 0;
|
|
334
|
+
for (const auto& daq_list : daq_lists) {
|
|
335
|
+
auto first_pid = m_first_pids[daq_list_num];
|
|
336
|
+
|
|
337
|
+
for (std::uint16_t idx = first_pid; idx < daq_list->get_odt_count() + first_pid; ++idx) {
|
|
338
|
+
m_odt_to_daq_map[idx] = { daq_list_num, (idx - first_pid) };
|
|
339
|
+
}
|
|
340
|
+
daq_list_num++;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
std::tuple<std::uint16_t, std::uint16_t> get_id(blob_t const * buf) {
|
|
346
|
+
std::uint16_t odt_num = 0;
|
|
347
|
+
|
|
348
|
+
switch (m_id_size) {
|
|
349
|
+
case 1:
|
|
350
|
+
odt_num = uint8(buf, 0); // Get 1-byte ODT number...
|
|
351
|
+
return m_odt_to_daq_map[odt_num]; // ...and return mapped values.
|
|
352
|
+
case 2:
|
|
353
|
+
return { uint8(buf, 1), uint8(buf, 0) };
|
|
354
|
+
case 3:
|
|
355
|
+
return { uint16(buf, 1), uint8(buf, 0) };
|
|
356
|
+
case 4:
|
|
357
|
+
return { uint16(buf, 2), uint8(buf, 0) };
|
|
358
|
+
default:
|
|
359
|
+
throw std::runtime_error("Unsupported ID size: " + std::to_string(m_id_size));
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
std::uint8_t m_id_size;
|
|
364
|
+
std::uint8_t m_ts_size;
|
|
365
|
+
std::function<std::int8_t(blob_t const * buf, std::uint64_t offset)> int8;
|
|
366
|
+
std::function<std::uint8_t(blob_t const * buf, std::uint64_t offset)> uint8;
|
|
367
|
+
std::function<std::int16_t(blob_t const * buf, std::uint64_t offset)> int16;
|
|
368
|
+
std::function<std::int32_t(blob_t const * buf, std::uint64_t offset)> int32;
|
|
369
|
+
std::function<std::int64_t(blob_t const * buf, std::uint64_t offset)> int64;
|
|
370
|
+
std::function<std::uint16_t(blob_t const * buf, std::uint64_t offset)> uint16;
|
|
371
|
+
std::function<std::uint32_t(blob_t const * buf, std::uint64_t offset)> uint32;
|
|
372
|
+
std::function<std::uint64_t(blob_t const * buf, std::uint64_t offset)> uint64;
|
|
373
|
+
std::function<float(blob_t const * buf, std::uint64_t offset)> float_;
|
|
374
|
+
std::function<double(blob_t const * buf, std::uint64_t offset)> double_;
|
|
375
|
+
#if HAS_FLOAT16 == 1
|
|
376
|
+
std::function<std::float16_t(blob_t const * buf, std::uint64_t offset)> float16;
|
|
377
|
+
#endif
|
|
378
|
+
#if HAS_BFLOAT16 == 1
|
|
379
|
+
std::function<std::bfloat16_t(blob_t const * buf, std::uint64_t offset)> bfloat16;
|
|
380
|
+
#endif
|
|
381
|
+
std::vector<std::uint16_t> m_first_pids;
|
|
382
|
+
std::map<std::uint16_t, std::tuple<std::uint16_t, std::uint16_t>> m_odt_to_daq_map;
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
386
|
+
struct Setter {
|
|
387
|
+
Setter() = default;
|
|
388
|
+
|
|
389
|
+
explicit Setter(bool requires_swap, std::uint8_t id_size, std::uint8_t ts_size) : m_id_size(id_size), m_ts_size(ts_size) {
|
|
390
|
+
int8 = set_value<std::int8_t>;
|
|
391
|
+
uint8 = set_value<std::uint8_t>;
|
|
392
|
+
|
|
393
|
+
if (requires_swap) {
|
|
394
|
+
int16 = set_value_swapped<std::int16_t>;
|
|
395
|
+
int32 = set_value_swapped<std::int32_t>;
|
|
396
|
+
int64 = set_value_swapped<std::int64_t>;
|
|
397
|
+
uint16 = set_value_swapped<std::uint16_t>;
|
|
398
|
+
uint32 = set_value_swapped<std::uint32_t>;
|
|
399
|
+
uint64 = set_value_swapped<std::uint64_t>;
|
|
400
|
+
float_ = set_value_swapped<float>;
|
|
401
|
+
double_ = set_value_swapped<double>;
|
|
402
|
+
#if HAS_FLOAT16 == 1
|
|
403
|
+
float16 = set_value_swapped<std::float16_t>;
|
|
404
|
+
#endif
|
|
405
|
+
#if HAS_BFLOAT16 == 1
|
|
406
|
+
bfloat16 = set_value_swapped<std::bfloat16_t>;
|
|
407
|
+
#endif
|
|
408
|
+
} else {
|
|
409
|
+
int16 = set_value<std::int16_t>;
|
|
410
|
+
int32 = set_value<std::int32_t>;
|
|
411
|
+
int64 = set_value<std::int64_t>;
|
|
412
|
+
uint16 = set_value<std::uint16_t>;
|
|
413
|
+
uint32 = set_value<std::uint32_t>;
|
|
414
|
+
uint64 = set_value<std::uint64_t>;
|
|
415
|
+
float_ = set_value<float>;
|
|
416
|
+
double_ = set_value<double>;
|
|
417
|
+
#if HAS_FLOAT16 == 1
|
|
418
|
+
float16 = set_value<std::float16_t>;
|
|
419
|
+
#endif
|
|
420
|
+
#if HAS_BFLOAT16 == 1
|
|
421
|
+
bfloat16 = set_value<std::bfloat16_t>;
|
|
422
|
+
#endif
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
void set_timestamp(blob_t* buf, std::uint32_t timestamp) {
|
|
427
|
+
switch (m_ts_size) {
|
|
428
|
+
case 0:
|
|
429
|
+
break;
|
|
430
|
+
case 1:
|
|
431
|
+
uint8(buf, m_id_size, timestamp);
|
|
432
|
+
break;
|
|
433
|
+
case 2:
|
|
434
|
+
uint16(buf, m_id_size, timestamp);
|
|
435
|
+
break;
|
|
436
|
+
case 4:
|
|
437
|
+
uint32(buf, m_id_size, timestamp);
|
|
438
|
+
break;
|
|
439
|
+
default:
|
|
440
|
+
throw std::runtime_error("Unsupported timestamp size: " + std::to_string(m_ts_size));
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
void writer(std::uint16_t tp, blob_t* buf, std::uint16_t offset, const measurement_value_t& value) {
|
|
445
|
+
switch (tp) {
|
|
446
|
+
case 0:
|
|
447
|
+
uint8(buf, offset, static_cast<std::uint8_t>(std::get<std::uint64_t>(value)));
|
|
448
|
+
break;
|
|
449
|
+
case 1:
|
|
450
|
+
int8(buf, offset, static_cast<std::int8_t>(std::get<std::int64_t>(value)));
|
|
451
|
+
break;
|
|
452
|
+
case 2:
|
|
453
|
+
uint16(buf, offset, static_cast<std::uint16_t>(std::get<std::uint64_t>(value)));
|
|
454
|
+
break;
|
|
455
|
+
case 3:
|
|
456
|
+
int16(buf, offset, static_cast<std::int16_t>(std::get<std::int64_t>(value)));
|
|
457
|
+
break;
|
|
458
|
+
case 4:
|
|
459
|
+
uint32(buf, offset, static_cast<std::uint32_t>(std::get<std::uint64_t>(value)));
|
|
460
|
+
break;
|
|
461
|
+
case 5:
|
|
462
|
+
int32(buf, offset, static_cast<std::int32_t>(std::get<std::int64_t>(value)));
|
|
463
|
+
break;
|
|
464
|
+
case 6:
|
|
465
|
+
uint64(buf, offset, std::get<std::uint64_t>(value));
|
|
466
|
+
break;
|
|
467
|
+
case 7:
|
|
468
|
+
int64(buf, offset, std::get<std::int64_t>(value));
|
|
469
|
+
break;
|
|
470
|
+
case 8:
|
|
471
|
+
float_(buf, offset, static_cast<float>(std::get<long double>(value)));
|
|
472
|
+
break;
|
|
473
|
+
case 9:
|
|
474
|
+
double_(buf, offset, static_cast<double>(std::get<long double>(value)));
|
|
475
|
+
break;
|
|
476
|
+
#if HAS_FLOAT16 == 1
|
|
477
|
+
case 10:
|
|
478
|
+
float16(buf, offset, static_cast<std::float16_t>(std::get<long double>(value)));
|
|
479
|
+
break;
|
|
480
|
+
#endif
|
|
481
|
+
#if HAS_BFLOAT16 == 1
|
|
482
|
+
case 11:
|
|
483
|
+
bfloat16(buf, offset, static_cast<std::bfloat16_t>(std::get<long double>(value)));
|
|
484
|
+
break;
|
|
485
|
+
#endif
|
|
486
|
+
default:
|
|
487
|
+
throw std::runtime_error("Unsupported data type: " + std::to_string(tp));
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
#if 0
|
|
492
|
+
std::tuple<std::uint16_t, std::uint16_t> set_id(blob_t const * buf) {
|
|
493
|
+
std::uint16_t odt_num = 0;
|
|
494
|
+
|
|
495
|
+
switch (m_id_size) {
|
|
496
|
+
case 1:
|
|
497
|
+
odt_num = uint8(buf, 0); // Get 1-byte ODT number...
|
|
498
|
+
return m_odt_to_daq_map[odt_num]; // ...and return mapped values.
|
|
499
|
+
case 2:
|
|
500
|
+
return { uint8(buf, 1), uint8(buf, 0) };
|
|
501
|
+
case 3:
|
|
502
|
+
return { uint16(buf, 1), uint8(buf, 0) };
|
|
503
|
+
case 4:
|
|
504
|
+
return { uint16(buf, 2), uint8(buf, 0) };
|
|
505
|
+
default:
|
|
506
|
+
throw std::runtime_error("Unsupported ID size: " + std::to_string(m_id_size));
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
#endif
|
|
510
|
+
std::uint8_t m_id_size;
|
|
511
|
+
std::uint8_t m_ts_size;
|
|
512
|
+
std::function<void(blob_t* buf, std::uint64_t offset, std::int8_t)> int8;
|
|
513
|
+
std::function<void(blob_t* buf, std::uint64_t offset, std::uint8_t)> uint8;
|
|
514
|
+
std::function<void(blob_t* buf, std::uint64_t offset, std::int16_t)> int16;
|
|
515
|
+
std::function<void(blob_t* buf, std::uint64_t offset, std::int32_t)> int32;
|
|
516
|
+
std::function<void(blob_t* buf, std::uint64_t offset, std::int64_t)> int64;
|
|
517
|
+
std::function<void(blob_t* buf, std::uint64_t offset, std::uint16_t)> uint16;
|
|
518
|
+
std::function<void(blob_t* buf, std::uint64_t offset, std::uint32_t)> uint32;
|
|
519
|
+
std::function<void(blob_t* buf, std::uint64_t offset, std::uint64_t)> uint64;
|
|
520
|
+
std::function<void(blob_t* buf, std::uint64_t offset, float)> float_;
|
|
521
|
+
std::function<void(blob_t* buf, std::uint64_t offset, double)> double_;
|
|
522
|
+
#if HAS_FLOAT16 == 1
|
|
523
|
+
std::function<void(blob_t* buf, std::uint64_t offset, std::float16_t)> float16;
|
|
524
|
+
#endif
|
|
525
|
+
#if HAS_BFLOAT16 == 1
|
|
526
|
+
std::function<void(blob_t* buf, std::uint64_t offset, std::bfloat16_t)> bfloat16;
|
|
527
|
+
#endif
|
|
528
|
+
std::map<std::uint16_t, std::tuple<std::uint16_t, std::uint16_t>> m_odt_to_daq_map;
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
532
|
+
|
|
533
|
+
struct MeasurementParameters {
|
|
534
|
+
MeasurementParameters() = default;
|
|
535
|
+
|
|
536
|
+
MeasurementParameters(MeasurementParameters&&) = default;
|
|
537
|
+
MeasurementParameters(const MeasurementParameters&) = default;
|
|
538
|
+
MeasurementParameters& operator=(MeasurementParameters&&) = default;
|
|
539
|
+
MeasurementParameters& operator=(const MeasurementParameters&) = default;
|
|
540
|
+
|
|
541
|
+
explicit MeasurementParameters(
|
|
542
|
+
std::uint8_t byte_order, std::uint8_t id_field_size, bool timestamps_supported, bool ts_fixed, bool prescaler_supported,
|
|
543
|
+
bool selectable_timestamps, double ts_scale_factor, std::uint8_t ts_size, std::uint16_t min_daq,
|
|
544
|
+
const TimestampInfo& timestamp_info, const std::vector<std::shared_ptr<DaqListBase>>& daq_lists, const std::vector<std::uint16_t>& first_pids
|
|
545
|
+
) :
|
|
546
|
+
m_byte_order(byte_order),
|
|
547
|
+
m_id_field_size(id_field_size),
|
|
548
|
+
m_timestamps_supported(timestamps_supported),
|
|
549
|
+
m_ts_fixed(ts_fixed),
|
|
550
|
+
m_prescaler_supported(prescaler_supported),
|
|
551
|
+
m_selectable_timestamps(selectable_timestamps),
|
|
552
|
+
m_ts_scale_factor(ts_scale_factor),
|
|
553
|
+
m_ts_size(ts_size),
|
|
554
|
+
m_min_daq(min_daq),
|
|
555
|
+
m_timestamp_info(timestamp_info),
|
|
556
|
+
m_daq_lists(daq_lists),
|
|
557
|
+
m_first_pids(first_pids) {
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
std::string dumps() const {
|
|
561
|
+
std::stringstream ss;
|
|
562
|
+
|
|
563
|
+
ss << to_binary(m_byte_order);
|
|
564
|
+
ss << to_binary(m_id_field_size);
|
|
565
|
+
ss << to_binary(m_timestamps_supported);
|
|
566
|
+
ss << to_binary(m_ts_fixed);
|
|
567
|
+
ss << to_binary(m_prescaler_supported);
|
|
568
|
+
ss << to_binary(m_selectable_timestamps);
|
|
569
|
+
ss << to_binary(m_ts_scale_factor);
|
|
570
|
+
ss << to_binary(m_ts_size);
|
|
571
|
+
ss << to_binary(m_min_daq);
|
|
572
|
+
std::size_t dl_count = m_daq_lists.size();
|
|
573
|
+
ss << to_binary(dl_count);
|
|
574
|
+
////
|
|
575
|
+
ss << to_binary<std::uint64_t>(m_timestamp_info.get_timestamp_ns());
|
|
576
|
+
ss << to_binary(m_timestamp_info.get_timezone());
|
|
577
|
+
ss << to_binary<std::int16_t>(m_timestamp_info.get_utc_offset());
|
|
578
|
+
ss << to_binary<std::int16_t>(m_timestamp_info.get_dst_offset());
|
|
579
|
+
////
|
|
580
|
+
|
|
581
|
+
for (const auto& daq_list : m_daq_lists) {
|
|
582
|
+
ss << daq_list->dumps();
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
std::size_t fp_count = m_first_pids.size();
|
|
586
|
+
ss << to_binary(fp_count);
|
|
587
|
+
for (const auto& fp : m_first_pids) {
|
|
588
|
+
ss << to_binary(fp);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
return to_binary(std::size(ss.str())) + ss.str();
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
auto get_byte_order() const noexcept {
|
|
595
|
+
return m_byte_order;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
auto get_id_field_size() const noexcept {
|
|
599
|
+
return m_id_field_size;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
auto get_timestamps_supported() const noexcept {
|
|
603
|
+
return m_timestamps_supported;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
auto get_ts_fixed() const noexcept {
|
|
607
|
+
return m_ts_fixed;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
auto get_prescaler_supported() const noexcept {
|
|
611
|
+
return m_prescaler_supported;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
auto get_selectable_timestamps() const noexcept {
|
|
615
|
+
return m_selectable_timestamps;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
auto get_ts_scale_factor() const noexcept {
|
|
619
|
+
return m_ts_scale_factor;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
auto get_ts_size() const noexcept {
|
|
623
|
+
return m_ts_size;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
auto get_min_daq() const noexcept {
|
|
627
|
+
return m_min_daq;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
auto get_timestamp_info() const noexcept {
|
|
631
|
+
return m_timestamp_info;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
auto get_daq_lists() const noexcept {
|
|
635
|
+
return m_daq_lists;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
auto get_first_pids() const noexcept {
|
|
639
|
+
return m_first_pids;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
#undef max // Thanks to Windows.
|
|
643
|
+
|
|
644
|
+
auto get_overflow_value() const -> std::uint64_t {
|
|
645
|
+
std::uint64_t ov_value{};
|
|
646
|
+
switch (m_ts_size) {
|
|
647
|
+
case 0:
|
|
648
|
+
return 0ULL;
|
|
649
|
+
case 1:
|
|
650
|
+
ov_value = std::numeric_limits<std::uint8_t>::max();
|
|
651
|
+
break;
|
|
652
|
+
case 2:
|
|
653
|
+
ov_value = std::numeric_limits<std::uint16_t>::max();
|
|
654
|
+
break;
|
|
655
|
+
case 4:
|
|
656
|
+
ov_value = std::numeric_limits<std::uint32_t>::max();
|
|
657
|
+
break;
|
|
658
|
+
// case 8:
|
|
659
|
+
// ov_value = std::numeric_limits<std::uint64_t>::max() + 1;
|
|
660
|
+
// break;
|
|
661
|
+
default:
|
|
662
|
+
throw std::runtime_error("Invalid timestamp size");
|
|
663
|
+
}
|
|
664
|
+
ov_value++;
|
|
665
|
+
ov_value = static_cast<std::uint64_t>(ov_value * m_ts_scale_factor);
|
|
666
|
+
return ov_value;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
std::uint8_t m_byte_order;
|
|
670
|
+
std::uint8_t m_id_field_size;
|
|
671
|
+
bool m_timestamps_supported;
|
|
672
|
+
bool m_ts_fixed;
|
|
673
|
+
bool m_prescaler_supported;
|
|
674
|
+
bool m_selectable_timestamps;
|
|
675
|
+
double m_ts_scale_factor;
|
|
676
|
+
std::uint8_t m_ts_size;
|
|
677
|
+
std::uint16_t m_min_daq;
|
|
678
|
+
TimestampInfo m_timestamp_info;
|
|
679
|
+
std::vector<std::shared_ptr<DaqListBase>> m_daq_lists;
|
|
680
|
+
std::vector<std::uint16_t> m_first_pids;
|
|
681
|
+
};
|
|
682
|
+
|
|
683
|
+
class Deserializer {
|
|
684
|
+
public:
|
|
685
|
+
|
|
686
|
+
explicit Deserializer(const std::string& buf) : m_buf(buf) {
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
MeasurementParameters run() {
|
|
690
|
+
std::uint8_t byte_order;
|
|
691
|
+
std::uint8_t id_field_size;
|
|
692
|
+
bool timestamps_supported;
|
|
693
|
+
bool ts_fixed;
|
|
694
|
+
bool prescaler_supported;
|
|
695
|
+
bool selectable_timestamps;
|
|
696
|
+
double ts_scale_factor;
|
|
697
|
+
std::uint8_t ts_size;
|
|
698
|
+
std::uint16_t min_daq;
|
|
699
|
+
std::size_t dl_count;
|
|
700
|
+
std::vector<std::shared_ptr<DaqListBase>> daq_lists;
|
|
701
|
+
std::size_t fp_count;
|
|
702
|
+
std::uint64_t timestamp_ns;
|
|
703
|
+
std::int16_t utc_offset;
|
|
704
|
+
std::int16_t dst_offset;
|
|
705
|
+
std::string timezone;
|
|
706
|
+
std::vector<std::uint16_t> first_pids;
|
|
707
|
+
// TimestampInfo timestamp_info{ 0 };
|
|
708
|
+
|
|
709
|
+
byte_order = from_binary<std::uint8_t>();
|
|
710
|
+
id_field_size = from_binary<std::uint8_t>();
|
|
711
|
+
timestamps_supported = from_binary<bool>();
|
|
712
|
+
ts_fixed = from_binary<bool>();
|
|
713
|
+
prescaler_supported = from_binary<bool>();
|
|
714
|
+
selectable_timestamps = from_binary<bool>();
|
|
715
|
+
ts_scale_factor = from_binary<double>();
|
|
716
|
+
ts_size = from_binary<std::uint8_t>();
|
|
717
|
+
min_daq = from_binary<std::uint16_t>();
|
|
718
|
+
dl_count = from_binary<std::size_t>();
|
|
719
|
+
|
|
720
|
+
timestamp_ns = from_binary<std::uint64_t>();
|
|
721
|
+
timezone = from_binary_str();
|
|
722
|
+
utc_offset = from_binary<std::int16_t>();
|
|
723
|
+
dst_offset = from_binary<std::int16_t>();
|
|
724
|
+
|
|
725
|
+
TimestampInfo timestamp_info{ timestamp_ns, timezone, utc_offset, dst_offset };
|
|
726
|
+
|
|
727
|
+
for (std::size_t i = 0; i < dl_count; i++) {
|
|
728
|
+
auto discr = from_binary<std::uint8_t>();
|
|
729
|
+
|
|
730
|
+
if (discr == 1) {
|
|
731
|
+
daq_lists.push_back(create_daq_list());
|
|
732
|
+
} else if (discr == 2) {
|
|
733
|
+
daq_lists.push_back(create_predefined_daq_list());
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
fp_count = from_binary<std::size_t>();
|
|
738
|
+
for (std::size_t i = 0; i < fp_count; i++) {
|
|
739
|
+
first_pids.push_back(from_binary<std::uint16_t>());
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
return MeasurementParameters(
|
|
743
|
+
byte_order, id_field_size, timestamps_supported, ts_fixed, prescaler_supported, selectable_timestamps, ts_scale_factor,
|
|
744
|
+
ts_size, min_daq, timestamp_info, daq_lists, first_pids
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
protected:
|
|
749
|
+
|
|
750
|
+
std::shared_ptr<DaqListBase> create_daq_list() {
|
|
751
|
+
std::string name;
|
|
752
|
+
std::uint16_t event_num;
|
|
753
|
+
std::uint16_t prescaler;
|
|
754
|
+
bool stim;
|
|
755
|
+
bool enable_timestamps;
|
|
756
|
+
std::vector<McObject> measurements;
|
|
757
|
+
std::vector<Bin> measurements_opt;
|
|
758
|
+
std::vector<std::string> header_names;
|
|
759
|
+
|
|
760
|
+
std::uint16_t odt_count;
|
|
761
|
+
std::uint16_t total_entries;
|
|
762
|
+
std::uint16_t total_length;
|
|
763
|
+
|
|
764
|
+
flatten_odts_t flatten_odts;
|
|
765
|
+
|
|
766
|
+
std::vector<DaqList::daq_list_initialzer_t> initializer_list{};
|
|
767
|
+
|
|
768
|
+
name = from_binary_str();
|
|
769
|
+
event_num = from_binary<std::uint16_t>();
|
|
770
|
+
stim = from_binary<bool>();
|
|
771
|
+
enable_timestamps = from_binary<bool>();
|
|
772
|
+
std::uint8_t priority = from_binary<std::uint8_t>();
|
|
773
|
+
prescaler = from_binary<std::uint8_t>();
|
|
774
|
+
|
|
775
|
+
odt_count = from_binary<std::uint16_t>(); // not used
|
|
776
|
+
total_entries = from_binary<std::uint16_t>(); // not used
|
|
777
|
+
total_length = from_binary<std::uint16_t>(); // not used
|
|
778
|
+
|
|
779
|
+
std::size_t meas_size = from_binary<std::size_t>();
|
|
780
|
+
for (std::size_t i = 0; i < meas_size; ++i) {
|
|
781
|
+
auto meas = create_mc_object();
|
|
782
|
+
measurements.push_back(meas);
|
|
783
|
+
initializer_list.push_back({ meas.get_name(), meas.get_address(), meas.get_ext(), meas.get_data_type() });
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
std::size_t meas_opt_size = from_binary<std::size_t>();
|
|
787
|
+
for (std::size_t i = 0; i < meas_opt_size; ++i) {
|
|
788
|
+
measurements_opt.emplace_back(create_bin());
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
std::size_t hname_size = from_binary<std::size_t>();
|
|
792
|
+
for (std::size_t i = 0; i < hname_size; ++i) {
|
|
793
|
+
auto header = from_binary_str();
|
|
794
|
+
header_names.push_back(header);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
auto dl = std::make_shared<DaqList>(name, event_num, stim, enable_timestamps, initializer_list, priority, prescaler);
|
|
798
|
+
dl->set_measurements_opt(measurements_opt);
|
|
799
|
+
return dl;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
std::shared_ptr<DaqListBase> create_predefined_daq_list() {
|
|
803
|
+
std::string name;
|
|
804
|
+
std::uint16_t event_num;
|
|
805
|
+
std::uint8_t priority;
|
|
806
|
+
std::uint8_t prescaler;
|
|
807
|
+
bool stim;
|
|
808
|
+
bool enable_timestamps;
|
|
809
|
+
std::vector<Bin> measurements_opt;
|
|
810
|
+
std::vector<std::string> header_names;
|
|
811
|
+
PredefinedDaqList::predefined_daq_list_initializer_t odts;
|
|
812
|
+
std::uint16_t odt_count;
|
|
813
|
+
std::uint16_t total_entries;
|
|
814
|
+
std::uint16_t total_length;
|
|
815
|
+
|
|
816
|
+
name = from_binary_str();
|
|
817
|
+
event_num = from_binary<std::uint16_t>();
|
|
818
|
+
stim = from_binary<bool>();
|
|
819
|
+
enable_timestamps = from_binary<bool>();
|
|
820
|
+
priority = from_binary<std::uint8_t>();
|
|
821
|
+
prescaler = from_binary<std::uint8_t>();
|
|
822
|
+
|
|
823
|
+
odt_count = from_binary<std::uint16_t>(); // not used
|
|
824
|
+
total_entries = from_binary<std::uint16_t>(); // not used
|
|
825
|
+
total_length = from_binary<std::uint16_t>(); // not used
|
|
826
|
+
|
|
827
|
+
std::size_t meas_opt_size = from_binary<std::size_t>();
|
|
828
|
+
for (std::size_t i = 0; i < meas_opt_size; ++i) {
|
|
829
|
+
measurements_opt.emplace_back(create_bin());
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
std::size_t hname_size = from_binary<std::size_t>();
|
|
833
|
+
for (std::size_t i = 0; i < hname_size; ++i) {
|
|
834
|
+
auto header = from_binary_str();
|
|
835
|
+
header_names.push_back(header);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
// Build `odts` from `measurements_opt` so the constructor is properly initialized
|
|
839
|
+
odts.clear();
|
|
840
|
+
odts.reserve(measurements_opt.size());
|
|
841
|
+
for (const auto& bin : measurements_opt) {
|
|
842
|
+
PredefinedDaqList::odt_initializer_t odt_init;
|
|
843
|
+
for (const auto& mc_obj : bin.get_entries()) {
|
|
844
|
+
const auto& comps = mc_obj.get_components();
|
|
845
|
+
if (comps.empty()) {
|
|
846
|
+
odt_init.emplace_back(mc_obj.get_name(), mc_obj.get_data_type());
|
|
847
|
+
} else {
|
|
848
|
+
for (const auto& component : comps) {
|
|
849
|
+
odt_init.emplace_back(component.get_name(), component.get_data_type());
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
odts.emplace_back(std::move(odt_init));
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
auto dl = std::make_shared<PredefinedDaqList>(name, event_num, stim, enable_timestamps, odts, priority, prescaler);
|
|
857
|
+
dl->set_measurements_opt(measurements_opt);
|
|
858
|
+
return dl;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
McObject create_mc_object() {
|
|
862
|
+
std::string name;
|
|
863
|
+
std::uint32_t address;
|
|
864
|
+
std::uint8_t ext;
|
|
865
|
+
std::uint16_t length;
|
|
866
|
+
std::string data_type;
|
|
867
|
+
std::int16_t type_index;
|
|
868
|
+
std::vector<McObject> components{};
|
|
869
|
+
|
|
870
|
+
name = from_binary_str();
|
|
871
|
+
address = from_binary<std::uint32_t>();
|
|
872
|
+
ext = from_binary<std::uint8_t>();
|
|
873
|
+
length = from_binary<std::uint16_t>();
|
|
874
|
+
data_type = from_binary_str();
|
|
875
|
+
type_index = from_binary<std::int16_t>(); // not used
|
|
876
|
+
std::size_t comp_size = from_binary<std::size_t>();
|
|
877
|
+
for (auto i = 0U; i < comp_size; i++) {
|
|
878
|
+
components.push_back(create_mc_object());
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
return McObject(name, address, ext, length, data_type, components);
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
Bin create_bin() {
|
|
885
|
+
std::uint16_t size;
|
|
886
|
+
std::uint16_t residual_capacity;
|
|
887
|
+
std::vector<McObject> entries{};
|
|
888
|
+
|
|
889
|
+
size = from_binary<std::uint16_t>();
|
|
890
|
+
residual_capacity = from_binary<std::uint16_t>();
|
|
891
|
+
std::size_t entry_size = from_binary<std::size_t>();
|
|
892
|
+
for (auto i = 0U; i < entry_size; i++) {
|
|
893
|
+
entries.push_back(create_mc_object());
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
return Bin(size, residual_capacity, entries);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
template<typename T>
|
|
900
|
+
inline T from_binary() {
|
|
901
|
+
auto tmp = *reinterpret_cast<const T*>(&m_buf[m_offset]);
|
|
902
|
+
m_offset += sizeof(T);
|
|
903
|
+
return tmp;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
inline std::string from_binary_str() {
|
|
907
|
+
auto length = from_binary<std::size_t>();
|
|
908
|
+
std::string result;
|
|
909
|
+
auto start = m_buf.cbegin() + m_offset;
|
|
910
|
+
|
|
911
|
+
std::copy(start, start + length, std::back_inserter(result));
|
|
912
|
+
m_offset += length;
|
|
913
|
+
return result;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
private:
|
|
917
|
+
|
|
918
|
+
std::string m_buf;
|
|
919
|
+
std::size_t m_offset = 0;
|
|
920
|
+
};
|
|
921
|
+
|
|
922
|
+
class DaqListState {
|
|
923
|
+
public:
|
|
924
|
+
|
|
925
|
+
enum class state_t : std::uint8_t {
|
|
926
|
+
IDLE = 0,
|
|
927
|
+
COLLECTING = 1,
|
|
928
|
+
FINISHED = 2,
|
|
929
|
+
_IGNORE = 3, // Duplicate frame.
|
|
930
|
+
_ERROR = 4, // Out-of-order/missing sequence/ODT number.
|
|
931
|
+
};
|
|
932
|
+
|
|
933
|
+
DaqListState(
|
|
934
|
+
std::uint16_t daq_list_num, std::uint16_t num_odts, std::uint16_t total_entries, bool enable_timestamps,
|
|
935
|
+
std::uint16_t initial_offset, const flatten_odts_t& flatten_odts, const Getter& getter, MeasurementParameters params
|
|
936
|
+
) :
|
|
937
|
+
m_daq_list_num(daq_list_num),
|
|
938
|
+
m_num_odts(num_odts),
|
|
939
|
+
m_total_entries(total_entries),
|
|
940
|
+
m_enable_timestamps(enable_timestamps),
|
|
941
|
+
m_initial_offset(initial_offset),
|
|
942
|
+
m_next_odt(0),
|
|
943
|
+
m_current_idx(0),
|
|
944
|
+
m_timestamp0(0ULL),
|
|
945
|
+
m_timestamp1(0ULL),
|
|
946
|
+
m_state(state_t::IDLE),
|
|
947
|
+
m_buffer{},
|
|
948
|
+
m_flatten_odts(flatten_odts),
|
|
949
|
+
m_getter(getter),
|
|
950
|
+
m_params(params) {
|
|
951
|
+
m_buffer.resize(m_total_entries);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
state_t check_state(uint16_t odt_num) {
|
|
955
|
+
if ((m_state == state_t::IDLE) && (odt_num == 0x00)) {
|
|
956
|
+
// "synch pulse".
|
|
957
|
+
if (m_num_odts == 0x01) {
|
|
958
|
+
resetSM();
|
|
959
|
+
return state_t::FINISHED;
|
|
960
|
+
} else {
|
|
961
|
+
m_state = state_t::COLLECTING;
|
|
962
|
+
m_next_odt = 1;
|
|
963
|
+
}
|
|
964
|
+
} else if (m_state == state_t::COLLECTING) {
|
|
965
|
+
if (odt_num == m_next_odt) {
|
|
966
|
+
m_next_odt++;
|
|
967
|
+
if (m_next_odt == m_num_odts) {
|
|
968
|
+
resetSM();
|
|
969
|
+
return state_t::FINISHED;
|
|
970
|
+
}
|
|
971
|
+
} else {
|
|
972
|
+
resetSM();
|
|
973
|
+
return state_t::_ERROR;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
return m_state;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
bool feed(uint16_t odt_num, std::uint64_t timestamp, const std::string& payload) {
|
|
980
|
+
auto state = check_state(odt_num);
|
|
981
|
+
auto finished = false;
|
|
982
|
+
|
|
983
|
+
if (state == state_t::COLLECTING) {
|
|
984
|
+
m_timestamp0 = timestamp;
|
|
985
|
+
parse_Odt(odt_num, payload);
|
|
986
|
+
} else if (state == state_t::FINISHED) {
|
|
987
|
+
m_timestamp0 = timestamp;
|
|
988
|
+
parse_Odt(odt_num, payload);
|
|
989
|
+
finished = true;
|
|
990
|
+
}
|
|
991
|
+
return finished;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
void add_result(std::vector<measurement_tuple_t>& result_buffer) {
|
|
995
|
+
result_buffer.emplace_back(m_daq_list_num, m_timestamp0, m_timestamp1, m_buffer);
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
void add_result(measurement_tuple_t& result_buffer) {
|
|
999
|
+
result_buffer = { m_daq_list_num, m_timestamp0, m_timestamp1, m_buffer };
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
protected:
|
|
1003
|
+
|
|
1004
|
+
void resetSM() {
|
|
1005
|
+
m_state = state_t::IDLE;
|
|
1006
|
+
m_next_odt = 0;
|
|
1007
|
+
m_timestamp0 = 0ULL;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
void parse_Odt(uint16_t odt_num, const std::string& payload) {
|
|
1011
|
+
auto offset = m_initial_offset; // consider ID field size.
|
|
1012
|
+
auto payload_data = reinterpret_cast<const blob_t*>(payload.data());
|
|
1013
|
+
auto payload_size = std::size(payload);
|
|
1014
|
+
|
|
1015
|
+
if (odt_num == 0) {
|
|
1016
|
+
m_current_idx = 0;
|
|
1017
|
+
if (m_params.m_timestamps_supported &&
|
|
1018
|
+
(m_params.m_ts_fixed || (m_params.m_selectable_timestamps && m_enable_timestamps == true))) {
|
|
1019
|
+
m_timestamp1 = static_cast<std::uint64_t>(m_getter.get_timestamp(payload_data) * m_params.m_ts_scale_factor);
|
|
1020
|
+
offset += m_params.m_ts_size;
|
|
1021
|
+
} else {
|
|
1022
|
+
m_timestamp1 = 0ULL;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
for (const auto& param : m_flatten_odts[odt_num]) {
|
|
1027
|
+
const auto& [name, address, ext, size, type_index] = param;
|
|
1028
|
+
|
|
1029
|
+
if (offset >= payload_size) {
|
|
1030
|
+
throw std::runtime_error(
|
|
1031
|
+
"Offset is out of range! " + std::to_string(offset) + " >= " + std::to_string(payload_size)
|
|
1032
|
+
);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
m_buffer[m_current_idx++] = m_getter.reader(type_index, payload_data, offset);
|
|
1036
|
+
offset += size;
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
private:
|
|
1041
|
+
|
|
1042
|
+
std::uint16_t m_daq_list_num = 0;
|
|
1043
|
+
std::uint16_t m_num_odts = 0;
|
|
1044
|
+
std::uint16_t m_total_entries = 0;
|
|
1045
|
+
bool m_enable_timestamps = false;
|
|
1046
|
+
std::uint16_t m_initial_offset;
|
|
1047
|
+
std::uint16_t m_next_odt = 0;
|
|
1048
|
+
std::uint16_t m_current_idx = 0;
|
|
1049
|
+
std::uint64_t m_timestamp0 = 0ULL;
|
|
1050
|
+
std::uint64_t m_timestamp1 = 0ULL;
|
|
1051
|
+
state_t m_state = state_t::IDLE;
|
|
1052
|
+
std::vector<measurement_value_t> m_buffer;
|
|
1053
|
+
flatten_odts_t m_flatten_odts;
|
|
1054
|
+
Getter m_getter;
|
|
1055
|
+
MeasurementParameters m_params;
|
|
1056
|
+
};
|
|
1057
|
+
|
|
1058
|
+
auto requires_swap(std::uint8_t byte_order) -> bool {
|
|
1059
|
+
// INTEL(LITTLE)=0, MOTOROLA(BIG)=1
|
|
1060
|
+
std::endian target_byte_order = (byte_order == 1) ? std::endian::big : std::endian::little;
|
|
1061
|
+
return (target_byte_order != std::endian::native) ? true : false;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
class DAQProcessor {
|
|
1065
|
+
public:
|
|
1066
|
+
|
|
1067
|
+
explicit DAQProcessor(const MeasurementParameters& params) : m_params(params) {
|
|
1068
|
+
create_state_vars(params);
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
DAQProcessor() = delete;
|
|
1072
|
+
virtual ~DAQProcessor() = default;
|
|
1073
|
+
|
|
1074
|
+
std::optional<measurement_tuple_t> feed(std::uint64_t timestamp, const std::string& payload) noexcept {
|
|
1075
|
+
const auto data = reinterpret_cast<blob_t const *>(payload.data());
|
|
1076
|
+
auto [daq_num, odt_num] = m_getter.get_id(data);
|
|
1077
|
+
|
|
1078
|
+
if (m_state[daq_num].feed(odt_num, timestamp, payload)) {
|
|
1079
|
+
// DAQ list completed.
|
|
1080
|
+
measurement_tuple_t result;
|
|
1081
|
+
|
|
1082
|
+
m_state[daq_num].add_result(result); // get_result()???
|
|
1083
|
+
return result;
|
|
1084
|
+
}
|
|
1085
|
+
return std::nullopt;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
private:
|
|
1089
|
+
|
|
1090
|
+
void create_state_vars(const MeasurementParameters& params) noexcept {
|
|
1091
|
+
m_getter = Getter(requires_swap(params.m_byte_order), params.m_id_field_size, params.m_ts_size);
|
|
1092
|
+
for (std::uint16_t idx = 0; idx < params.m_daq_lists.size(); ++idx) {
|
|
1093
|
+
m_state.emplace_back(DaqListState(
|
|
1094
|
+
idx, params.m_daq_lists[idx]->get_odt_count(), params.m_daq_lists[idx]->get_total_entries(),
|
|
1095
|
+
params.m_daq_lists[idx]->get_enable_timestamps(), params.m_id_field_size, params.m_daq_lists[idx]->get_flatten_odts(),
|
|
1096
|
+
m_getter, params
|
|
1097
|
+
));
|
|
1098
|
+
}
|
|
1099
|
+
m_getter.set_first_pids(m_params.m_daq_lists, m_params.m_first_pids);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
MeasurementParameters m_params;
|
|
1103
|
+
Getter m_getter;
|
|
1104
|
+
std::map<std::uint16_t, std::uint16_t> m_first_pids;
|
|
1105
|
+
std::vector<DaqListState> m_state;
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
class DAQPolicyBase {
|
|
1109
|
+
public:
|
|
1110
|
+
|
|
1111
|
+
virtual ~DAQPolicyBase() {
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
virtual void set_parameters(const MeasurementParameters& params) noexcept {
|
|
1115
|
+
m_overflow_value = params.get_overflow_value();
|
|
1116
|
+
m_overflow_counter = 0ULL;
|
|
1117
|
+
// std::cout << "Overflow value: " << m_overflow_value << ", Overflow counter: " << m_overflow_counter << std::endl;
|
|
1118
|
+
initialize();
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
virtual void feed(std::uint8_t frame_cat, std::uint16_t counter, std::uint64_t timestamp, const std::string& payload) = 0;
|
|
1122
|
+
|
|
1123
|
+
virtual void initialize() = 0;
|
|
1124
|
+
|
|
1125
|
+
virtual void finalize() = 0;
|
|
1126
|
+
private:
|
|
1127
|
+
std::uint64_t m_overflow_value{};
|
|
1128
|
+
std::uint64_t m_overflow_counter{};
|
|
1129
|
+
};
|
|
1130
|
+
|
|
1131
|
+
class DaqRecorderPolicy : public DAQPolicyBase {
|
|
1132
|
+
public:
|
|
1133
|
+
|
|
1134
|
+
~DaqRecorderPolicy() {
|
|
1135
|
+
finalize();
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
DaqRecorderPolicy() = default;
|
|
1139
|
+
|
|
1140
|
+
void set_parameters(const MeasurementParameters& params) noexcept override {
|
|
1141
|
+
m_params = params;
|
|
1142
|
+
DAQPolicyBase::set_parameters(params);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
void feed(std::uint8_t frame_cat, std::uint16_t counter, std::uint64_t timestamp, const std::string& payload) override {
|
|
1146
|
+
if (frame_cat != static_cast<std::uint8_t>(FrameCategory::DAQ) || (!m_initialized)) {
|
|
1147
|
+
// Only record DAQ frames for now.
|
|
1148
|
+
// also make sure policy is initialized.
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
m_writer->add_frame(frame_cat, counter, timestamp, static_cast<std::uint16_t>(payload.size()), payload.c_str());
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
void create_writer(const std::string& file_name, std::uint32_t prealloc, std::uint32_t chunk_size, std::string_view metadata) {
|
|
1155
|
+
m_writer = std::make_unique<XcpLogFileWriter>(file_name, prealloc, chunk_size, metadata);
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
void initialize() override {
|
|
1159
|
+
m_initialized = true;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
void finalize() override {
|
|
1163
|
+
if (!m_initialized) {
|
|
1164
|
+
return;
|
|
1165
|
+
}
|
|
1166
|
+
m_writer->finalize();
|
|
1167
|
+
m_initialized = false;
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
private:
|
|
1171
|
+
|
|
1172
|
+
std::unique_ptr<XcpLogFileWriter> m_writer{ nullptr };
|
|
1173
|
+
MeasurementParameters m_params;
|
|
1174
|
+
bool m_initialized{ false };
|
|
1175
|
+
};
|
|
1176
|
+
|
|
1177
|
+
class DaqTimeTracker {
|
|
1178
|
+
public:
|
|
1179
|
+
|
|
1180
|
+
DaqTimeTracker(std::uint64_t overflow_value) : m_overflow_value(overflow_value), m_overflow_counter(0ULL), m_previous_timestamp(0ULL) {
|
|
1181
|
+
m_ts_base_set=false;
|
|
1182
|
+
m_ts0_base=0ULL; m_ts1_base=0ULL;
|
|
1183
|
+
//std::cout << "\tOverflow value: " << overflow_value << "\n";
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
std::pair<std::uint64_t,std::uint64_t> normalize(std::uint64_t ts0, std::uint64_t ts1) noexcept {
|
|
1187
|
+
|
|
1188
|
+
if (m_previous_timestamp > ts1) {
|
|
1189
|
+
m_overflow_counter++;
|
|
1190
|
+
}
|
|
1191
|
+
m_previous_timestamp = ts1;
|
|
1192
|
+
|
|
1193
|
+
if (!m_ts_base_set) {
|
|
1194
|
+
m_ts0_base = ts0;
|
|
1195
|
+
m_ts1_base = ts1;
|
|
1196
|
+
m_ts_base_set = true;
|
|
1197
|
+
// std::cout << "\tSet ts0: " << ts0 << " ts1:" << ts1 << "\n";
|
|
1198
|
+
}
|
|
1199
|
+
// std::cout << "\t\tts0: " << ts0 << " Base: " << m_ts0_base << " ts1: " << ts1 << " Base: " << m_ts1_base << "\n";
|
|
1200
|
+
return {ts0 - m_ts0_base, (ts1 - m_ts1_base) + (m_overflow_value * m_overflow_counter) };
|
|
1201
|
+
}
|
|
1202
|
+
private:
|
|
1203
|
+
|
|
1204
|
+
std::uint64_t m_overflow_value{};
|
|
1205
|
+
std::uint64_t m_overflow_counter{};
|
|
1206
|
+
std::uint64_t m_previous_timestamp{};
|
|
1207
|
+
bool m_ts_base_set{false};
|
|
1208
|
+
std::uint64_t m_ts0_base{0ULL};
|
|
1209
|
+
std::uint64_t m_ts1_base{0ULL};
|
|
1210
|
+
};
|
|
1211
|
+
|
|
1212
|
+
|
|
1213
|
+
class DaqOnlinePolicy : public DAQPolicyBase {
|
|
1214
|
+
public:
|
|
1215
|
+
|
|
1216
|
+
~DaqOnlinePolicy() {
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
DaqOnlinePolicy() = default;
|
|
1220
|
+
|
|
1221
|
+
void set_parameters(const MeasurementParameters& params) noexcept {
|
|
1222
|
+
m_decoder = std::make_unique<DAQProcessor>(params);
|
|
1223
|
+
for (auto idx=0; idx < params.get_daq_lists().size(); ++idx) {
|
|
1224
|
+
m_overflows.emplace_back(DaqTimeTracker(params.get_overflow_value()));
|
|
1225
|
+
}
|
|
1226
|
+
DAQPolicyBase::set_parameters(params);
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
virtual void on_daq_list(
|
|
1230
|
+
std::uint16_t daq_list_num, std::uint64_t timestamp0, std::uint64_t timestamp1,
|
|
1231
|
+
const std::vector<measurement_value_t>& measurement
|
|
1232
|
+
) = 0;
|
|
1233
|
+
|
|
1234
|
+
void feed(std::uint8_t frame_cat, std::uint16_t counter, std::uint64_t timestamp, const std::string& payload) {
|
|
1235
|
+
if (frame_cat != static_cast<std::uint8_t>(FrameCategory::DAQ)) {
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
auto result = m_decoder->feed(timestamp, payload);
|
|
1239
|
+
if (result) {
|
|
1240
|
+
const auto& [daq_list, ts0, ts1, meas] = *result;
|
|
1241
|
+
auto& overflow = m_overflows[daq_list];
|
|
1242
|
+
|
|
1243
|
+
auto [norm_ts0, norm_ts1] = overflow.normalize(ts0, ts1);
|
|
1244
|
+
|
|
1245
|
+
on_daq_list(daq_list, norm_ts0, norm_ts1, meas);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
virtual void initialize() {
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
virtual void finalize() {
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
private:
|
|
1256
|
+
|
|
1257
|
+
std::unique_ptr<DAQProcessor> m_decoder;
|
|
1258
|
+
std::vector<DaqTimeTracker> m_overflows;
|
|
1259
|
+
};
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
class XcpLogFileDecoder {
|
|
1263
|
+
public:
|
|
1264
|
+
|
|
1265
|
+
explicit XcpLogFileDecoder(const std::string& file_name) : m_reader(file_name) {
|
|
1266
|
+
auto metadata = m_reader.get_metadata();
|
|
1267
|
+
if (metadata != "") {
|
|
1268
|
+
auto des = Deserializer(metadata);
|
|
1269
|
+
m_params = des.run();
|
|
1270
|
+
|
|
1271
|
+
for (auto idx=0; idx < m_params.get_daq_lists().size(); ++idx) {
|
|
1272
|
+
m_overflows.emplace_back(DaqTimeTracker(m_params.get_overflow_value()));
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
m_decoder = std::make_unique<DAQProcessor>(m_params);
|
|
1276
|
+
} else {
|
|
1277
|
+
throw std::runtime_error("XcpLogFileDecoder: missing metadata.");
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
XcpLogFileDecoder() = delete;
|
|
1282
|
+
virtual ~XcpLogFileDecoder() = default;
|
|
1283
|
+
|
|
1284
|
+
virtual void initialize() {
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
virtual void finalize() {
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
void run() {
|
|
1291
|
+
initialize();
|
|
1292
|
+
const auto converter = [](const blob_t* in_str, std::size_t length) -> std::string {
|
|
1293
|
+
std::string result;
|
|
1294
|
+
result.resize(length);
|
|
1295
|
+
|
|
1296
|
+
for (std::size_t idx = 0; idx < length; ++idx) {
|
|
1297
|
+
result[idx] = static_cast<char>(in_str[idx]);
|
|
1298
|
+
}
|
|
1299
|
+
|
|
1300
|
+
return result;
|
|
1301
|
+
};
|
|
1302
|
+
|
|
1303
|
+
while (true) {
|
|
1304
|
+
const auto& block = m_reader.next_block();
|
|
1305
|
+
if (!block) {
|
|
1306
|
+
finalize();
|
|
1307
|
+
return;
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
for (const auto& [frame_cat, counter, timestamp, length, payload] : block.value()) {
|
|
1311
|
+
auto str_data = converter(payload.data(), std::size(payload));
|
|
1312
|
+
if (frame_cat != static_cast<std::uint8_t>(FrameCategory::DAQ)) {
|
|
1313
|
+
continue;
|
|
1314
|
+
}
|
|
1315
|
+
auto result = m_decoder->feed(timestamp, str_data);
|
|
1316
|
+
if (result) {
|
|
1317
|
+
const auto& [daq_list, ts0, ts1, meas] = *result;
|
|
1318
|
+
auto& overflow = m_overflows[daq_list];
|
|
1319
|
+
|
|
1320
|
+
auto [norm_ts0, norm_ts1] = overflow.normalize(ts0, ts1);
|
|
1321
|
+
|
|
1322
|
+
on_daq_list(daq_list, norm_ts0, norm_ts1, meas);
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
virtual void on_daq_list(
|
|
1330
|
+
std::uint16_t daq_list_num, std::uint64_t timestamp0, std::uint64_t timestamp1,
|
|
1331
|
+
const std::vector<measurement_value_t>& measurement
|
|
1332
|
+
) = 0;
|
|
1333
|
+
|
|
1334
|
+
MeasurementParameters get_parameters() const {
|
|
1335
|
+
return m_params;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
auto get_daq_lists() const {
|
|
1339
|
+
return m_params.m_daq_lists;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
auto get_header() const {
|
|
1343
|
+
return m_reader.get_header();
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
private:
|
|
1347
|
+
|
|
1348
|
+
XcpLogFileReader m_reader;
|
|
1349
|
+
std::unique_ptr<DAQProcessor> m_decoder;
|
|
1350
|
+
MeasurementParameters m_params;
|
|
1351
|
+
std::vector<DaqTimeTracker> m_overflows;
|
|
1352
|
+
};
|
|
1353
|
+
|
|
1354
|
+
#endif // RECORDER_UNFOLDER_HPP
|