pyxcp 0.23.8__cp313-cp313-macosx_11_0_arm64.whl → 0.25.7__cp313-cp313-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.
Files changed (89) hide show
  1. pyxcp/__init__.py +1 -1
  2. pyxcp/cmdline.py +14 -29
  3. pyxcp/config/__init__.py +1257 -1258
  4. pyxcp/cpp_ext/aligned_buffer.hpp +168 -0
  5. pyxcp/cpp_ext/bin.hpp +7 -6
  6. pyxcp/cpp_ext/cpp_ext.cpython-310-darwin.so +0 -0
  7. pyxcp/cpp_ext/cpp_ext.cpython-311-darwin.so +0 -0
  8. pyxcp/cpp_ext/cpp_ext.cpython-312-darwin.so +0 -0
  9. pyxcp/cpp_ext/cpp_ext.cpython-313-darwin.so +0 -0
  10. pyxcp/cpp_ext/daqlist.hpp +241 -73
  11. pyxcp/cpp_ext/extension_wrapper.cpp +123 -15
  12. pyxcp/cpp_ext/framing.hpp +360 -0
  13. pyxcp/cpp_ext/helper.hpp +280 -280
  14. pyxcp/cpp_ext/mcobject.hpp +248 -246
  15. pyxcp/cpp_ext/sxi_framing.hpp +332 -0
  16. pyxcp/daq_stim/__init__.py +145 -67
  17. pyxcp/daq_stim/optimize/binpacking.py +2 -2
  18. pyxcp/daq_stim/scheduler.cpp +8 -8
  19. pyxcp/errormatrix.py +2 -2
  20. pyxcp/examples/run_daq.py +5 -4
  21. pyxcp/examples/xcp_policy.py +6 -6
  22. pyxcp/examples/xcp_read_benchmark.py +2 -2
  23. pyxcp/examples/xcp_skel.py +1 -2
  24. pyxcp/examples/xcp_unlock.py +10 -12
  25. pyxcp/examples/xcp_user_supplied_driver.py +1 -2
  26. pyxcp/examples/xcphello.py +2 -15
  27. pyxcp/examples/xcphello_recorder.py +2 -2
  28. pyxcp/master/__init__.py +1 -0
  29. pyxcp/master/errorhandler.py +134 -4
  30. pyxcp/master/master.py +823 -252
  31. pyxcp/recorder/.idea/.gitignore +8 -0
  32. pyxcp/recorder/.idea/misc.xml +4 -0
  33. pyxcp/recorder/.idea/modules.xml +8 -0
  34. pyxcp/recorder/.idea/recorder.iml +6 -0
  35. pyxcp/recorder/.idea/sonarlint/issuestore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +7 -0
  36. pyxcp/recorder/.idea/sonarlint/issuestore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
  37. pyxcp/recorder/.idea/sonarlint/issuestore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
  38. pyxcp/recorder/.idea/sonarlint/issuestore/index.pb +7 -0
  39. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/3/8/3808afc69ac1edb9d760000a2f137335b1b99728 +0 -0
  40. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/9/a/9a2aa4db38d3115ed60da621e012c0efc0172aae +0 -0
  41. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/b/4/b49006702b459496a8e8c94ebe60947108361b91 +0 -0
  42. pyxcp/recorder/.idea/sonarlint/securityhotspotstore/index.pb +7 -0
  43. pyxcp/recorder/.idea/vcs.xml +10 -0
  44. pyxcp/recorder/__init__.py +96 -98
  45. pyxcp/recorder/converter/__init__.py +4 -10
  46. pyxcp/recorder/reader.hpp +138 -139
  47. pyxcp/recorder/reco.py +1 -0
  48. pyxcp/recorder/rekorder.cpython-310-darwin.so +0 -0
  49. pyxcp/recorder/rekorder.cpython-311-darwin.so +0 -0
  50. pyxcp/recorder/rekorder.cpython-312-darwin.so +0 -0
  51. pyxcp/recorder/rekorder.cpython-313-darwin.so +0 -0
  52. pyxcp/recorder/rekorder.hpp +274 -274
  53. pyxcp/recorder/unfolder.hpp +1354 -1319
  54. pyxcp/recorder/wrap.cpp +184 -183
  55. pyxcp/recorder/writer.hpp +302 -302
  56. pyxcp/scripts/xcp_daq_recorder.py +54 -0
  57. pyxcp/scripts/xcp_fetch_a2l.py +2 -2
  58. pyxcp/scripts/xcp_id_scanner.py +1 -2
  59. pyxcp/scripts/xcp_info.py +66 -51
  60. pyxcp/scripts/xcp_profile.py +1 -2
  61. pyxcp/tests/test_daq.py +1 -1
  62. pyxcp/tests/test_framing.py +262 -0
  63. pyxcp/tests/test_master.py +210 -100
  64. pyxcp/tests/test_transport.py +138 -42
  65. pyxcp/timing.py +1 -1
  66. pyxcp/transport/__init__.py +8 -5
  67. pyxcp/transport/base.py +70 -180
  68. pyxcp/transport/can.py +58 -7
  69. pyxcp/transport/eth.py +32 -15
  70. pyxcp/transport/hdf5_policy.py +167 -0
  71. pyxcp/transport/sxi.py +126 -52
  72. pyxcp/transport/transport_ext.cpython-310-darwin.so +0 -0
  73. pyxcp/transport/transport_ext.cpython-311-darwin.so +0 -0
  74. pyxcp/transport/transport_ext.cpython-312-darwin.so +0 -0
  75. pyxcp/transport/transport_ext.cpython-313-darwin.so +0 -0
  76. pyxcp/transport/transport_ext.hpp +214 -0
  77. pyxcp/transport/transport_wrapper.cpp +249 -0
  78. pyxcp/transport/usb_transport.py +47 -31
  79. pyxcp/types.py +0 -13
  80. pyxcp/{utils.py → utils/__init__.py} +1 -2
  81. pyxcp/utils/cli.py +78 -0
  82. {pyxcp-0.23.8.dist-info → pyxcp-0.25.7.dist-info}/METADATA +4 -2
  83. pyxcp-0.25.7.dist-info/RECORD +158 -0
  84. {pyxcp-0.23.8.dist-info → pyxcp-0.25.7.dist-info}/WHEEL +1 -1
  85. pyxcp/examples/conf_sxi.json +0 -9
  86. pyxcp/examples/conf_sxi.toml +0 -7
  87. pyxcp-0.23.8.dist-info/RECORD +0 -135
  88. {pyxcp-0.23.8.dist-info → pyxcp-0.25.7.dist-info}/entry_points.txt +0 -0
  89. {pyxcp-0.23.8.dist-info → pyxcp-0.25.7.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,168 @@
1
+
2
+ #if !defined(__ALIGNED_BUFFER_HPP)
3
+ #define __ALIGNED_BUFFER_HPP
4
+
5
+ #include <variant>
6
+
7
+ #include <cstdint>
8
+ #include <cstdlib>
9
+ #include <vector>
10
+ #include <string_view>
11
+ #include <stdexcept>
12
+ #include <algorithm>
13
+ #include <cstring>
14
+
15
+ #include <pybind11/pybind11.h>
16
+
17
+ #if (defined(_WIN32) || defined(_WIN64)) && defined(_MSC_VER)
18
+ #include <malloc.h>
19
+ #endif
20
+
21
+ namespace py = pybind11;
22
+
23
+ class AlignedBuffer {
24
+
25
+ public:
26
+
27
+ AlignedBuffer(size_t size = 0xffff) : m_size(size), m_current_pos(0) {
28
+ m_buffer = nullptr;
29
+ // Create naturally aligned buffer.
30
+ constexpr std::size_t align = alignof(int);
31
+ // aligned_alloc requires size to be a multiple of alignment.
32
+ const std::size_t aligned_size = ((m_size + align - 1) / align) * align;
33
+ #if (defined(_WIN32) || defined(_WIN64)) && defined(_MSC_VER)
34
+ m_buffer = static_cast<uint8_t*>(::_aligned_malloc(aligned_size, align));
35
+ #else
36
+ m_buffer = static_cast<uint8_t*>(::aligned_alloc(align, aligned_size));
37
+ #endif
38
+ }
39
+
40
+ AlignedBuffer(const AlignedBuffer& other) = delete;
41
+ AlignedBuffer& operator=(const AlignedBuffer& other) = delete;
42
+ AlignedBuffer(AlignedBuffer&& other) = delete;
43
+ AlignedBuffer& operator=(AlignedBuffer&& other) = delete;
44
+
45
+ ~AlignedBuffer() {
46
+ if (m_buffer) {
47
+ #if (defined(_WIN32) || defined(_WIN64)) && defined(_MSC_VER)
48
+ ::_aligned_free(m_buffer);
49
+ #else
50
+ ::free(m_buffer);
51
+ #endif
52
+ m_buffer = nullptr;
53
+ }
54
+ }
55
+
56
+ void reset() noexcept {
57
+ m_current_pos = 0;
58
+ }
59
+
60
+ std::size_t size() const noexcept {
61
+ return m_current_pos;
62
+ }
63
+
64
+ // Get an element by index
65
+ uint8_t get(size_t index) const {
66
+ if (index >= size()) throw std::out_of_range("Index out of range");
67
+ return m_buffer[index];
68
+ }
69
+
70
+ void append(uint8_t value) {
71
+ if ((m_current_pos + 1) > m_size) {
72
+ throw std::overflow_error("Buffer overflow");
73
+ }
74
+ m_buffer[m_current_pos] = value;
75
+ m_current_pos++;
76
+ }
77
+
78
+ // Set an element by index
79
+ void set(size_t index, uint8_t value) {
80
+ if (index >= size()) throw std::out_of_range("Index out of range");
81
+ m_buffer[index] = value;
82
+ }
83
+
84
+ static std::string_view bytes_as_string_view(const py::bytes& data) {
85
+ char* buf = nullptr;
86
+ Py_ssize_t len = 0;
87
+ if (PyBytes_AsStringAndSize(data.ptr(), &buf, &len) != 0 || buf == nullptr || len < 0) {
88
+ return std::string_view{};
89
+ }
90
+ return std::string_view(buf, static_cast<std::size_t>(len));
91
+ }
92
+
93
+
94
+ void extend(const py::bytes& values) {
95
+ auto data_view = bytes_as_string_view(values);
96
+
97
+ if ((data_view.size() + m_current_pos) > m_size) {
98
+ throw std::invalid_argument("Values vector is too large");
99
+ }
100
+ if (!data_view.empty()) {
101
+ std::memcpy(m_buffer + m_current_pos, data_view.data(), data_view.size());
102
+ m_current_pos += data_view.size();
103
+ }
104
+ }
105
+
106
+ void extend(const std::vector<std::uint8_t>& values) {
107
+ if ((values.size() + m_current_pos) > m_size) {
108
+ throw std::invalid_argument("Values vector is too large");
109
+ }
110
+ if (!values.empty()) {
111
+ std::memcpy(m_buffer + m_current_pos, values.data(), values.size());
112
+ m_current_pos += values.size();
113
+ }
114
+ }
115
+
116
+ std::variant<uint8_t, py::bytes> get_item(py::object index) const {
117
+ if (py::isinstance<py::slice>(index)) {
118
+ py::slice slice = index.cast<py::slice>();
119
+ size_t start, stop, step, length;
120
+ if (!slice.compute(size(), &start, &stop, &step, &length)) {
121
+ throw py::error_already_set();
122
+ }
123
+ return slice(start, stop, step);
124
+ } else if (py::isinstance<py::int_>(index)) {
125
+ Py_ssize_t idx = index.cast<Py_ssize_t>();
126
+ if (idx < 0) {
127
+ idx += static_cast<Py_ssize_t>(size());
128
+ }
129
+ if (idx < 0 || static_cast<std::size_t>(idx) >= size()) {
130
+ throw std::out_of_range("Index out of range");
131
+ }
132
+ return get(static_cast<std::size_t>(idx));
133
+ } else {
134
+ throw py::type_error("Invalid index type");
135
+ }
136
+ }
137
+
138
+ py::bytes slice(size_t start, size_t stop, size_t step) const {
139
+ if (step == 0) {
140
+ throw std::invalid_argument("Step cannot be zero");
141
+ }
142
+ // Clamp indices to valid range
143
+ start = std::max(size_t(0), std::min(start, size_t(size())));
144
+ stop = std::max(size_t(0), std::min(stop, size_t(size())));
145
+
146
+ if (start >= stop) {
147
+ return py::bytes("");
148
+ }
149
+ if (step == 1) {
150
+ return py::bytes(reinterpret_cast<const char*>(m_buffer) + start, stop - start);
151
+ }
152
+ // General step handling (build result with stride)
153
+ std::string out;
154
+ out.reserve((stop - start + step - 1) / step);
155
+ for (size_t i = start; i < stop; i += step) {
156
+ out.push_back(static_cast<char>(m_buffer[i]));
157
+ }
158
+ return py::bytes(out);
159
+ }
160
+
161
+ private:
162
+ size_t m_size;
163
+ size_t m_current_pos;
164
+ uint8_t * m_buffer;
165
+ };
166
+
167
+
168
+ #endif // __ALIGNED_BUFFER_HPP
pyxcp/cpp_ext/bin.hpp CHANGED
@@ -79,17 +79,18 @@ std::string bin_entries_to_string(const std::vector<McObject>& entries);
79
79
 
80
80
  std::string to_string(const Bin& obj) {
81
81
  std::stringstream ss;
82
-
83
- ss << "Bin(residual_capacity=" << obj.get_residual_capacity() << ", entries=[" << bin_entries_to_string(obj.get_entries())
84
- << "])";
82
+ ss << "Bin(size=" << obj.get_size() << ", residual_capacity=" << obj.get_residual_capacity() << ", entries=["
83
+ << bin_entries_to_string(obj.get_entries()) << "])";
85
84
  return ss.str();
86
85
  }
87
86
 
88
87
  std::string bin_entries_to_string(const std::vector<McObject>& entries) {
89
88
  std::stringstream ss;
90
-
91
- for (const auto& entry : entries) {
92
- ss << to_string(entry) << ",\n ";
89
+ for (std::size_t i = 0; i < entries.size(); ++i) {
90
+ ss << to_string(entries[i]);
91
+ if (i + 1 < entries.size()) {
92
+ ss << ", ";
93
+ }
93
94
  }
94
95
  return ss.str();
95
96
  }
Binary file
Binary file
Binary file
Binary file
pyxcp/cpp_ext/daqlist.hpp CHANGED
@@ -8,22 +8,70 @@
8
8
 
9
9
  using flatten_odts_t = std::vector<std::vector<std::tuple<std::string, std::uint32_t, std::uint8_t, std::uint16_t, std::int16_t>>>;
10
10
 
11
- class DaqList {
11
+ class Odt {
12
12
  public:
13
+ using odt_entry_initializer_t = std::tuple<std::string, std::string>;
13
14
 
14
- using daq_list_initialzer_t = std::tuple<std::string, std::uint32_t, std::uint16_t, std::string>;
15
+ Odt(const std::vector<odt_entry_initializer_t>& entries) {
16
+ for (const auto& entry : entries) {
17
+ const auto& [name, dt_name] = entry;
18
+ m_entries.emplace_back(McObject(name, 0, 0, 0, dt_name));
19
+ }
20
+ }
15
21
 
16
- DaqList(
17
- std::string_view meas_name, std::uint16_t event_num, bool stim, bool enable_timestamps,
18
- const std::vector<daq_list_initialzer_t>& measurements, std::uint8_t priority=0x00, std::uint8_t prescaler=0x01
19
- ) :
20
- m_name(meas_name), m_event_num(event_num), m_priority(priority), m_prescaler(prescaler), m_stim(stim), m_enable_timestamps(enable_timestamps) {
21
- for (const auto& measurement : measurements) {
22
- auto const& [name, address, ext, dt_name] = measurement;
23
- m_measurements.emplace_back(McObject(name, address, static_cast<std::uint8_t>(ext), 0, dt_name));
22
+ const std::vector<McObject>& get_entries() const {
23
+ return m_entries;
24
+ }
25
+
26
+ std::string dumps() const {
27
+ std::stringstream ss;
28
+ ss << to_binary(m_entries.size());
29
+ for (const auto& entry : m_entries) {
30
+ ss << entry.dumps();
24
31
  }
32
+ return ss.str();
25
33
  }
26
34
 
35
+ std::string to_string() const {
36
+ std::stringstream ss;
37
+ ss << "Odt(entries=[";
38
+ for (std::size_t i = 0; i < m_entries.size(); ++i) {
39
+ ss << ::to_string(m_entries[i]);
40
+ if (i + 1 < m_entries.size()) {
41
+ ss << ", ";
42
+ }
43
+ }
44
+ ss << "])";
45
+ return ss.str();
46
+ }
47
+
48
+ private:
49
+ std::vector<McObject> m_entries;
50
+ };
51
+
52
+ inline std::string to_string(const Odt& odt) {
53
+ return odt.to_string();
54
+ }
55
+
56
+ class DaqListBase {
57
+ public:
58
+ DaqListBase(std::string_view name, std::uint16_t event_num, bool stim, bool enable_timestamps, std::uint8_t priority, std::uint8_t prescaler) :
59
+ m_name(name),
60
+ m_event_num(event_num),
61
+ m_priority(priority),
62
+ m_prescaler(prescaler),
63
+ m_stim(stim),
64
+ m_enable_timestamps(enable_timestamps),
65
+ m_odt_count(0),
66
+ m_total_entries(0),
67
+ m_total_length(0) {
68
+ }
69
+
70
+ virtual ~DaqListBase() = default;
71
+
72
+ virtual std::string dumps() const = 0;
73
+ virtual std::string to_string() const = 0;
74
+
27
75
  bool get_enable_timestamps() const {
28
76
  return m_enable_timestamps;
29
77
  }
@@ -52,10 +100,6 @@ class DaqList {
52
100
  return m_stim;
53
101
  }
54
102
 
55
- const std::vector<McObject>& get_measurements() const {
56
- return m_measurements;
57
- }
58
-
59
103
  const std::vector<Bin>& get_measurements_opt() const {
60
104
  return m_measurements_opt;
61
105
  }
@@ -86,6 +130,10 @@ class DaqList {
86
130
 
87
131
  void set_measurements_opt(const std::vector<Bin>& measurements_opt) {
88
132
  m_measurements_opt = measurements_opt;
133
+ m_header_names.clear();
134
+ m_headers.clear();
135
+ m_flatten_odts.clear();
136
+
89
137
  auto odt_count = 0u;
90
138
  auto total_entries = 0u;
91
139
  auto total_length = 0u;
@@ -93,31 +141,85 @@ class DaqList {
93
141
  odt_count++;
94
142
  std::vector<std::tuple<std::string, std::uint32_t, std::uint8_t, std::uint16_t, std::int16_t>> flatten_odt{};
95
143
  for (const auto& mc_obj : bin.get_entries()) {
96
- for (const auto& component : mc_obj.get_components()) {
97
- m_header_names.emplace_back(component.get_name());
144
+ const auto& components = mc_obj.get_components();
145
+ if (!components.empty()) {
146
+ for (const auto& component : components) {
147
+ m_header_names.emplace_back(component.get_name());
148
+ flatten_odt.emplace_back(
149
+ component.get_name(), component.get_address(), component.get_ext(), component.get_length(),
150
+ component.get_type_index()
151
+ );
152
+ // TYPE_MAP_REV::at may throw if key is invalid; this indicates a programming error upstream.
153
+ m_headers.emplace_back(component.get_name(), TYPE_MAP_REV.at(static_cast<std::uint16_t>(component.get_type_index())));
154
+ total_entries++;
155
+ total_length += component.get_length();
156
+ }
157
+ } else {
158
+ // Treat the McObject itself as an entry when it has no components.
159
+ m_header_names.emplace_back(mc_obj.get_name());
98
160
  flatten_odt.emplace_back(
99
- component.get_name(), component.get_address(), component.get_ext(), component.get_length(),
100
- component.get_type_index()
161
+ mc_obj.get_name(), mc_obj.get_address(), mc_obj.get_ext(), mc_obj.get_length(), mc_obj.get_type_index()
101
162
  );
102
- m_headers.emplace_back(component.get_name(), TYPE_MAP_REV.at(component.get_type_index()));
163
+ m_headers.emplace_back(mc_obj.get_name(), TYPE_MAP_REV.at(static_cast<std::uint16_t>(mc_obj.get_type_index())));
103
164
  total_entries++;
104
- total_length += component.get_length();
165
+ total_length += mc_obj.get_length();
105
166
  }
106
167
  }
107
- m_flatten_odts.emplace_back(flatten_odt);
168
+ m_flatten_odts.emplace_back(std::move(flatten_odt));
108
169
  }
109
- m_odt_count = odt_count;
110
- m_total_entries = total_entries;
111
- m_total_length = total_length;
170
+ m_odt_count = static_cast<std::uint16_t>(odt_count);
171
+ m_total_entries = static_cast<std::uint16_t>(total_entries);
172
+ m_total_length = static_cast<std::uint16_t>(total_length);
112
173
  }
113
174
 
114
- std::string dumps() const {
175
+ protected:
176
+ std::string m_name;
177
+ std::uint16_t m_event_num;
178
+ std::uint8_t m_priority;
179
+ std::uint8_t m_prescaler;
180
+ bool m_stim;
181
+ bool m_enable_timestamps;
182
+ std::vector<Bin> m_measurements_opt;
183
+ std::vector<std::string> m_header_names;
184
+ std::vector<std::tuple<std::string, std::string>> m_headers;
185
+ std::uint16_t m_odt_count;
186
+ std::uint16_t m_total_entries;
187
+ std::uint16_t m_total_length;
188
+ flatten_odts_t m_flatten_odts;
189
+ };
190
+
191
+ class DaqList : public DaqListBase {
192
+ public:
193
+
194
+ using daq_list_initialzer_t = std::tuple<std::string, std::uint32_t, std::uint16_t, std::string>;
195
+
196
+ DaqList(
197
+ std::string_view meas_name, std::uint16_t event_num, bool stim, bool enable_timestamps,
198
+ const std::vector<daq_list_initialzer_t>& measurements, std::uint8_t priority=0x00, std::uint8_t prescaler=0x01
199
+ ) :
200
+ DaqListBase(meas_name, event_num, stim, enable_timestamps, priority, prescaler) {
201
+ for (const auto& measurement : measurements) {
202
+ auto const& [name, address, ext, dt_name] = measurement;
203
+ m_measurements.emplace_back(McObject(name, address, static_cast<std::uint8_t>(ext), 0, dt_name));
204
+ }
205
+ }
206
+
207
+ const std::vector<McObject>& get_measurements() const {
208
+ return m_measurements;
209
+ }
210
+
211
+ std::string dumps() const override {
115
212
  std::stringstream ss;
116
213
 
214
+ std::uint8_t discr=1;
215
+
216
+ ss << to_binary(discr);
117
217
  ss << to_binary(m_name);
118
218
  ss << to_binary(m_event_num);
119
219
  ss << to_binary(m_stim);
120
220
  ss << to_binary(m_enable_timestamps);
221
+ ss << to_binary(m_priority);
222
+ ss << to_binary(m_prescaler);
121
223
 
122
224
  ss << to_binary(m_odt_count);
123
225
  ss << to_binary(m_total_entries);
@@ -138,47 +240,39 @@ class DaqList {
138
240
  for (const auto& hdr_obj : m_header_names) {
139
241
  ss << to_binary(hdr_obj);
140
242
  }
141
- /////
142
- std::size_t odt_size = m_flatten_odts.size();
143
- ss << to_binary(odt_size);
144
- for (const auto& odt : m_flatten_odts) {
145
- ss << to_binary(odt.size());
146
- for (const auto& odt_entry : odt) {
147
- const auto& [name, address, ext, size, type_index] = odt_entry;
148
- ss << to_binary(name);
149
- ss << to_binary(address);
150
- ss << to_binary(ext);
151
- ss << to_binary(size);
152
- ss << to_binary(type_index);
153
- }
154
- }
155
243
  return ss.str();
156
244
  }
157
245
 
158
- std::string to_string() const {
246
+ std::string to_string() const override {
159
247
  std::stringstream ss;
160
-
161
248
  ss << "DaqList(";
162
- ss << "name=\"" << m_name << "\", ";
249
+ ss << "name='" << m_name << "', ";
163
250
  ss << "event_num=" << static_cast<std::uint16_t>(m_event_num) << ", ";
164
251
  ss << "stim=" << bool_to_string(m_stim) << ", ";
165
- ss << "enable_timestamps" << bool_to_string(m_enable_timestamps) << ", ";
166
- ss << "measurements=[\n";
167
- for (const auto& meas : m_measurements) {
168
- ss << ::to_string(meas) << ",\n";
169
- }
170
- ss << "],\n";
171
- ss << "measurements_opt=[\n";
172
- for (const auto& meas : m_measurements_opt) {
173
- ss << ::to_string(meas) << ",\n";
174
- }
175
- ss << "],\n";
176
- ss << "header_names=[\n";
177
- for (const auto& header : m_header_names) {
178
- ss << "\"" << header << "\",";
179
- }
180
- ss << "\n]";
181
- ss << ")";
252
+ ss << "enable_timestamps=" << bool_to_string(m_enable_timestamps) << ", ";
253
+ ss << "priority=" << static_cast<std::uint16_t>(m_priority) << ", ";
254
+ ss << "prescaler=" << static_cast<std::uint16_t>(m_prescaler) << ", ";
255
+ ss << "odt_count=" << static_cast<std::uint16_t>(m_odt_count) << ", ";
256
+ ss << "total_entries=" << static_cast<std::uint16_t>(m_total_entries) << ", ";
257
+ ss << "total_length=" << static_cast<std::uint16_t>(m_total_length) << ", ";
258
+ ss << "measurements=[";
259
+ for (std::size_t i = 0; i < m_measurements.size(); ++i) {
260
+ ss << ::to_string(m_measurements[i]);
261
+ if (i + 1 < m_measurements.size()) ss << ", ";
262
+ }
263
+ ss << "], ";
264
+ ss << "measurements_opt=[";
265
+ for (std::size_t i = 0; i < m_measurements_opt.size(); ++i) {
266
+ ss << ::to_string(m_measurements_opt[i]);
267
+ if (i + 1 < m_measurements_opt.size()) ss << ", ";
268
+ }
269
+ ss << "], ";
270
+ ss << "header_names=[";
271
+ for (std::size_t i = 0; i < m_header_names.size(); ++i) {
272
+ ss << "'" << m_header_names[i] << "'";
273
+ if (i + 1 < m_header_names.size()) ss << ", ";
274
+ }
275
+ ss << "])";
182
276
  return ss.str();
183
277
  }
184
278
 
@@ -186,21 +280,95 @@ class DaqList {
186
280
  }
187
281
 
188
282
  private:
283
+ std::vector<McObject> m_measurements;
284
+ };
189
285
 
190
- std::string m_name;
191
- std::uint16_t m_event_num;
192
- std::uint8_t m_priority;
193
- std::uint8_t m_prescaler;
194
- bool m_stim;
195
- bool m_enable_timestamps;
196
- std::vector<McObject> m_measurements;
197
- std::vector<Bin> m_measurements_opt;
198
- std::vector<std::string> m_header_names;
199
- std::vector<std::tuple<std::string, std::string>> m_headers;
200
- std::uint16_t m_odt_count;
201
- std::uint16_t m_total_entries;
202
- std::uint16_t m_total_length;
203
- flatten_odts_t m_flatten_odts;
286
+ class PredefinedDaqList : public DaqListBase {
287
+ public:
288
+ using odt_initializer_t = std::vector<Odt::odt_entry_initializer_t>;
289
+ using predefined_daq_list_initializer_t = std::vector<odt_initializer_t>;
290
+
291
+ PredefinedDaqList(
292
+ std::string_view name, std::uint16_t event_num, bool stim, bool enable_timestamps,
293
+ const predefined_daq_list_initializer_t& odts, std::uint8_t priority = 0x00, std::uint8_t prescaler = 0x01) :
294
+ DaqListBase(name, event_num, stim, enable_timestamps, priority, prescaler) {
295
+ std::vector<Bin> bins;
296
+ bins.reserve(odts.size());
297
+ for (const auto& odt_init : odts) {
298
+ Bin bin(0);
299
+ std::uint16_t total_length = 0;
300
+ for (const auto& entry : odt_init) {
301
+ const auto& [name, dt_name] = entry;
302
+ // McObject will validate dt_name and set length accordingly.
303
+ McObject obj(name, 0, 0, 0, dt_name);
304
+ total_length = static_cast<std::uint16_t>(total_length + obj.get_length());
305
+ bin.append(obj);
306
+ }
307
+ // Derive Bin size and residual capacity from sum of entry lengths.
308
+ bin.set_size(total_length);
309
+ bin.set_residual_capacity(total_length);
310
+ bins.emplace_back(std::move(bin));
311
+ }
312
+ set_measurements_opt(bins);
313
+ }
314
+
315
+ std::string dumps() const override {
316
+ std::stringstream ss;
317
+
318
+ std::uint8_t discr=2;
319
+
320
+ ss << to_binary(discr);
321
+
322
+ ss << to_binary(m_name);
323
+ ss << to_binary(m_event_num);
324
+ ss << to_binary(m_stim);
325
+ ss << to_binary(m_enable_timestamps);
326
+ ss << to_binary(m_priority);
327
+ ss << to_binary(m_prescaler);
328
+
329
+ ss << to_binary(m_odt_count);
330
+ ss << to_binary(m_total_entries);
331
+ ss << to_binary(m_total_length);
332
+
333
+ std::size_t meas_opt_size = m_measurements_opt.size();
334
+ ss << to_binary(meas_opt_size);
335
+ for (const auto& mc_obj : m_measurements_opt) {
336
+ ss << mc_obj.dumps();
337
+ }
338
+ std::size_t hname_size = m_header_names.size();
339
+ ss << to_binary(hname_size);
340
+ for (const auto& hdr_obj : m_header_names) {
341
+ ss << to_binary(hdr_obj);
342
+ }
343
+ return ss.str();
344
+ }
345
+
346
+ std::string to_string() const override {
347
+ std::stringstream ss;
348
+ ss << "PredefinedDaqList(";
349
+ ss << "name='" << m_name << "', ";
350
+ ss << "event_num=" << static_cast<std::uint16_t>(m_event_num) << ", ";
351
+ ss << "stim=" << bool_to_string(m_stim) << ", ";
352
+ ss << "enable_timestamps=" << bool_to_string(m_enable_timestamps) << ", ";
353
+ ss << "priority=" << static_cast<std::uint16_t>(m_priority) << ", ";
354
+ ss << "prescaler=" << static_cast<std::uint16_t>(m_prescaler) << ", ";
355
+ ss << "odt_count=" << static_cast<std::uint16_t>(m_odt_count) << ", ";
356
+ ss << "total_entries=" << static_cast<std::uint16_t>(m_total_entries) << ", ";
357
+ ss << "total_length=" << static_cast<std::uint16_t>(m_total_length) << ", ";
358
+ ss << "measurements_opt=[";
359
+ for (std::size_t i = 0; i < m_measurements_opt.size(); ++i) {
360
+ ss << ::to_string(m_measurements_opt[i]);
361
+ if (i + 1 < m_measurements_opt.size()) ss << ", ";
362
+ }
363
+ ss << "], ";
364
+ ss << "header_names=[";
365
+ for (std::size_t i = 0; i < m_header_names.size(); ++i) {
366
+ ss << "'" << m_header_names[i] << "'";
367
+ if (i + 1 < m_header_names.size()) ss << ", ";
368
+ }
369
+ ss << "])";
370
+ return ss.str();
371
+ }
204
372
  };
205
373
 
206
374
  #endif // __DAQ_LIST_HPP