SRS-control 0.1.4
Loading...
Searching...
No Matches
StructSerializer.cpp
Go to the documentation of this file.
7#include <algorithm>
8#include <bit>
9#include <bitset>
10#include <concepts>
11#include <cstddef>
12#include <cstdint>
13#include <expected>
14#include <string_view>
15#include <type_traits>
16#include <vector>
17#include <zpp_bits.h>
18
19namespace srs::process
20{
21 namespace
22 {
23 template <class T>
24 auto check_compact_max_size(const T& value, size_t length) -> std::expected<void, std::string_view>
25 {
26 if (value >= 1ULL << length)
27 {
28 return std::unexpected("Serialization: exceeding size limit!");
29 }
30 return {};
31 }
32
33 auto marker_to_compact(const MarkerData& marker_data, internal::MarkerDataCompact& marker_data_compact)
34 -> std::expected<void, std::string_view>
35 {
36 auto is_correct_sizes =
37 check_compact_max_size(marker_data.vmm_id, internal::VMM_ID_BIT_LENGTH)
38 .and_then(
39 [&]
40 {
41 return check_compact_max_size(
42 marker_data.srs_timestamp,
44 });
45 if (!is_correct_sizes)
46 {
47 return std::unexpected(is_correct_sizes.error());
48 }
49 auto timestamp_bits =
50 std::bitset<common::SRS_TIMESTAMP_HIGH_BIT_LENGTH + common::SRS_TIMESTAMP_LOW_BIT_LENGTH>(
51 marker_data.srs_timestamp);
52 auto timestamp_low_bits = common::get_low_bits<common::SRS_TIMESTAMP_LOW_BIT_LENGTH>(timestamp_bits);
53 auto timestamp_high_bits = common::get_high_bits<common::SRS_TIMESTAMP_HIGH_BIT_LENGTH>(timestamp_bits);
54 marker_data_compact.timestamp_low_bits =
55 static_cast<decltype(marker_data_compact.timestamp_low_bits)>(timestamp_low_bits.to_ulong());
56 marker_data_compact.timestamp_high_bits =
57 static_cast<decltype(marker_data_compact.timestamp_high_bits)>(timestamp_high_bits.to_ullong());
58 marker_data_compact.flag = static_cast<decltype(marker_data_compact.flag)>(0);
59 marker_data_compact.vmm_id = static_cast<decltype(marker_data_compact.vmm_id)>(marker_data.vmm_id);
60 return {};
61 }
62
63 auto hit_to_compact(const HitData& hit_data, internal::HitDataCompact& hit_data_compact)
64 -> std::expected<void, std::string_view>
65 {
66 auto is_correct_sizes =
67 check_compact_max_size(hit_data.channel_num, internal::CHANNEL_NUM_BIT_LENGTH)
68 .and_then([&] { return check_compact_max_size(hit_data.bc_id, internal::BC_ID_BIT_LENGTH); })
69 .and_then([&] { return check_compact_max_size(hit_data.adc, internal::ADC_BIT_LENGTH); })
70 .and_then([&] { return check_compact_max_size(hit_data.vmm_id, internal::VMM_ID_BIT_LENGTH); })
71 .and_then([&] { return check_compact_max_size(hit_data.offset, internal::OFFSET_BIT_LENGTH); });
72 if (!is_correct_sizes)
73 {
74 return std::unexpected(is_correct_sizes.error());
75 }
76 hit_data_compact.vmm_id = static_cast<decltype(hit_data_compact.vmm_id)>(hit_data.vmm_id);
77 hit_data_compact.flag = static_cast<decltype(hit_data_compact.flag)>(1);
78 hit_data_compact.adc = static_cast<decltype(hit_data_compact.adc)>(hit_data.adc);
79 hit_data_compact.bc_id = static_cast<decltype(hit_data_compact.bc_id)>(hit_data.bc_id);
80 hit_data_compact.bc_id = common::binary_to_gray(hit_data_compact.bc_id);
81 hit_data_compact.channel_num = static_cast<decltype(hit_data_compact.channel_num)>(hit_data.channel_num);
82 hit_data_compact.is_over_threshold =
83 static_cast<decltype(hit_data_compact.is_over_threshold)>(hit_data.is_over_threshold);
84 hit_data_compact.offset = static_cast<decltype(hit_data_compact.offset)>(hit_data.offset);
85 hit_data_compact.tdc = static_cast<decltype(hit_data_compact.tdc)>(hit_data.tdc);
86 return {};
87 }
88
89 template <class T>
90 requires(std::same_as<std::remove_cvref_t<T>, internal::HitDataCompact> ||
91 std::same_as<std::remove_cvref_t<T>, internal::MarkerDataCompact>)
92 auto compact_to_vector(const T& compact_data, std::vector<char>& output) -> void
93 {
94 auto compact_bitset =
95 std::bitset<sizeof(std::uint64_t) * common::BYTE_BIT_LENGTH>{ std::bit_cast<uint64_t>(compact_data) };
96 output.resize(sizeof(std::uint64_t));
97 auto write_to_output = zpp::bits::out{ output, zpp::bits::endian::network{}, zpp::bits::no_size{} };
98 write_to_output(compact_bitset).or_throw();
99 output.erase(output.begin(), output.begin() + 2);
100 std::ranges::reverse(output);
101 }
102 }; // namespace
103
105 : ConverterTask{ "Struct deserializer", none, n_lines }
106 {
107 output_data_.resize(n_lines);
108 compact_data_buffer_.resize(n_lines);
109 }
110
111 // NOLINTBEGIN
112 auto StructSerializer::convert([[maybe_unused]] const StructData* input,
113 [[maybe_unused]] std::vector<char>& output,
114 std::vector<char>& compact_data_buffer)
115 -> std::expected<std::size_t, std::string_view>
116 {
117 compact_data_buffer.resize(0, 0);
118 auto serialize_to = zpp::bits::out{ output, zpp::bits::endian::network{}, zpp::bits::no_size{} };
119 serialize_to(input->header).or_throw();
120 for (auto hit : input->hit_data)
121 {
122 std::ranges::fill(compact_data_buffer, 0);
123 auto hit_compact = internal::HitDataCompact{};
124 if (auto res = hit_to_compact(hit, hit_compact); !res)
125 {
126 return std::unexpected(res.error());
127 }
128 compact_to_vector(hit_compact, compact_data_buffer);
129 serialize_to(compact_data_buffer_).or_throw();
130 }
131 for (auto marker : input->marker_data)
132 {
133 std::ranges::fill(compact_data_buffer, 0);
134 auto marker_compact = internal::MarkerDataCompact{};
135 if (auto res = marker_to_compact(marker, marker_compact); !res)
136 {
137 return std::unexpected(res.error());
138 }
139 compact_to_vector(marker_compact, compact_data_buffer);
140 serialize_to(compact_data_buffer).or_throw();
141 }
142 return input->marker_data.size() + input->hit_data.size();
143 }
144 // NOLINTEND
145} // namespace srs::process
ConverterTask(std::string_view name, DataConvertOptions prev_convert, std::size_t n_lines=1)
std::vector< std::vector< char > > output_data_
auto convert(const StructData *input, std::vector< char > &output, std::vector< char > &compact_data_buffer) -> std::expected< std::size_t, std::string_view >
std::vector< std::vector< char > > compact_data_buffer_
constexpr auto binary_to_gray(T bin_val)
constexpr auto get_low_bits(const std::bitset< total_size > &bits) -> std::bitset< low_size >
constexpr auto SRS_TIMESTAMP_LOW_BIT_LENGTH
constexpr auto BYTE_BIT_LENGTH
constexpr auto SRS_TIMESTAMP_HIGH_BIT_LENGTH
constexpr auto get_high_bits(const std::bitset< total_size > &bits) -> std::bitset< high_size >
constexpr auto OFFSET_BIT_LENGTH
constexpr auto ADC_BIT_LENGTH
constexpr auto BC_ID_BIT_LENGTH
constexpr auto VMM_ID_BIT_LENGTH
constexpr auto CHANNEL_NUM_BIT_LENGTH