datatamer_parser.cpp
Go to the documentation of this file.
1 #include <sstream>
2 #include <iostream>
3 
4 #include "datatamer_parser.h"
6 
7 using namespace PJ;
8 
9 namespace DataTamer
10 {
11 enum class ValueType
12 {
13  UINT8,
14  UINT16,
15  UINT32,
16  UINT64,
17 
18  INT8,
19  INT16,
20  INT32,
21  INT64,
22 
23  FLOAT,
24  DOUBLE,
25 
26  OTHER
27 };
28 
29 ValueType FromStr(std::string const& str) {
30 
31  static std::unordered_map<std::string, ValueType> names = {
32  { "UINT8", ValueType::UINT8 },
33  { "UINT16", ValueType::UINT16 },
34  { "UINT32", ValueType::UINT32 },
35  { "UINT64", ValueType::UINT64 },
36 
37  { "INT8", ValueType::INT8 },
38  { "INT16", ValueType::INT16 },
39  { "INT32", ValueType::INT32 },
40  { "INT64", ValueType::INT64 },
41 
42  { "FLOAT", ValueType::FLOAT },
43  { "DOUBLE", ValueType::DOUBLE }
44  };
45  auto const it = names.find(str);
46  return it == names.end() ? ValueType::OTHER : it->second;
47 }
48 
49 }
50 
51 template <typename T>
52 T Deserialize(const uint8_t* ptr, int& offset)
53 {
54  T out = {};
55  std::memcpy(&out, ptr + offset, sizeof(T));
56  offset += sizeof(T);
57  return out;
58 }
59 
61 {
62  public:
63  DataTamerParser(const std::string &topic_name,
64  const std::string &type_name,
65  const std::string &schema,
67  MessageParser(topic_name, data),
68  topic_name_(topic_name)
69  {
70  // the expected schema contains a series per line
71  std::istringstream ss(schema);
72  std::string line;
73 
74  while (std::getline(ss, line))
75  {
76  TimeSeries ts;
77  auto pos = line.find(' ');
78  ts.name = line.substr(0, pos);
79  ts.type = DataTamer::FromStr(line.substr(pos+1));
80  timeseries_.push_back(std::move(ts));
81  }
82  }
83 
84  bool parseMessage(const MessageRef serialized_msg, double& timestamp) override
85  {
86  int offset = 0;
87 
88  const auto* msg_ptr = serialized_msg.data();
89  uint32_t flags_size = Deserialize<uint32_t>(msg_ptr, offset);
90 
91  thread_local std::vector<uint8_t> enable_vector;
92  enable_vector.resize(flags_size);
93  std::memcpy(enable_vector.data(), msg_ptr + offset, flags_size);
94  offset += flags_size;
95 
96  const uint32_t remaining_bytes = Deserialize<uint32_t>(msg_ptr, offset);
97 
98  if(remaining_bytes + offset != serialized_msg.size())
99  {
100  throw std::runtime_error("DataTamerParser: corrupted size");
101  }
102 
103  for(size_t i=0; i<timeseries_.size(); i++)
104  {
105  const uint8_t flag_byte = enable_vector[i/8];
106  const uint8_t mask = uint8_t(1 << (i%8));
107  if(flag_byte & mask)
108  {
109  double val = 0;
110  switch(timeseries_[i].type)
111  {
113  val = static_cast<double>(Deserialize<uint8_t>(msg_ptr, offset));
114  break;
116  val = static_cast<double>(Deserialize<uint16_t>(msg_ptr, offset));
117  break;
119  val = static_cast<double>(Deserialize<uint32_t>(msg_ptr, offset));
120  break;
122  val = static_cast<double>(Deserialize<uint64_t>(msg_ptr, offset));
123  break;
124 
126  val = static_cast<double>(Deserialize<int8_t>(msg_ptr, offset));
127  break;
129  val = static_cast<double>(Deserialize<int16_t>(msg_ptr, offset));
130  break;
132  val = static_cast<double>(Deserialize<int32_t>(msg_ptr, offset));
133  break;
135  val = static_cast<double>(Deserialize<int64_t>(msg_ptr, offset));
136  break;
137 
139  val = static_cast<double>(Deserialize<float>(msg_ptr, offset));
140  break;
142  val = Deserialize<double>(msg_ptr, offset);
143  break;
144  default:
145  break;
146  }
147  auto& ts = timeseries_[i];
148  if(!ts.plot_data)
149  {
150  ts.plot_data = &(_plot_data.addNumeric(topic_name_ + "/" + ts.name)->second);
151  }
152  ts.plot_data->pushBack({timestamp, val});
153  }
154  }
155  return true;
156  }
157 
158  private:
159 
160  struct TimeSeries {
161  std::string name;
163  PlotData* plot_data = nullptr;
164  };
165 
166  std::string topic_name_;
167  std::vector<TimeSeries> timeseries_;
168 };
169 
170 
171 MessageParserPtr ParserDataTamer::createParser(const std::string &topic_name,
172  const std::string &type_name,
173  const std::string &schema,
175 {
176  return std::make_shared<DataTamerParser>(topic_name, type_name, schema, data);
177 }
std::string topic_name_
PJ::MessageParserPtr createParser(const std::string &topic_name, const std::string &type_name, const std::string &schema, PJ::PlotDataMapRef &data) override
size_t size() const
std::vector< TimeSeries > timeseries_
type
Definition: core.h:1059
std::shared_ptr< MessageParser > MessageParserPtr
DataTamerParser(const std::string &topic_name, const std::string &type_name, const std::string &schema, PJ::PlotDataMapRef &data)
ValueType FromStr(std::string const &str)
std::string type_name(lua_State *L, type t)
Definition: sol.hpp:8079
T * ptr(T &val)
Definition: sol.hpp:2106
const T & move(const T &v)
Definition: backward.hpp:394
const uint8_t * data() const
The MessageParser is the base class used to parse a message with a specific encoding+schema.
dictionary data
Definition: mqtt_test.py:22
bool parseMessage(const MessageRef serialized_msg, double &timestamp) override
T Deserialize(const uint8_t *ptr, int &offset)
Definition: format.h:895


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Jun 19 2023 03:01:02