10 #include <unordered_map> 18 size_t &data_offset)
const = 0;
19 virtual bool hasFixedSize()
const = 0;
20 virtual size_t fixedSize()
const {
21 throw std::runtime_error(
"Node does not have a fixed size");
28 const std::string &name)
const {
32 virtual size_t elementCount(
const MessageParser &parser)
const {
return 0; }
33 virtual std::string toString(
const MessageParser &parser)
const {
36 virtual double toDouble(
const MessageParser &parser)
const {
return 0; }
37 virtual int64_t toInteger(
const MessageParser &parser)
const {
return 0; }
40 struct PrimitiveNode : MessageParser::Node {
44 struct TimeNode : PrimitiveNode {
46 virtual bool hasFixedSize()
const override {
return true; }
47 virtual size_t fixedSize()
const override {
return 8; }
49 size_t &start)
const override {
50 start +=
sizeof(fixedSize());
53 uint32_t sec = parser.data<uint32_t>(parser._data_start + 0);
54 uint32_t nsec = parser.data<uint32_t>(parser._data_start + 4);
55 return ros::Time(sec, nsec);
57 virtual double toDouble(
const MessageParser &parser)
const override {
58 return value(parser).toSec();
60 virtual int64_t toInteger(
const MessageParser &parser)
const override {
61 return value(parser).toNSec();
68 struct DurationNode : PrimitiveNode {
70 virtual bool hasFixedSize()
const override {
return true; }
71 virtual size_t fixedSize()
const override {
return 8; }
73 size_t &start)
const override {
74 start +=
sizeof(fixedSize());
77 uint32_t sec = parser.data<uint32_t>(parser._data_start + 0);
78 uint32_t nsec = parser.data<uint32_t>(parser._data_start + 4);
79 return ros::Duration(sec, nsec);
81 virtual double toDouble(
const MessageParser &parser)
const override {
82 return value(parser).toSec();
84 virtual int64_t toInteger(
const MessageParser &parser)
const override {
85 return value(parser).toNSec();
92 struct StringNode : PrimitiveNode {
94 virtual bool hasFixedSize()
const override {
return false; }
96 size_t &data_offset)
const override {
97 auto len = parser.data<uint32_t>(data_offset);
98 data_offset += 4 + len;
100 virtual std::string toString(
const MessageParser &parser)
const override {
101 size_t len = parser.data<uint32_t>(parser._data_start);
102 return std::string((
const char *)parser.data(parser._data_start + 4, len),
107 struct ArrayNode : Node {
108 bool has_fixed_element_count =
false;
109 size_t fixed_element_count = 0;
110 std::shared_ptr<Node> element_node;
111 virtual bool hasFixedSize()
const override {
112 return has_fixed_element_count && element_node->hasFixedSize();
114 virtual size_t fixedSize()
const override {
115 return fixed_element_count * element_node->fixedSize();
118 size_t &data_offset)
const override {
119 size_t element_count = fixed_element_count;
120 if (!has_fixed_element_count) {
121 element_count = parser.data<uint32_t>(data_offset);
122 data_offset +=
sizeof(uint32_t);
124 if (element_node->hasFixedSize()) {
125 data_offset += element_node->fixedSize() * element_count;
127 auto *index = parser._data->index.get();
128 size_t index_start = index->alloc(element_count * 2);
129 for (
size_t i = 0; i < element_count; i++) {
130 index->at(index_start + i * 2 + 0) = index->size();
131 index->at(index_start + i * 2 + 1) = data_offset;
132 element_node->index(parser, data_offset);
137 element_node->init(parser);
139 virtual size_t elementCount(
const MessageParser &parser)
const override {
140 if (has_fixed_element_count) {
141 return fixed_element_count;
143 return parser.data<uint32_t>(parser._data_start);
147 size_t index)
const override {
149 size_t element_count = fixed_element_count;
150 size_t data_start = parser._data_start;
151 if (!has_fixed_element_count) {
152 element_count = parser.data<uint32_t>(parser._data_start);
153 data_start +=
sizeof(uint32_t);
155 if (index < element_count) {
156 ret._data = parser._data;
157 ret._node = element_node;
158 if (element_node->hasFixedSize()) {
159 ret._index_start = parser._index_start;
160 ret._data_start = data_start + element_node->fixedSize() * index;
163 parser._data->index->at(parser._index_start + index * 2 + 0);
165 parser._data->index->at(parser._index_start + index * 2 + 1);
173 std::string type_name;
175 std::string value_string;
178 struct MessageNode : Node {
180 std::vector<std::shared_ptr<Node>> field_nodes;
181 std::vector<std::string> field_names;
182 std::unordered_map<std::string, size_t> field_map;
183 std::vector<std::shared_ptr<ConstNode>> const_nodes;
184 std::unordered_map<std::string, size_t> const_map;
185 bool fixed_size_initialized =
false;
186 bool has_fixed_size =
false;
187 size_t fixed_size = 0;
188 std::vector<size_t> fixed_offsets;
190 for (
auto &field : field_nodes) {
193 has_fixed_size =
true;
194 for (
auto &field : field_nodes) {
195 if (!field->hasFixedSize()) {
196 has_fixed_size =
false;
201 fixed_offsets.clear();
202 if (has_fixed_size) {
203 for (
auto &field : field_nodes) {
204 fixed_offsets.push_back(fixed_size);
205 fixed_size += field->fixedSize();
208 fixed_size_initialized =
true;
210 virtual bool hasFixedSize()
const override {
211 if (!fixed_size_initialized) {
212 throw std::runtime_error(
"Fixed size not initialized");
214 return has_fixed_size;
216 virtual size_t fixedSize()
const override {
217 if (!fixed_size_initialized) {
218 throw std::runtime_error(
"Fixed size not initialized");
223 size_t &data_offset)
const override {
224 if (!fixed_size_initialized) {
225 throw std::runtime_error(
"Fixed size not initialized");
227 if (has_fixed_size) {
228 data_offset += fixed_size;
230 auto *index = parser._data->index.get();
231 size_t index_start = index->alloc(field_nodes.size() * 2);
232 for (
size_t i = 0; i < field_nodes.size(); i++) {
233 index->at(index_start + i * 2 + 0) = index->size();
234 index->at(index_start + i * 2 + 1) = data_offset;
235 field_nodes[i]->index(parser, data_offset);
239 virtual size_t elementCount(
const MessageParser &parser)
const override {
240 return field_nodes.size();
243 const std::string &name)
const override {
244 auto it = field_map.find(name);
245 if (it != field_map.end()) {
252 size_t index)
const override {
253 if (!fixed_size_initialized) {
254 throw std::runtime_error(
"Fixed size not initialized");
257 if (index < field_nodes.size()) {
258 ret._data = parser._data;
259 ret._node = field_nodes.at(index);
260 if (has_fixed_size) {
261 ret._index_start = parser._index_start;
262 ret._data_start = parser._data_start + fixed_offsets.at(index);
265 parser._data->index->at(parser._index_start + index * 2 + 0);
267 parser._data->index->at(parser._index_start + index * 2 + 1);
275 std::vector<size_t> _data;
278 inline size_t alloc(
size_t size) {
279 size_t ret = _data.size();
280 _data.resize(_data.size() + size, 0);
283 inline void clear() { _data.clear(); }
284 inline size_t at(
size_t index)
const {
return _data.at(index); }
285 inline size_t &at(
size_t index) {
return _data.at(index); }
288 inline void push(
size_t v) { _data.push_back(v); }
289 inline size_t size()
const {
return _data.size(); }
293 std::shared_ptr<const Message> message;
294 std::shared_ptr<Index> index;
295 std::unordered_map<std::string, std::shared_ptr<Node>> type_map;
298 const void *data(
size_t start,
size_t size)
const {
299 if (_data->message->size() < start + size) {
300 throw std::runtime_error(
"Index out of range");
302 return _data->message->data() + start;
305 template <
class T>
const T &data(
size_t start)
const {
306 return *(
const T *)data(start,
sizeof(T));
309 void parseDefinition(
const std::shared_ptr<const MessageType> &type);
312 void registerType(
const std::string &name,
const std::shared_ptr<T> &t) {
314 _data->type_map[name] = t;
317 template <
class T,
class... Args>
318 void registerType(
const std::string &name,
const Args &... args) {
319 registerType(name, std::make_shared<T>(args...));
322 template <
class T>
void registerPrimitiveType(
const std::string &name) {
323 struct NodeType : PrimitiveNode {
324 virtual bool hasFixedSize()
const override {
return true; }
325 virtual size_t fixedSize()
const override {
return sizeof(T); }
327 size_t &data_offset)
const override {
328 data_offset +=
sizeof(T);
331 return *(
const T *)parser.data(parser._data_start,
sizeof(T));
333 virtual std::string toString(
const MessageParser &parser)
const override {
334 return std::to_string(value(parser));
337 return value(parser);
339 virtual int64_t toInteger(
const MessageParser &parser)
const {
340 return value(parser);
343 auto node = std::make_shared<NodeType>();
344 registerType(name, node);
347 std::shared_ptr<Node> findType(
const std::string &name,
348 const std::string &ns =
"");
350 std::shared_ptr<Data> _data;
351 std::shared_ptr<const Node> _node;
352 size_t _data_start = 0;
353 size_t _index_start = 0;
357 MessageParser(
const std::shared_ptr<const Message> &message) {
360 void parse(
const std::shared_ptr<const Message> &message);
361 ssize_t fieldIndex(
const std::string &name)
const {
365 return _node->fieldIndex(*
this, name);
372 return _node->elementAt(*
this, index);
375 MessageParser operator[](
size_t index)
const {
return at(index); }
377 return at(fieldIndex(name));
379 bool isNull()
const {
return _data ==
nullptr || _node ==
nullptr; }
380 bool isPrimitive()
const {
382 dynamic_cast<const PrimitiveNode *
>(_node.get()) !=
nullptr;
384 bool isMessage()
const {
386 dynamic_cast<const MessageNode *
>(_node.get()) !=
nullptr;
388 bool isArray()
const {
389 return !isNull() &&
dynamic_cast<const ArrayNode *
>(_node.get()) !=
nullptr;
391 bool isString()
const {
393 dynamic_cast<const StringNode *
>(_node.get()) !=
nullptr;
395 bool isTime()
const {
396 return !isNull() &&
dynamic_cast<const TimeNode *
>(_node.get()) !=
nullptr;
398 size_t size()
const {
return _node->elementCount(*
this); }
399 const std::string &fieldName(
size_t i)
const {
400 return dynamic_cast<const MessageNode *
>(_node.get())->field_names.at(i);
402 void print(std::ostream &stream)
const;
403 std::string print()
const;
404 std::string toString()
const {
408 return _node->toString(*
this);
411 double toDouble()
const {
415 return _node->toDouble(*
this);
418 int64_t toInteger()
const {
422 return _node->toInteger(*
this);