13 #include <unordered_map>
45 using VarNumber = std::variant<bool, char, int8_t, uint8_t, int16_t, uint16_t, int32_t,
46 uint32_t, int64_t, uint64_t, float,
double>;
50 const uint8_t*
data =
nullptr;
111 const std::string&) {};
119 template <
typename NumberCallback,
typename CustomCallback = decltype(NullCustomCallback)>
120 bool ParseSnapshot(
const Schema& schema, SnapshotView snapshot,
121 const NumberCallback& callback_number,
128 template <
typename T>
132 const auto N =
sizeof(T);
133 std::memcpy(&
var, buffer.
data, N);
137 throw std::runtime_error(
"Buffer overflow");
148 return Deserialize<bool>(buffer);
150 return Deserialize<char>(buffer);
153 return Deserialize<int8_t>(buffer);
155 return Deserialize<uint8_t>(buffer);
158 return Deserialize<int16_t>(buffer);
160 return Deserialize<uint16_t>(buffer);
163 return Deserialize<int32_t>(buffer);
165 return Deserialize<uint32_t>(buffer);
168 return Deserialize<int64_t>(buffer);
170 return Deserialize<uint64_t>(buffer);
173 return Deserialize<float>(buffer);
175 return Deserialize<double>(buffer);
178 return double(std::numeric_limits<double>::quiet_NaN());
185 const uint8_t&
byte = mask.
data[index >> 3];
186 return 0 != (
byte & uint8_t(1 << (index % 8)));
192 const std::hash<std::string> str_hasher;
193 const std::hash<BasicType> type_hasher;
194 const std::hash<bool> bool_hasher;
195 const std::hash<uint32_t> uint_hasher;
197 auto combine = [&hash](
const auto& hasher,
const auto& val) {
198 hash ^= hasher(val) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
221 auto trimString = [](std::string& str) {
222 while (str.back() ==
' ' || str.back() ==
'\r')
226 while (str.front() ==
' ' || str.front() ==
'\r')
232 std::istringstream ss(txt);
235 uint64_t declared_schema = 0;
237 std::vector<TypeField>* field_vector = &schema.
fields;
239 while (std::getline(ss, line))
246 if (line.find(
"==============================") != std::string::npos)
249 std::getline(ss, line);
250 auto msg_pos = line.find(
"MSG: ");
251 if (msg_pos == std::string::npos)
253 throw std::runtime_error(
"Expecting \"MSG: \" at the beginning of line: " + line);
262 auto space_pos = line.find(
' ');
263 if (space_pos == std::string::npos)
265 throw std::runtime_error(
"Unexpected line: " + line);
267 if (line.find(
"### ") == 0)
269 space_pos = line.find(
' ', 5);
272 std::string str_left = line.substr(0, space_pos);
273 std::string str_right = line.substr(space_pos + 1, line.size() - (space_pos + 1));
274 trimString(str_left);
275 trimString(str_right);
277 const std::string* str_type = &str_left;
278 const std::string* str_name = &str_right;
280 if (str_left ==
"### version:" || str_left ==
"__version__:")
284 if (str_left ==
"### hash:" || str_left ==
"__hash__:")
287 declared_schema = std::stoul(str_right);
291 if (str_left ==
"### channel_name:" || str_left ==
"__channel_name__:")
301 static const std::array<std::string, TypesCount> kNamesNew = {
302 "bool",
"char",
"int8",
"uint8",
"int16",
"uint16",
"int32",
303 "uint32",
"int64",
"uint64",
"float32",
"float64",
"other"};
305 static const std::array<std::string, TypesCount> kNamesOld = {
306 "BOOL",
"CHAR",
"INT8",
"UINT8",
"INT16",
"UINT16",
"INT32",
307 "UINT32",
"INT64",
"UINT64",
"FLOAT",
"DOUBLE",
"OTHER"};
311 if (str_left.find(kNamesNew[i]) == 0)
316 if (str_right.find(kNamesOld[i]) == 0)
324 auto offset = str_type->find_first_of(
" [");
327 field.type_name = kNamesNew[
static_cast<size_t>(
field.type)];
330 field.type_name = str_type->substr(0, offset);
333 if (offset != std::string::npos && str_type->at(offset) ==
'[')
335 field.is_vector =
true;
336 auto pos = str_type->find(
']', offset);
337 if (pos != offset + 1)
340 std::string number_string = line.substr(offset + 1, pos - offset - 1);
341 field.array_size =
static_cast<uint16_t
>(std::stoi(number_string));
345 field.field_name = *str_name;
346 trimString(
field.field_name);
349 if (field_vector == &schema.
fields)
354 field_vector->push_back(
field);
356 if (declared_schema != 0 && declared_schema != schema.
hash)
358 throw std::runtime_error(
"Error in hash calculation");
363 template <
typename NumberCallback>
365 const std::map<std::string, FieldsVector>& types_list,
367 const NumberCallback& callback_number,
368 const std::string& prefix)
371 [[maybe_unused]] uint32_t vect_size =
field.array_size;
375 vect_size = Deserialize<uint32_t>(buffer);
378 auto new_prefix = (prefix.empty()) ?
field.field_name : (prefix +
"/" +
field.field_name);
380 auto doParse = [&](
const std::string& var_name)
385 callback_number(var_name,
var);
389 for(
const auto& sub_field: fields)
402 for(uint32_t a=0; a < vect_size; a++)
404 const auto& name = new_prefix +
"[" + std::to_string(a) +
"]";
412 template <
typename NumberCallback,
typename CustomCallback>
414 const NumberCallback& callback_number,
415 const CustomCallback& callback_custom)
423 for (
size_t i = 0; i < schema.
fields.size(); i++)