17 #include <fmt/format.h>
24 namespace configuration
26 namespace xml_config_parsing
28 inline const tinyxml2::XMLElement*
getFirstChildElement(
const tinyxml2::XMLElement* parent,
const char* name)
30 const tinyxml2::XMLElement* child = parent->FirstChildElement(name);
34 fmt::format(
"Could not parse. Element <{}> is missing a child <{}>.", parent->Name(), name));
40 const char*
getText(
const tinyxml2::XMLElement* element)
42 const char* element_str = element->GetText();
43 if (element_str ==
nullptr || strlen(element_str) == 0)
51 inline bool textIsEqual(
const tinyxml2::XMLElement* element,
const char* str)
53 return strcmp(
getText(element), str) == 0;
60 const tinyxml2::XMLElement* xml_set_detail_element =
getFirstChildElement(xml_set_element,
"zoneSetDetail");
62 while (xml_set_detail_element)
64 const tinyxml2::XMLElement* xml_set_detail_type_element =
getFirstChildElement(xml_set_detail_element,
"type");
65 const tinyxml2::XMLElement* xml_set_detail_ro_element =
getFirstChildElement(xml_set_detail_element,
"ro");
67 if (
textIsEqual(xml_set_detail_type_element,
"roOSSD1"))
71 else if (
textIsEqual(xml_set_detail_type_element,
"roOSSD2"))
75 else if (
textIsEqual(xml_set_detail_type_element,
"roOSSD3"))
79 else if (
textIsEqual(xml_set_detail_type_element,
"warn1"))
83 else if (
textIsEqual(xml_set_detail_type_element,
"warn2"))
87 else if (
textIsEqual(xml_set_detail_type_element,
"muting1"))
91 else if (
textIsEqual(xml_set_detail_type_element,
"muting2"))
98 "\"roOSSD3\", \"warn1\", \"warn2\", \"muting1\" or \"muting2\".");
101 xml_set_detail_element = xml_set_detail_element->NextSiblingElement(
"zoneSetDetail");
112 const tinyxml2::XMLElement* xml_set_detail_element =
getFirstChildElement(xml_set_element,
"zoneSetDetail");
114 while (xml_set_detail_element)
116 const tinyxml2::XMLElement* xml_set_detail_type_element =
getFirstChildElement(xml_set_detail_element,
"type");
117 const tinyxml2::XMLElement* xml_set_detail_ro_element =
getFirstChildElement(xml_set_detail_element,
"ro");
119 if (
textIsEqual(xml_set_detail_type_element,
"roOSSD1"))
123 else if (
textIsEqual(xml_set_detail_type_element,
"roOSSD2"))
127 else if (
textIsEqual(xml_set_detail_type_element,
"roOSSD3"))
131 else if (
textIsEqual(xml_set_detail_type_element,
"warn1"))
135 else if (
textIsEqual(xml_set_detail_type_element,
"warn2"))
139 else if (
textIsEqual(xml_set_detail_type_element,
"muting1"))
143 else if (
textIsEqual(xml_set_detail_type_element,
"muting2"))
150 "\"roOSSD3\", \"warn1\", \"warn2\", \"muting1\" or \"muting2\".");
153 xml_set_detail_element = xml_set_detail_element->NextSiblingElement(
"zoneSetDetail");
164 const tinyxml2::XMLElement* xml_set_detail_element =
getFirstChildElement(xml_set_element,
"zoneSetDetail");
166 while (xml_set_detail_element)
168 const tinyxml2::XMLElement* xml_set_detail_type_element =
getFirstChildElement(xml_set_detail_element,
"type");
169 const tinyxml2::XMLElement* xml_set_detail_ro_element =
getFirstChildElement(xml_set_detail_element,
"ro");
171 if (
textIsEqual(xml_set_detail_type_element,
"roOSSD1"))
175 else if (
textIsEqual(xml_set_detail_type_element,
"roOSSD2"))
179 else if (
textIsEqual(xml_set_detail_type_element,
"roOSSD3"))
183 else if (
textIsEqual(xml_set_detail_type_element,
"warn1"))
187 else if (
textIsEqual(xml_set_detail_type_element,
"warn2"))
191 else if (
textIsEqual(xml_set_detail_type_element,
"muting1"))
195 else if (
textIsEqual(xml_set_detail_type_element,
"muting2"))
202 "\"roOSSD3\", \"warn1\", \"warn2\", \"muting1\" or \"muting2\".");
205 xml_set_detail_element = xml_set_detail_element->NextSiblingElement(
"zoneSetDetail");
216 const tinyxml2::XMLElement* xml_set_detail_element =
getFirstChildElement(xml_set_element,
"zoneSetDetail");
218 while (xml_set_detail_element)
220 const tinyxml2::XMLElement* xml_set_detail_type_element =
getFirstChildElement(xml_set_detail_element,
"type");
221 const tinyxml2::XMLElement* xml_set_detail_ro_element =
getFirstChildElement(xml_set_detail_element,
"ro");
223 if (
textIsEqual(xml_set_detail_type_element,
"roOSSD1"))
227 else if (
textIsEqual(xml_set_detail_type_element,
"roOSSD2"))
231 else if (
textIsEqual(xml_set_detail_type_element,
"roOSSD3"))
235 else if (
textIsEqual(xml_set_detail_type_element,
"warn1"))
239 else if (
textIsEqual(xml_set_detail_type_element,
"warn2"))
243 else if (
textIsEqual(xml_set_detail_type_element,
"muting1"))
247 else if (
textIsEqual(xml_set_detail_type_element,
"muting2"))
254 "\"roOSSD3\", \"warn1\", \"warn2\", \"muting1\" or \"muting2\".");
257 xml_set_detail_element = xml_set_detail_element->NextSiblingElement(
"zoneSetDetail");
268 const tinyxml2::XMLElement* xml_zone_set_speed_range_element =
271 const tinyxml2::XMLElement* xml_zone_set_select_element_min =
274 const tinyxml2::XMLElement* xml_zone_set_select_element_max =
277 unsigned int min_speed, max_speed;
278 if (xml_zone_set_select_element_min->QueryUnsignedText(&min_speed) != tinyxml2::XML_SUCCESS)
283 if (xml_zone_set_select_element_max->QueryUnsignedText(&max_speed) != tinyxml2::XML_SUCCESS)
293 const tinyxml2::XMLElement* enc_enabled_element = doc_handle.FirstChildElement(
"MIB")
294 .FirstChildElement(
"clusterDescr")
295 .FirstChildElement(
"zoneSetConfiguration")
296 .FirstChildElement(
"encEnable")
298 if (!enc_enabled_element)
301 "Could not parse. Chain MIB->clusterDescr->zoneSetConfiguration->encEnabled is broken.");
305 if (enc_enabled_element->QueryBoolText(&enc_enabled) != tinyxml2::XML_SUCCESS)
308 "Could not parse. Value inside <encEnable> could not be evaluated to true or false");
314 std::vector<ZoneSet>
parseZoneSets(
const tinyxml2::XMLConstHandle& doc_handle)
316 std::vector<ZoneSet> zonesets;
317 int nr_subcribers = 0;
319 for (tinyxml2::XMLConstHandle scanner_handle = doc_handle.FirstChildElement(
"MIB").FirstChildElement(
"scannerDescr");
320 scanner_handle.ToElement();
321 scanner_handle = scanner_handle.NextSiblingElement(
"scannerDescr"))
326 tinyxml2::XMLConstHandle xml_set_info_handle = doc_handle.FirstChildElement(
"MIB").FirstChildElement(
"scannerDescr");
328 const tinyxml2::XMLElement* scanner_descr_element_master = xml_set_info_handle.ToElement();
329 const tinyxml2::XMLElement* zone_set_definition_element_master =
331 const tinyxml2::XMLElement* zone_set_info_element_master =
334 if (nr_subcribers == 1)
336 while (zone_set_info_element_master)
339 zonesets.push_back(set_master);
340 zone_set_info_element_master = zone_set_info_element_master->NextSiblingElement(
"zoneSetInfo");
344 else if (nr_subcribers == 2)
346 const tinyxml2::XMLElement* scanner_descr_element_sub0 =
347 scanner_descr_element_master->NextSiblingElement(
"scannerDescr");
348 const tinyxml2::XMLElement* zone_set_definition_element_sub0 =
350 const tinyxml2::XMLElement* zone_set_info_element_sub0 =
352 while (zone_set_info_element_master && zone_set_info_element_sub0)
356 zonesets.push_back(set_sub0);
357 zone_set_info_element_master = zone_set_info_element_master->NextSiblingElement(
"zoneSetInfo");
358 zone_set_info_element_sub0 = zone_set_info_element_sub0->NextSiblingElement(
"zoneSetInfo");
362 else if (nr_subcribers == 3)
364 const tinyxml2::XMLElement* scanner_descr_element_sub0 =
365 scanner_descr_element_master->NextSiblingElement(
"scannerDescr");
366 const tinyxml2::XMLElement* zone_set_definition_element_sub0 =
368 const tinyxml2::XMLElement* zone_set_info_element_sub0 =
370 const tinyxml2::XMLElement* scanner_descr_element_sub1 =
371 scanner_descr_element_sub0->NextSiblingElement(
"scannerDescr");
372 const tinyxml2::XMLElement* zone_set_definition_element_sub1 =
374 const tinyxml2::XMLElement* zone_set_info_element_sub1 =
376 while (zone_set_info_element_master && zone_set_info_element_sub0 && zone_set_info_element_sub1)
381 zonesets.push_back(set_sub1);
382 zone_set_info_element_master = zone_set_info_element_master->NextSiblingElement(
"zoneSetInfo");
383 zone_set_info_element_sub0 = zone_set_info_element_sub0->NextSiblingElement(
"zoneSetInfo");
384 zone_set_info_element_sub1 = zone_set_info_element_sub1->NextSiblingElement(
"zoneSetInfo");
387 else if (nr_subcribers == 4)
389 const tinyxml2::XMLElement* scanner_descr_element_sub0 =
390 scanner_descr_element_master->NextSiblingElement(
"scannerDescr");
391 const tinyxml2::XMLElement* zone_set_definition_element_sub0 =
393 const tinyxml2::XMLElement* zone_set_info_element_sub0 =
395 const tinyxml2::XMLElement* scanner_descr_element_sub1 =
396 scanner_descr_element_sub0->NextSiblingElement(
"scannerDescr");
397 const tinyxml2::XMLElement* zone_set_definition_element_sub1 =
399 const tinyxml2::XMLElement* zone_set_info_element_sub1 =
401 const tinyxml2::XMLElement* scanner_descr_element_sub2 =
402 scanner_descr_element_sub1->NextSiblingElement(
"scannerDescr");
403 const tinyxml2::XMLElement* zone_set_definition_element_sub2 =
405 const tinyxml2::XMLElement* zone_set_info_element_sub2 =
407 while (zone_set_info_element_master && zone_set_info_element_sub0 && zone_set_info_element_sub1 &&
408 zone_set_info_element_sub2)
414 zonesets.push_back(set_sub2);
415 zone_set_info_element_master = zone_set_info_element_master->NextSiblingElement(
"zoneSetInfo");
416 zone_set_info_element_sub0 = zone_set_info_element_sub0->NextSiblingElement(
"zoneSetInfo");
417 zone_set_info_element_sub1 = zone_set_info_element_sub1->NextSiblingElement(
"zoneSetInfo");
418 zone_set_info_element_sub2 = zone_set_info_element_sub2->NextSiblingElement(
"zoneSetInfo");
424 std::vector<ZoneSetSpeedRange>
parseSpeedRanges(
const tinyxml2::XMLConstHandle& doc_handle)
426 const tinyxml2::XMLElement* xml_zone_set_select_element = doc_handle.FirstChildElement(
"MIB")
427 .FirstChildElement(
"clusterDescr")
428 .FirstChildElement(
"zoneSetConfiguration")
429 .FirstChildElement(
"zoneSetSelCode")
430 .FirstChildElement(
"zoneSetSelector")
433 if (!xml_zone_set_select_element)
436 "Could not parse. Chain MIB->clusterDescr->zoneSetConfiguration->zoneSetSelCode->zoneSetSelector is "
440 std::vector<ZoneSetSpeedRange> speed_ranges;
442 while (xml_zone_set_select_element)
445 speed_ranges.push_back(speed_range);
447 xml_zone_set_select_element = xml_zone_set_select_element->NextSiblingElement(
"zoneSetSelector");
455 tinyxml2::XMLConstHandle doc_handle(&doc);
463 if (zonesets.size() == speed_ranges.size())
465 for (
size_t i = 0; i < zonesets.size(); i++)
467 zonesets.at(i).speed_range_ = speed_ranges.at(i);
473 fmt::format(
"Parsing failed. SpeedRanges are enabled by <encEnable>true</Enable>"
474 "but there are {} speedRanges and {} defined zones.",
484 return zoneset_config;
489 tinyxml2::XMLDocument doc;
490 auto parse_result = doc.LoadFile(filename);
491 if (parse_result != tinyxml2::XML_SUCCESS)
501 tinyxml2::XMLDocument doc;
502 auto parse_result = doc.Parse(xml);
503 if (parse_result != tinyxml2::XML_SUCCESS)