37 #ifndef _PROTOBUF_COMM_MESSAGE_REGISTER_H_ 38 #define _PROTOBUF_COMM_MESSAGE_REGISTER_H_ 40 #include <google/protobuf/descriptor.h> 41 #include <google/protobuf/message.h> 42 #include <protobuf_comm/frame_header.h> 44 #include <boost/thread/mutex.hpp> 45 #include <boost/utility.hpp> 52 #include <type_traits> 63 namespace protobuf_comm {
81 typename std::enable_if<std::is_base_of<google::protobuf::Message, MT>::value,
void>::type
84 KeyType key(component_id, msg_type);
85 if (message_by_comp_type_.find(key) != message_by_comp_type_.end()) {
86 #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)) 87 std::string msg =
"Message type " + std::to_string((
long long)component_id) +
":" 88 + std::to_string((
long long)msg_type) +
" already registered";
90 std::string msg =
"Message type " + std::to_string(component_id) +
":" 91 + std::to_string(msg_type) +
" already registered";
93 throw std::runtime_error(msg);
96 message_by_comp_type_[key] = m;
97 message_by_typename_[m->GetDescriptor()->full_name()] = m;
105 typename std::enable_if<std::is_base_of<google::protobuf::Message, MT>::value,
void>::type
109 const google::protobuf::Descriptor *desc = m.GetDescriptor();
110 KeyType key = key_from_desc(desc);
111 if (message_by_comp_type_.find(key) != message_by_comp_type_.end()) {
112 #if defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)) 113 std::string msg =
"Message type " + std::to_string((
long long int)key.first) +
":" 114 + std::to_string((
long long int)key.second) +
" already registered";
116 std::string msg =
"Message type " + std::to_string(key.first) +
":" 117 + std::to_string(key.second) +
" already registered";
119 throw std::runtime_error(msg);
121 MT *new_m =
new MT();
122 message_by_comp_type_[key] = new_m;
123 message_by_typename_[new_m->GetTypeName()] = new_m;
128 std::shared_ptr<google::protobuf::Message>
new_message_for(uint16_t component_id,
131 std::shared_ptr<google::protobuf::Message>
new_message_for(
const std::string &full_name);
135 const google::protobuf::Message &msg,
139 std::shared_ptr<google::protobuf::Message>
153 return failed_to_load_types_;
157 typedef std::pair<uint16_t, uint16_t> KeyType;
158 typedef std::map<KeyType, google::protobuf::Message *> TypeMap;
159 typedef std::map<std::string, google::protobuf::Message *> TypeNameMap;
161 KeyType key_from_desc(
const google::protobuf::Descriptor *desc);
162 google::protobuf::Message *create_msg(
const std::string &msg_type);
164 std::mutex maps_mutex_;
165 TypeMap message_by_comp_type_;
166 TypeNameMap message_by_typename_;
168 google::protobuf::compiler::DiskSourceTree *pb_srctree_;
169 google::protobuf::compiler::Importer * pb_importer_;
170 google::protobuf::MessageFactory * pb_factory_;
171 std::multimap<std::string, std::string> failed_to_load_types_;
void remove_message_type(uint16_t component_id, uint16_t msg_type)
Remove the given message type.
std::enable_if< std::is_base_of< google::protobuf::Message, MT >::value, void >::type add_message_type(uint16_t component_id, uint16_t msg_type)
Add a new message type.
Register to map msg type numbers to Protobuf messages.
std::shared_ptr< google::protobuf::Message > deserialize(frame_header_t &frame_header, message_header_t &message_header, void *data)
Deserialize message.
void serialize(uint16_t component_id, uint16_t msg_type, const google::protobuf::Message &msg, frame_header_t &frame_header, message_header_t &message_header, std::string &data)
Serialize a message.
const LoadFailMap & load_failures() const
Get failure messages from loading.
std::shared_ptr< google::protobuf::Message > new_message_for(uint16_t component_id, uint16_t msg_type)
Create a new message instance.
~MessageRegister()
Destructor.
std::multimap< std::string, std::string > LoadFailMap
Mapping from message type to load error message.
std::enable_if< std::is_base_of< google::protobuf::Message, MT >::value, void >::type add_message_type()
Add a new message type.
MessageRegister()
Constructor.