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\".");
102 xml_set_detail_element = xml_set_detail_element->NextSiblingElement(
"zoneSetDetail");
113 const tinyxml2::XMLElement* xml_zone_set_speed_range_element =
116 const tinyxml2::XMLElement* xml_zone_set_select_element_min =
119 const tinyxml2::XMLElement* xml_zone_set_select_element_max =
122 unsigned int min_speed, max_speed;
123 if (xml_zone_set_select_element_min->QueryUnsignedText(&min_speed) != tinyxml2::XML_SUCCESS)
128 if (xml_zone_set_select_element_max->QueryUnsignedText(&max_speed) != tinyxml2::XML_SUCCESS)
138 const tinyxml2::XMLElement* enc_enabled_element = doc_handle.FirstChildElement(
"MIB")
139 .FirstChildElement(
"clusterDescr")
140 .FirstChildElement(
"zoneSetConfiguration")
141 .FirstChildElement(
"encEnable")
143 if (!enc_enabled_element)
146 "Could not parse. Chain MIB->clusterDescr->zoneSetConfiguration->encEnabled is broken.");
150 if (enc_enabled_element->QueryBoolText(&enc_enabled) != tinyxml2::XML_SUCCESS)
153 "Could not parse. Value inside <encEnable> could not be evaluated to true or false");
159 std::vector<ZoneSet>
parseZoneSets(
const tinyxml2::XMLConstHandle& doc_handle)
161 tinyxml2::XMLConstHandle xml_set_info_handle = doc_handle.FirstChildElement(
"MIB")
162 .FirstChildElement(
"scannerDescr")
163 .FirstChildElement(
"zoneSetDefinition")
164 .FirstChildElement(
"zoneSetInfo");
166 const tinyxml2::XMLElement* xml_set_element = xml_set_info_handle.ToElement();
168 if (!xml_set_element)
171 "Could not parse. Chain MIB->scannerDescr->zoneSetDefinition->zoneSetInfo not complete.");
174 std::vector<ZoneSet> zonesets;
176 while (xml_set_element)
180 zonesets.push_back(
set);
181 xml_set_element = xml_set_element->NextSiblingElement(
"zoneSetInfo");
187 std::vector<ZoneSetSpeedRange>
parseSpeedRanges(
const tinyxml2::XMLConstHandle& doc_handle)
189 const tinyxml2::XMLElement* xml_zone_set_select_element = doc_handle.FirstChildElement(
"MIB")
190 .FirstChildElement(
"clusterDescr")
191 .FirstChildElement(
"zoneSetConfiguration")
192 .FirstChildElement(
"zoneSetSelCode")
193 .FirstChildElement(
"zoneSetSelector")
196 if (!xml_zone_set_select_element)
199 "Could not parse. Chain MIB->clusterDescr->zoneSetConfiguration->zoneSetSelCode->zoneSetSelector is " 203 std::vector<ZoneSetSpeedRange> speed_ranges;
205 while (xml_zone_set_select_element)
208 speed_ranges.push_back(speed_range);
210 xml_zone_set_select_element = xml_zone_set_select_element->NextSiblingElement(
"zoneSetSelector");
218 tinyxml2::XMLConstHandle doc_handle(&doc);
226 if (zonesets.size() == speed_ranges.size())
228 for (
size_t i = 0; i < zonesets.size(); i++)
230 zonesets.at(i).speed_range_ = speed_ranges.at(i);
236 fmt::format(
"Parsing failed. SpeedRanges are enabled by <encEnable>true</Enable>" 237 "but there are {} speedRanges and {} defined zones.",
247 return zoneset_config;
252 tinyxml2::XMLDocument doc;
253 auto parse_result = doc.LoadFile(filename);
254 if (parse_result != tinyxml2::XML_SUCCESS)
264 tinyxml2::XMLDocument doc;
265 auto parse_result = doc.Parse(xml);
266 if (parse_result != tinyxml2::XML_SUCCESS)
std::vector< ZoneSet > parseZoneSets(const tinyxml2::XMLConstHandle &doc_handle)
const char * getText(const tinyxml2::XMLElement *element)
ZoneSet parseZoneSet(const tinyxml2::XMLElement *xml_set_element)
std::vector< ZoneSetSpeedRange > parseSpeedRanges(const tinyxml2::XMLConstHandle &doc_handle)
ZoneSetConfiguration parseTinyXML(const tinyxml2::XMLDocument &doc)
ZoneSetSpeedRange parseZoneSetSpeedRange(const tinyxml2::XMLElement *xml_zone_set_select_element)
bool textIsEqual(const tinyxml2::XMLElement *element, const char *str)
Root namespace in which the software components to communicate with the scanner (firmware-version: 2)...
bool isEncoderEnabled(const tinyxml2::XMLConstHandle &doc_handle)
A set of simultanously active zones.
ZoneSetConfiguration parseString(const char *xml)
ZoneSetConfiguration parseFile(const char *filename)
static const util::TenthOfDegree DEFAULT_ZONESET_ANGLE_STEP(5)
The speedrange at which a ZoneSet is active.
const tinyxml2::XMLElement * getFirstChildElement(const tinyxml2::XMLElement *parent, const char *name)
std::vector< unsigned long > ro_string_to_vec(const std::string &ro_string)
Convert string from a <ro> element to values.
std::vector< ZoneSet > zonesets_