ulog_parser.cpp
Go to the documentation of this file.
1 #include "ulog_parser.h"
2 #include "ulog_messages.h"
3 
4 #include <string.h>
5 #include <iosfwd>
6 #include <sstream>
7 #include <iomanip>
8 #include <QDebug>
9 
10 using ios = std::ios;
11 
12 ULogParser::ULogParser(DataStream& datastream) : _file_start_time(0)
13 {
14  bool ret = readFileHeader(datastream);
15 
16  if (!ret)
17  {
18  throw std::runtime_error("ULog: wrong header");
19  }
20 
21  if (!readFileDefinitions(datastream))
22  {
23  throw std::runtime_error("ULog: error loading definitions");
24  }
25 
26  datastream.offset = _data_section_start;
27 
28  while (datastream)
29  {
30  ulog_message_header_s message_header;
31  datastream.read((char*)&message_header, ULOG_MSG_HEADER_LEN);
32 
33  _read_buffer.reserve(message_header.msg_size + 1);
34  char* message = (char*)_read_buffer.data();
35  datastream.read(message, message_header.msg_size);
36  message[message_header.msg_size] = '\0';
37 
38  switch (message_header.msg_type)
39  {
41  Subscription sub;
42 
43  sub.multi_id = *reinterpret_cast<uint8_t*>(message);
44  sub.msg_id = *reinterpret_cast<uint16_t*>(message + 1);
45  message += 3;
46  sub.message_name.assign(message, message_header.msg_size - 3);
47 
48  const auto it = _formats.find(sub.message_name);
49  if (it != _formats.end())
50  {
51  sub.format = &it->second;
52  }
53  _subscriptions.insert({ sub.msg_id, sub });
54 
55  if (sub.multi_id > 0)
56  {
58  }
59 
60  // printf("ADD_LOGGED_MSG: %d %d %s\n", sub.msg_id, sub.multi_id,
61  // sub.message_name.c_str() ); std::cout << std::endl;
62  }
63  break;
65  printf("REMOVE_LOGGED_MSG\n");
66  {
67  uint16_t msg_id = *reinterpret_cast<uint16_t*>(message);
68  _subscriptions.erase(msg_id);
69  }
70  break;
71  case (int)ULogMessageType::DATA: {
72  uint16_t msg_id = *reinterpret_cast<uint16_t*>(message);
73  message += 2;
74  auto sub_it = _subscriptions.find(msg_id);
75  if (sub_it == _subscriptions.end())
76  {
77  continue;
78  }
79  const Subscription& sub = sub_it->second;
80 
81  parseDataMessage(sub, message);
82  }
83  break;
84 
85  case (int)ULogMessageType::LOGGING: {
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);
92  // printf("LOG %c (%ld): %s\n", msg.level, msg.timestamp, msg.msg.c_str() );
93  _message_logs.push_back(std::move(msg));
94  }
95  break;
96  case (int)ULogMessageType::SYNC: // printf("SYNC\n" );
97  break;
98  case (int)ULogMessageType::DROPOUT: // printf("DROPOUT\n" );
99  break;
100  case (int)ULogMessageType::INFO: // printf("INFO\n" );
101  break;
102  case (int)ULogMessageType::INFO_MULTIPLE: // printf("INFO_MULTIPLE\n" );
103  break;
104  case (int)ULogMessageType::PARAMETER_DEFAULT: // printf("PARAMETER_DEFAULT\n" );
105  break;
106  case (int)ULogMessageType::PARAMETER:
107  Parameter new_param;
108  new_param.readFromBuffer(message);
109  bool found = false;
110  for (auto& prev_param : _parameters)
111  {
112  if (prev_param.name == new_param.name)
113  {
114  prev_param = std::move(new_param);
115  found = true;
116  break;
117  }
118  }
119  if (!found)
120  {
121  _parameters.push_back(new_param);
122  }
123  break;
124  }
125  }
126 }
127 
129 {
130  size_t other_fields_count = 0;
131  std::string ts_name = sub.message_name;
132 
133  for (const auto& field : sub.format->fields)
134  {
135  if (field.type == OTHER)
136  {
137  other_fields_count++;
138  }
139  }
140 
141  if (_message_name_with_multi_id.count(ts_name) > 0)
142  {
143  char buff[16];
144  sprintf(buff, ".%02d", sub.multi_id);
145  ts_name += std::string(buff);
146  }
147 
148  // get the timeseries or create if if it doesn't exist
149  auto ts_it = _timeseries.find(ts_name);
150  if (ts_it == _timeseries.end())
151  {
152  ts_it = _timeseries.insert({ ts_name, createTimeseries(sub.format) }).first;
153  }
154  Timeseries& timeseries = ts_it->second;
155 
156  size_t index = 0;
157  parseSimpleDataMessage(timeseries, sub.format, message, &index);
158 }
159 
161  char* message, size_t* index)
162 {
163  for (const auto& field : format->fields)
164  {
165  // skip _padding messages which are one byte in size
166  if (StringView(field.field_name).starts_with("_padding"))
167  {
168  message += field.array_size;
169  continue;
170  }
171 
172  bool timestamp_done = false;
173  for (int array_pos = 0; array_pos < field.array_size; array_pos++)
174  {
175  if (*index == format->timestamp_idx && !timestamp_done)
176  {
177  timestamp_done = true;
178  uint64_t time_val = *reinterpret_cast<uint64_t*>(message);
179  timeseries.timestamps.push_back(time_val);
180  message += sizeof(uint64_t);
181  }
182  double value = 0;
183  switch (field.type)
184  {
185  case UINT8: {
186  value = static_cast<double>(*reinterpret_cast<uint8_t*>(message));
187  message += 1;
188  }
189  break;
190  case INT8: {
191  value = static_cast<double>(*reinterpret_cast<int8_t*>(message));
192  message += 1;
193  }
194  break;
195  case UINT16: {
196  value = static_cast<double>(*reinterpret_cast<uint16_t*>(message));
197  message += 2;
198  }
199  break;
200  case INT16: {
201  value = static_cast<double>(*reinterpret_cast<int16_t*>(message));
202  message += 2;
203  }
204  break;
205  case UINT32: {
206  value = static_cast<double>(*reinterpret_cast<uint32_t*>(message));
207  message += 4;
208  }
209  break;
210  case INT32: {
211  value = static_cast<double>(*reinterpret_cast<int32_t*>(message));
212  message += 4;
213  }
214  break;
215  case UINT64: {
216  value = static_cast<double>(*reinterpret_cast<uint64_t*>(message));
217  message += 8;
218  }
219  break;
220  case INT64: {
221  value = static_cast<double>(*reinterpret_cast<int64_t*>(message));
222  message += 8;
223  }
224  break;
225  case FLOAT: {
226  value = static_cast<double>(*reinterpret_cast<float*>(message));
227  message += 4;
228  }
229  break;
230  case DOUBLE: {
231  value = (*reinterpret_cast<double*>(message));
232  message += 8;
233  }
234  break;
235  case CHAR: {
236  value = static_cast<double>(*reinterpret_cast<char*>(message));
237  message += 1;
238  }
239  break;
240  case BOOL: {
241  value = static_cast<double>(*reinterpret_cast<bool*>(message));
242  message += 1;
243  }
244  break;
245  case OTHER: {
246  // recursion!!!
247  auto child_format = _formats.at(field.other_type_ID);
248  message += sizeof(uint64_t); // skip timestamp
249  message = parseSimpleDataMessage(timeseries, &child_format, message, index);
250  }
251  break;
252 
253  } // end switch
254 
255  if (field.type != OTHER)
256  {
257  timeseries.data[(*index)++].second.push_back(value);
258  }
259  } // end for
260  }
261  return message;
262 }
263 
264 const std::map<std::string, ULogParser::Timeseries>& ULogParser::getTimeseriesMap() const
265 {
266  return _timeseries;
267 }
268 
269 const std::vector<ULogParser::Parameter>& ULogParser::getParameters() const
270 {
271  return _parameters;
272 }
273 
274 const std::map<std::string, std::string>& ULogParser::getInfo() const
275 {
276  return _info;
277 }
278 
279 const std::vector<ULogParser::MessageLog>& ULogParser::getLogs() const
280 {
281  return _message_logs;
282 }
283 
284 bool ULogParser::readSubscription(DataStream& datastream, uint16_t msg_size)
285 {
286  _read_buffer.reserve(msg_size + 1);
287  char* message = (char*)_read_buffer.data();
288 
289  datastream.read(message, msg_size);
290  message[msg_size] = 0;
291 
292  if (!datastream)
293  {
294  return false;
295  }
296 
297  return true;
298 }
299 
301 {
302  size_t count = 0;
303  for (const auto& field : format.fields)
304  {
305  if (field.type == OTHER)
306  {
307  // recursion!
308  count += fieldsCount(_formats.at(field.other_type_ID));
309  }
310  else
311  {
312  count += size_t(field.array_size);
313  }
314  }
315  return count;
316 }
317 
318 std::vector<StringView> ULogParser::splitString(const StringView& strToSplit,
319  char delimeter)
320 {
321  std::vector<StringView> splitted_strings;
322  splitted_strings.reserve(4);
323 
324  size_t pos = 0;
325  while (pos < strToSplit.size())
326  {
327  size_t new_pos = strToSplit.find_first_of(delimeter, pos);
328  if (new_pos == std::string::npos)
329  {
330  new_pos = strToSplit.size();
331  }
332  StringView sv = { &strToSplit.data()[pos], new_pos - pos };
333  splitted_strings.push_back(sv);
334  pos = new_pos + 1;
335  }
336  return splitted_strings;
337 }
338 
340 {
341  ulog_file_header_s msg_header;
342  datastream.read((char*)&msg_header, sizeof(msg_header));
343 
344  if (!datastream)
345  {
346  return false;
347  }
348 
349  _file_start_time = msg_header.timestamp;
350 
351  // verify it's an ULog file
352  char magic[8];
353  magic[0] = 'U';
354  magic[1] = 'L';
355  magic[2] = 'o';
356  magic[3] = 'g';
357  magic[4] = 0x01;
358  magic[5] = 0x12;
359  magic[6] = 0x35;
360  return memcmp(magic, msg_header.magic, 7) == 0;
361 }
362 
364 {
365  ulog_message_header_s message_header;
366 
367  while (true)
368  {
369  // qDebug() <<"\noffset before" << datastream.offset;
370  datastream.read((char*)&message_header, ULOG_MSG_HEADER_LEN);
371  // qDebug() <<"msg_size" << message_header.msg_size;
372  // qDebug() <<"type" << char(message_header.msg_type);
373  // qDebug() <<"offset after" << datastream.offset;
374 
375  if (!datastream)
376  {
377  return false;
378  }
379 
380  switch (message_header.msg_type)
381  {
382  case (int)ULogMessageType::FLAG_BITS:
383  if (!readFlagBits(datastream, message_header.msg_size))
384  {
385  return false;
386  }
387  break;
388 
389  case (int)ULogMessageType::FORMAT:
390  if (!readFormat(datastream, message_header.msg_size))
391  {
392  return false;
393  }
394 
395  break;
396 
397  case (int)ULogMessageType::PARAMETER:
398  if (!readParameter(datastream, message_header.msg_size))
399  {
400  return false;
401  }
402 
403  break;
404 
407  return true;
408  }
409 
410  case (int)ULogMessageType::INFO: {
411  if (!readInfo(datastream, message_header.msg_size))
412  {
413  return false;
414  }
415  }
416  break;
417  case (int)ULogMessageType::INFO_MULTIPLE: // skip
418  case (int)ULogMessageType::PARAMETER_DEFAULT: // skip
419  datastream.offset += message_header.msg_size;
420  break;
421 
422  default:
423  printf("unknown log definition type %i, size %i (offset %i)\n",
424  (int)message_header.msg_type, (int)message_header.msg_size,
425  (int)datastream.offset);
426  datastream.offset += message_header.msg_size;
427  break;
428  }
429  }
430  return true;
431 }
432 
433 bool ULogParser::readFlagBits(DataStream& datastream, uint16_t msg_size)
434 {
435  if (msg_size != 40)
436  {
437  printf("unsupported message length for FLAG_BITS message (%i)", msg_size);
438  return false;
439  }
440 
441  _read_buffer.reserve(msg_size);
442  uint8_t* message = (uint8_t*)_read_buffer.data();
443  datastream.read((char*)message, msg_size);
444 
445  // uint8_t *compat_flags = message;
446  uint8_t* incompat_flags = message + 8;
447 
448  // handle & validate the flags
449  bool contains_appended_data =
450  incompat_flags[0] & ULOG_INCOMPAT_FLAG0_DATA_APPENDED_MASK;
451  bool has_unknown_incompat_bits = false;
452 
453  if (incompat_flags[0] & ~0x1)
454  {
455  has_unknown_incompat_bits = true;
456  }
457 
458  for (int i = 1; i < 8; ++i)
459  {
460  if (incompat_flags[i])
461  {
462  has_unknown_incompat_bits = true;
463  }
464  }
465 
466  if (has_unknown_incompat_bits)
467  {
468  printf("Log contains unknown incompat bits set. Refusing to parse");
469  return false;
470  }
471 
472  if (contains_appended_data)
473  {
474  uint64_t appended_offsets[3];
475  memcpy(appended_offsets, message + 16, sizeof(appended_offsets));
476 
477  if (appended_offsets[0] > 0)
478  {
479  // the appended data is currently only used for hardfault dumps, so it's safe to
480  // ignore it.
481  // LOG_INFO("Log contains appended data. Replay will ignore this data" );
482  _read_until_file_position = appended_offsets[0];
483  }
484  }
485  return true;
486 }
487 
488 bool ULogParser::readFormat(DataStream& datastream, uint16_t msg_size)
489 {
490  static int count = 0;
491 
492  _read_buffer.reserve(msg_size + 1);
493  char* buffer = (char*)_read_buffer.data();
494  datastream.read(buffer, msg_size);
495  buffer[msg_size] = 0;
496 
497  if (!datastream)
498  {
499  return false;
500  }
501 
502  std::string str_format(buffer);
503  size_t pos = str_format.find(':');
504 
505  if (pos == std::string::npos)
506  {
507  return false;
508  }
509 
510  std::string name = str_format.substr(0, pos);
511  std::string fields = str_format.substr(pos + 1);
512 
513  Format format;
514  auto fields_split = splitString(fields, ';');
515  format.fields.reserve(fields_split.size());
516  for (auto field_section : fields_split)
517  {
518  auto field_pair = splitString(field_section, ' ');
519  auto field_type = field_pair.at(0);
520  auto field_name = field_pair.at(1);
521 
522  Field field;
523  if (field_type.starts_with("int8_t"))
524  {
525  field.type = INT8;
526  field_type.remove_prefix(6);
527  }
528  else if (field_type.starts_with("int16_t"))
529  {
530  field.type = INT16;
531  field_type.remove_prefix(7);
532  }
533  else if (field_type.starts_with("int32_t"))
534  {
535  field.type = INT32;
536  field_type.remove_prefix(7);
537  }
538  else if (field_type.starts_with("int64_t"))
539  {
540  field.type = INT64;
541  field_type.remove_prefix(7);
542  }
543  else if (field_type.starts_with("uint8_t"))
544  {
545  field.type = UINT8;
546  field_type.remove_prefix(7);
547  }
548  else if (field_type.starts_with("uint16_t"))
549  {
550  field.type = UINT16;
551  field_type.remove_prefix(8);
552  }
553  else if (field_type.starts_with("uint32_t"))
554  {
555  field.type = UINT32;
556  field_type.remove_prefix(8);
557  }
558  else if (field_type.starts_with("uint64_t"))
559  {
560  field.type = UINT64;
561  field_type.remove_prefix(8);
562  }
563  else if (field_type.starts_with("double"))
564  {
565  field.type = DOUBLE;
566  field_type.remove_prefix(6);
567  }
568  else if (field_type.starts_with("float"))
569  {
570  field.type = FLOAT;
571  field_type.remove_prefix(5);
572  }
573  else if (field_type.starts_with("bool"))
574  {
575  field.type = BOOL;
576  field_type.remove_prefix(4);
577  }
578  else if (field_type.starts_with("char"))
579  {
580  field.type = CHAR;
581  field_type.remove_prefix(4);
582  }
583  else
584  {
585  field.type = OTHER;
586 
587  if (field_type.ends_with("]"))
588  {
589  StringView helper = field_type;
590  while (!helper.ends_with("["))
591  {
592  helper.remove_suffix(1);
593  }
594 
595  helper.remove_suffix(1);
596  field.other_type_ID = helper.to_string();
597 
598  while (!field_type.starts_with("["))
599  {
600  field_type.remove_prefix(1);
601  }
602  }
603  else
604  {
605  field.other_type_ID = field_type.to_string();
606  }
607  }
608 
609  field.array_size = 1;
610 
611  if (field_type.size() > 0 && field_type[0] == '[')
612  {
613  field_type.remove_prefix(1);
614  field.array_size = field_type[0] - '0';
615  field_type.remove_prefix(1);
616 
617  while (field_type[0] != ']')
618  {
619  field.array_size = 10 * field.array_size + field_type[0] - '0';
620  field_type.remove_prefix(1);
621  }
622  }
623 
624  if (field.type == UINT64 && field_name == StringView("timestamp"))
625  {
626  format.timestamp_idx = format.fields.size();
627  }
628  else
629  {
630  field.field_name = field_name.to_string();
631  format.fields.push_back(field);
632  }
633  }
634 
635  if (format.timestamp_idx < 0)
636  {
637  // Required timestamp is not found in definition
638  return false;
639  }
640 
641  format.name = name;
642  _formats[name] = std::move(format);
643 
644  return true;
645 }
646 
647 template <typename T>
648 std::string int_to_hex(T i)
649 {
650  std::stringstream stream;
651  stream << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex << i;
652  return stream.str();
653 }
654 
655 bool ULogParser::readInfo(DataStream& datastream, uint16_t msg_size)
656 {
657  _read_buffer.reserve(msg_size);
658  uint8_t* message = (uint8_t*)_read_buffer.data();
659  datastream.read((char*)message, msg_size);
660 
661  if (!datastream)
662  {
663  return false;
664  }
665  uint8_t key_len = message[0];
666  message++;
667  std::string raw_key((char*)message, key_len);
668  message += key_len;
669  std::string raw_value((char*)message, msg_size - key_len - 1);
670 
671  auto key_parts = splitString(raw_key, ' ');
672 
673  std::string key = key_parts[1].to_string();
674  std::string value;
675 
676  if (key_parts[0].starts_with("char["))
677  {
678  value = raw_value;
679  }
680  else if (key_parts[0] == StringView("bool"))
681  {
682  bool val = *reinterpret_cast<const bool*>(raw_value.data());
683  value = std::to_string(val);
684  }
685  else if (key_parts[0] == StringView("uint8_t"))
686  {
687  uint8_t val = *reinterpret_cast<const uint8_t*>(raw_value.data());
688  value = std::to_string(val);
689  }
690  else if (key_parts[0] == StringView("int8_t"))
691  {
692  int8_t val = *reinterpret_cast<const int8_t*>(raw_value.data());
693  value = std::to_string(val);
694  }
695  else if (key_parts[0] == StringView("uint16_t"))
696  {
697  uint16_t val = *reinterpret_cast<const uint16_t*>(raw_value.data());
698  value = std::to_string(val);
699  }
700  else if (key_parts[0] == StringView("int16_t"))
701  {
702  int16_t val = *reinterpret_cast<const int16_t*>(raw_value.data());
703  value = std::to_string(val);
704  }
705  else if (key_parts[0] == StringView("uint32_t"))
706  {
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"))
709  {
710  value = int_to_hex(val);
711  }
712  else
713  {
714  value = std::to_string(val);
715  }
716  }
717  else if (key_parts[0] == StringView("int32_t"))
718  {
719  int32_t val = *reinterpret_cast<const int32_t*>(raw_value.data());
720  value = std::to_string(val);
721  }
722  else if (key_parts[0] == StringView("float"))
723  {
724  float val = *reinterpret_cast<const float*>(raw_value.data());
725  value = std::to_string(val);
726  }
727  else if (key_parts[0] == StringView("double"))
728  {
729  double val = *reinterpret_cast<const double*>(raw_value.data());
730  value = std::to_string(val);
731  }
732  else if (key_parts[0] == StringView("uint64_t"))
733  {
734  uint64_t val = *reinterpret_cast<const uint64_t*>(raw_value.data());
735  value = std::to_string(val);
736  }
737  else if (key_parts[0] == StringView("int64_t"))
738  {
739  int64_t val = *reinterpret_cast<const int64_t*>(raw_value.data());
740  value = std::to_string(val);
741  }
742 
743  _info.insert({ key, value });
744  return true;
745 }
746 
747 bool ULogParser::readParameter(DataStream& datastream, uint16_t msg_size)
748 {
749  _read_buffer.reserve(msg_size);
750  char* message = (char*)_read_buffer.data();
751  datastream.read((char*)message, msg_size);
752  if (!datastream)
753  {
754  return false;
755  }
756 
758  param.readFromBuffer(message);
759  _parameters.push_back(param);
760  return true;
761 }
762 
764 {
765  std::function<void(const Format& format, const std::string& prefix)> appendVector;
766 
767  Timeseries timeseries;
768 
769  appendVector = [&appendVector, this, &timeseries](const Format& format,
770  const std::string& prefix) {
771  for (const auto& field : format.fields)
772  {
773  // skip padding messages
774  if (StringView(field.field_name).starts_with("_padding"))
775  {
776  continue;
777  }
778 
779  std::string new_prefix = prefix + "/" + field.field_name;
780  for (int i = 0; i < field.array_size; i++)
781  {
782  std::string array_suffix = "";
783  if (field.array_size > 1)
784  {
785  char buff[16];
786  sprintf(buff, ".%02d", i);
787  array_suffix = buff;
788  }
789  if (field.type != OTHER)
790  {
791  timeseries.data.push_back({ new_prefix + array_suffix, std::vector<double>() });
792  }
793  else
794  {
795  appendVector(this->_formats.at(field.other_type_ID), new_prefix + array_suffix);
796  }
797  }
798  }
799  };
800 
801  appendVector(*format, {});
802  return timeseries;
803 }
804 
805 bool ULogParser::Parameter::readFromBuffer(const char* message)
806 {
807  const uint8_t key_len = static_cast<uint8_t>(message[0]);
808  message++;
809  std::string key((char*)message, key_len);
810 
811  const size_t pos = key.find(' ');
812  if (pos == std::string::npos)
813  {
814  return false;
815  }
816 
817  const std::string type = key.substr(0, pos);
818  this->name = key.substr(pos + 1);
819  message += key_len;
820 
821  if (type == "int32_t")
822  {
823  this->value.val_int = *reinterpret_cast<const int32_t*>(message);
824  this->val_type = INT32;
825  }
826  else if (type == "float")
827  {
828  this->value.val_real = *reinterpret_cast<const float*>(message);
829  this->val_type = FLOAT;
830  }
831  else
832  {
833  throw std::runtime_error("unknown parameter type");
834  }
835  return true;
836 }
ULogParser::Format::fields
std::vector< Field > fields
Definition: ulog_parser.h:86
ULogParser::readParameter
bool readParameter(DataStream &datastream, uint16_t msg_size)
Definition: ulog_parser.cpp:747
ULogParser::readFileDefinitions
bool readFileDefinitions(DataStream &datastream)
Definition: ulog_parser.cpp:363
detail::first
auto first(const T &value, const Tail &...) -> const T &
Definition: compile.h:60
ULogParser::_file_start_time
uint64_t _file_start_time
Definition: ulog_parser.h:146
ULogParser::Timeseries::data
std::vector< std::pair< std::string, std::vector< double > > > data
Definition: ulog_parser.h:113
ULogMessageType::ADD_LOGGED_MSG
@ ADD_LOGGED_MSG
ULogParser::Parameter::val_type
FormatType val_type
Definition: ulog_parser.h:75
ULogParser::_subscriptions
std::map< uint16_t, Subscription > _subscriptions
Definition: ulog_parser.h:163
printf
auto printf(string_view fmt, const T &... args) -> int
Definition: printf.h:663
ULogParser::_timeseries
std::map< std::string, Timeseries > _timeseries
Definition: ulog_parser.h:165
ios
std::ios ios
Definition: ulog_parser.cpp:10
backward::ColorMode::type
type
Definition: backward.hpp:3600
nonstd::span_lite::size_t
span_CONFIG_SIZE_TYPE size_t
Definition: span.hpp:576
ULogParser::UINT8
@ UINT8
Definition: ulog_parser.h:41
str_format
static int str_format(lua_State *L)
Definition: lstrlib.c:1227
ULogParser::getParameters
const std::vector< Parameter > & getParameters() const
Definition: ulog_parser.cpp:269
ULogParser::Subscription::multi_id
uint8_t multi_id
Definition: ulog_parser.h:105
ULogParser::createTimeseries
Timeseries createTimeseries(const Format *format)
Definition: ulog_parser.cpp:763
ULogParser::DataStream::offset
size_t offset
Definition: ulog_parser.h:21
ULogParser::Parameter::value
union ULogParser::Parameter::@57 value
ULogParser::UINT32
@ UINT32
Definition: ulog_parser.h:43
ULogParser::splitString
std::vector< StringView > splitString(const StringView &strToSplit, char delimeter)
Definition: ulog_parser.cpp:318
ULogParser::_message_logs
std::vector< MessageLog > _message_logs
Definition: ulog_parser.h:171
ULogParser::DataStream::read
void read(char *dst, int len)
Definition: ulog_parser.h:27
ULogParser::CHAR
@ CHAR
Definition: ulog_parser.h:52
ULogParser::_data_section_start
std::streampos _data_section_start
first ADD_LOGGED_MSG message
Definition: ulog_parser.h:152
ULogParser::Format
Definition: ulog_parser.h:80
ULogParser::fieldsCount
size_t fieldsCount(const Format &format) const
Definition: ulog_parser.cpp:300
mqtt_test_proto.msg
msg
Definition: mqtt_test_proto.py:43
ULogParser::_parameters
std::vector< Parameter > _parameters
Definition: ulog_parser.h:148
ULOG_INCOMPAT_FLAG0_DATA_APPENDED_MASK
#define ULOG_INCOMPAT_FLAG0_DATA_APPENDED_MASK
Definition: ulog_messages.h:195
ULogParser::getTimeseriesMap
const std::map< std::string, Timeseries > & getTimeseriesMap() const
Definition: ulog_parser.cpp:264
ULogParser::UINT64
@ UINT64
Definition: ulog_parser.h:44
ULogParser::readSubscription
bool readSubscription(DataStream &datastream, uint16_t msg_size)
Definition: ulog_parser.cpp:284
ULogParser::INT32
@ INT32
Definition: ulog_parser.h:47
ULogParser::MessageLog
Definition: ulog_parser.h:91
detail::count
constexpr auto count() -> size_t
Definition: core.h:1222
ULogParser::BOOL
@ BOOL
Definition: ulog_parser.h:51
ulog_message_header_s
Definition: ulog_messages.h:66
StringView
nonstd::string_view StringView
Definition: ulog_parser.h:12
ULogMessageType::DROPOUT
@ DROPOUT
backward::details::move
const T & move(const T &v)
Definition: backward.hpp:394
ULogParser::_info
std::map< std::string, std::string > _info
Definition: ulog_parser.h:161
int_to_hex
std::string int_to_hex(T i)
Definition: ulog_parser.cpp:648
ULogParser::_read_until_file_position
int64_t _read_until_file_position
read limit if log contains appended data
Definition: ulog_parser.h:154
ULogMessageType::INFO
@ INFO
ULogParser::Timeseries
Definition: ulog_parser.h:110
ULogParser::getLogs
const std::vector< MessageLog > & getLogs() const
Definition: ulog_parser.cpp:279
ULogParser::Timeseries::timestamps
std::vector< uint64_t > timestamps
Definition: ulog_parser.h:112
nlohmann::detail::void
j template void())
Definition: json.hpp:4061
ULogMessageType::SYNC
@ SYNC
ULogParser::Field
Definition: ulog_parser.h:56
ULogParser::Subscription::message_name
std::string message_name
Definition: ulog_parser.h:106
ULogMessageType::LOGGING
@ LOGGING
ULogParser::Subscription
Definition: ulog_parser.h:98
ULogParser::UINT16
@ UINT16
Definition: ulog_parser.h:42
ULogParser::INT8
@ INT8
Definition: ulog_parser.h:45
ulog_messages.h
format
auto format(const text_style &ts, const S &format_str, const Args &... args) -> std::basic_string< Char >
Definition: color.h:543
ULogMessageType::PARAMETER_DEFAULT
@ PARAMETER_DEFAULT
ULogParser::_formats
std::map< std::string, Format > _formats
Definition: ulog_parser.h:159
ULogMessageType::REMOVE_LOGGED_MSG
@ REMOVE_LOGGED_MSG
ULOG_MSG_HEADER_LEN
#define ULOG_MSG_HEADER_LEN
Definition: ulog_messages.h:65
ULogParser::parseSimpleDataMessage
char * parseSimpleDataMessage(Timeseries &timeseries, const Format *format, char *message, size_t *index)
Definition: ulog_parser.cpp:160
ULogParser::ULogParser
ULogParser(DataStream &datastream)
Definition: ulog_parser.cpp:12
ULogMessageType::FORMAT
@ FORMAT
ULogParser::DataStream
Definition: ulog_parser.h:17
ULogMessageType::FLAG_BITS
@ FLAG_BITS
ULogParser::Parameter
Definition: ulog_parser.h:67
ULogParser::parseDataMessage
void parseDataMessage(const Subscription &sub, char *message)
Definition: ulog_parser.cpp:128
ULogParser::DOUBLE
@ DOUBLE
Definition: ulog_parser.h:50
ULogParser::Parameter::readFromBuffer
bool readFromBuffer(const char *message)
Definition: ulog_parser.cpp:805
field_type
def field_type(f)
ULogParser::readFlagBits
bool readFlagBits(DataStream &datastream, uint16_t msg_size)
Definition: ulog_parser.cpp:433
ULogParser::INT64
@ INT64
Definition: ulog_parser.h:48
ULogParser::_message_name_with_multi_id
std::set< std::string > _message_name_with_multi_id
Definition: ulog_parser.h:169
ULogMessageType::INFO_MULTIPLE
@ INFO_MULTIPLE
field
static void field(LexState *ls, ConsControl *cc)
Definition: lparser.c:891
ULogParser::readFileHeader
bool readFileHeader(DataStream &datastream)
Definition: ulog_parser.cpp:339
param
T param(const std::string &param_name, const T &default_val)
ULogMessageType::PARAMETER
@ PARAMETER
ULogParser::_read_buffer
std::vector< uint8_t > _read_buffer
Definition: ulog_parser.h:150
ULogParser::readFormat
bool readFormat(DataStream &datastream, uint16_t msg_size)
Definition: ulog_parser.cpp:488
ULogMessageType::DATA
@ DATA
ULogParser::INT16
@ INT16
Definition: ulog_parser.h:46
ulog_parser.h
ULogParser::Parameter::name
std::string name
Definition: ulog_parser.h:69
ULogParser::Subscription::format
const Format * format
Definition: ulog_parser.h:107
sprintf
auto sprintf(const S &fmt, const T &... args) -> std::basic_string< Char >
Definition: printf.h:612
ULogParser::FLOAT
@ FLOAT
Definition: ulog_parser.h:49
ulog_file_header_s
Definition: ulog_messages.h:59
ULogParser::getInfo
const std::map< std::string, std::string > & getInfo() const
Definition: ulog_parser.cpp:274
ULogParser::Subscription::msg_id
uint16_t msg_id
Definition: ulog_parser.h:104
ULogParser::readInfo
bool readInfo(DataStream &datastream, uint16_t msg_size)
Definition: ulog_parser.cpp:655
mqtt_test.ret
ret
Definition: mqtt_test.py:30
ULogParser::OTHER
@ OTHER
Definition: ulog_parser.h:53


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Jan 26 2025 03:23:27