42 using VarNumber = std::variant<bool, char, int8_t, uint8_t, int16_t, uint16_t, int32_t,
43 uint32_t, int64_t, uint64_t, float,
double>;
47 const uint8_t*
data =
nullptr;
108 const std::string&) {};
116 template <
typename NumberCallback,
typename CustomCallback = decltype(NullCustomCallback)>
117 bool ParseSnapshot(
const Schema& schema, SnapshotView snapshot,
118 const NumberCallback& callback_number,
125 template <
typename T>
129 const auto N =
sizeof(T);
130 std::memcpy(&
var, buffer.
data, N);
134 throw std::runtime_error(
"Buffer overflow");
145 return Deserialize<bool>(buffer);
147 return Deserialize<char>(buffer);
150 return Deserialize<int8_t>(buffer);
152 return Deserialize<uint8_t>(buffer);
155 return Deserialize<int16_t>(buffer);
157 return Deserialize<uint16_t>(buffer);
160 return Deserialize<int32_t>(buffer);
162 return Deserialize<uint32_t>(buffer);
165 return Deserialize<int64_t>(buffer);
167 return Deserialize<uint64_t>(buffer);
170 return Deserialize<float>(buffer);
172 return Deserialize<double>(buffer);
175 return double(std::numeric_limits<double>::quiet_NaN());
182 const uint8_t&
byte = mask.
data[index >> 3];
183 return 0 != (
byte & uint8_t(1 << (index % 8)));
189 const std::hash<std::string> str_hasher;
190 const std::hash<BasicType> type_hasher;
191 const std::hash<bool> bool_hasher;
192 const std::hash<uint32_t> uint_hasher;
194 auto combine = [&hash](
const auto& hasher,
const auto& val) {
195 hash ^= hasher(val) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
218 auto trimString = [](std::string& str) {
219 while (!str.empty() && (str.back() ==
' ' || str.back() ==
'\r'))
223 while (!str.empty() && (str.front() ==
' ' || str.front() ==
'\r'))
229 std::istringstream ss(txt);
232 uint64_t declared_schema = 0;
234 std::vector<TypeField>* field_vector = &schema.
fields;
236 while (std::getline(ss, line))
243 if (line.find(
"==============================") != std::string::npos)
246 std::getline(ss, line);
247 auto msg_pos = line.find(
"MSG: ");
248 if (msg_pos == std::string::npos)
250 throw std::runtime_error(
"Expecting \"MSG: \" at the beginning of line: " + line);
259 auto space_pos = line.find(
' ');
260 if (space_pos == std::string::npos)
262 throw std::runtime_error(
"Unexpected line: " + line);
264 if (line.find(
"### ") == 0)
266 space_pos = line.find(
' ', 5);
269 std::string str_left = line.substr(0, space_pos);
270 std::string str_right = line.substr(space_pos + 1, line.size() - (space_pos + 1));
271 trimString(str_left);
272 trimString(str_right);
274 const std::string* str_type = &str_left;
275 const std::string* str_name = &str_right;
277 if (str_left ==
"### version:" || str_left ==
"__version__:")
281 if (str_left ==
"### hash:" || str_left ==
"__hash__:")
284 declared_schema = std::stoull(str_right);
288 if (str_left ==
"### channel_name:" || str_left ==
"__channel_name__:")
298 static const std::array<std::string, TypesCount> kNamesNew = {
299 "bool",
"char",
"int8",
"uint8",
"int16",
"uint16",
"int32",
300 "uint32",
"int64",
"uint64",
"float32",
"float64",
"other"};
302 static const std::array<std::string, TypesCount> kNamesOld = {
303 "BOOL",
"CHAR",
"INT8",
"UINT8",
"INT16",
"UINT16",
"INT32",
304 "UINT32",
"INT64",
"UINT64",
"FLOAT",
"DOUBLE",
"OTHER"};
308 if (str_left.find(kNamesNew[i]) == 0)
313 if (str_right.find(kNamesOld[i]) == 0)
321 auto offset = str_type->find_first_of(
" [");
324 field.type_name = kNamesNew[
static_cast<size_t>(
field.type)];
327 field.type_name = str_type->substr(0, offset);
330 if (offset != std::string::npos && str_type->at(offset) ==
'[')
332 field.is_vector =
true;
333 auto pos = str_type->find(
']', offset);
334 if (pos != offset + 1)
337 std::string number_string = line.substr(offset + 1, pos - offset - 1);
338 field.array_size =
static_cast<uint16_t
>(std::stoi(number_string));
342 field.field_name = *str_name;
343 trimString(
field.field_name);
346 if (field_vector == &schema.
fields)
351 field_vector->push_back(
field);
353 if (declared_schema != 0 && declared_schema != schema.
hash)
361 template <
typename NumberCallback>
363 const std::map<std::string, FieldsVector>& types_list,
365 const NumberCallback& callback_number,
366 const std::string& prefix)
369 [[maybe_unused]] uint32_t vect_size =
field.array_size;
373 vect_size = Deserialize<uint32_t>(buffer);
376 auto new_prefix = (prefix.empty()) ?
field.field_name : (prefix +
"/" +
field.field_name);
378 auto doParse = [&](
const std::string& var_name)
383 callback_number(var_name,
var);
387 for(
const auto& sub_field: fields)
400 for(uint32_t a=0; a < vect_size; a++)
402 const auto& name = new_prefix +
"[" + std::to_string(a) +
"]";
410 template <
typename NumberCallback,
typename CustomCallback>
412 const NumberCallback& callback_number,
413 const CustomCallback& callback_custom)
421 for (
size_t i = 0; i < schema.
fields.size(); i++)