18 throw std::runtime_error(
"ULog: wrong header");
23 throw std::runtime_error(
"ULog: error loading definitions");
35 datastream.
read(message, message_header.msg_size);
36 message[message_header.msg_size] =
'\0';
38 switch (message_header.msg_type)
43 sub.
multi_id = *
reinterpret_cast<uint8_t*
>(message);
44 sub.
msg_id = *
reinterpret_cast<uint16_t*
>(message + 1);
46 sub.
message_name.assign(message, message_header.msg_size - 3);
65 printf(
"REMOVE_LOGGED_MSG\n");
67 uint16_t msg_id = *
reinterpret_cast<uint16_t*
>(message);
72 uint16_t msg_id = *
reinterpret_cast<uint16_t*
>(message);
87 msg.level =
static_cast<char>(message[0]);
88 message +=
sizeof(char);
89 msg.timestamp = *
reinterpret_cast<uint64_t*
>(message);
90 message +=
sizeof(uint64_t);
91 msg.msg.assign(message, message_header.msg_size - 9);
112 if (prev_param.name == new_param.
name)
130 size_t other_fields_count = 0;
137 other_fields_count++;
145 ts_name += std::string(buff);
161 char* message,
size_t* index)
168 message +=
field.array_size;
172 bool timestamp_done =
false;
173 for (
int array_pos = 0; array_pos <
field.array_size; array_pos++)
175 if (*index ==
format->timestamp_idx && !timestamp_done)
177 timestamp_done =
true;
178 uint64_t time_val = *
reinterpret_cast<uint64_t*
>(message);
180 message +=
sizeof(uint64_t);
186 value =
static_cast<double>(*
reinterpret_cast<uint8_t*
>(message));
191 value =
static_cast<double>(*
reinterpret_cast<int8_t*
>(message));
196 value =
static_cast<double>(*
reinterpret_cast<uint16_t*
>(message));
201 value =
static_cast<double>(*
reinterpret_cast<int16_t*
>(message));
206 value =
static_cast<double>(*
reinterpret_cast<uint32_t*
>(message));
211 value =
static_cast<double>(*
reinterpret_cast<int32_t*
>(message));
216 value =
static_cast<double>(*
reinterpret_cast<uint64_t*
>(message));
221 value =
static_cast<double>(*
reinterpret_cast<int64_t*
>(message));
226 value =
static_cast<double>(*
reinterpret_cast<float*
>(message));
231 value = (*
reinterpret_cast<double*
>(message));
236 value =
static_cast<double>(*
reinterpret_cast<char*
>(message));
241 value =
static_cast<double>(*
reinterpret_cast<bool*
>(message));
248 message +=
sizeof(uint64_t);
257 timeseries.
data[(*index)++].second.push_back(value);
289 datastream.
read(message, msg_size);
290 message[msg_size] = 0;
321 std::vector<StringView> splitted_strings;
322 splitted_strings.reserve(4);
325 while (pos < strToSplit.size())
327 size_t new_pos = strToSplit.find_first_of(delimeter, pos);
328 if (new_pos == std::string::npos)
330 new_pos = strToSplit.size();
332 StringView sv = { &strToSplit.data()[pos], new_pos - pos };
333 splitted_strings.push_back(sv);
336 return splitted_strings;
342 datastream.
read((
char*)&msg_header,
sizeof(msg_header));
360 return memcmp(magic, msg_header.magic, 7) == 0;
380 switch (message_header.msg_type)
390 if (!
readFormat(datastream, message_header.msg_size))
411 if (!
readInfo(datastream, message_header.msg_size))
419 datastream.
offset += message_header.msg_size;
423 printf(
"unknown log definition type %i, size %i (offset %i)\n",
424 (
int)message_header.msg_type, (
int)message_header.msg_size,
426 datastream.
offset += message_header.msg_size;
437 printf(
"unsupported message length for FLAG_BITS message (%i)", msg_size);
443 datastream.
read((
char*)message, msg_size);
446 uint8_t* incompat_flags = message + 8;
449 bool contains_appended_data =
451 bool has_unknown_incompat_bits =
false;
453 if (incompat_flags[0] & ~0x1)
455 has_unknown_incompat_bits =
true;
458 for (
int i = 1; i < 8; ++i)
460 if (incompat_flags[i])
462 has_unknown_incompat_bits =
true;
466 if (has_unknown_incompat_bits)
468 printf(
"Log contains unknown incompat bits set. Refusing to parse");
472 if (contains_appended_data)
474 uint64_t appended_offsets[3];
475 memcpy(appended_offsets, message + 16,
sizeof(appended_offsets));
477 if (appended_offsets[0] > 0)
490 static int count = 0;
494 datastream.
read(buffer, msg_size);
495 buffer[msg_size] = 0;
505 if (pos == std::string::npos)
511 std::string fields =
str_format.substr(pos + 1);
515 format.fields.reserve(fields_split.size());
516 for (
auto field_section : fields_split)
520 auto field_name = field_pair.at(1);
590 while (!helper.ends_with(
"["))
592 helper.remove_suffix(1);
595 helper.remove_suffix(1);
596 field.other_type_ID = helper.to_string();
609 field.array_size = 1;
630 field.field_name = field_name.to_string();
635 if (
format.timestamp_idx < 0)
647 template <
typename T>
650 std::stringstream stream;
651 stream <<
"0x" << std::setfill(
'0') << std::setw(
sizeof(T) * 2) << std::hex << i;
659 datastream.
read((
char*)message, msg_size);
665 uint8_t key_len = message[0];
667 std::string raw_key((
char*)message, key_len);
669 std::string raw_value((
char*)message, msg_size - key_len - 1);
673 std::string key = key_parts[1].to_string();
676 if (key_parts[0].starts_with(
"char["))
682 bool val = *
reinterpret_cast<const bool*
>(raw_value.data());
683 value = std::to_string(val);
685 else if (key_parts[0] ==
StringView(
"uint8_t"))
687 uint8_t val = *
reinterpret_cast<const uint8_t*
>(raw_value.data());
688 value = std::to_string(val);
690 else if (key_parts[0] ==
StringView(
"int8_t"))
692 int8_t val = *
reinterpret_cast<const int8_t*
>(raw_value.data());
693 value = std::to_string(val);
695 else if (key_parts[0] ==
StringView(
"uint16_t"))
697 uint16_t val = *
reinterpret_cast<const uint16_t*
>(raw_value.data());
698 value = std::to_string(val);
700 else if (key_parts[0] ==
StringView(
"int16_t"))
702 int16_t val = *
reinterpret_cast<const int16_t*
>(raw_value.data());
703 value = std::to_string(val);
705 else if (key_parts[0] ==
StringView(
"uint32_t"))
707 uint32_t val = *
reinterpret_cast<const uint32_t*
>(raw_value.data());
708 if (key_parts[1].starts_with(
"ver_") && key_parts[1].ends_with(
"_release"))
714 value = std::to_string(val);
717 else if (key_parts[0] ==
StringView(
"int32_t"))
719 int32_t val = *
reinterpret_cast<const int32_t*
>(raw_value.data());
720 value = std::to_string(val);
724 float val = *
reinterpret_cast<const float*
>(raw_value.data());
725 value = std::to_string(val);
727 else if (key_parts[0] ==
StringView(
"double"))
729 double val = *
reinterpret_cast<const double*
>(raw_value.data());
730 value = std::to_string(val);
732 else if (key_parts[0] ==
StringView(
"uint64_t"))
734 uint64_t val = *
reinterpret_cast<const uint64_t*
>(raw_value.data());
735 value = std::to_string(val);
737 else if (key_parts[0] ==
StringView(
"int64_t"))
739 int64_t val = *
reinterpret_cast<const int64_t*
>(raw_value.data());
740 value = std::to_string(val);
743 _info.insert({ key, value });
751 datastream.
read((
char*)message, msg_size);
758 param.readFromBuffer(message);
765 std::function<
void(
const Format&
format,
const std::string& prefix)> appendVector;
769 appendVector = [&appendVector,
this, ×eries](
const Format&
format,
770 const std::string& prefix) {
779 std::string new_prefix = prefix +
"/" +
field.field_name;
780 for (
int i = 0; i <
field.array_size; i++)
782 std::string array_suffix =
"";
783 if (
field.array_size > 1)
791 timeseries.
data.push_back({ new_prefix + array_suffix, std::vector<double>() });
795 appendVector(this->
_formats.at(
field.other_type_ID), new_prefix + array_suffix);
801 appendVector(*
format, {});
807 const uint8_t key_len =
static_cast<uint8_t
>(message[0]);
809 std::string key((
char*)message, key_len);
811 const size_t pos = key.find(
' ');
812 if (pos == std::string::npos)
817 const std::string
type = key.substr(0, pos);
818 this->
name = key.substr(pos + 1);
821 if (
type ==
"int32_t")
823 this->
value.val_int = *
reinterpret_cast<const int32_t*
>(message);
826 else if (type ==
"float")
828 this->
value.val_real = *
reinterpret_cast<const float*
>(message);
833 throw std::runtime_error(
"unknown parameter type");