From 1dfd42ceb79677e171d5dedcac34900776574000 Mon Sep 17 00:00:00 2001 From: imarom Date: Wed, 29 Jun 2016 10:35:54 +0300 Subject: added enhanced parsing for the YAML wrapper module --- src/utl_yaml.cpp | 225 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 181 insertions(+), 44 deletions(-) (limited to 'src/utl_yaml.cpp') diff --git a/src/utl_yaml.cpp b/src/utl_yaml.cpp index bf30d661..22772ffe 100755 --- a/src/utl_yaml.cpp +++ b/src/utl_yaml.cpp @@ -83,6 +83,33 @@ bool utl_yaml_read_ip_addr(const YAML::Node& node, return (res); } + + +bool utl_yaml_read_uint32(const YAML::Node& node, + const std::string &name, + uint32_t & val){ + bool res=false; + if ( node.FindValue(name) ) { + node[name] >> val ; + res=true; + } + return (res); +} + +bool utl_yaml_read_uint16(const YAML::Node& node, + const std::string &name, + uint16_t & val){ + uint32_t val_tmp; + bool res=false; + if ( node.FindValue(name) ) { + node[name] >> val_tmp ; + val = (uint16_t)val_tmp; + res=true; + } + + return (res); +} + static void split_str_by_delimiter(std::string str, char delim, std::vector &tokens) { size_t pos = 0; @@ -99,23 +126,13 @@ split_str_by_delimiter(std::string str, char delim, std::vector &to } } -bool utl_yaml_read_mac_addr(const YAML::Node &node, - const std::string &name, - uint64_t &val) { - - std::string mac_str; - - if (!node.FindValue(name)) { - return false; - } - - node[name] >> mac_str; - +static bool mac2uint64(const std::string &mac_str, uint64_t &mac_num) { std::vector tokens; - split_str_by_delimiter(mac_str, ':', tokens); + uint64_t val; + split_str_by_delimiter(mac_str, ':', tokens); if (tokens.size() != 6) { - throw YAML::InvalidScalar(node[name].GetMark()); + return false; } val = 0; @@ -125,51 +142,171 @@ bool utl_yaml_read_mac_addr(const YAML::Node &node, unsigned long octet = strtoul(tokens[i].c_str(), &endptr, 16); if ( (*endptr != 0) || (octet > 0xff) ) { - throw YAML::InvalidScalar(node[name].GetMark()); + return false; } - //mac_addr[i] = (uint8_t)octet; val = (val << 8) + octet; - } - + } + + mac_num = val; + return true; } +/************************ + * YAML Parser Wrapper + * + ***********************/ +bool +YAMLParserWrapper::parse_bool(const YAML::Node &node, const std::string &name, bool def) { + if (!node.FindValue(name)) { + return def; + } -bool utl_yaml_read_uint32(const YAML::Node& node, - const std::string &name, - uint32_t & val){ - bool res=false; - if ( node.FindValue(name) ) { - node[name] >> val ; - res=true; + return parse_bool(node, name); +} + +bool +YAMLParserWrapper::parse_bool(const YAML::Node &node, const std::string &name) { + try { + bool val; + node[name] >> val; + return (val); + + } catch (const YAML::InvalidScalar &ex) { + parse_err("expecting true/false for field '" + name + "'", node[name]); + + } catch (const YAML::KeyNotFound &ex) { + parse_err("cannot locate mandatory field '" + name + "'", node); } - return (res); + + assert(0); } -bool utl_yaml_read_uint16(const YAML::Node& node, - const std::string &name, - uint16_t & val){ - uint32_t val_tmp; - bool res=false; - if ( node.FindValue(name) ) { - node[name] >> val_tmp ; - val = (uint16_t)val_tmp; - res=true; +const YAML::Node & +YAMLParserWrapper::parse_list(const YAML::Node &node, const std::string &name) { + + try { + const YAML::Node &val = node[name]; + if (val.Type() != YAML::NodeType::Sequence) { + throw YAML::InvalidScalar(node[name].GetMark()); + } + return val; + + } catch (const YAML::InvalidScalar &ex) { + parse_err("expecting sequence/list for field '" + name + "'", node[name]); + + } catch (const YAML::KeyNotFound &ex) { + parse_err("cannot locate mandatory field '" + name + "'", node); } - return (res); + assert(0); } -bool utl_yaml_read_bool(const YAML::Node& node, - const std::string &name, - bool & val){ - bool res=false; - if ( node.FindValue(name) ) { - node[name] >> val ; - res=true; +const YAML::Node & +YAMLParserWrapper::parse_map(const YAML::Node &node, const std::string &name) { + + try { + const YAML::Node &val = node[name]; + if (val.Type() != YAML::NodeType::Map) { + throw YAML::InvalidScalar(node[name].GetMark()); + } + return val; + + } catch (const YAML::InvalidScalar &ex) { + parse_err("expecting map for field '" + name + "'", node[name]); + + } catch (const YAML::KeyNotFound &ex) { + parse_err("cannot locate mandatory field '" + name + "'", node); + } + + assert(0); +} + +uint32_t +YAMLParserWrapper::parse_ip(const YAML::Node &node, const std::string &name) { + + + try { + std::string ip_str; + uint32_t ip_num; + + node[name] >> ip_str; + int rc = my_inet_pton4((char *)ip_str.c_str(), (unsigned char *)&ip_num); + if (!rc) { + parse_err("invalid IP address: " + ip_str, node[name]); + } + + return PKT_NTOHL(ip_num); + + } catch (const YAML::InvalidScalar &ex) { + parse_err("expecting valid IP address for field '" + name + "'", node[name]); + + } catch (const YAML::KeyNotFound &ex) { + parse_err("cannot locate mandatory field '" + name + "'", node); } - return( res); + + assert(0); +} + +uint64_t +YAMLParserWrapper::parse_mac_addr(const YAML::Node &node, const std::string &name) { + + std::string mac_str; + uint64_t mac_num; + + try { + + node[name] >> mac_str; + bool rc = mac2uint64(mac_str, mac_num); + if (!rc) { + parse_err("invalid MAC address: " + mac_str, node[name]); + } + return mac_num; + + } catch (const YAML::InvalidScalar &ex) { + parse_err("expecting true/false for field '" + name + "'", node[name]); + + } catch (const YAML::KeyNotFound &ex) { + parse_err("cannot locate mandatory field '" + name + "'", node); + } + + assert(0); } +uint64_t +YAMLParserWrapper::parse_uint(const YAML::Node &node, const std::string &name, uint64_t low, uint64_t high) { + + try { + + uint64_t val; + node[name] >> val; + + if ( (val < low) || (val > high) ) { + std::stringstream ss; + ss << "valid range for field '" << name << "' is: [" << low << " - " << high << "]"; + parse_err(ss.str(), node[name]); + } + + return (val); + + } catch (const YAML::InvalidScalar &ex) { + parse_err("expecting true/false for field '" + name + "'", node[name]); + + } catch (const YAML::KeyNotFound &ex) { + parse_err("cannot locate mandatory field '" + name + "'", node); + } + + assert(0); +} + +void +YAMLParserWrapper::parse_err(const std::string &err, const YAML::Node &node) const { + std::stringstream ss; + + ss << "\n*** '" << m_header << "' - YAML parsing error at line " << node.GetMark().line << ": "; + ss << err; + + throw std::runtime_error(ss.str()); +} -- cgit 1.2.3-korg