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)