MessageDataType.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 <sstream>
20 
30 
31 namespace variant_topic_tools {
32 
33 /*****************************************************************************/
34 /* Constructors and Destructor */
35 /*****************************************************************************/
36 
38 }
39 
40 MessageDataType::MessageDataType(const std::string& identifier,
41  const MessageFieldCollection<MessageConstant>& constantMembers,
42  const MessageFieldCollection<MessageVariable>& variableMembers) {
44  new ImplV(identifier, constantMembers, variableMembers)));
45 }
46 
47 MessageDataType::MessageDataType(const std::string& identifier, const
48  std::string& definition) {
50  new ImplV(identifier, definition)));
51 }
52 
54  DataType(src) {
55 }
56 
58  DataType(src) {
59  if (impl)
60  BOOST_ASSERT(boost::dynamic_pointer_cast<Impl>(*impl));
61 }
62 
64 }
65 
67  constantMembers, const MessageFieldCollection<MessageVariable>&
68  variableMembers) :
69  constantMembers(constantMembers),
70  variableMembers(variableMembers) {
71  for (size_t i = 0; i < constantMembers.getNumFields(); ++i)
72  if (!constantMembers[i].isValid())
74 
75  for (size_t i = 0; i < variableMembers.getNumFields(); ++i)
76  if (!variableMembers[i].isValid())
78 }
79 
80 MessageDataType::Impl::Impl(const std::string& identifier, const std::string&
81  definition) {
82  BOOST_ASSERT(!definition.empty());
83 
84  std::string package, plainType;
85  if (!MessageTypeParser::matchType(identifier, package, plainType))
86  throw InvalidMessageTypeException(identifier);
87 
88  DataTypeRegistry registry;
89  std::istringstream stream(definition);
90  std::string line;
91 
92  while (std::getline(stream, line)) {
93  std::string memberName, memberType, memberValue;
94 
95  if (MessageDefinitionParser::matchVariable(line, memberName,
96  memberType)) {
97  std::string bareMemberType, memberPackage, plainMemberType;
98  bool isArrayMember = false;
99  size_t memberSize;
100 
101  if (MessageDefinitionParser::matchArray(line, memberName,
102  bareMemberType, memberSize))
103  isArrayMember = true;
104  else
105  bareMemberType = memberType;
106 
107  if (!MessageTypeParser::matchType(bareMemberType, memberPackage,
108  plainMemberType))
109  throw InvalidMessageTypeException(bareMemberType);
110 
111  if (!registry.getDataType(bareMemberType).isBuiltin()) {
112  if (memberPackage.empty()) {
113  if (plainMemberType == "Header")
114  memberPackage = "std_msgs";
115  else
116  memberPackage = package;
117 
118  if (isArrayMember) {
119  if (memberSize)
120  memberType = memberPackage+"/"+plainMemberType+"["+
121  boost::lexical_cast<std::string>(memberSize)+"]";
122  else
123  memberType = memberPackage+"/"+plainMemberType+"[]";
124  }
125  else
126  memberType = memberPackage+"/"+plainMemberType;
127  }
128  }
129 
130  if (registry.getDataType(memberType).isValid()) {
131  MessageVariable member(memberName, memberType);
132  variableMembers.appendField(memberName, member);
133  }
134  else
135  throw NoSuchDataTypeException(memberType);
136  }
137  else if (MessageDefinitionParser::matchConstant(line, memberName,
138  memberType, memberValue)) {
139  if (registry.getDataType(memberType).isValid()) {
140  MessageConstant member(memberName, memberType, memberValue);
141  constantMembers.appendField(memberName, member);
142  }
143  else
144  throw NoSuchDataTypeException(memberType);
145  }
147  break;
148  }
149 }
150 
152 }
153 
154 MessageDataType::ImplV::ImplV(const std::string& identifier,
157  Impl(constantMembers, variableMembers),
158  identifier(identifier) {
159  std::ostringstream stream;
160 
161  for (size_t i = 0; i < constantMembers.getNumFields(); ++i)
162  stream << constantMembers[i] << "\n";
163 
164  for (size_t i = 0; i < variableMembers.getNumFields(); ++i)
165  stream << variableMembers[i] << "\n";
166 
167  definition = stream.str();
168 
170 }
171 
172 MessageDataType::ImplV::ImplV(const std::string& identifier, const
173  std::string& definition) :
174  Impl(identifier, definition),
175  identifier(identifier),
176  definition(definition) {
178 }
179 
181 }
182 
183 /*****************************************************************************/
184 /* Accessors */
185 /*****************************************************************************/
186 
187 std::string MessageDataType::getMD5Sum() const {
188  if (impl)
189  return boost::static_pointer_cast<Impl>(*impl)->getMD5Sum();
190  else
191  return std::string("*");
192 }
193 
194 const std::string& MessageDataType::getDefinition() const {
195  if (!impl) {
196  static std::string definition;
197  return definition;
198  }
199  else
200  return boost::static_pointer_cast<Impl>(*impl)->getDefinition();
201 }
202 
205 }
206 
208  if (impl)
209  return boost::static_pointer_cast<Impl>(*impl)->constantMembers.
210  getNumFields();
211  else
212  return 0;
213 }
214 
216  if (impl)
217  return boost::static_pointer_cast<Impl>(*impl)->variableMembers.
218  getNumFields();
219  else
220  return 0;
221 }
222 
223 const MessageMember& MessageDataType::getMember(const std::string& name)
224  const {
225  if (hasConstantMember(name))
226  return boost::static_pointer_cast<Impl>(*impl)->constantMembers[name].
227  getValue();
228  else if (hasVariableMember(name))
229  return boost::static_pointer_cast<Impl>(*impl)->variableMembers[name].
230  getValue();
231  else
232  throw NoSuchMemberException(name);
233 }
234 
235 const MessageMember& MessageDataType::getMember(int index) const {
236  if (index >= 0) {
237  if (index < getNumConstantMembers())
238  return boost::static_pointer_cast<Impl>(*impl)->constantMembers[index].
239  getValue();
240  else if (index < getNumConstantMembers()+getNumVariableMembers())
241  return boost::static_pointer_cast<Impl>(*impl)->variableMembers[
242  index-getNumConstantMembers()].getValue();
243  }
244 
245  throw NoSuchMemberException(index);
246 }
247 
249  name) const {
250  if (hasConstantMember(name))
251  return boost::static_pointer_cast<Impl>(*impl)->constantMembers[name].
252  getValue();
253  else
254  throw NoSuchMemberException(name);
255 }
256 
258  if ((index >= 0) && (index < getNumConstantMembers()))
259  return boost::static_pointer_cast<Impl>(*impl)->constantMembers[index].
260  getValue();
261  else
262  throw NoSuchMemberException(index);
263 }
264 
266  name) const {
267  if (hasVariableMember(name))
268  return boost::static_pointer_cast<Impl>(*impl)->variableMembers[name].
269  getValue();
270  else
271  throw NoSuchMemberException(name);
272 }
273 
275  if ((index >= 0) && (index < getNumVariableMembers()))
276  return boost::static_pointer_cast<Impl>(*impl)->variableMembers[index].
277  getValue();
278  else
279  throw NoSuchMemberException(index);
280 }
281 
282 bool MessageDataType::hasMember(const std::string& name) const {
283  return hasConstantMember(name) || hasVariableMember(name);
284 }
285 
286 bool MessageDataType::hasConstantMember(const std::string& name) const {
287  if (impl)
288  return boost::static_pointer_cast<Impl>(*impl)->constantMembers.
289  hasField(name);
290  else
291  return false;
292 }
293 
294 bool MessageDataType::hasVariableMember(const std::string& name) const {
295  if (impl)
296  return boost::static_pointer_cast<Impl>(*impl)->variableMembers.
297  hasField(name);
298  else
299  return false;
300 }
301 
303  if (impl)
304  return (boost::static_pointer_cast<Impl>(*impl)->variableMembers.
305  hasField("header") &&
306  (boost::static_pointer_cast<Impl>(*impl)->variableMembers["header"].
307  getValue().getType().getIdentifier() == "std_msgs/Header"));
308  else
309  return false;
310 }
311 
312 const std::string& MessageDataType::ImplV::getIdentifier() const {
313  return identifier;
314 }
315 
317  return md5Sum.toString();
318 }
319 
320 const std::string& MessageDataType::ImplV::getDefinition() const {
321  return definition;
322 }
323 
325  if (isFixedSize()) {
326  size_t size = 0;
327 
328  for (size_t i = 0; i < variableMembers.getNumFields(); ++i)
329  size += variableMembers[i].getValue().getType().getSize();
330 
331  return size;
332  }
333  else
334  return 0;
335 }
336 
338  bool fixedSize = true;
339 
340  for (size_t i = 0; i < variableMembers.getNumFields(); ++i)
341  fixedSize &= variableMembers[i].getValue().getType().isFixedSize();
342 
343  return fixedSize;
344 }
345 
347  return false;
348 }
349 
350 /*****************************************************************************/
351 /* Methods */
352 /*****************************************************************************/
353 
355  if (impl)
356  boost::static_pointer_cast<Impl>(*impl)->addConstantMember(member);
357  else
358  throw InvalidDataTypeException();
359 }
360 
362  const Variant& value) {
363  MessageConstant member(name, value);
364  addConstantMember(member);
365 
366  return member;
367 }
368 
370  if (impl)
371  boost::static_pointer_cast<Impl>(*impl)->addVariableMember(member);
372  else
373  throw InvalidDataTypeException();
374 }
375 
377  const DataType& type) {
378  MessageVariable member(name, type);
379  addVariableMember(member);
380 
381  return member;
382 }
383 
385  const {
386  MessageFieldCollection<Serializer> memberSerializers;
387 
388  for (size_t i = 0; i < variableMembers.getNumFields(); ++i)
389  memberSerializers.appendField(variableMembers[i].getName(),
390  variableMembers[i].getValue().getType().createSerializer());
391 
392  return MessageSerializer(memberSerializers);
393 }
394 
397 
398  for (size_t i = 0; i < variableMembers.getNumFields(); ++i)
399  members.appendField(variableMembers[i].getName(),
400  variableMembers[i].getValue().getType().createVariant());
401 
402  return MessageVariant(type, members);
403 }
404 
406  member) {
407  constantMembers.appendField(member.getName(), member);
408 
409  std::ostringstream stream;
410  stream << member << "\n";
411 
412  definition += stream.str();
413 
415 }
416 
418  member) {
419  variableMembers.appendField(member.getName(), member);
420 
421  std::ostringstream stream;
422  stream << member << "\n";
423 
424  definition += stream.str();
425 
427 }
428 
430  std::ostringstream stream;
431 
432  for (size_t i = 0; i < constantMembers.getNumFields(); ++i) {
433  const MessageConstant& constantMember = constantMembers[i].getValue();
434 
435  stream << constantMember.getType().getIdentifier() << " " <<
436  constantMember.getName() << "=" << constantMember.getValue() << "\n";
437  }
438 
439  for (size_t i = 0; i < variableMembers.getNumFields(); ++i) {
440  const MessageVariable& variableMember = variableMembers[i].getValue();
441 
442  DataType memberType = variableMember.getType();
443  DataType bareMemberType = memberType;
444 
445  while (bareMemberType.isArray()) {
446  ArrayDataType arrayMemberType = bareMemberType;
447  bareMemberType = arrayMemberType.getMemberType();
448  }
449 
450  if (bareMemberType.isBuiltin()) {
451  stream << memberType.getIdentifier() << " " <<
452  variableMember.getName() << "\n";
453  }
454  else if (bareMemberType.isMessage()) {
455  MessageDataType messageMemberType = bareMemberType;
456  stream << messageMemberType.getMD5Sum() << " " <<
457  variableMember.getName() << "\n";
458  }
459  }
460 
461  std::string md5SumText = stream.str();
462  if (!md5SumText.empty())
463  md5SumText.erase(md5SumText.size()-1);
464 
465  md5Sum.clear();
466  md5Sum.update(md5SumText);
467 }
468 
469 /*****************************************************************************/
470 /* Operators */
471 /*****************************************************************************/
472 
474  DataType::operator=(src);
475 
476  if (impl)
477  BOOST_ASSERT(boost::dynamic_pointer_cast<MessageDataType::Impl>(*impl));
478 
479  return *this;
480 }
481 
483  return getMember(index);
484 }
485 
486 }
void addVariableMember(const MessageVariable &member)
Add a variable member to this message data type (implementation)
static bool matchConstant(const std::string &expression, std::string &name, std::string &type, std::string &value)
Match a constant message member expression.
void addVariableMember(const MessageVariable &member)
Add a variable member to this message data type (overloaded version taking a message variable) ...
Header file providing the MessageMember class interface.
Exception thrown in case of an invalid data type.
Definition: Exceptions.h:51
MD5Sum md5Sum
The MD5 sum of this message data type.
string package
MessageFieldCollection< MessageConstant > constantMembers
The constant members of this message data type.
MessageDataType & operator=(const DataType &src)
Assignment operator.
MessageDataType()
Default constructor.
std::string getMD5Sum() const
Retrieve the MD5 sum of this message data type (implementation)
Header file providing the MessageVariant class interface.
MessageFieldCollection< MessageVariable > variableMembers
The variable members of this message data type.
bool isArray() const
True, if this data type represents an array type.
Definition: DataType.cpp:98
bool hasMember(const std::string &name) const
True, if the message data type contains the member with the specified name.
bool isMessage() const
True, if this data type represents a message type.
Definition: DataType.cpp:112
Header file providing the MessageDefinitionParser class interface.
static bool matchSeparator(const std::string &expression)
Match a separator expression.
size_t getNumVariableMembers() const
Retrieve the number of variable members of this message data type.
bool isSimple() const
True, if this data type represents a simple data type (implementation)
std::string getMD5Sum() const
Retrieve the MD5 sum of this message data type.
void addConstantMember(const MessageConstant &member)
Add a constant member to this message data type (implementation)
virtual const std::string & getDefinition() const =0
Retrieve the definition this message data type (abstract declaration)
size_t getNumMembers() const
Retrieve the number of members of this message data type.
void addConstantMember(const MessageConstant &member)
Add a constant member to this message data type (overloaded version taking a message constant) ...
void update(const std::string &text)
Update the MD5 sum using the given string.
Definition: MD5Sum.cpp:108
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
ImplPtr impl
The data type&#39;s implementation adapter.
Definition: DataType.h:226
void appendField(const MessageField< T > &field)
Append a field to the message field collection.
const MessageConstant & getConstantMember(const std::string &name) const
Access a constant member of the message data type by name.
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
const std::string & getIdentifier() const
Retrieve the identifier representing this data type.
Definition: DataType.cpp:75
Message data type implementation (variant-typed version)
const std::string & getIdentifier() const
Retrieve the identifier representing this data type (implementation)
const Variant & getValue() const
Retrieve the value of this message constant.
Header file defining exceptions for the variant topic tools.
const std::string & getName() const
Retrieve the name of this message member.
std::string toString() const
Convert the MD5 sum to a hexadecimal format string.
Definition: MD5Sum.cpp:128
Header file providing the DataTypeRegistry class interface.
virtual DataType & operator=(const DataType &src)
Assignment operator.
Definition: DataType.cpp:179
Header file providing the MessageDataType class interface.
const MessageVariable & getVariableMember(const std::string &name) const
Access a variable member of the message data type by name.
DataType getDataType(const std::string &identifier)
Retrieve a data type from the registry by identifier (non-const version)
ImplV(const std::string &identifier, const MessageFieldCollection< MessageConstant > &constantMembers, const MessageFieldCollection< MessageVariable > &variableMembers)
Constructor (overloaded version taking an identifier, a sequence of constant members, and a sequence of variable members)
Header file providing the MessageConstant class interface.
const std::string & getDefinition() const
Retrieve the definition this message data type (implementation)
size_t getSize() const
Retrieve the size of the instances of this data type (implementation)
void clear()
Clear the MD5 sum.
Definition: MD5Sum.cpp:117
static bool matchType(const std::string &expression, std::string &package, std::string &type)
Match any message type expression.
Exception thrown in case of an invalid message member.
Definition: Exceptions.h:127
virtual void addConstantMember(const MessageConstant &member)=0
Add a constant member to this message data type (abstract declaration)
Header file providing the MessageTypeParser class interface.
void recalculateMD5Sum()
Re-calculate the MD5 sum of this message data type.
virtual void addVariableMember(const MessageVariable &member)=0
Add a variable member to this message data type (abstract declaration)
Serializer createSerializer(const DataType &type) const
Create a serializer for this data type (re-implementation)
const DataType & getType() const
Retrieve the type of this message member.
bool hasVariableMember(const std::string &name) const
True, if the message data type contains the variable member with the specified name.
Message data type implementation.
const MessageMember & getMember(const std::string &name) const
Access a member of the message data type by name.
size_t getNumConstantMembers() const
Retrieve the number of constant members of this message data type.
bool hasConstantMember(const std::string &name) const
True, if the message data type contains the constant member with the specified name.
const MessageMember & operator[](int index) const
Operator for accessing the members of the message data type by index.
bool isBuiltin() const
True, if this data type represents a built-in type.
Definition: DataType.cpp:105
Exception thrown in case of a non-existent data type.
Definition: Exceptions.h:72
virtual std::string getMD5Sum() const =0
Retrieve the MD5 sum of this message data type (abstract declaration)
Variant createVariant(const DataType &type) const
Create a variant from this data type (re-implementation)
size_t getNumFields() const
Retrieve the number of fields of the message field collection.
bool hasHeader() const
True, if this message data type has a header.
const DataType & getMemberType() const
Retrieve the member type of this array data type.
Header file providing the MessageVariable class interface.
Exception thrown in case of a non-existent member.
Definition: Exceptions.h:113
std::string definition
The definition of this message data type.
static bool matchVariable(const std::string &expression, std::string &name, std::string &type)
Match a variable message member expression.
bool isFixedSize() const
True, if this data type represents a fixed-size data type (implementation)
Forward declaration of the message field collection.
Definition: Forwards.h:64
std::string identifier
The identifier representing this message data type.


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