template <typename Traits> inline shared_ptr<typename detector_impl<Traits>::definition_type> detector_impl<Traits>::parse_complex_definition(char const *name, xmlNodePtr node) const { typedef complex_definition<Traits> complex_type; shared_ptr<complex_type> parent(new complex_type(name)); xml_elems elems(node, "pattern"); for (xml_elems::const_iterator i = elems.begin(), end = elems.end(); i != end; ++i) { if (disabled(*i)) { continue; } char const *value = xml_attr_text(*i, "value"), *type = xml_attr_text(*i, "type"); if (strncasecmp(type, "string", sizeof("string")) == 0) { parent->add(shared_ptr<definition_type>(new string_definition<Traits>(name, xml_node_text(*i), value))); } else if (strncasecmp(type, "regex", sizeof("regex")) == 0) { parent->add(shared_ptr<definition_type>(new regex_definition<Traits>(name, xml_node_text(*i), value))); } else { resource<xmlChar*, xml_string_traits> path(xmlGetNodePath(node)); throw error("unknown pattern type %s in [%s]", type, (char const*) path.get()); } } return parent->has_only_one() ? parent->release_child() : parent.template cast<definition_type>(); }
template <typename Traits> inline shared_ptr<typename detector_impl<Traits>::definition_type> detector_impl<Traits>::parse_definition(xmlNodePtr node) const { char const *name = xml_attr_text(node, "name"), *value = xml_attr_text(node, "value"); if (static_cast<char const*>(0) == name) { resource<xmlChar*, xml_string_traits> path(xmlGetNodePath(node)); throw error("definition without name in [%s]", (char const*) path.get()); } else if (static_cast<char const*>(0) == value) { return parse_complex_definition(name, node); } else { return shared_ptr<definition_type>(new static_definition<Traits>(name, value)); } }
void detector_helper::check_version(xmlNodePtr node) { char const *value = xml_attr_text(node, "minver"); if (0 == value) { throw error("legacy format browser.xml, minver not found"); } int main_minversion = 0, major_minversion = 0; if (2 != sscanf(value, "%d.%d", &main_minversion, &major_minversion)) { throw error("invalid format browser.xml, strange minver value: %s", value); } if (main_version < main_minversion || (main_version == main_minversion && major_version < major_minversion)) { throw error("old library version: " UATRAITS_PACKAGE_VERSION " < %s", value); } }
template <typename Traits> inline shared_ptr<typename detector_impl<Traits>::branch_type> detector_impl<Traits>::parse_branch(xmlNodePtr node) const { shared_ptr<branch_type> result(new branch_type()); for (xmlNodePtr n = xmlFirstElementChild(node); 0 != n; n = xmlNextElementSibling(n)) { if (disabled(n)) { continue; } else if (xmlStrncasecmp(n->name, (xmlChar const*) "match", sizeof("match")) == 0) { xml_elems elems(n, "pattern"); for (xml_elems::iterator i = elems.begin(), end = elems.end(); i != end; ++i) { if (disabled(*i)) { continue; } char const *type = xml_attr_text(*i, "type"); if (strncasecmp(type, "string", sizeof("string")) == 0) { result->add_match(xml_node_text(*i)); } else if (strncasecmp(type, "regex", sizeof("regex")) == 0) { result->add_regex_match(xml_node_text(*i)); } else { resource<xmlChar*, xml_string_traits> path(xmlGetNodePath(*i)); throw error("unknown pattern type %s in [%s]", type, (char const*) path.get()); } } } else if (xmlStrncasecmp(n->name, (xmlChar const*) "branch", sizeof("branch")) == 0) { result->add_child(parse_branch(n)); } else if (xmlStrncasecmp(n->name, (xmlChar const*) "define", sizeof("definition")) == 0) { result->add_definition(parse_definition(n)); } } return result; }
bool detector_helper::disabled(xmlNodePtr node) { char const *value = xml_attr_text(node, "disabled"); return value && (0 == strncasecmp(value, "true", sizeof("true"))); }
template <typename Traits> inline bool detector_impl<Traits>::disabled(xmlNodePtr node) const { char const *value = xml_attr_text(node, "disabled"); return value && (0 == strncasecmp(value, "true", sizeof("true"))); }