TAMSVIZ
Visualization and annotation tool for ROS
message.h
1 // TAMSVIZ
2 // (c) 2020 Philipp Ruppel
3 
4 #pragma once
5 
6 #include "log.h"
7 
8 #include <ros/ros.h>
9 
10 class MessageType {
11  std::string _hash, _name, _definition;
12 
13 private:
14  MessageType() {}
15  MessageType(const MessageType &) = delete;
16  MessageType &operator=(const MessageType &) = delete;
17 
18 public:
19  static std::shared_ptr<MessageType> instance(const std::string &hash,
20  const std::string &name,
21  const std::string &definition);
22  const std::string &hash() const { return _hash; }
23  const std::string &name() const { return _name; }
24  const std::string &definition() const { return _definition; }
25 };
26 
27 class Message : public std::enable_shared_from_this<Message> {
28  std::shared_ptr<const MessageType> _type;
29  std::vector<uint8_t> _data;
30  ros::Time _time;
31  template <class T> void instantiateImpl(std::shared_ptr<const T> &ret) const {
32  if (_data.empty() || _type == nullptr ||
33  ros::message_traits::datatype<T>() != _type->name() ||
34  ros::message_traits::md5sum<T>() != _type->hash()) {
35  ret = nullptr;
36  } else {
37  auto m = std::make_shared<T>();
38  ros::serialization::IStream s((uint8_t *)_data.data(), _data.size());
39  ros::serialization::deserialize(s, *m);
40  ret = std::move(m);
41  }
42  }
43  void instantiateImpl(std::shared_ptr<const Message> &ret) const {
44  ret = shared_from_this();
45  }
46 
47 public:
48  template <class T> std::shared_ptr<const T> instantiate() const {
49  std::shared_ptr<const typename std::decay<T>::type> ret;
50  instantiateImpl(ret);
51  return std::move(ret);
52  }
53  template <class Stream> void read(Stream &stream) {
54  _data.resize(stream.getLength());
55  std::memcpy(_data.data(), stream.getData(), _data.size());
56  }
57  void type(const std::shared_ptr<const MessageType> &type) { _type = type; }
58  const std::shared_ptr<const MessageType> &type() const { return _type; }
59  const ros::Time &time() const { return _time; }
60  void time(const ros::Time &time) { _time = time; }
61  const uint8_t *data() const { return _data.data(); }
62  size_t size() const { return _data.size(); }
63 };
64 
65 namespace ros {
66 namespace message_traits {
67 template <> struct MD5Sum<Message> {
68  static const char *value() { return "*"; }
69 };
70 template <> struct DataType<Message> {
71  static const char *value() { return "*"; }
72 };
73 } // namespace message_traits
74 namespace serialization {
75 template <> struct Serializer<Message> {
76  template <typename Stream>
77  inline static void read(Stream &stream, Message &m) {
78  m.read(stream);
79  }
80 };
81 template <> struct PreDeserialize<Message> {
82  static void notify(const PreDeserializeParams<Message> &params) {
83  params.message->type(MessageType::instance(
84  (*params.connection_header)["md5sum"],
85  (*params.connection_header)["type"],
86  (*params.connection_header)["message_definition"]));
87  }
88 };
89 } // namespace serialization
90 } // namespace ros
Definition: message.h:65