MessageDefinition.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 <list>
20 #include <set>
21 
22 #include <boost/unordered_map.hpp>
23 
30 
31 namespace variant_topic_tools {
32 
33 /*****************************************************************************/
34 /* Constructors and Destructor */
35 /*****************************************************************************/
36 
38 }
39 
41  setMessageType(messageType);
42 }
43 
45  messageDataType(messageDataType) {
46 }
47 
51 }
52 
54 }
55 
56 /*****************************************************************************/
57 /* Accessors */
58 /*****************************************************************************/
59 
61  clear();
62 
63  if (messageType.isValid()) {
64  DataType dataType(messageType.getDataType());
65 
66  if (!dataType.isValid()) {
67  DataTypeRegistry registry;
68 
69  std::vector<MessageType> messageTypes;
70  boost::unordered_map<std::string, size_t> definedTypes;
71  boost::unordered_map<size_t, std::set<size_t> > requiredTypes;
72 
74  messageType.getDefinition(), messageTypes);
75 
76  for (size_t i = 0; i < messageTypes.size(); ++i)
77  definedTypes[messageTypes[i].getDataType()] = i;
78 
79  for (size_t i = 0; i < messageTypes.size(); ++i) {
80  std::string package, plainType;
81 
82  if (!MessageTypeParser::matchType(messageTypes[i].getDataType(),
83  package, plainType))
84  throw InvalidMessageTypeException(messageTypes[i].getDataType());
85 
86  std::istringstream stream(messageTypes[i].getDefinition());
87  std::string line;
88 
89  while (std::getline(stream, line)) {
90  std::string memberName, memberType;
91  size_t memberSize;
92 
93  if (MessageDefinitionParser::matchArray(line, memberName, memberType,
94  memberSize) || MessageDefinitionParser::match(line, memberName,
95  memberType)) {
96  std::string memberPackage, plainMemberType;
97 
98  if (!MessageTypeParser::matchType(memberType, memberPackage,
99  plainMemberType))
100  throw InvalidMessageTypeException(memberType);
101 
102  if (memberPackage.empty()) {
103  if (plainMemberType == "Header")
104  memberPackage = "std_msgs";
105  else
106  memberPackage = package;
107 
108  memberType = memberPackage+"/"+plainMemberType;
109  }
110 
111  boost::unordered_map<std::string, size_t>::iterator it =
112  definedTypes.find(memberType);
113 
114  if (it != definedTypes.end())
115  requiredTypes[i].insert(it->second);
116  }
117  }
118  }
119 
120  std::list<size_t> typesToBeDefined;
121  typesToBeDefined.push_back(definedTypes[messageType.getDataType()]);
122 
123  while (!typesToBeDefined.empty()) {
124  size_t i = typesToBeDefined.back();
125  const std::set<size_t>& currentRequiredTypes = requiredTypes[i];
126  bool allRequiredTypesDefined = true;
127 
128  for (std::set<size_t>::const_iterator it = currentRequiredTypes.
129  begin(); it != currentRequiredTypes.end(); ++it) {
130  if (!registry.getDataType(messageTypes[*it].getDataType()).
131  isValid()) {
132  typesToBeDefined.push_back(*it);
133  allRequiredTypesDefined = false;
134 
135  break;
136  }
137  }
138 
139  if (allRequiredTypesDefined) {
140  registry.addMessageDataType(messageTypes[i].getDataType(),
141  messageTypes[i].getDefinition());
142  typesToBeDefined.pop_back();
143  }
144  }
145  }
146 
148  fill(messageDataType, *this);
149  }
150 }
151 
153  messageDataType) {
154  setMessageType(messageDataType);
155 }
156 
158  return messageDataType;
159 }
160 
162  return messageDataType.isValid();
163 }
164 
165 /*****************************************************************************/
166 /* Methods */
167 /*****************************************************************************/
168 
169 void MessageDefinition::load(const std::string& messageDataType) {
170  clear();
171 
173  messageType.load(messageDataType);
174 
175  setMessageType(messageType);
176 }
177 
181 }
182 
183 void MessageDefinition::fill(const MessageDataType& currentDataType,
184  MessageFieldCollection<DataType>& currentCollection) {
185  for (size_t i = 0; i < currentDataType.getNumMembers(); ++i) {
186  currentCollection.appendField(currentDataType[i].getName(),
187  currentDataType[i].getType());
188 
189  if (currentDataType[i].getType().isMessage())
190  fill(currentDataType[i].getType(), currentCollection[i]);
191  }
192 }
193 
194 void MessageDefinition::write(std::ostream& stream) const {
196 }
197 
198 /*****************************************************************************/
199 /* Operators */
200 /*****************************************************************************/
201 
202 std::ostream& operator<<(std::ostream& stream, const MessageDefinition&
204  messageDefinition.write(stream);
205  return stream;
206 }
207 
208 }
Header file providing the MessageDefinition class interface.
DataType messageDataType
The message data type represented by this message definition.
string package
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.
variant_topic_tools::MessageDefinition messageDefinition
Definition: info.cpp:30
void fill(const MessageDataType &currentDataType, MessageFieldCollection< DataType > &currentCollection)
Recursively fill the fields of the message definition.
std::string getName(void *handle)
Header file providing the MessageDefinitionParser class interface.
const std::string & getDefinition() const
Retrieve the message definition.
Definition: MessageType.cpp:90
size_t getNumMembers() const
Retrieve the number of members of this message data type.
void write(std::ostream &stream) const
Write the message definition to a stream.
static bool matchArray(const std::string &expression, std::string &name, std::string &memberType, size_t &size)
Match an array message member expression.
bool isValid() const
True, if this data type is valid.
Definition: DataType.cpp:133
void appendField(const MessageField< T > &field)
Append a field to the message field collection.
const std::string & getDefinition() const
Retrieve the definition this message data type.
Exception thrown in case of an invalid message type.
Definition: Exceptions.h:148
void load(const std::string &messageDataType)
Attempt to load the message definition for the specified message data type.
Header file defining exceptions for the variant topic tools.
void setMessageType()
Set the message type represented by this message definition (templated version)
const std::string & getDataType() const
Retrieve the data type of the message.
Definition: MessageType.cpp:74
MessageDataType getMessageDataType() const
Retrieve the message data type represented by this message definition.
Header file providing the DataTypeRegistry class interface.
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.
void clear()
Clear the message definition.
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.
bool isValid() const
True, if this message type is valid.
Definition: MessageType.cpp:94
static size_t parse(const std::string &messageDataType, const std::string &messageDefinition, std::vector< MessageType > &messageTypes)
Parse a message definition and generate the message types.
variant_topic_tools::MessageType messageType
Definition: publish.cpp:33
MessageDataType addMessageDataType(const std::string &identifier, const MessageFieldCollection< MessageConstant > &constantMembers=MessageFieldCollection< MessageConstant >(), const MessageFieldCollection< MessageVariable > &variableMembers=MessageFieldCollection< MessageVariable >())
Add a message data type to the data type registry (variant-typed version taking an identifier...
bool isValid() const
True, if this message definition is valid.
virtual void clear()
Clear the message field collection.
void setMessageDataType(const MessageDataType &messageDataType)
Set the message data type represented by this message definition.
Forward declaration of the message field collection.
Definition: Forwards.h:64


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