ADTF  3.18.2
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 
19 #include <ddl/dd/dd_error.h>
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  }
295  static void createNode(DOM_NODE_TYPE& parent_node,
297  const Version& file_ddl_version)
298  {
299  DOM_NODE_TYPE sub_node = parent_node.createChild("struct");
300  sub_node.setAttribute("name", struct_type.getName());
301  sub_node.setAttribute("version", struct_type.getVersion());
302 
303  setOptionalAttribute<size_t>(sub_node, "alignment", struct_type.getAlignment());
304  setOptionalAttribute(sub_node, "comment", struct_type.getComment());
305  if (struct_type.getLanguageVersion() != Version(0, 0)) {
306  sub_node.setAttribute("ddlversion",
307  VersionConversion::toString(struct_type.getLanguageVersion()));
308  }
309  const auto& elements = struct_type.getElements();
310  for (auto elem = elements.cbegin(); elem != elements.cend(); ++elem) {
311  auto current_elem = *elem;
312  createNode(sub_node, *current_elem, file_ddl_version);
313  }
314  }
321  static void createNode(DOM_NODE_TYPE& parent_node,
323  {
324  DOM_NODE_TYPE sub_node = parent_node.createChild("streammetatype");
325  sub_node.setAttribute("name", stream_meta_type.getName());
326  sub_node.setAttribute("version", stream_meta_type.getVersion());
327  setOptionalAttribute(sub_node, "parent", stream_meta_type.getParent());
328 
329  const auto& props = stream_meta_type.getProperties();
330  for (auto prop = props.cbegin(); prop != props.cend(); ++prop) {
331  DOM_NODE_TYPE sub_prop_node = sub_node.createChild("property");
332  sub_prop_node.setAttribute("name", prop->second->getName());
333  sub_prop_node.setAttribute("type", prop->second->getType());
334  }
335  }
336 
343  static void createNode(DOM_NODE_TYPE& parent_node, const datamodel::Stream& stream)
344  {
345  DOM_NODE_TYPE sub_node = parent_node.createChild("stream");
346  sub_node.setAttribute("name", stream.getName());
347  sub_node.setAttribute("type", stream.getStreamTypeName());
348  setOptionalAttribute(sub_node, "description", stream.getDescription());
349 
350  const auto& stream_structs = stream.getStructs();
351  for (auto stream_struct = stream_structs.cbegin(); stream_struct != stream_structs.cend();
352  ++stream_struct) {
353  DOM_NODE_TYPE sub_struct_node = sub_node.createChild("struct");
354  setOptionalAttribute(sub_struct_node, "name", (*stream_struct)->getName());
355  sub_struct_node.setAttribute("type", (*stream_struct)->getTypeName());
356  auto byte_pos = (*stream_struct)->getBytePos();
357  if (!byte_pos) {
358  byte_pos = 0;
359  }
360  sub_struct_node.setAttribute("bytepos", std::to_string(*byte_pos));
361  }
362  }
363 
370  static void createNode(DOM_NODE_TYPE& parent_node, const datamodel::DataDefinition& dd)
371  {
372  createNode(parent_node, *(dd.getHeader()));
373 
374  DOM_NODE_TYPE units_node = parent_node.createChild("units");
375  // write base unit types
376  const auto& base_units = dd.getBaseUnits();
377  for (auto base_unit = base_units.cbegin(); base_unit != base_units.cend(); ++base_unit) {
378  createNode(units_node, *(base_unit->second));
379  }
380  // write unit prefix types
381  const auto& unit_prefixes = dd.getUnitPrefixes();
382  for (auto unit_prefix = unit_prefixes.cbegin(); unit_prefix != unit_prefixes.cend();
383  ++unit_prefix) {
384  createNode(units_node, *(unit_prefix->second));
385  }
386  // write unit types
387  const auto& units = dd.getUnits();
388  for (auto unit = units.cbegin(); unit != units.cend(); ++unit) {
389  createNode(units_node, *(unit->second));
390  }
391 
392  // write data types
393  DOM_NODE_TYPE data_types_node = parent_node.createChild("datatypes");
394  const auto& data_types = dd.getDataTypes();
395  for (auto data_type = data_types.cbegin(); data_type != data_types.cend(); ++data_type) {
396  createNode(data_types_node, *(data_type->second), dd.getVersion());
397  }
398  // write enum types
399  DOM_NODE_TYPE enum_types_node = parent_node.createChild("enums");
400  const auto& enum_types = dd.getEnumTypes();
401  for (auto enum_type = enum_types.cbegin(); enum_type != enum_types.cend(); ++enum_type) {
402  createNode(enum_types_node, *(enum_type->second));
403  }
404  // write struct types
405  DOM_NODE_TYPE struct_types_node = parent_node.createChild("structs");
406  const auto& struct_types = dd.getStructTypes();
407  for (auto struct_type = struct_types.cbegin(); struct_type != struct_types.cend();
408  ++struct_type) {
409  createNode(struct_types_node, *(struct_type->second), dd.getVersion());
410  }
411 
412  // write stream meta types types
413  if (dd.getVersion() >= dd::Version(4, 0)) {
414  DOM_NODE_TYPE stream_meta_types_node = parent_node.createChild("streammetatypes");
415  const auto& stream_meta_types_types = dd.getStreamMetaTypes();
416  for (auto stream_meta_type = stream_meta_types_types.cbegin();
417  stream_meta_type != stream_meta_types_types.cend();
418  ++stream_meta_type) {
419  createNode(stream_meta_types_node, *(stream_meta_type->second));
420  }
421  }
422 
423  DOM_NODE_TYPE streams_node = parent_node.createChild("streams");
424  const auto& streams = dd.getStreams();
425  for (auto stream = streams.cbegin(); stream != streams.cend(); ++stream) {
426  createNode(streams_node, *(stream->second));
427  }
428  }
429 };
430 } // namespace dd
431 } // namespace ddl
432 
433 #endif // DD_DD_TO_XML_FACTORY_H_INCLUDED
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 & 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.
OO DataDefinition Optional Implementation.
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.