ADTF
Loading...
Searching...
No Matches
xml_ddfromxml_factory.h
Go to the documentation of this file.
1
14
15#ifndef DD_DD_FROM_XML_FACTORY_H_INCLUDED
16#define DD_DD_FROM_XML_FACTORY_H_INCLUDED
17
25
26#include <list>
27#include <regex>
28#include <stdexcept>
29#include <string>
30#include <string_view>
31
32namespace ddl {
33namespace dd {
34
35namespace detail {
43template <typename T>
44T toType(std::string from_string, T default_value) noexcept;
52template <typename T>
53T toRequiredType(std::string from_string);
54
55template <>
56inline int toType<int>(std::string from_string, int default_value) noexcept
57{
58 try {
59 int i_converted = std::stoi(std::move(from_string));
60 return i_converted;
61 }
62 catch (const std::invalid_argument&) {
63 return default_value;
64 }
65 catch (const std::exception&) {
66 return default_value;
67 }
68}
69
70template <>
71inline int toRequiredType<int>(std::string from_string)
72{
73 int i_converted = std::stoi(std::move(from_string));
74 return i_converted;
75}
76
77template <>
78inline size_t toType<size_t>(std::string from_string, size_t default_value) noexcept
79{
80 try {
81 int size_converted = std::stoi(std::move(from_string));
82 if (size_converted < 0) {
83 // this is if we set i.e. the bytepos to -1 if it is after a dynamic array
84 return default_value;
85 }
86 else {
87 return size_converted;
88 }
89 }
90 catch (const std::invalid_argument&) {
91 return default_value;
92 }
93 catch (const std::exception&) {
94 return default_value;
95 }
96}
97template <>
98inline size_t toRequiredType<size_t>(std::string from_string)
99{
100 int size_converted = std::stoi(std::move(from_string));
101 if (size_converted < 0) {
102 // this is if we set i.e. the bytepos to -1 if it is after a dynamic array
103 return 0;
104 }
105 else {
106 return size_converted;
107 }
108}
109template <>
110inline std::string toType<std::string>(std::string from_string, std::string default_value) noexcept
111{
112 if (from_string.empty()) {
113 return std::move(default_value);
114 }
115 else {
116 return std::move(from_string);
117 }
118}
119template <>
120inline std::string toRequiredType<std::string>(std::string from_string)
121{
122 using namespace std::string_literals;
123 if (from_string.empty()) {
124 throw std::invalid_argument("Empty string"s);
125 }
126 else {
127 return std::move(from_string);
128 }
129}
130} // namespace detail
131
144template <typename DOM_NODE_TYPE>
151 static bool isInteger(const std::string& string_to_check) noexcept
152 {
153 return utility::isInteger(string_to_check);
154 }
155
156 struct Mandatory final {};
157 struct AsOptional final {};
158
170 template <typename T>
171 static utility::Optional<T> getAttribute(const DOM_NODE_TYPE& dom_node,
172 const std::string& attribute_name,
173 AsOptional /*tag*/)
174 {
175 using namespace std::string_literals;
176 auto value = dom_node.getAttribute(attribute_name);
177 if (value.empty()) {
178 return {};
179 }
180 else {
181 try {
182 return detail::toRequiredType<T>(std::move(value));
183 }
184 catch (const std::exception& e) {
185 throw Error("DDFromXMLFactory::getAttribute"s,
186 {"..."s, attribute_name},
187 dom_node.getName() + " has invalid data in "s + attribute_name +
188 " attribute: "s + e.what());
189 }
190 }
191 }
192
193 template <typename T>
194 static T getAttribute(const DOM_NODE_TYPE& dom_node,
195 const std::string& attribute_name,
196 T default_value) noexcept
197 {
198 using namespace std::string_literals;
199 auto value = dom_node.getAttribute(attribute_name);
200 if (value.empty()) {
201 return std::move(default_value);
202 }
203 else {
204 return detail::toType<T>(std::move(value), std::move(default_value));
205 }
206 }
207
208 template <typename T>
209 static T getAttribute(const DOM_NODE_TYPE& dom_node,
210 const std::string& attribute_name,
211 Mandatory /*tag*/)
212 {
213 using namespace std::string_literals;
214 auto value = dom_node.getAttribute(attribute_name);
215 if (value.empty()) {
216 throw Error("DDFromXMLFactory::getAttribute"s,
217 {"..."s, attribute_name},
218 dom_node.getName() + " has no mandatory "s + attribute_name +
219 " attribute."s);
220 }
221 else {
222 try {
223 return detail::toRequiredType<T>(std::move(value));
224 }
225 catch (const std::exception& e) {
226 throw Error("DDFromXMLFactory::getAttribute"s,
227 {"..."s, attribute_name},
228 dom_node.getName() + " has invalid data in "s + attribute_name +
229 " attribute: "s + e.what());
230 }
231 }
232 }
233
248 template <typename T>
249 static utility::Optional<T> getData(const DOM_NODE_TYPE& dom_node,
250 const std::string& sub_node_name,
251 AsOptional /*tag*/)
252 {
253 using namespace std::string_literals;
254 DOM_NODE_TYPE sub_node;
255 std::string value = {};
256 if (dom_node.findNode(sub_node_name, sub_node)) {
257 value = sub_node.getData();
258 }
259 if (value.empty()) {
260 return {};
261 }
262 else {
263 try {
264 return detail::toRequiredType<T>(std::move(value));
265 }
266 catch (const std::exception& e) {
267 throw Error("DDFromXMLFactory::getData"s,
268 {"..."s, sub_node_name},
269 dom_node.getName() + " has invalid data in '"s + sub_node_name +
270 "' child:"s + e.what());
271 }
272 }
273 }
274
275 template <typename T>
276 static T getData(const DOM_NODE_TYPE& dom_node,
277 const std::string& sub_node_name,
278 T default_value) noexcept
279 {
280 using namespace std::string_literals;
281 DOM_NODE_TYPE sub_node;
282 std::string value = {};
283 if (dom_node.findNode(sub_node_name, sub_node)) {
284 value = sub_node.getData();
285 }
286 if (value.empty()) {
287 return std::move(default_value);
288 }
289 else {
290 return detail::toType<T>(std::move(value), std::move(default_value));
291 }
292 }
293 template <typename T>
294 static T getData(const DOM_NODE_TYPE& dom_node,
295 const std::string& sub_node_name,
296 Mandatory /*tag*/)
297 {
298 using namespace std::string_literals;
299 DOM_NODE_TYPE sub_node;
300 std::string value = {};
301 if (dom_node.findNode(sub_node_name, sub_node)) {
302 value = sub_node.getData();
303 }
304 if (value.empty()) {
305 throw Error("DDFromXMLFactory::getData"s,
306 {"..."s, sub_node_name},
307 dom_node.getName() + " has no mandatory '"s + sub_node_name + "' child."s);
308 }
309 else {
310 try {
311 return detail::toRequiredType<T>(std::move(value));
312 }
313 catch (const std::exception& e) {
314 throw Error("DDFromXMLFactory::getData"s,
315 {"..."s, sub_node_name},
316 dom_node.getName() + " has invalid data in '"s + sub_node_name +
317 "' child: "s + e.what());
318 }
319 }
320 }
321
330 const DOM_NODE_TYPE& dom_node)
331 {
332 const auto& literals = DDXmlLiterals::getInstance();
333 using namespace std::string_literals;
334 auto key_attrib = getAttribute<std::string>(dom_node, literals.key, Mandatory{});
335 auto value_attrib = getAttribute<std::string>(dom_node, literals.value, Mandatory{});
336 return datamodel::Header::ExtDeclaration(std::move(key_attrib), std::move(value_attrib));
337 }
338
345 static datamodel::Header createHeader(const DOM_NODE_TYPE& dom_node)
346 {
347 const auto& literals = DDXmlLiterals::getInstance();
348 // read header exts
349 std::vector<datamodel::Header::ExtDeclaration> exts;
350 std::list<DOM_NODE_TYPE> header_ext_nodes;
351 if (dom_node.findNodes(literals.ext_declaration, header_ext_nodes)) {
352 for (const auto& current_header_ext_node: header_ext_nodes) {
353 exts.emplace_back(createHeaderExtDeclaration(current_header_ext_node));
354 }
355 }
356 // read the header itself
357 Version version_to_set = {};
358 if (auto file_ddl_version =
359 getData<std::string>(dom_node, literals.language_version, AsOptional{})) {
360 version_to_set = VersionConversion::fromString(*file_ddl_version);
361 }
362
363 // optional
364 auto author = getData<std::string>(dom_node, literals.author, std::string{});
365 auto date_creation = getData<std::string>(dom_node, literals.date_creation, std::string{});
366 auto date_change = getData<std::string>(dom_node, literals.date_change, std::string{});
367 auto description = getData<std::string>(dom_node, literals.description, std::string{});
368
369 return datamodel::Header(std::move(version_to_set),
370 std::move(author),
371 std::move(date_creation),
372 std::move(date_change),
373 std::move(description),
374 exts);
375 }
376
383 static datamodel::BaseUnit createBaseUnit(const DOM_NODE_TYPE& dom_node)
384 {
385 const auto& literals = DDXmlLiterals::getInstance();
386 auto name = getAttribute<std::string>(dom_node, literals.name, Mandatory{});
387 auto symbol = getAttribute<std::string>(dom_node, literals.symbol, std::string{});
388 auto description = getAttribute<std::string>(dom_node, literals.description, std::string{});
389 return datamodel::BaseUnit(std::move(name), std::move(symbol), std::move(description));
390 }
391
398 static datamodel::UnitPrefix createUnitPrefix(const DOM_NODE_TYPE& dom_node)
399 {
400 const auto& literals = DDXmlLiterals::getInstance();
401 auto name = getAttribute<std::string>(dom_node, literals.name, Mandatory{});
402 auto symbol = getAttribute<std::string>(dom_node, literals.symbol, std::string{});
403 auto power = getAttribute<int32_t>(dom_node, literals.power, Mandatory{});
404 return datamodel::UnitPrefix(std::move(name), std::move(symbol), std::move(power));
405 }
406
413 static datamodel::Unit::RefUnit createRefUnit(const DOM_NODE_TYPE& dom_node)
414 {
415 const auto& literals = DDXmlLiterals::getInstance();
416 auto unit_name = getAttribute<std::string>(dom_node, literals.name, Mandatory{});
417 auto power = getAttribute<int32_t>(dom_node, literals.power, Mandatory{});
418 auto prefix_name = getAttribute<std::string>(dom_node, literals.prefix, Mandatory{});
419 return datamodel::Unit::RefUnit(std::move(unit_name), power, std::move(prefix_name));
420 }
421
428 static datamodel::Unit createUnit(const DOM_NODE_TYPE& dom_node)
429 {
430 const auto& literals = DDXmlLiterals::getInstance();
431
432 // read u exts
433 std::vector<datamodel::Unit::RefUnit> ref_units;
434 std::list<DOM_NODE_TYPE> ref_unit_nodes;
435 if (dom_node.findNodes(literals.refUnit, ref_unit_nodes)) {
436 for (const auto& current_ref_unit_node: ref_unit_nodes) {
437 ref_units.emplace_back(createRefUnit(current_ref_unit_node));
438 }
439 }
440 auto name = getAttribute<std::string>(dom_node, literals.name, Mandatory{});
441 auto numerator = getData<std::string>(dom_node, literals.numerator, Mandatory{});
442 auto denominator = getData<std::string>(dom_node, literals.denominator, Mandatory{});
443 auto offset = getData<std::string>(dom_node, literals.offset, Mandatory{});
444 return datamodel::Unit(std::move(name),
445 std::move(numerator),
446 std::move(denominator),
447 std::move(offset),
448 ref_units);
449 }
450
460 static datamodel::DataType createDataType(const DOM_NODE_TYPE& dom_node,
461 const Version& file_ddl_version,
462 bool strict)
463 {
464 const auto& literals = DDXmlLiterals::getInstance();
465
466 // changes between 2.0 and 3.0
467 // attribute name changed to "name" from "type"
468 std::string name;
469 // mandatory
470 if (strict && (file_ddl_version >= Version(3, 0))) {
471 name = getAttribute<std::string>(dom_node, literals.name, Mandatory{});
472 }
473 else {
474 // "type" was mandatory, but there are wrong files in the world that already used "name"
475 // instead of "type" !
476 auto name_attrib = getAttribute<std::string>(dom_node, literals.name, AsOptional{});
477 name = name_attrib ?
478 getAttribute<std::string>(dom_node, literals.type__, *name_attrib) :
479 getAttribute<std::string>(dom_node, literals.type__, Mandatory{});
480 }
481 auto type_size = getAttribute<size_t>(dom_node, literals.size, Mandatory{});
482
483 // optional
484 auto description = getAttribute<std::string>(dom_node, literals.description, std::string{});
485
486 OptionalSize array_size;
487 if (auto array_size_attrib =
488 getAttribute<size_t>(dom_node, literals.arraysize, AsOptional{})) {
489 array_size = *array_size_attrib;
490 }
491
492 auto unit_name = getAttribute<std::string>(dom_node, literals.unit, std::string{});
493
494 // min / max introduced in DataDefinition 3.0
495 std::string min_val, max_val;
496 if (file_ddl_version >= Version(3, 0) || file_ddl_version == Version(0, 0)) {
497 min_val = getAttribute<std::string>(dom_node, literals.min, std::string{});
498 max_val = getAttribute<std::string>(dom_node, literals.max, std::string{});
499 }
500
501 auto default_type_alignment =
503
504 // create the type
505 return datamodel::DataType(std::move(name),
506 type_size,
507 std::move(description),
508 std::move(array_size),
509 std::move(unit_name),
510 std::move(min_val),
511 std::move(max_val),
512 default_type_alignment);
513 }
514
521 static datamodel::EnumType::Element createEnumTypeElement(const DOM_NODE_TYPE& dom_node)
522 {
523 const auto& literals = DDXmlLiterals::getInstance();
524 auto name_attrib = getAttribute<std::string>(dom_node, literals.name, Mandatory{});
525 auto value_attrib = getAttribute<std::string>(dom_node, literals.value, Mandatory{});
526 return datamodel::EnumType::Element(std::move(name_attrib), std::move(value_attrib));
527 }
528
535 static datamodel::EnumType createEnumType(const DOM_NODE_TYPE& dom_node)
536 {
537 const auto& literals = DDXmlLiterals::getInstance();
538 auto name_attrib = getAttribute<std::string>(dom_node, literals.name, Mandatory{});
539 auto type_attrib = getAttribute<std::string>(dom_node, literals.type__, Mandatory{});
540
541 datamodel::EnumType created_enum(std::move(name_attrib), std::move(type_attrib));
542 std::list<DOM_NODE_TYPE> enum_element_nodes;
543 if (dom_node.findNodes(literals.element, enum_element_nodes)) {
544 for (const auto& current_enum_element_node: enum_element_nodes) {
545 created_enum.getElements().emplace(
546 createEnumTypeElement(current_enum_element_node));
547 }
548 }
549 return created_enum;
550 }
551
562 static datamodel::StructType::Element createStructTypeElement(const DOM_NODE_TYPE& dom_node,
563 const Version& file_ddl_version,
564 bool strict)
565 {
566 const auto& literals = DDXmlLiterals::getInstance();
567 auto name_attrib = getAttribute<std::string>(dom_node, literals.name, Mandatory{});
568 auto type_attrib = getAttribute<std::string>(dom_node, literals.type__, Mandatory{});
569
571 ByteOrder byte_order(ByteOrder::e_le);
574 Alignment alignment_to_set = Alignment::e0;
575
576 Version used_file_version = file_ddl_version;
577 if (file_ddl_version == Version(0, 0) || !strict) {
578 // we need to figure out the version because it i.e. a string parsing where no header is
579 // set
580 DOM_NODE_TYPE serialized_node;
581 if (dom_node.findNode(literals.serialized, serialized_node)) {
582 used_file_version = Version(4, 0);
583 if (dom_node.hasAttribute(literals.valid_element_count)) {
584 used_file_version = Version(4, 2);
585 }
586 }
587 else {
588 // this is a guess!
589 used_file_version = Version(3, 0);
590 }
591 }
592
593 // From version 4.0 on this information is specified within the <serialized> tag.
594 // From version 4.0 on this information is specified within the <deserialized> tag.
595 if (used_file_version >= Version(4, 0)) {
596 DOM_NODE_TYPE serialized_node;
597 if (dom_node.findNode(literals.serialized, serialized_node)) {
598 // mandatory serialized info
599 auto byte_pos_int =
600 getAttribute<int>(serialized_node, literals.bytepos, Mandatory{});
601 if (byte_pos_int == -1) {
602 byte_pos = {};
603 }
604 else {
605 byte_pos = static_cast<size_t>(byte_pos_int);
606 }
607 auto byte_order_attrib =
608 getAttribute<std::string>(serialized_node, literals.byteorder, Mandatory{});
609 byte_order = ByteOrderConversion::fromString(byte_order_attrib, byte_order);
610
611 bit_pos = getAttribute<size_t>(serialized_node, literals.bitpos, AsOptional{});
612 num_bits = getAttribute<size_t>(serialized_node, literals.numbits, AsOptional{});
613 }
614 else {
615 throw Error("DDFromXMLFactory::getAttribute",
616 "struct/element/deserialized tag was not found");
617 }
618
619 DOM_NODE_TYPE deserialized_node;
620 if (dom_node.findNode(literals.deserialized, deserialized_node)) {
621 auto alignment_attrib =
622 getAttribute<std::string>(deserialized_node, literals.alignment, Mandatory{});
623 alignment_to_set =
624 AlignmentConversion::fromString(alignment_attrib, alignment_to_set);
625 }
626 else {
627 throw Error("DDFromXMLFactory::getAttribute",
628 "struct/element/serialized tag was not found");
629 }
630 }
631 else {
632 // mandatory serialized info
633 auto byte_pos_int = getAttribute<int>(dom_node, literals.bytepos, Mandatory{});
634 if (byte_pos_int == -1) {
635 byte_pos = {};
636 }
637 else {
638 byte_pos = static_cast<size_t>(byte_pos_int);
639 }
640 auto byte_order_attrib =
641 getAttribute<std::string>(dom_node, literals.byteorder, Mandatory{});
642 byte_order = ByteOrderConversion::fromString(byte_order_attrib, byte_order);
643
644 bit_pos = getAttribute<size_t>(dom_node, literals.bitpos, AsOptional{});
645 num_bits = getAttribute<size_t>(dom_node, literals.numbits, AsOptional{});
646
647 // mandatory deserialized info
648 auto alignment_attrib =
649 getAttribute<std::string>(dom_node, literals.alignment, Mandatory{});
650 alignment_to_set = AlignmentConversion::fromString(alignment_attrib, alignment_to_set);
651 }
652
653 // introduced in DataDefinition 2.0
654 dd::ArraySize array_size;
655 if (auto arraysize_attrib =
656 getAttribute<std::string>(dom_node, literals.arraysize, AsOptional{})) {
657 // we check for an integrer to prevent an excpetion doin this for us
658
659 if (isInteger(*arraysize_attrib)) {
660 array_size =
661 ArraySize(detail::toRequiredType<size_t>(*std::move(arraysize_attrib)));
662 }
663 else // array size is set to a string (or an invalid value) and
664 // introduced in DataDefinition 2.0 //Dynamic array support
665 {
666 if (file_ddl_version >= Version(2, 0) || file_ddl_version == Version(0, 0) ||
667 !strict) {
668 array_size = ArraySize(*std::move(arraysize_attrib));
669 }
670 }
671 }
672
673 // optional
674 auto description = getAttribute<std::string>(dom_node, literals.description, std::string{});
675 auto comment = getAttribute<std::string>(dom_node, literals.comment, std::string{});
676 auto unit_name = getAttribute<std::string>(dom_node, literals.unit, std::string{});
677
678 std::string value, minimum_value, maximum_value, default_value, scale, offset,
679 valid_element_count;
680 // introduced in DataDefinition 2.0
681 if (used_file_version >= Version(2, 0) || file_ddl_version == Version(0, 0) || !strict) {
682 value = getAttribute<std::string>(dom_node, literals.value, std::string{});
683 }
684 // introduced in DataDefinition 3.0
685 if (used_file_version >= Version(3, 0) || file_ddl_version == Version(0, 0) || !strict) {
686 minimum_value = getAttribute<std::string>(dom_node, literals.min, std::string{});
687 maximum_value = getAttribute<std::string>(dom_node, literals.max, std::string{});
688 default_value = getAttribute<std::string>(dom_node, literals.default__, std::string{});
689 scale = getAttribute<std::string>(dom_node, literals.scale, std::string{});
690 offset = getAttribute<std::string>(dom_node, literals.offset, std::string{});
691 }
692 // introduced in DataDefinition 4.2
693 if (used_file_version >= Version(4, 2) || file_ddl_version == Version(0, 0) || !strict) {
694 valid_element_count =
695 getAttribute<std::string>(dom_node, literals.valid_element_count, std::string{});
696 }
697
699 std::move(name_attrib),
700 std::move(type_attrib),
702 datamodel::StructType::SerializedInfo(byte_pos, byte_order, bit_pos, num_bits),
703 std::move(array_size),
704 std::move(description),
705 std::move(comment),
706 std::move(unit_name),
707 std::move(value),
708 std::move(minimum_value),
709 std::move(maximum_value),
710 std::move(default_value),
711 std::move(scale),
712 std::move(offset),
713 std::move(valid_element_count));
714 }
715
725 static datamodel::StructType createStructType(const DOM_NODE_TYPE& dom_node,
726 const Version& file_ddl_version,
727 bool strict)
728 {
729 using namespace std::string_literals;
730 const auto& literals = DDXmlLiterals::getInstance();
731 // this is very old compatibility where structs where named with type attribute
732 auto type_attrib = getAttribute<std::string>(dom_node, literals.type__, AsOptional{});
733 auto name_attrib = type_attrib ?
734 getAttribute<std::string>(dom_node, literals.name, *type_attrib) :
735 getAttribute<std::string>(dom_node, literals.name, Mandatory{});
736 // usually the version is mandatory, but the regression test says, there are description,
737 // where it is not set :-(
738 auto version_attrib = getAttribute<std::string>(dom_node, literals.version, "1"s);
739
740 OptionalSize alignment_to_set;
741 if (auto alignment_attrib =
742 getAttribute<std::string>(dom_node, literals.alignment, AsOptional{})) {
743 alignment_to_set = AlignmentConversion::fromString(*alignment_attrib);
744 }
745 auto comment_attrib = getAttribute<std::string>(dom_node, literals.comment, std::string{});
746
747 auto ddl_version_to_set = Version(0, 0);
748 if (auto ddl_version_attrib =
749 getAttribute<std::string>(dom_node, literals.ddlversion, AsOptional{})) {
750 ddl_version_to_set = VersionConversion::fromString(*ddl_version_attrib);
751 }
752
753 datamodel::StructType struct_type(std::move(name_attrib),
754 std::move(version_attrib),
755 std::move(alignment_to_set),
756 std::move(comment_attrib),
757 std::move(ddl_version_to_set));
758 // read elements
759 std::list<DOM_NODE_TYPE> struct_element_nodes;
760 if (dom_node.findNodes(literals.element, struct_element_nodes)) {
761 for (const auto& current_struct_element_node: struct_element_nodes) {
762 struct_type.getElements().emplace(
763 createStructTypeElement(current_struct_element_node, file_ddl_version, strict));
764 }
765 }
766 return struct_type;
767 }
768
777 const DOM_NODE_TYPE& dom_node)
778 {
779 const auto& literals = DDXmlLiterals::getInstance();
780 auto name_attrib = getAttribute<std::string>(dom_node, literals.name, Mandatory{});
781 auto type_attrib = getAttribute<std::string>(dom_node, literals.type__, Mandatory{});
782 return datamodel::StreamMetaType::Property(std::move(name_attrib), std::move(type_attrib));
783 }
784
791 static datamodel::StreamMetaType createStreamMetaType(const DOM_NODE_TYPE& dom_node)
792 {
793 const auto& literals = DDXmlLiterals::getInstance();
794 auto name_attrib = getAttribute<std::string>(dom_node, literals.name, Mandatory{});
795 auto version_attrib = getAttribute<std::string>(dom_node, literals.version, Mandatory{});
796 auto parent_attrib = getAttribute<std::string>(dom_node, literals.parent, std::string{});
797
799 std::move(name_attrib), std::move(version_attrib), std::move(parent_attrib));
800
801 // read properties
802 std::list<DOM_NODE_TYPE> smt_prop_nodes;
803 if (dom_node.findNodes(literals.property, smt_prop_nodes)) {
804 for (const auto& current_smt_prop_node: smt_prop_nodes) {
805 created_type.getProperties().emplace(
806 createStreamMetaTypeProperty(current_smt_prop_node));
807 }
808 }
809 return created_type;
810 }
811
818 static datamodel::Stream::Struct createStreamStruct(const DOM_NODE_TYPE& dom_node)
819 {
820 const auto& literals = DDXmlLiterals::getInstance();
821 auto name_attrib = getAttribute<std::string>(dom_node, literals.name, std::string{});
822 auto type_attrib = getAttribute<std::string>(dom_node, literals.type__, Mandatory{});
823 auto byte_pos = getAttribute<size_t>(dom_node, literals.bytepos, AsOptional{});
825 std::move(name_attrib), std::move(type_attrib), std::move(byte_pos));
826 }
827
834 static datamodel::Stream createStream(const DOM_NODE_TYPE& dom_node)
835 {
836 const auto& literals = DDXmlLiterals::getInstance();
837 auto type_attrib = getAttribute<std::string>(dom_node, literals.type__, Mandatory{});
838 // we need to "try" because, there are stream definitions "in the world" where only "type"
839 // was used (also as name)!
840 auto name_attrib = getAttribute<std::string>(dom_node, literals.name, type_attrib);
841
842 auto desc_attrib = getAttribute<std::string>(dom_node, literals.description, std::string{});
843
844 datamodel::Stream created_stream = datamodel::Stream(
845 std::move(name_attrib), std::move(type_attrib), std::move(desc_attrib));
846 // read the structs
847 std::list<DOM_NODE_TYPE> ss_nodes;
848 if (dom_node.findNodes(literals.struct__, ss_nodes)) {
849 for (const auto& current_stream_struct_node: ss_nodes) {
850 created_stream.getStructs().emplace(createStreamStruct(current_stream_struct_node));
851 }
852 }
853 return created_stream;
854 }
855
866 static datamodel::DataDefinition createDD(const DOM_NODE_TYPE& dom_node,
867 const dd::Version& language_version,
868 bool strict)
869 {
870 using namespace std::string_literals;
871 const auto& literals = DDXmlLiterals::getInstance();
872 // we use the version given, but if header exists we use the headers version
873 datamodel::DataDefinition new_ddl(language_version);
874 {
875 DOM_NODE_TYPE header_element;
876 if (dom_node.findNode(literals.header, header_element)) {
877 // read header
878 new_ddl.setHeader(createHeader(header_element));
879 }
880 }
881 {
882 // read BaseUnits
883 std::list<DOM_NODE_TYPE> baseunit_nodes;
884 if (dom_node.findNodes("//units/baseunit"s, baseunit_nodes)) {
885 for (const auto& current_base_unit_node: baseunit_nodes) {
886 new_ddl.getBaseUnits().emplace(createBaseUnit(current_base_unit_node));
887 }
888 }
889 }
890 {
891 // read UnitPrefix
892 std::list<DOM_NODE_TYPE> prefix_nodes;
893 if (dom_node.findNodes("//units/prefixes"s, prefix_nodes)) {
894 for (const auto& current_prefix_node: prefix_nodes) {
895 new_ddl.getUnitPrefixes().emplace(createUnitPrefix(current_prefix_node));
896 }
897 }
898 }
899 {
900 // read Unit
901 std::list<DOM_NODE_TYPE> unit_nodes;
902 if (dom_node.findNodes("//units/unit"s, unit_nodes)) {
903 for (const auto& current_unit_node: unit_nodes) {
904 new_ddl.getUnits().emplace(
906 }
907 }
908 }
909 {
910 // read datatypes
911 std::list<DOM_NODE_TYPE> datatype_nodes;
912 if (dom_node.findNodes("//datatypes/datatype"s, datatype_nodes)) {
913 for (const auto& current_datatype_node: datatype_nodes) {
914 new_ddl.getDataTypes().emplace(
915 createDataType(current_datatype_node, new_ddl.getVersion(), strict));
916 }
917 }
918 }
919 {
920 // read enum types
921 std::list<DOM_NODE_TYPE> enum_nodes;
922 if (dom_node.findNodes("//enums/enum"s, enum_nodes)) {
923 for (const auto& current_enum_node: enum_nodes) {
924 new_ddl.getEnumTypes().emplace(
926 }
927 }
928 }
929 {
930 // read struct types
931 std::list<DOM_NODE_TYPE> struct_nodes;
932 if (dom_node.findNodes("//structs/struct"s, struct_nodes)) {
933 for (const auto& current_struct_node: struct_nodes) {
934 new_ddl.getStructTypes().emplace(
935 createStructType(current_struct_node, new_ddl.getVersion(), strict));
936 }
937 }
938 }
939 // read struct types very special (only <struct></struct> is possible)
940 if (dom_node.getName() == literals.struct__) {
941 new_ddl.getStructTypes().emplace(
942 createStructType(dom_node, new_ddl.getVersion(), strict));
943 }
944 // read streammetatypes
945 if ((new_ddl.getVersion() >= dd::Version(4, 0)) || !strict) {
946 std::list<DOM_NODE_TYPE> stream_meta_type_nodes;
947 if (dom_node.findNodes("//streammetatypes/streammetatype"s, stream_meta_type_nodes)) {
948 for (const auto& current_smt_node: stream_meta_type_nodes) {
949 new_ddl.getStreamMetaTypes().emplace(createStreamMetaType(current_smt_node));
950 }
951 }
952 }
953
954 {
955 std::list<DOM_NODE_TYPE> stream_nodes;
956 if (dom_node.findNodes("//streams/stream"s, stream_nodes)) {
957 for (const auto& current_stream_node: stream_nodes) {
958 new_ddl.getStreams().emplace(createStream(current_stream_node));
959 }
960 }
961 }
962 return new_ddl;
963 }
964};
965
966} // namespace dd
967} // namespace ddl
968
969#endif // DD_FROM_XML_FACTORY_H_INCLUDED
static const PredefinedDataTypes & getInstance()
Get the Instance object.
dd::OptionalSize getDefaultAlignment(const std::string &name) const
Get the default alignment of a Predefined Type by name.
static Alignment fromString(const std::string &alignment, const Alignment &default_val=Alignment::e_invalid)
convert a string to an alignment.
Definition dd_common_types.h:378
static ByteOrder fromString(const std::string &byte_order, const ByteOrder &default_val=ByteOrder::platform_not_supported)
convert a string to a byte_order.
Exception helper class to collect information while parsing, adding DD Objects or other failed operat...
Definition ddl_error.h:31
static Version fromString(const std::string &version, const Version &default_val=Version(0, 0))
Creates the Version from a string.
DDL Version.
Definition dd_common_types.h:203
BaseUnit.
Definition datamodel_units.h:108
DataDefinition Datamodel This datamodel is observable for any change of:
Definition datamodel_datadefinition.h:64
const EnumTypes & getEnumTypes() const
Get the Enum Types object.
const StreamMetaTypes & getStreamMetaTypes() const
Get the Stream Meta Types object.
const UnitPrefixes & getUnitPrefixes() const
Get the Unit Prefixes object.
Version getVersion() const
Get the DDL Version.
const BaseUnits & getBaseUnits() const
Get the Base Units object.
const Units & getUnits() const
Get the Units object.
const Streams & getStreams() const
Get the Streams object.
void setHeader(const Header &header)
Set the Header object.
const StructTypes & getStructTypes() const
Get the Struct Types object.
const DataTypes & getDataTypes() const
Get the Data Types object.
observable DataDefinition object class to describe (POD) DataType.
Definition datamodel_types.h:113
observable DataDefinition object class to describe EnumType.
Definition datamodel_types.h:320
const Elements & getElements() const
Get the Elements object.
KeyValuePair Element
Enum type element defintion as Name Value pair.
Definition datamodel_types.h:326
Data Definition datamodel for the Header.
Definition datamodel_header.h:37
KeyValuePair ExtDeclaration
Use of the key value pair to declare the ext declaration.
Definition datamodel_header.h:72
observable DataDefinition object class to describe StreamMetaType.
Definition datamodel_types.h:1224
const Properties & getProperties() const
Get the Properties object.
KeyValuePair Property
defintion of properties by using name - type pair.
Definition datamodel_types.h:1230
DataDefinition object class of datamodel to hold a streamstruct.
Definition datamodel_streams.h:80
observable Stream DataDefinition object.
Definition datamodel_streams.h:41
const Structs & getStructs() const
Get the Structs object.
class to describe the deserialized information of a StructType::Element.
Definition datamodel_types.h:644
observable DataDefinition object class for a Element of a StructType.
Definition datamodel_types.h:736
class to describe the serialized information of a StructType::Element.
Definition datamodel_types.h:493
observable DataDefinition object class to describe StructType.
Definition datamodel_types.h:453
Unit Prefix - datamodel pefixes.
Definition datamodel_units.h:221
datamodel for the refUnit
Definition datamodel_units.h:377
BaseUnit.
Definition datamodel_units.h:338
void emplace(DDL_TYPE_TO_ACCESS &&type_to_add)
emplace the given item
Definition access_list.h:432
void emplace(DDL_TYPE_TO_ACCESS &&type_to_add)
emplaces the given item
Definition access_map.h:368
Error
Enumerates possible error values for filesystem interaction.
Definition filesystem.h:27
bool isInteger(const std::string &string_to_check) noexcept
Checks if the given string is an integer value.
definition of the dd namespace
Definition datamodel_base.h:26
ByteOrder
Definition dd_common_types.h:152
Alignment
Alignment defintion.
Definition dd_common_types.h:98
@ e0
Definition dd_common_types.h:99
utility::Optional< size_t > OptionalSize
Optional Size Type.
Definition dd_common_types.h:38
@ struct_type
the type is a struct type (StructType)
Definition dd_common_types.h:64
definition of the ddl namespace
Definition codec.h:21
Definition xml_ddfromxml_factory.h:157
Definition xml_ddfromxml_factory.h:156
Factory to create a DataDefinition out of a XML based description. This factory uses a template type ...
Definition xml_ddfromxml_factory.h:145
static utility::Optional< T > getAttribute(const DOM_NODE_TYPE &dom_node, const std::string &attribute_name, AsOptional)
Get the Attribute from the dom_node. Return a valid Optional<T> if set, otherwise return default_valu...
Definition xml_ddfromxml_factory.h:171
static datamodel::StructType createStructType(const DOM_NODE_TYPE &dom_node, const Version &file_ddl_version, bool strict)
Create a Struct Type object.
Definition xml_ddfromxml_factory.h:725
static datamodel::Unit createUnit(const DOM_NODE_TYPE &dom_node)
Create a Unit object.
Definition xml_ddfromxml_factory.h:428
static datamodel::Header::ExtDeclaration createHeaderExtDeclaration(const DOM_NODE_TYPE &dom_node)
Create a Header Ext Declaration object.
Definition xml_ddfromxml_factory.h:329
static datamodel::BaseUnit createBaseUnit(const DOM_NODE_TYPE &dom_node)
Create a Base Unit object.
Definition xml_ddfromxml_factory.h:383
static datamodel::StructType::Element createStructTypeElement(const DOM_NODE_TYPE &dom_node, const Version &file_ddl_version, bool strict)
Create a Struct Type Element object.
Definition xml_ddfromxml_factory.h:562
static utility::Optional< T > getData(const DOM_NODE_TYPE &dom_node, const std::string &sub_node_name, AsOptional)
Get the data content of a subnode of dom_node. Return a valid Optional<T> if set, otherwise return de...
Definition xml_ddfromxml_factory.h:249
static datamodel::DataType createDataType(const DOM_NODE_TYPE &dom_node, const Version &file_ddl_version, bool strict)
Create a Data Type object.
Definition xml_ddfromxml_factory.h:460
static datamodel::Unit::RefUnit createRefUnit(const DOM_NODE_TYPE &dom_node)
Create a Ref Unit object.
Definition xml_ddfromxml_factory.h:413
static datamodel::EnumType::Element createEnumTypeElement(const DOM_NODE_TYPE &dom_node)
Create a Enum Type Element object.
Definition xml_ddfromxml_factory.h:521
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.
Definition xml_ddfromxml_factory.h:866
static datamodel::UnitPrefix createUnitPrefix(const DOM_NODE_TYPE &dom_node)
Create a Unit Prefix object.
Definition xml_ddfromxml_factory.h:398
static datamodel::EnumType createEnumType(const DOM_NODE_TYPE &dom_node)
Create a Enum Type object.
Definition xml_ddfromxml_factory.h:535
static datamodel::StreamMetaType::Property createStreamMetaTypeProperty(const DOM_NODE_TYPE &dom_node)
Create a Stream Meta Type Property object.
Definition xml_ddfromxml_factory.h:776
static datamodel::Stream::Struct createStreamStruct(const DOM_NODE_TYPE &dom_node)
Create a Stream Struct object.
Definition xml_ddfromxml_factory.h:818
static datamodel::StreamMetaType createStreamMetaType(const DOM_NODE_TYPE &dom_node)
Create a Stream Meta Type object.
Definition xml_ddfromxml_factory.h:791
static datamodel::Header createHeader(const DOM_NODE_TYPE &dom_node)
Create a Header object.
Definition xml_ddfromxml_factory.h:345
static bool isInteger(const std::string &string_to_check) noexcept
Checks if the given string is an integer value.
Definition xml_ddfromxml_factory.h:151
static datamodel::Stream createStream(const DOM_NODE_TYPE &dom_node)
Create a Stream object.
Definition xml_ddfromxml_factory.h:834
An optional template as long as the std::optional is not available here.
Definition access_optional.h:31
T toType(std::string from_string, T default_value) noexcept
Conversion to T.
T toRequiredType(std::string from_string)
Conversion to T without fallback.