ADTF
xml_ddtoxml_factory.h
Go to the documentation of this file.
1 
15 #ifndef DD_DD_TO_XML_FACTORY_H_INCLUDED
16 #define DD_DD_TO_XML_FACTORY_H_INCLUDED
17 
22 
23 #include <stdexcept>
24 #include <string>
25 
26 namespace ddl {
27 namespace dd {
28 
37 template <typename DOM_NODE_TYPE>
49  template <typename T>
50  static bool setOptionalAttribute(DOM_NODE_TYPE& dom_node,
51  const char* attribute_name,
52  const utility::Optional<T>& value)
53  {
54  if (value) {
55  dom_node.setAttribute(attribute_name, std::to_string(*value));
56  return true;
57  }
58  return false;
59  }
60 
71  static bool setOptionalAttribute(DOM_NODE_TYPE& dom_node,
72  const char* attribute_name,
73  const std::string& value)
74  {
75  if (!value.empty()) {
76  dom_node.setAttribute(attribute_name, value);
77  return true;
78  }
79  return false;
80  }
81 
89  static void setData(DOM_NODE_TYPE& dom_node,
90  const std::string& sub_node_name,
91  const std::string& value)
92  {
93  DOM_NODE_TYPE sub_node = dom_node.createChild(sub_node_name);
94  sub_node.setData(value);
95  }
96 
103  static void createNode(DOM_NODE_TYPE& parent_node, const datamodel::Header& header)
104  {
105  DOM_NODE_TYPE sub_node = parent_node.createChild("header");
106  setData(
107  sub_node, "language_version", VersionConversion::toString(header.getLanguageVersion()));
108  setData(sub_node, "author", header.getAuthor());
109  setData(sub_node, "date_creation", header.getDateCreation());
110  setData(sub_node, "date_change", header.getDateChange());
111  setData(sub_node, "description", header.getDescription());
112  const auto& declarations = header.getExtDeclarations();
113  for (auto ext = declarations.cbegin(); ext != declarations.cend(); ++ext) {
114  DOM_NODE_TYPE sub_ext_node = sub_node.createChild("ext_declaration");
115  sub_ext_node.setAttribute("key", ext->second->getKey());
116  sub_ext_node.setAttribute("value", ext->second->getValue());
117  }
118  }
119 
126  static void createNode(DOM_NODE_TYPE& parent_node, const datamodel::BaseUnit& base_unit)
127  {
128  DOM_NODE_TYPE sub_node = parent_node.createChild("baseunit");
129  sub_node.setAttribute("name", base_unit.getName());
130  sub_node.setAttribute("symbol", base_unit.getSymbol());
131  sub_node.setAttribute("description", base_unit.getDescription());
132  }
133 
140  static void createNode(DOM_NODE_TYPE& parent_node, const datamodel::UnitPrefix& unit_prefix)
141  {
142  DOM_NODE_TYPE sub_node = parent_node.createChild("prefixes");
143  sub_node.setAttribute("name", unit_prefix.getName());
144  auto power = std::to_string(unit_prefix.getPower());
145  sub_node.setAttribute("power", power);
146  sub_node.setAttribute("symbol", unit_prefix.getSymbol());
147  }
148 
155  static void createNode(DOM_NODE_TYPE& parent_node, const datamodel::Unit& unit)
156  {
157  DOM_NODE_TYPE sub_node = parent_node.createChild("unit");
158  sub_node.setAttribute("name", unit.getName());
159  setData(sub_node, "numerator", unit.getNumerator());
160  setData(sub_node, "denominator", unit.getDenominator());
161  setData(sub_node, "offset", unit.getOffset());
162  const auto& ref_units = unit.getRefUnits();
163  for (auto ref_unit = ref_units.cbegin(); ref_unit != ref_units.cend(); ++ref_unit) {
164  DOM_NODE_TYPE sub_node_elem = sub_node.createChild("refUnit");
165  sub_node_elem.setAttribute("name", (*ref_unit).getUnitName());
166  sub_node_elem.setAttribute("power", std::to_string((*ref_unit).getPower()));
167  sub_node_elem.setAttribute("prefix", (*ref_unit).getPrefixName());
168  }
169  }
170 
178  static void createNode(DOM_NODE_TYPE& parent_node,
180  const Version& file_ddl_version)
181  {
182  DOM_NODE_TYPE sub_node = parent_node.createChild("datatype");
183  // changes between 2.0 and 3.0
184  // attribute name changed to "name" from "type"
185  // mandatory
186  if (file_ddl_version >= Version(3, 0)) {
187  sub_node.setAttribute("name", data_type.getName());
188  }
189  else {
190  sub_node.setAttribute("type", data_type.getName());
191  }
192  sub_node.setAttribute("size", std::to_string(data_type.getBitSize()));
193  // optional
194  setOptionalAttribute(sub_node, "description", data_type.getDescription());
195  setOptionalAttribute<size_t>(sub_node, "arraysize", data_type.getArraySize());
196  setOptionalAttribute(sub_node, "unit", data_type.getUnitName());
197  // min / max introduced in DataDefinition 3.0
198  if (file_ddl_version >= Version(3, 0)) {
199  setOptionalAttribute(sub_node, "min", data_type.getMin());
200  setOptionalAttribute(sub_node, "max", data_type.getMax());
201  }
202  }
203 
210  static void createNode(DOM_NODE_TYPE& parent_node, const datamodel::EnumType& enum_type)
211  {
212  DOM_NODE_TYPE sub_node = parent_node.createChild("enum");
213  sub_node.setAttribute("name", enum_type.getName());
214  sub_node.setAttribute("type", enum_type.getDataTypeName());
215  const auto& elems = enum_type.getElements();
216  for (auto elem = elems.cbegin(); elem != elems.cend(); ++elem) {
217  DOM_NODE_TYPE sub_node_elem = sub_node.createChild("element");
218  sub_node_elem.setAttribute("name", elem->second->getName());
219  sub_node_elem.setAttribute("value", elem->second->getValue());
220  }
221  }
222 
230  static void createNode(DOM_NODE_TYPE& parent_node,
231  const datamodel::StructType::Element& element,
232  const Version& file_ddl_version)
233  {
234  DOM_NODE_TYPE sub_node = parent_node.createChild("element");
235  sub_node.setAttribute("name", element.getName());
236  sub_node.setAttribute("type", element.getTypeName());
237 
238  // From version 4.0 on this information is specified within the <deserialized> tag.
239  DOM_NODE_TYPE* serialized_node = &sub_node;
240  DOM_NODE_TYPE serialized_node_version_40;
241  if (file_ddl_version >= Version(4, 0)) {
242  serialized_node_version_40 = sub_node.createChild("serialized");
243  serialized_node = &serialized_node_version_40;
244  }
245  serialized_node->setAttribute("bytepos", std::to_string(*element.getBytePos()));
246  serialized_node->setAttribute("byteorder",
248  setOptionalAttribute<size_t>(*serialized_node, "bitpos", element.getBitPos());
249  setOptionalAttribute<size_t>(*serialized_node, "numbits", element.getNumBits());
250  // From version 4.0 on this information is specified within the <serialized> tag.
251  DOM_NODE_TYPE* deserialized_node = &sub_node;
252  DOM_NODE_TYPE deserialized_node_version_40;
253  if (file_ddl_version >= Version(4, 0)) {
254  deserialized_node_version_40 = sub_node.createChild("deserialized");
255  deserialized_node = &deserialized_node_version_40;
256  }
257  deserialized_node->setAttribute("alignment", std::to_string(element.getAlignment()));
258  // optional
259  setOptionalAttribute(sub_node, "description", element.getDescription());
260  setOptionalAttribute(sub_node, "unit", element.getUnitName());
261  setOptionalAttribute(sub_node, "comment", element.getComment());
262 
263  // in DataDefinition 2.0 dynamic arrays are introduced
264  if (file_ddl_version >= Version(2, 0) && element.getArraySize().isDynamicArraySize()) {
266  sub_node, "arraysize", element.getArraySize().getArraySizeElementName());
267  }
268  else {
269  auto array_size = element.getArraySize().getArraySizeValue();
270  if (array_size == 0) {
271  array_size = 1;
272  }
273  sub_node.setAttribute("arraysize", std::to_string(array_size));
274  }
275  // introduced in DataDefinition 2.0
276  if (file_ddl_version >= Version(2, 0)) {
277  setOptionalAttribute(sub_node, "value", element.getValue());
278  }
279  // introduced in DataDefinition 3.0
280  if (file_ddl_version >= Version(3, 0)) {
281  setOptionalAttribute(sub_node, "min", element.getMin());
282  setOptionalAttribute(sub_node, "max", element.getMax());
283  setOptionalAttribute(sub_node, "default", element.getDefault());
284  setOptionalAttribute(sub_node, "scale", element.getScale());
285  setOptionalAttribute(sub_node, "offset", element.getOffset());
286  }
287  if (file_ddl_version >= Version(4, 2)) {
288  setOptionalAttribute(sub_node, "valid_element_count", element.getValidElementCount());
289  }
290  }
298  static void createNode(DOM_NODE_TYPE& parent_node,
300  const Version& file_ddl_version)
301  {
302  DOM_NODE_TYPE sub_node = parent_node.createChild("struct");
303  sub_node.setAttribute("name", struct_type.getName());
304  sub_node.setAttribute("version", struct_type.getVersion());
305 
306  setOptionalAttribute<size_t>(sub_node, "alignment", struct_type.getAlignment());
307  setOptionalAttribute(sub_node, "comment", struct_type.getComment());
308  if (struct_type.getLanguageVersion() != Version(0, 0)) {
309  sub_node.setAttribute("ddlversion",
310  VersionConversion::toString(struct_type.getLanguageVersion()));
311  }
312  const auto& elements = struct_type.getElements();
313  for (auto elem = elements.cbegin(); elem != elements.cend(); ++elem) {
314  auto current_elem = *elem;
315  createNode(sub_node, *current_elem, file_ddl_version);
316  }
317  }
324  static void createNode(DOM_NODE_TYPE& parent_node,
326  {
327  DOM_NODE_TYPE sub_node = parent_node.createChild("streammetatype");
328  sub_node.setAttribute("name", stream_meta_type.getName());
329  sub_node.setAttribute("version", stream_meta_type.getVersion());
330  setOptionalAttribute(sub_node, "parent", stream_meta_type.getParent());
331 
332  const auto& props = stream_meta_type.getProperties();
333  for (auto prop = props.cbegin(); prop != props.cend(); ++prop) {
334  DOM_NODE_TYPE sub_prop_node = sub_node.createChild("property");
335  sub_prop_node.setAttribute("name", prop->second->getName());
336  sub_prop_node.setAttribute("type", prop->second->getType());
337  }
338  }
339 
346  static void createNode(DOM_NODE_TYPE& parent_node, const datamodel::Stream& stream)
347  {
348  DOM_NODE_TYPE sub_node = parent_node.createChild("stream");
349  sub_node.setAttribute("name", stream.getName());
350  sub_node.setAttribute("type", stream.getStreamTypeName());
351  setOptionalAttribute(sub_node, "description", stream.getDescription());
352 
353  const auto& stream_structs = stream.getStructs();
354  for (auto stream_struct = stream_structs.cbegin(); stream_struct != stream_structs.cend();
355  ++stream_struct) {
356  DOM_NODE_TYPE sub_struct_node = sub_node.createChild("struct");
357  setOptionalAttribute(sub_struct_node, "name", (*stream_struct)->getName());
358  sub_struct_node.setAttribute("type", (*stream_struct)->getTypeName());
359  auto byte_pos = (*stream_struct)->getBytePos();
360  if (!byte_pos) {
361  byte_pos = 0;
362  }
363  sub_struct_node.setAttribute("bytepos", std::to_string(*byte_pos));
364  }
365  }
366 
373  static void createNode(DOM_NODE_TYPE& parent_node, const datamodel::DataDefinition& dd)
374  {
375  createNode(parent_node, *(dd.getHeader()));
376 
377  DOM_NODE_TYPE units_node = parent_node.createChild("units");
378  // write base unit types
379  const auto& base_units = dd.getBaseUnits();
380  for (auto base_unit = base_units.cbegin(); base_unit != base_units.cend(); ++base_unit) {
381  createNode(units_node, *(base_unit->second));
382  }
383  // write unit prefix types
384  const auto& unit_prefixes = dd.getUnitPrefixes();
385  for (auto unit_prefix = unit_prefixes.cbegin(); unit_prefix != unit_prefixes.cend();
386  ++unit_prefix) {
387  createNode(units_node, *(unit_prefix->second));
388  }
389  // write unit types
390  const auto& units = dd.getUnits();
391  for (auto unit = units.cbegin(); unit != units.cend(); ++unit) {
392  createNode(units_node, *(unit->second));
393  }
394 
395  // write data types
396  DOM_NODE_TYPE data_types_node = parent_node.createChild("datatypes");
397  const auto& data_types = dd.getDataTypes();
398  for (auto data_type = data_types.cbegin(); data_type != data_types.cend(); ++data_type) {
399  createNode(data_types_node, *(data_type->second), dd.getVersion());
400  }
401  // write enum types
402  DOM_NODE_TYPE enum_types_node = parent_node.createChild("enums");
403  const auto& enum_types = dd.getEnumTypes();
404  for (auto enum_type = enum_types.cbegin(); enum_type != enum_types.cend(); ++enum_type) {
405  createNode(enum_types_node, *(enum_type->second));
406  }
407  // write struct types
408  DOM_NODE_TYPE struct_types_node = parent_node.createChild("structs");
409  const auto& struct_types = dd.getStructTypes();
410  for (auto struct_type = struct_types.cbegin(); struct_type != struct_types.cend();
411  ++struct_type) {
412  createNode(struct_types_node, *(struct_type->second), dd.getVersion());
413  }
414 
415  // write stream meta types types
416  if (dd.getVersion() >= dd::Version(4, 0)) {
417  DOM_NODE_TYPE stream_meta_types_node = parent_node.createChild("streammetatypes");
418  const auto& stream_meta_types_types = dd.getStreamMetaTypes();
419  for (auto stream_meta_type = stream_meta_types_types.cbegin();
420  stream_meta_type != stream_meta_types_types.cend();
421  ++stream_meta_type) {
422  createNode(stream_meta_types_node, *(stream_meta_type->second));
423  }
424  }
425 
426  DOM_NODE_TYPE streams_node = parent_node.createChild("streams");
427  const auto& streams = dd.getStreams();
428  for (auto stream = streams.cbegin(); stream != streams.cend(); ++stream) {
429  createNode(streams_node, *(stream->second));
430  }
431  }
432 };
433 } // namespace dd
434 } // namespace ddl
435 
436 #endif // DD_DD_TO_XML_FACTORY_H_INCLUDED
OO DataDefinition Optional Implementation.
bool isDynamicArraySize() const
indicates if this is a dynamic erray size.
size_t getArraySizeValue() const
get the array size
const std::string & getArraySizeElementName() const
gets the dynamic array size
static std::string toString(ByteOrder byte_order)
convert byte_order to a string.
static std::string toString(const Version &version)
Version to string conversion.
DataDefinition Datamodel This datamodel is observable for any change of:
const EnumTypes & getEnumTypes() const
Get the Enum Types object.
const BaseUnits & getBaseUnits() const
Get the Base Units object.
const StructTypes & getStructTypes() const
Get the Struct Types object.
std::shared_ptr< const Header > getHeader() const
Get the Header object.
const StreamMetaTypes & getStreamMetaTypes() const
Get the Stream Meta Types object.
const DataTypes & getDataTypes() const
Get the Data Types object.
const Streams & getStreams() const
Get the Streams object.
const Units & getUnits() const
Get the Units object.
Version getVersion() const
Get the DDL Version.
const UnitPrefixes & getUnitPrefixes() const
Get the Unit Prefixes object.
observable DataDefinition object class to describe (POD) DataType.
observable DataDefinition object class to describe EnumType.
Data Definition datamodel for the Header.
const ExtDeclarations & getExtDeclarations() const
Get the Ext Declarations object.
const std::string & getDescription() const
Get the Description.
const std::string & getAuthor() const
Get the Author.
Version getLanguageVersion() const
Get the Language Version.
const std::string & getDateCreation() const
Get the Date of Creation.
const std::string & getDateChange() const
Get the Date of last Change.
observable Stream DataDefinition object.
const std::string & getDescription() const
Get the Description.
const Structs & getStructs() const
Get the Structs object.
const std::string & getName() const
Get the Name.
const std::string & getStreamTypeName() const
Get the Stream Type Name.
observable DataDefinition object class to describe StreamMetaType.
virtual size_t getAlignment() const
Get the Alignment.
observable DataDefinition object class for a Element of a StructType.
const std::string & getTypeName() const
Get the Type Name.
const std::string & getDescription() const
Get the Description.
const std::string & getScale() const
Get the Scale (for information only)
const ArraySize & getArraySize() const
Get the Array Size.
const std::string & getComment() const
Get the Comment.
const std::string & getValue() const
Get the value.
const std::string & getMax() const
Get the Max (for information only).
const std::string & getValidElementCount() const
Get the Valid Element Count element name.
const std::string & getName() const
Get the Name.
const std::string & getMin() const
Get the Min (for information only).
const std::string & getUnitName() const
Get the Unit Name.
const std::string & getDefault() const
Get the Default object.
const std::string & getOffset() const
Get the Offset (for information only)
ByteOrder getByteOrder() const
Get the Byte Order.
OptionalSize getBytePos() const
Get the Byte Pos.
OptionalSize getBitPos() const
Get the Bit Pos (if set)
OptionalSize getNumBits() const
Get the Num Bits (if set)
observable DataDefinition object class to describe StructType.
Unit Prefix - datamodel pefixes.
const std::string & getSymbol() const
Get the Symbol.
const std::string & getName() const
Get the Name.
int32_t getPower() const
Get the Power.
OO DataDefinition Redesign.
cString to_string(const tResult &i_oResult, eResultFormatFlags i_eFormatFlags=eResultFormatFlags::RFF_DisableNone, const tChar *i_strFormat=nullptr)
Copy all information of an assigned result object to a (formatted) string.
@ enum_type
the type is a enum type (EnumType)
@ data_type
the type is a data type (DataType)
@ struct_type
the type is a struct type (StructType)
@ stream_meta_type
the type is an stream meta type (StreamMetaType)
@ unit
the unit is a unit (Unit)
@ base_unit
the unit is a base unit (BaseUnit)
Utility for the Neutrino gcc5 compiler which has really no std::to_string implementation!
Template class to create DD DOM nodes with the help of the type DOM_NODE_TYPE.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::BaseUnit &base_unit)
Create a Node for the base_unit.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::DataDefinition &dd)
Create a Node for the DD.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::StructType::Element &element, const Version &file_ddl_version)
Create a Node for the struct_type element.
static bool setOptionalAttribute(DOM_NODE_TYPE &dom_node, const char *attribute_name, const std::string &value)
Set the Optional Attribute.
static void setData(DOM_NODE_TYPE &dom_node, const std::string &sub_node_name, const std::string &value)
Set the data of the new created tag with the name sub_node_name.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::EnumType &enum_type)
Create a Node for the enum_type.
static bool setOptionalAttribute(DOM_NODE_TYPE &dom_node, const char *attribute_name, const utility::Optional< T > &value)
Set the Optional Attribute.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::Header &header)
Create a Node for the header.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::DataType &data_type, const Version &file_ddl_version)
Create a Node for the data_type.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::Unit &unit)
Create a Node for the unit.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::UnitPrefix &unit_prefix)
Create a Node for the unit_prefix.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::Stream &stream)
Create a Node for the stream.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::StructType &struct_type, const Version &file_ddl_version)
Create a Node for the struct_type.
static void createNode(DOM_NODE_TYPE &parent_node, const datamodel::StreamMetaType &stream_meta_type)
Create a Node for the stream_meta_type.
An optional template as long as the std::optional is not available here.
OO DataDefinition Redesign.