ADTF  3.18.2
xml_ddfromxml_factory.h
Go to the documentation of this file.
1 
15 #ifndef DD_DD_FROM_XML_FACTORY_H_INCLUDED
16 #define DD_DD_FROM_XML_FACTORY_H_INCLUDED
17 
19 #include <ddl/dd/dd_error.h>
24 
25 #include <list>
26 #include <regex>
27 #include <stdexcept>
28 #include <string>
29 
30 namespace ddl {
31 namespace dd {
44 template <typename DOM_NODE_TYPE>
51  static bool isInteger(const std::string& string_to_check)
52  {
53  return utility::isInteger(string_to_check);
54  }
55 
63  static utility::Optional<int> toType(const std::string& from_string,
64  const utility::Optional<int>& default_value = {})
65  {
66  try {
67  int i_converted = std::stoi(from_string);
68  return i_converted;
69  }
70  catch (const std::invalid_argument&) {
71  return default_value;
72  }
73  catch (const std::exception&) {
74  return default_value;
75  }
76  }
77 
85  static utility::Optional<size_t> toType(const std::string& from_string,
86  const utility::Optional<size_t>& default_value = {})
87  {
88  try {
89  int size_converted = std::stoi(from_string);
90  if (size_converted < 0) {
91  // this is if we set i.e. the bytepos to -1 if it is after a dynamic array
92  return default_value;
93  }
94  else {
95  return size_converted;
96  }
97  }
98  catch (const std::invalid_argument&) {
99  return default_value;
100  }
101  catch (const std::exception&) {
102  return default_value;
103  }
104  }
105 
115  const std::string& from_string, const utility::Optional<std::string>& default_value = {})
116  {
117  if (from_string.empty()) {
118  return default_value;
119  }
120  else {
121  return from_string;
122  }
123  }
124 
141  template <typename T>
142  static utility::Optional<T> getAttribute(const DOM_NODE_TYPE& dom_node,
143  const char* attribute_name,
144  const utility::Optional<T>& default_value = {},
145  bool is_mandatory = false,
146  const std::string& parse_error_message = {})
147  {
148  auto value = dom_node.getAttribute(attribute_name);
149  if (value.empty()) {
150  if (is_mandatory) {
151  throw Error(
152  "DDFromXMLFactory::getAttribute", {"...", attribute_name}, parse_error_message);
153  }
154  return default_value;
155  }
156  else {
157  return toType(value, default_value);
158  }
159  }
160 
177  template <typename T>
178  static utility::Optional<T> getData(const DOM_NODE_TYPE& dom_node,
179  const std::string& sub_node_name,
180  const utility::Optional<T>& default_value = {},
181  bool is_mandatory = false,
182  const char* parse_error_message = "")
183  {
184  DOM_NODE_TYPE sub_node;
185  std::string value = {};
186  if (dom_node.findNode(sub_node_name, sub_node)) {
187  value = sub_node.getData();
188  }
189  if (value.empty()) {
190  if (is_mandatory) {
191  throw Error(
192  "DDFromXMLFactory::getData", {"...", sub_node_name}, parse_error_message);
193  }
194  return default_value;
195  }
196  else {
197  return toType(value, default_value);
198  }
199  }
200 
209  const DOM_NODE_TYPE& dom_node)
210  {
211  auto key_attrib = getAttribute<std::string>(
212  dom_node,
213  "key",
214  {},
215  true,
216  "header/ext_declaration tag has no mandatory 'key' attribute");
217  auto value_attrib = getAttribute<std::string>(
218  dom_node,
219  "value",
220  {},
221  true,
222  "header/ext_declaration tag has no mandatory 'value' attribute");
223  return datamodel::Header::ExtDeclaration(*key_attrib, *value_attrib);
224  }
225 
232  static datamodel::Header createHeader(const DOM_NODE_TYPE& dom_node)
233  {
234  // read header exts
235  std::vector<datamodel::Header::ExtDeclaration> exts;
236  std::list<DOM_NODE_TYPE> header_ext_nodes;
237  if (dom_node.findNodes("ext_declaration", header_ext_nodes)) {
238  for (const auto& current_header_ext_node: header_ext_nodes) {
239  exts.emplace_back(createHeaderExtDeclaration(current_header_ext_node));
240  }
241  }
242  // read the header itself
243  Version version_to_set = {};
244  auto file_ddl_version = getData<std::string>(dom_node, "language_version", {});
245  if (file_ddl_version) {
246  version_to_set = VersionConversion::fromString(*file_ddl_version);
247  }
248  datamodel::Header created_header(version_to_set, {}, {}, {}, {}, exts);
249 
250  auto author = getData<std::string>(dom_node, "author", {});
251  if (author) {
252  created_header.setAuthor(author);
253  }
254  auto date_crea = getData<std::string>(dom_node, "date_creation", {});
255  if (date_crea) {
256  created_header.setDateCreation(date_crea);
257  }
258  auto date_cha = getData<std::string>(dom_node, "date_change", {});
259  if (date_cha) {
260  created_header.setDateChange(date_cha);
261  }
262  auto description = getData<std::string>(dom_node, "description", {});
263  if (description) {
264  created_header.setDescription(description);
265  }
266  return created_header;
267  }
268 
275  static datamodel::BaseUnit createBaseUnit(const DOM_NODE_TYPE& dom_node)
276  {
277  auto name = getAttribute<std::string>(
278  dom_node, "name", {}, true, "baseunit tag has no mandatory 'name' attribute");
279  auto symbol = getAttribute<std::string>(dom_node, "symbol", std::string(""));
280  auto description = getAttribute<std::string>(dom_node, "description", std::string(""));
281  return datamodel::BaseUnit(*name, *symbol, *description);
282  }
283 
290  static datamodel::UnitPrefix createUnitPrefix(const DOM_NODE_TYPE& dom_node)
291  {
292  auto name = getAttribute<std::string>(
293  dom_node, "name", {}, true, "prefixes tag has no mandatory 'name' attribute");
294  auto symbol = getAttribute<std::string>(
295  dom_node, "symbol", {}, true, "prefixes tag has no mandatory 'symbol' attribute");
296  auto power = getAttribute<int32_t>(
297  dom_node, "power", {}, true, "prefixes tag has no mandatory 'power' attribute");
298  return datamodel::UnitPrefix(*name, *symbol, *power);
299  }
300 
307  static datamodel::Unit::RefUnit createRefUnit(const DOM_NODE_TYPE& dom_node)
308  {
309  auto unit_name = getAttribute<std::string>(
310  dom_node, "name", {}, true, "unit/refUnit tag has no mandatory 'name' attribute");
311  auto power = getAttribute<int32_t>(
312  dom_node, "power", {}, true, "unit/refUnit tag has no mandatory 'power' attribute");
313  auto prefix_name = getAttribute<std::string>(
314  dom_node, "prefix", {}, true, "unit/refUnit tag has no mandatory 'prefix' attribute");
315  return datamodel::Unit::RefUnit(*unit_name, *power, *prefix_name);
316  }
317 
324  static datamodel::Unit createUnit(const DOM_NODE_TYPE& dom_node)
325  {
326  // read u exts
327  std::vector<datamodel::Unit::RefUnit> ref_units;
328  std::list<DOM_NODE_TYPE> ref_unit_nodes;
329  if (dom_node.findNodes("refUnit", ref_unit_nodes)) {
330  for (const auto& current_ref_unit_node: ref_unit_nodes) {
331  ref_units.emplace_back(createRefUnit(current_ref_unit_node));
332  }
333  }
334  auto name = getAttribute<std::string>(
335  dom_node, "name", {}, true, "unit tag has no mandatory 'name' attribute");
336  auto numerator = getData<std::string>(
337  dom_node, "numerator", {}, true, "unit tag has no mandatory 'numerator' tag");
338  auto denominator = getData<std::string>(
339  dom_node, "denominator", {}, true, "unit tag has no mandatory 'denominator' tag");
340  auto offset = getData<std::string>(
341  dom_node, "offset", {}, true, "unit tag has no mandatory 'offset' tag");
342  return datamodel::Unit(*name, *numerator, *denominator, *offset, ref_units);
343  }
344 
354  static datamodel::DataType createDataType(const DOM_NODE_TYPE& dom_node,
355  const Version& file_ddl_version,
356  bool strict)
357  {
358  // changes between 2.0 and 3.0
359  // attribute name changed to "name" from "type"
360  std::string name;
361  // mandatory
362  if (strict && (file_ddl_version >= Version(3, 0))) {
363  auto name_attrib = getAttribute<std::string>(
364  dom_node, "name", {}, true, "datatype tag has no mandatory 'name' attribute");
365  name = *name_attrib;
366  }
367  else {
368  // this must be mandatory, but there are wrong files in the world that uses name instead
369  // of type !
370  auto name_attrib = getAttribute<std::string>(dom_node, "name", {});
371  auto type_attrib = getAttribute<std::string>(dom_node, "type", {});
372  if (!type_attrib && !name_attrib) {
373  type_attrib = getAttribute<std::string>(
374  dom_node, "type", {}, true, "datatype tag has no mandatory 'type' attribute");
375  }
376  else {
377  if (type_attrib) {
378  name = *type_attrib;
379  }
380  else {
381  name = *name_attrib;
382  }
383  }
384  }
385  auto type_size = getAttribute<size_t>(
386  dom_node, "size", {}, true, "datatype tag has no mandatory 'size' attribute");
387  // create the type
388  datamodel::DataType created_type(
389  name,
390  type_size,
391  {},
392  {},
393  {},
394  {},
395  {},
397 
398  // optional
399  auto description = getAttribute<std::string>(dom_node, "description");
400  if (description) {
401  created_type.setDescription(*description);
402  }
403  auto array_size = getAttribute<size_t>(dom_node, "arraysize");
404  if (array_size) {
405  created_type.setArraySize(*array_size);
406  }
407  auto unit = getAttribute<std::string>(dom_node, "unit");
408  if (unit) {
409  created_type.setUnitName(unit);
410  }
411  // min / max introduced in DataDefinition 3.0
412  if (file_ddl_version >= Version(3, 0) || file_ddl_version == Version(0, 0)) {
413  auto min_val = getAttribute<std::string>(dom_node, "min");
414  if (min_val) {
415  created_type.setMin(*min_val);
416  }
417  auto max_val = getAttribute<std::string>(dom_node, "max");
418  if (max_val) {
419  created_type.setMax(*max_val);
420  }
421  }
422  return created_type;
423  }
424 
431  static datamodel::EnumType::Element createEnumTypeElement(const DOM_NODE_TYPE& dom_node)
432  {
433  auto name_attrib = getAttribute<std::string>(
434  dom_node, "name", {}, true, "enum/element tag has no mandatory 'name' attribute");
435  auto value_attrib = getAttribute<std::string>(
436  dom_node, "value", {}, true, "enum/element tag has no mandatory 'value' attribute");
437  return datamodel::EnumType::Element(*name_attrib, *value_attrib);
438  }
439 
446  static datamodel::EnumType createEnumType(const DOM_NODE_TYPE& dom_node)
447  {
448  auto name_attrib = getAttribute<std::string>(
449  dom_node, "name", {}, true, "enum tag has no mandatory 'name' attribute");
450  auto type_attrib = getAttribute<std::string>(
451  dom_node, "type", {}, true, "type tag has no mandatory 'type' attribute");
452 
453  datamodel::EnumType created_enum(*name_attrib, *type_attrib);
454  std::list<DOM_NODE_TYPE> enum_element_nodes;
455  if (dom_node.findNodes("element", enum_element_nodes)) {
456  for (const auto& current_enum_element_node: enum_element_nodes) {
457  created_enum.getElements().emplace(
458  createEnumTypeElement(current_enum_element_node));
459  }
460  }
461  return created_enum;
462  }
463 
474  static datamodel::StructType::Element createStructTypeElement(const DOM_NODE_TYPE& dom_node,
475  const Version& file_ddl_version,
476  bool strict)
477  {
478  auto name_attrib = getAttribute<std::string>(
479  dom_node, "name", {}, true, "struct/element tag has no mandatory 'name' attribute");
480  auto type_attrib = getAttribute<std::string>(dom_node,
481  "type",
482  {},
483  true,
484  "struct/element tag '" + *name_attrib +
485  "' has no mandatory 'type' attribute");
486 
487  utility::Optional<size_t> byte_pos;
488  ByteOrder byte_order(ByteOrder::e_le);
490  utility::Optional<size_t> num_bits;
491  Alignment alignment_to_set = Alignment::e0;
492 
493  Version used_file_version = file_ddl_version;
494  if (file_ddl_version == Version(0, 0) || !strict) {
495  // we need to figure out the version because it i.e. a string parsing where no header is
496  // set
497  DOM_NODE_TYPE serialized_node;
498  if (dom_node.findNode("serialized", serialized_node)) {
499  used_file_version = Version(4, 0);
500  }
501  else {
502  // this is a guess!
503  used_file_version = Version(3, 0);
504  }
505  }
506 
507  // From version 4.0 on this information is specified within the <serialized> tag.
508  // From version 4.0 on this information is specified within the <deserialized> tag.
509  if (used_file_version >= Version(4, 0)) {
510  DOM_NODE_TYPE serialized_node;
511  if (dom_node.findNode("serialized", serialized_node)) {
512  // mandatory serialized info
513  auto byte_pos_int = getAttribute<int>(serialized_node,
514  "bytepos",
515  {},
516  true,
517  "struct/element tag '" + *name_attrib +
518  "' has no mandatory 'bytepos' attribute");
519  if (*byte_pos_int == -1) {
520  byte_pos = {};
521  }
522  else {
523  byte_pos = static_cast<size_t>(*byte_pos_int);
524  }
525  auto byte_order_attrib =
526  getAttribute<std::string>(serialized_node,
527  "byteorder",
528  {},
529  true,
530  "struct/element/serialized tag '" + *name_attrib +
531  "' no mandatory 'byte_order' attribute");
532  byte_order = ByteOrderConversion::fromString(*byte_order_attrib, byte_order);
533 
534  bit_pos = getAttribute<size_t>(serialized_node, "bitpos", {});
535  num_bits = getAttribute<size_t>(serialized_node, "numbits", {});
536  }
537  else {
538  throw Error("DDFromXMLFactory::getAttribute",
539  "struct/element/deserialized tag was not found");
540  }
541 
542  DOM_NODE_TYPE deserialized_node;
543  if (dom_node.findNode("deserialized", deserialized_node)) {
544  auto alignment_attrib =
545  getAttribute<std::string>(deserialized_node,
546  "alignment",
547  {},
548  true,
549  "struct/element/deserialized tag '" + *name_attrib +
550  "' has no mandatory 'alignment' attribute");
551  alignment_to_set =
552  AlignmentConversion::fromString(*alignment_attrib, alignment_to_set);
553  }
554  else {
555  throw Error("DDFromXMLFactory::getAttribute",
556  "struct/element/serialized tag was not found");
557  }
558  }
559  else {
560  // mandatory serialized info
561  auto byte_pos_int = getAttribute<int>(dom_node,
562  "bytepos",
563  {},
564  true,
565  "struct/element tag '" + *name_attrib +
566  "' has no mandatory 'bytepos' attribute");
567  if (*byte_pos_int == -1) {
568  byte_pos = {};
569  }
570  else {
571  byte_pos = static_cast<size_t>(*byte_pos_int);
572  }
573  auto byte_order_attrib =
574  getAttribute<std::string>(dom_node,
575  "byteorder",
576  {},
577  true,
578  "struct/element tag '" + *name_attrib +
579  "' has no mandatory 'byte_order' attribute");
580  byte_order = ByteOrderConversion::fromString(*byte_order_attrib, byte_order);
581 
582  bit_pos = getAttribute<size_t>(dom_node, "bitpos", {});
583  num_bits = getAttribute<size_t>(dom_node, "numbits", {});
584 
585  // mandatory deserialized info
586  auto alignment_attrib = getAttribute<std::string>(
587  dom_node,
588  "alignment",
589  {},
590  true,
591  "struct/element tag '" + *name_attrib + "' has no mandatory 'alignment' attribute");
592  alignment_to_set = AlignmentConversion::fromString(*alignment_attrib, alignment_to_set);
593  }
594 
595  datamodel::StructType::Element created_element(
596  *name_attrib,
597  *type_attrib,
598  datamodel::StructType::DeserializedInfo(alignment_to_set),
599  datamodel::StructType::SerializedInfo(byte_pos, byte_order, bit_pos, num_bits));
600 
601  // optional
602  auto description = getAttribute<std::string>(dom_node, "description");
603  if (description) {
604  created_element.setDescription(*description);
605  }
606  auto unit_name = getAttribute<std::string>(dom_node, "unit");
607  if (unit_name) {
608  created_element.setUnitName(*unit_name);
609  }
610  auto comment = getAttribute<std::string>(dom_node, "comment");
611  if (comment) {
612  created_element.setComment(*comment);
613  }
614  auto arraysize_attrib =
615  getAttribute<std::string>(dom_node, "arraysize"); // introduced in DataDefinition 2.0
616  dd::OptionalSize arraysize_value = {};
617  // we check for an integrer to prevent an excpetion doin this for us
618  if (arraysize_attrib && isInteger(*arraysize_attrib)) {
619  arraysize_value = getAttribute<size_t>(dom_node, "arraysize");
620  }
621  if (arraysize_value) // the array size is set to a numeric value for size
622  {
623  created_element.setArraySize(*arraysize_value);
624  }
625  else if (arraysize_attrib) // array size is set to a string (or an invalid value) and
626  // introduced in DataDefinition 2.0 //Dynamic array support
627  {
628  if (file_ddl_version >= Version(2, 0) || file_ddl_version == Version(0, 0) || !strict) {
629  created_element.setArraySize(*arraysize_attrib);
630  }
631  }
632  // introduced in DataDefinition 2.0
633  if (used_file_version >= Version(2, 0) || file_ddl_version == Version(0, 0) || !strict) {
634  auto value_attrib = getAttribute<std::string>(dom_node, "value");
635  if (value_attrib) {
636  created_element.setValue(*value_attrib);
637  }
638  }
639  // introduced in DataDefinition 3.0
640  if (used_file_version >= Version(3, 0) || file_ddl_version == Version(0, 0) || !strict) {
641  auto min_attrib = getAttribute<std::string>(dom_node, "min");
642  if (min_attrib) {
643  created_element.setMin(*min_attrib);
644  }
645  auto max_attrib = getAttribute<std::string>(dom_node, "max");
646  if (max_attrib) {
647  created_element.setMax(*max_attrib);
648  }
649  auto default_attrib = getAttribute<std::string>(dom_node, "default");
650  if (default_attrib) {
651  created_element.setDefault(*default_attrib);
652  }
653  auto scale_attrib = getAttribute<std::string>(dom_node, "scale");
654  if (scale_attrib) {
655  created_element.setScale(*scale_attrib);
656  }
657  auto offset_attrib = getAttribute<std::string>(dom_node, "offset");
658  if (offset_attrib) {
659  created_element.setOffset(*offset_attrib);
660  }
661  }
662 
663  return created_element;
664  }
665 
675  static datamodel::StructType createStructType(const DOM_NODE_TYPE& dom_node,
676  const Version& file_ddl_version,
677  bool strict)
678  {
679  auto name_attrib = getAttribute<std::string>(dom_node, "name", {});
680  if (!name_attrib) {
681  // this is very old compatibility where structs where named with type attribute
682  auto type_attrib = getAttribute<std::string>(dom_node, "type", {});
683  if (type_attrib) {
684  name_attrib = type_attrib;
685  }
686  else {
687  // this is to set error
688  name_attrib = getAttribute<std::string>(
689  dom_node, "name", {}, true, "struct tag has no mandatory 'name' attribute");
690  }
691  }
692  // usually the version is mandatory, but the regression test says, there are description,
693  // where it is not set :-(
694  auto version_attrib = getAttribute<std::string>(dom_node, "version", {});
695  if (!version_attrib) {
696  version_attrib = "1";
697  }
698 
699  auto alignment_attrib = getAttribute<std::string>(dom_node, "alignment", {});
700  OptionalSize alignment_to_set;
701  if (alignment_attrib) {
702  alignment_to_set = AlignmentConversion::fromString(*alignment_attrib);
703  }
704  auto comment_attrib = getAttribute<std::string>(dom_node, "comment", {});
705  std::string comment_to_set = "";
706  if (comment_attrib) {
707  comment_to_set = *comment_attrib;
708  }
709  auto ddl_version_attrib = getAttribute<std::string>(dom_node, "ddlversion", {});
710  auto ddl_version_to_set = Version(0, 0);
711  if (ddl_version_attrib) {
712  ddl_version_to_set = VersionConversion::fromString(*ddl_version_attrib);
713  }
714 
716  *name_attrib, *version_attrib, alignment_to_set, comment_to_set, ddl_version_to_set);
717  // read elements
718  std::list<DOM_NODE_TYPE> struct_element_nodes;
719  if (dom_node.findNodes("element", struct_element_nodes)) {
720  for (const auto& current_struct_element_node: struct_element_nodes) {
721  struct_type.getElements().emplace(
722  createStructTypeElement(current_struct_element_node, file_ddl_version, strict));
723  }
724  }
725  return struct_type;
726  }
727 
736  const DOM_NODE_TYPE& dom_node)
737  {
738  auto name_attrib = getAttribute<std::string>(
739  dom_node,
740  "name",
741  {},
742  true,
743  "streammetatypename/property tag has no mandatory 'name' attribute");
744  auto type_attrib = getAttribute<std::string>(
745  dom_node,
746  "type",
747  {},
748  true,
749  "streammetatypename/property tag has no mandatory 'type' attribute");
750  return datamodel::StreamMetaType::Property(*name_attrib, *type_attrib);
751  }
752 
759  static datamodel::StreamMetaType createStreamMetaType(const DOM_NODE_TYPE& dom_node)
760  {
761  auto name_attrib = getAttribute<std::string>(
762  dom_node, "name", {}, true, "streammetatype tag has no mandatory 'name' attribute");
763  auto version_attrib =
764  getAttribute<std::string>(dom_node,
765  "version",
766  {},
767  true,
768  "streammetatype tag has no mandatory 'version' attribute");
769 
770  datamodel::StreamMetaType created_type =
771  datamodel::StreamMetaType(*name_attrib, *version_attrib, {});
772 
773  auto parent_attrib = getAttribute<std::string>(dom_node, "parent", {});
774  if (parent_attrib) {
775  created_type.setParent(*parent_attrib);
776  }
777  // read properties
778  std::list<DOM_NODE_TYPE> smt_prop_nodes;
779  if (dom_node.findNodes("property", smt_prop_nodes)) {
780  for (const auto& current_smt_prop_node: smt_prop_nodes) {
781  created_type.getProperties().emplace(
782  createStreamMetaTypeProperty(current_smt_prop_node));
783  }
784  }
785  return created_type;
786  }
787 
794  static datamodel::Stream::Struct createStreamStruct(const DOM_NODE_TYPE& dom_node)
795  {
796  auto name_attrib = getAttribute<std::string>(dom_node, "name", {});
797  auto type_attrib = getAttribute<std::string>(
798  dom_node, "type", {}, true, "stream/struct tag has no mandatory 'type' attribute");
799  auto byte_pos = getAttribute<size_t>(dom_node, "bytepos", {});
800  return datamodel::Stream::Struct(*name_attrib, *type_attrib, byte_pos);
801  }
802 
809  static datamodel::Stream createStream(const DOM_NODE_TYPE& dom_node)
810  {
811  auto name_attrib = getAttribute<std::string>(dom_node, "name", {});
812  auto type_attrib = getAttribute<std::string>(
813  dom_node, "type", {}, true, "stream tag has no mandatory 'type' attribute");
814  // we need to "try" because, there are stream definitions "in the world" where only "type"
815  // was used (also as name)!
816  if (!name_attrib) {
817  // we use type as name
818  name_attrib = *type_attrib;
819  }
820 
821  datamodel::Stream created_stream = datamodel::Stream(*name_attrib, *type_attrib);
822 
823  auto desc_attrib = getAttribute<std::string>(dom_node, "description", {});
824  if (desc_attrib) {
825  created_stream.setDescription(*desc_attrib);
826  }
827  // read the structs
828  std::list<DOM_NODE_TYPE> ss_nodes;
829  if (dom_node.findNodes("struct", ss_nodes)) {
830  for (const auto& current_stream_struct_node: ss_nodes) {
831  created_stream.getStructs().emplace(createStreamStruct(current_stream_struct_node));
832  }
833  }
834  return created_stream;
835  }
836 
847  static datamodel::DataDefinition createDD(const DOM_NODE_TYPE& dom_node,
848  const dd::Version& language_version,
849  bool strict)
850  {
851  // we use the version given, but if header exists we use the headers version
852  datamodel::DataDefinition new_ddl(language_version);
853  DOM_NODE_TYPE header_element;
854  if (dom_node.findNode("header", header_element)) {
855  // read header
856  new_ddl.setHeader(createHeader(header_element));
857  }
858  // read BaseUnits
859  std::list<DOM_NODE_TYPE> baseunit_nodes;
860  if (dom_node.findNodes("//units/baseunit", baseunit_nodes)) {
861  for (const auto& current_base_unit_node: baseunit_nodes) {
862  new_ddl.getBaseUnits().emplace(createBaseUnit(current_base_unit_node));
863  }
864  }
865  // read UnitPrefix
866  std::list<DOM_NODE_TYPE> prefix_nodes;
867  if (dom_node.findNodes("//units/prefixes", prefix_nodes)) {
868  for (const auto& current_prefix_node: prefix_nodes) {
869  new_ddl.getUnitPrefixes().emplace(createUnitPrefix(current_prefix_node));
870  }
871  }
872  // read Unit
873  std::list<DOM_NODE_TYPE> unit_nodes;
874  if (dom_node.findNodes("//units/unit", unit_nodes)) {
875  for (const auto& current_unit_node: unit_nodes) {
876  new_ddl.getUnits().emplace(
878  }
879  }
880  // read datatypes
881  std::list<DOM_NODE_TYPE> datatype_nodes;
882  if (dom_node.findNodes("//datatypes/datatype", datatype_nodes)) {
883  for (const auto& current_datatype_node: datatype_nodes) {
884  new_ddl.getDataTypes().emplace(
885  createDataType(current_datatype_node, new_ddl.getVersion(), strict));
886  }
887  }
888  // read enum types
889  std::list<DOM_NODE_TYPE> enum_nodes;
890  if (dom_node.findNodes("//enums/enum", enum_nodes)) {
891  for (const auto& current_enum_node: enum_nodes) {
892  new_ddl.getEnumTypes().emplace(
894  }
895  }
896  // read struct types
897  std::list<DOM_NODE_TYPE> struct_nodes;
898  if (dom_node.findNodes("//structs/struct", struct_nodes)) {
899  for (const auto& current_struct_node: struct_nodes) {
900  new_ddl.getStructTypes().emplace(
901  createStructType(current_struct_node, new_ddl.getVersion(), strict));
902  }
903  }
904  // read struct types very special (only <struct></struct> is possible)
905  if (dom_node.getName() == "struct") {
906  new_ddl.getStructTypes().emplace(
907  createStructType(dom_node, new_ddl.getVersion(), strict));
908  }
909  // read streammetatypes
910  if ((new_ddl.getVersion() >= dd::Version(4, 0)) || !strict) {
911  std::list<DOM_NODE_TYPE> stream_meta_type_nodes;
912  if (dom_node.findNodes("//streammetatypes/streammetatype", stream_meta_type_nodes)) {
913  for (const auto& current_smt_node: stream_meta_type_nodes) {
914  new_ddl.getStreamMetaTypes().emplace(createStreamMetaType(current_smt_node));
915  }
916  }
917  }
918 
919  std::list<DOM_NODE_TYPE> stream_nodes;
920  if (dom_node.findNodes("//streams/stream", stream_nodes)) {
921  for (const auto& current_stream_node: stream_nodes) {
922  new_ddl.getStreams().emplace(createStream(current_stream_node));
923  }
924  }
925  return new_ddl;
926  }
927 };
928 
929 } // namespace dd
930 } // namespace ddl
931 
932 #endif // DD_FROM_XML_FACTORY_H_INCLUDED
dd::OptionalSize getDefaultAlignment(const std::string &name) const
Get the default alignment of a Predefined Type by name.
static const PredefinedDataTypes & getInstance()
Get the Instance object.
static Alignment fromString(const std::string &alignment, const Alignment &default_val=Alignment::e_invalid)
convert a string to an alignment.
static ByteOrder fromString(const std::string &byte_order, const ByteOrder &default_val=ByteOrder::platform_not_supported)
convert a string to a byte_order.
static Version fromString(const std::string &version, const Version &default_val=Version(0, 0))
Creates the Version from a string.
DataDefinition Datamodel This datamodel is observable for any change of:
void setHeader(const Header &header)
Set the Header object.
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.
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.
KeyValuePair Element
Enum type element defintion as Name Value pair.
Data Definition datamodel for the Header.
KeyValuePair ExtDeclaration
Use of the key value pair to declare the ext declaration.
void setAuthor(const std::string &author)
Set the Author.
DataDefinition object class of datamodel to hold a streamstruct.
observable Stream DataDefinition object.
void setDescription(const std::string &description)
Set the Description.
const Structs & getStructs() const
Get the Structs object.
observable DataDefinition object class to describe StreamMetaType.
KeyValuePair Property
defintion of properties by using name - type pair.
void setParent(const std::string &parent)
Set the Parent This is only valid if the parent is a valid other streammetatype.
class to describe the deserialized information of a StructType::Element.
observable DataDefinition object class for a Element of a StructType.
void setMax(const std::string &maximum_value)
Set the Max (for information only).
void setUnitName(const std::string &unit_name)
Set the Unit Name.
void setDefault(const std::string &default_value)
Set the Default Value.
void setDescription(const std::string &description)
Set the Description.
void setMin(const std::string &minimum_value)
Set the Min (for information only).
void setScale(const std::string &scale)
Set the Scale (for information only)
void setValue(const std::string &value)
Set the Value This is only valid if the data type is set to an enum type where this constant value is...
void setComment(const std::string &comment)
Set the Comment object.
void setOffset(const std::string &offset)
Set the Offset (for information only)
void setArraySize(const ArraySize &array_size)
Set the Array Size.
class to describe the serialized information of a StructType::Element.
observable DataDefinition object class to describe StructType.
datamodel for the refUnit
Unit Prefix - datamodel pefixes.
void emplace(DDL_TYPE_TO_ACCESS &&type_to_add)
emplace the given item
void emplace(DDL_TYPE_TO_ACCESS &&type_to_add)
emplaces the given item
OO DataDefinition Redesign.
OO DataDefinition Optional Implementation.
OO DataDefinition Redesign.
OO DataDefinition DataTypes header for template based DataType usages and the predefined types.
bool isInteger(const std::string &string_to_check)
Checks if the given string is an integer value.
datamodel::StreamMetaType StreamMetaType
Reuse of datamodel streammetatype class - ddl::dd::datamodel::StreamMetaType.
Definition: dd.h:58
datamodel::BaseUnit BaseUnit
Reuse of datamodel base unit class - ddl::dd::datamodel::BaseUnit.
Definition: dd.h:34
datamodel::UnitPrefix UnitPrefix
Reuse of datamodel unit prefix class - ddl::dd::datamodel::UnitPrefix.
Definition: dd.h:38
datamodel::Unit Unit
Reuse of datamodel unit class - ddl::dd::datamodel::Unit.
Definition: dd.h:42
@ struct_type
the type is a struct type (StructType)
@ unit
the unit is a unit (Unit)
ByteOrder
Representation of the byteorder enumeration.
datamodel::Stream Stream
Reuse of datamodel stream class - ddl::dd::datamodel::Stream.
Definition: dd.h:62
Alignment
Alignment defintion.
@ e0
for backward compatibility
Utility for the Neutrino gcc5 compiler which has really no std::to_string implementation!
Utility for string checkking within the DDFromXML header only factory.
Factory to create a DataDefinition out of a XML based description.
static datamodel::Unit::RefUnit createRefUnit(const DOM_NODE_TYPE &dom_node)
Create a Ref Unit object.
static utility::Optional< std::string > toType(const std::string &from_string, const utility::Optional< std::string > &default_value={})
specialized function to convert a string to an optional string which is only valid if set.
static datamodel::Stream createStream(const DOM_NODE_TYPE &dom_node)
Create a Stream object.
static datamodel::EnumType::Element createEnumTypeElement(const DOM_NODE_TYPE &dom_node)
Create a Enum Type Element object.
static bool isInteger(const std::string &string_to_check)
Checks if the given string is an integer value.
static datamodel::Header::ExtDeclaration createHeaderExtDeclaration(const DOM_NODE_TYPE &dom_node)
Create a Header Ext Declaration object.
static datamodel::BaseUnit createBaseUnit(const DOM_NODE_TYPE &dom_node)
Create a Base Unit object.
static datamodel::UnitPrefix createUnitPrefix(const DOM_NODE_TYPE &dom_node)
Create a Unit Prefix object.
static utility::Optional< size_t > toType(const std::string &from_string, const utility::Optional< size_t > &default_value={})
specialized conversion to the Optional<size_t>
static utility::Optional< T > getData(const DOM_NODE_TYPE &dom_node, const std::string &sub_node_name, const utility::Optional< T > &default_value={}, bool is_mandatory=false, const char *parse_error_message="")
Get the data content of a subnode of dom_node.
static datamodel::StructType::Element createStructTypeElement(const DOM_NODE_TYPE &dom_node, const Version &file_ddl_version, bool strict)
Create a Struct Type Element object.
static datamodel::StructType createStructType(const DOM_NODE_TYPE &dom_node, const Version &file_ddl_version, bool strict)
Create a Struct Type object.
static datamodel::EnumType createEnumType(const DOM_NODE_TYPE &dom_node)
Create a Enum Type object.
static datamodel::Unit createUnit(const DOM_NODE_TYPE &dom_node)
Create a Unit object.
static datamodel::Stream::Struct createStreamStruct(const DOM_NODE_TYPE &dom_node)
Create a Stream Struct object.
static datamodel::StreamMetaType createStreamMetaType(const DOM_NODE_TYPE &dom_node)
Create a Stream Meta Type object.
static datamodel::DataDefinition createDD(const DOM_NODE_TYPE &dom_node, const dd::Version &language_version, bool strict)
Creates a whole DataDefinition and read all sub node.
static datamodel::Header createHeader(const DOM_NODE_TYPE &dom_node)
Create a Header object.
static datamodel::StreamMetaType::Property createStreamMetaTypeProperty(const DOM_NODE_TYPE &dom_node)
Create a Stream Meta Type Property object.
static datamodel::DataType createDataType(const DOM_NODE_TYPE &dom_node, const Version &file_ddl_version, bool strict)
Create a Data Type object.
static utility::Optional< int > toType(const std::string &from_string, const utility::Optional< int > &default_value={})
specialized conversion to the Optional<int32_t>
static utility::Optional< T > getAttribute(const DOM_NODE_TYPE &dom_node, const char *attribute_name, const utility::Optional< T > &default_value={}, bool is_mandatory=false, const std::string &parse_error_message={})
Get the Attribute from the dom_node.
An optional template as long as the std::optional is not available here.