MessageType.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (C) 2014 by Ralf Kaestner *
3  * ralf.kaestner@gmail.com *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the Lesser GNU General Public License as published by*
7  * the Free Software Foundation; either version 3 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * Lesser GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the Lesser GNU General Public License *
16  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17  ******************************************************************************/
18 
19 #include <algorithm>
20 #include <fstream>
21 #include <list>
22 #include <set>
23 #include <sstream>
24 
25 #include <boost/unordered_map.hpp>
26 
27 #include <ros/package.h>
28 
37 
38 namespace variant_topic_tools {
39 
40 /*****************************************************************************/
41 /* Constructors and Destructor */
42 /*****************************************************************************/
43 
44 MessageType::MessageType(const std::string& dataType, const std::string&
45  md5Sum, const std::string& definition) :
46  dataType(dataType),
47  md5Sum(md5Sum),
48  definition(definition) {
49 }
50 
52  dataType(dataType.getIdentifier()),
53  md5Sum(dataType.getMD5Sum()),
54  definition(dataType.getDefinition()) {
55 }
56 
58  dataType(src.dataType),
59  md5Sum(src.md5Sum),
60  definition(src.definition) {
61 }
62 
64 }
65 
66 /*****************************************************************************/
67 /* Accessors */
68 /*****************************************************************************/
69 
70 void MessageType::setDataType(const std::string& dataType) {
71  this->dataType = dataType;
72 }
73 
74 const std::string& MessageType::getDataType() const {
75  return dataType;
76 }
77 
78 void MessageType::setMD5Sum(const std::string& md5Sum) {
79  this->md5Sum = md5Sum;
80 }
81 
82 const std::string& MessageType::getMD5Sum() const {
83  return md5Sum;
84 }
85 
86 void MessageType::setDefinition(const std::string& definition) {
87  this->definition = definition;
88 }
89 
90 const std::string& MessageType::getDefinition() const {
91  return definition;
92 }
93 
94 bool MessageType::isValid() const {
95  return !md5Sum.empty() && ((md5Sum == "*") || (md5Sum.length() == 32)) &&
96  !dataType.empty() && !definition.empty();
97 }
98 
99 /*****************************************************************************/
100 /* Methods */
101 /*****************************************************************************/
102 
103 void MessageType::load(const std::string& messageDataType) {
104  clear();
105 
106  std::string messagePackage, messagePlainType;
107  if (!MessageTypeParser::matchType(messageDataType, messagePackage,
108  messagePlainType))
109  throw InvalidMessageTypeException(messageDataType);
110 
111  DataTypeRegistry registry;
112  boost::unordered_map<std::string, std::string> definitions;
113  std::list<std::string> typesInOrder;
114  std::set<std::string> requiredTypes;
115 
116  requiredTypes.insert(messageDataType);
117  typesInOrder.push_back(messageDataType);
118 
119  std::list<std::string>::iterator it = typesInOrder.begin();
120 
121  while (it != typesInOrder.end()) {
122  std::string package, plainType;
123 
124  if (!MessageTypeParser::matchType(*it, package, plainType))
125  throw InvalidMessageTypeException(*it);
126 
127  if (package.empty()) {
128  if (plainType == "Header")
129  package = "std_msgs";
130  else
131  throw InvalidMessageTypeException(*it);
132  }
133 
134  std::string packagePath = ros::package::getPath(package);
135  if (packagePath.empty())
136  throw PackageNotFoundException(package);
137 
138  std::string messageFilename(packagePath+"/msg/"+plainType+".msg");
139  std::ifstream messageFile(messageFilename.c_str());
140  std::string messageDefinition;
141 
142  if (messageFile.is_open()) {
143  messageFile.seekg(0, std::ios::end);
144  messageDefinition.reserve(messageFile.tellg());
145  messageFile.seekg(0, std::ios::beg);
146 
147  messageDefinition.assign((std::istreambuf_iterator<char>(messageFile)),
148  std::istreambuf_iterator<char>());
149  }
150  else
151  throw FileOpenException(messageFilename);
152 
153  messageFile.close();
154 
155  if (!messageDefinition.empty()) {
156  std::istringstream stream(messageDefinition);
157  std::string line;
158 
159  while (std::getline(stream, line)) {
160  std::string memberName, memberType;
161  size_t memberSize;
162 
163  if (MessageDefinitionParser::matchArray(line, memberName, memberType,
164  memberSize) || MessageDefinitionParser::match(line, memberName,
165  memberType)) {
166  std::string memberPackage, plainMemberType;
167 
168  if (!MessageTypeParser::matchType(memberType, memberPackage,
169  plainMemberType))
170  throw InvalidMessageTypeException(memberType);
171 
172  if (!registry.getDataType(memberType).isBuiltin()) {
173  if (memberPackage.empty()) {
174  if (plainMemberType == "Header")
175  memberPackage = "std_msgs";
176  else
177  memberPackage = package;
178 
179  memberType = memberPackage+"/"+plainMemberType;
180  }
181 
182  if (requiredTypes.find(memberType) == requiredTypes.end()) {
183  requiredTypes.insert(memberType);
184  typesInOrder.push_back(memberType);
185  }
186  }
187  }
188  }
189  }
190 
191  definitions[*it] = messageDefinition;
192  ++it;
193  }
194 
195  for (std::list<std::string>::const_iterator it = typesInOrder.begin();
196  it != typesInOrder.end(); ++it) {
197  if (!definition.empty()) {
198  definition += "\n"+std::string(80, '=')+"\n";
199  definition += "MSG: "+*it+"\n";
200  }
201 
202  definition += definitions[*it];
203  }
204 
205  if (!definition.empty())
206  dataType = messageDataType;
207 }
208 
210  dataType.clear();
211  md5Sum = "*";
212  definition.clear();
213 }
214 
215 void MessageType::write(std::ostream& stream) const {
216  stream << dataType;
217 }
218 
220  const std::string& topic, size_t queueSize, bool latch, const
223 
224  if (isValid())
225  publisher.impl.reset(new Publisher::Impl(nodeHandle, *this, topic,
226  queueSize, latch, connectCallback));
227 
228  return publisher;
229 }
230 
232  std::string& topic, size_t queueSize, const SubscriberCallback&
233  callback) {
235 
236  subscriber.impl.reset(new Subscriber::Impl(nodeHandle, *this, topic,
237  queueSize, callback));
238 
239  return subscriber;
240 }
241 
242 /*****************************************************************************/
243 /* Operators */
244 /*****************************************************************************/
245 
246 bool MessageType::operator==(const MessageType& type) const {
247  return (dataType == type.dataType) && (md5Sum == type.md5Sum);
248 }
249 
250 bool MessageType::operator!=(const MessageType& type) const {
251  return (dataType != type.dataType) || (md5Sum != type.md5Sum);
252 }
253 
254 std::ostream& operator<<(std::ostream& stream, const MessageType&
255  messageType) {
256  messageType.write(stream);
257  return stream;
258 }
259 
260 }
Publisher advertise(ros::NodeHandle &nodeHandle, const std::string &topic, size_t queueSize, bool latch=false, const ros::SubscriberStatusCallback &connectCallback=ros::SubscriberStatusCallback())
Advertise this message type.
void clear()
Clear the message type.
boost::function< void(const SingleSubscriberPublisher &)> SubscriberStatusCallback
Variant message publisher.
Definition: Publisher.h:36
std::string definition
The definition of this message.
Definition: MessageType.h:129
MessageType(const std::string &dataType=std::string(), const std::string &md5Sum="*", const std::string &definition=std::string())
Default constructor.
Definition: MessageType.cpp:44
string package
Variant message subscriber.
Definition: Subscriber.h:36
bool operator!=(const MessageType &type) const
True, if this message type does not equal another message type.
Variant message type information.
Definition: MessageType.h:33
static bool match(const std::string &expression, std::string &name, std::string &type)
Match any message member expression.
void setDataType(const std::string &dataType)
Set the data type of the message.
Definition: MessageType.cpp:70
variant_topic_tools::MessageDefinition messageDefinition
Definition: info.cpp:30
Subscriber subscribe(ros::NodeHandle &nodeHandle, const std::string &topic, size_t queueSize, const SubscriberCallback &callback)
Subscribe to this message type.
Header file providing the MessageDefinitionParser class interface.
Header file providing the Publisher class interface.
Header file providing the Subscriber class interface.
const std::string & getDefinition() const
Retrieve the message definition.
Definition: MessageType.cpp:90
std::string md5Sum
The MD5 sum of this message.
Definition: MessageType.h:125
void callback(const variant_topic_tools::MessageVariant &variant, const ros::Time &receiptTime)
Definition: echo.cpp:58
variant_topic_tools::Subscriber subscriber
Definition: echo.cpp:25
void connectCallback(const ros::SingleSubscriberPublisher &)
Definition: relay.cpp:65
static bool matchArray(const std::string &expression, std::string &name, std::string &memberType, size_t &size)
Match an array message member expression.
Exception thrown in case of an error to open a file.
Definition: Exceptions.h:191
Exception thrown in case of an invalid message type.
Definition: Exceptions.h:148
boost::function< void(const MessageVariant &, const ros::Time &)> SubscriberCallback
Definition of the subscriber callback type.
Definition: Forwards.h:120
variant_topic_tools::Publisher publisher
Definition: publish.cpp:25
void setMD5Sum(const std::string &md5Sum)
Set the MD5 sum of the message.
Definition: MessageType.cpp:78
Header file defining exceptions for the variant topic tools.
const std::string & getDataType() const
Retrieve the data type of the message.
Definition: MessageType.cpp:74
ros::NodeHandlePtr nodeHandle
Definition: echo.cpp:23
Header file providing the DataTypeRegistry class interface.
const std::string & getMD5Sum() const
Retrieve the MD5 sum of the message.
Definition: MessageType.cpp:82
std::ostream & operator<<(std::ostream &stream, const DataType &dataType)
Operator for writing the data type to a stream.
Definition: DataType.cpp:190
Header file providing the MessageDataType class interface.
DataType getDataType(const std::string &identifier)
Retrieve a data type from the registry by identifier (non-const version)
void load(const std::string &messageDataType)
Attempt to load the message type corresponding to the specified message data type.
std::string dataType
The data type of this message.
Definition: MessageType.h:121
ROSLIB_DECL std::string getPath(const std::string &package_name)
Variant message publisher implementation.
Definition: Publisher.h:86
static bool matchType(const std::string &expression, std::string &package, std::string &type)
Match any message type expression.
Header file providing the MessageTypeParser class interface.
void write(std::ostream &stream) const
Write the message type to a stream.
bool isValid() const
True, if this message type is valid.
Definition: MessageType.cpp:94
ImplPtr impl
The publisher&#39;s implementation.
Definition: Publisher.h:140
ImplPtr impl
The subscriber&#39;s implementation.
Definition: Subscriber.h:133
variant_topic_tools::MessageType messageType
Definition: publish.cpp:33
bool isBuiltin() const
True, if this data type represents a built-in type.
Definition: DataType.cpp:105
Variant message subscriber implementation.
Definition: Subscriber.h:77
void setDefinition(const std::string &definition)
Set the message definition.
Definition: MessageType.cpp:86
bool operator==(const MessageType &type) const
True, if this message type equals another message type.
Header file providing the MessageType class interface.
Exception thrown in case of a package not being found.
Definition: Exceptions.h:181


variant_topic_tools
Author(s): Ralf Kaestner
autogenerated on Sat Jan 9 2021 03:56:49