From f03fa158116cfd65659d14698c91446dc9bdb4c4 Mon Sep 17 00:00:00 2001 From: imarom <imarom@cisco.com> Date: Mon, 27 Jun 2016 17:15:05 +0300 Subject: draft #3 of client config --- src/utl_yaml.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 8 deletions(-) (limited to 'src/utl_yaml.cpp') diff --git a/src/utl_yaml.cpp b/src/utl_yaml.cpp index 828817e4..bf30d661 100755 --- a/src/utl_yaml.cpp +++ b/src/utl_yaml.cpp @@ -21,7 +21,7 @@ See the License for the specific language governing permissions and limitations under the License. */ - +#include <istream> #define INADDRSZ 4 @@ -65,8 +65,8 @@ static int my_inet_pton4(const char *src, unsigned char *dst) bool utl_yaml_read_ip_addr(const YAML::Node& node, - std::string name, - uint32_t & val){ + const std::string &name, + uint32_t & val){ std::string tmp; uint32_t ip; bool res=false; @@ -83,8 +83,61 @@ bool utl_yaml_read_ip_addr(const YAML::Node& node, return (res); } +static void +split_str_by_delimiter(std::string str, char delim, std::vector<std::string> &tokens) { + size_t pos = 0; + std::string token; + + while ((pos = str.find(delim)) != std::string::npos) { + token = str.substr(0, pos); + tokens.push_back(token); + str.erase(0, pos + 1); + } + + if (str.size() > 0) { + tokens.push_back(str); + } +} + +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; + + std::vector<std::string> tokens; + split_str_by_delimiter(mac_str, ':', tokens); + + if (tokens.size() != 6) { + throw YAML::InvalidScalar(node[name].GetMark()); + } + + val = 0; + + for (int i = 0; i < 6 ; i++) { + char *endptr = NULL; + unsigned long octet = strtoul(tokens[i].c_str(), &endptr, 16); + + if ( (*endptr != 0) || (octet > 0xff) ) { + throw YAML::InvalidScalar(node[name].GetMark()); + } + + //mac_addr[i] = (uint8_t)octet; + val = (val << 8) + octet; + } + + return true; +} + + bool utl_yaml_read_uint32(const YAML::Node& node, - std::string name, + const std::string &name, uint32_t & val){ bool res=false; if ( node.FindValue(name) ) { @@ -95,8 +148,8 @@ bool utl_yaml_read_uint32(const YAML::Node& node, } bool utl_yaml_read_uint16(const YAML::Node& node, - std::string name, - uint16_t & val){ + const std::string &name, + uint16_t & val){ uint32_t val_tmp; bool res=false; if ( node.FindValue(name) ) { @@ -109,8 +162,8 @@ bool utl_yaml_read_uint16(const YAML::Node& node, } bool utl_yaml_read_bool(const YAML::Node& node, - std::string name, - bool & val){ + const std::string &name, + bool & val){ bool res=false; if ( node.FindValue(name) ) { node[name] >> val ; -- cgit From 1dfd42ceb79677e171d5dedcac34900776574000 Mon Sep 17 00:00:00 2001 From: imarom <imarom@cisco.com> 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<std::string> &tokens) { size_t pos = 0; @@ -99,23 +126,13 @@ split_str_by_delimiter(std::string str, char delim, std::vector<std::string> &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<std::string> 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 From 4242bc5ec3aa8816db9bdd57bd1f732da4305555 Mon Sep 17 00:00:00 2001 From: imarom <imarom@cisco.com> Date: Wed, 29 Jun 2016 15:39:46 +0300 Subject: client configuration: refactoring --- src/utl_yaml.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/utl_yaml.cpp') diff --git a/src/utl_yaml.cpp b/src/utl_yaml.cpp index 22772ffe..444031c6 100755 --- a/src/utl_yaml.cpp +++ b/src/utl_yaml.cpp @@ -249,6 +249,15 @@ YAMLParserWrapper::parse_ip(const YAML::Node &node, const std::string &name) { assert(0); } +uint64_t +YAMLParserWrapper::parse_mac_addr(const YAML::Node &node, const std::string &name, uint64_t def) { + if (!node.FindValue(name)) { + return def; + } + + return parse_mac_addr(node, name); +} + uint64_t YAMLParserWrapper::parse_mac_addr(const YAML::Node &node, const std::string &name) { @@ -274,6 +283,15 @@ YAMLParserWrapper::parse_mac_addr(const YAML::Node &node, const std::string &nam assert(0); } +uint64_t +YAMLParserWrapper::parse_uint(const YAML::Node &node, const std::string &name, uint64_t low, uint64_t high, uint64_t def) { + if (!node.FindValue(name)) { + return def; + } + + return parse_uint(node, name, low, high); +} + uint64_t YAMLParserWrapper::parse_uint(const YAML::Node &node, const std::string &name, uint64_t low, uint64_t high) { @@ -310,3 +328,11 @@ YAMLParserWrapper::parse_err(const std::string &err, const YAML::Node &node) con throw std::runtime_error(ss.str()); } +void +YAMLParserWrapper::parse_err(const std::string &err) const { + std::stringstream ss; + + ss << "\n*** '" << m_header << "' - YAML parsing error: " << err; + + throw std::runtime_error(ss.str()); +} -- cgit From c6c4a4307a8a0ae17d3e26c9dc98b874dd5ee60b Mon Sep 17 00:00:00 2001 From: imarom <imarom@cisco.com> Date: Sun, 3 Jul 2016 10:55:49 +0300 Subject: client config - cosmetics and gtest back on --- src/utl_yaml.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/utl_yaml.cpp') diff --git a/src/utl_yaml.cpp b/src/utl_yaml.cpp index 444031c6..66c83ac8 100755 --- a/src/utl_yaml.cpp +++ b/src/utl_yaml.cpp @@ -322,7 +322,7 @@ 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 << "'" << m_header << "' - YAML parsing error at line " << node.GetMark().line << ": "; ss << err; throw std::runtime_error(ss.str()); @@ -332,7 +332,7 @@ void YAMLParserWrapper::parse_err(const std::string &err) const { std::stringstream ss; - ss << "\n*** '" << m_header << "' - YAML parsing error: " << err; + ss << "'" << m_header << "' - YAML parsing error: " << err; throw std::runtime_error(ss.str()); } -- cgit From 483dfb7c5021d7dc9e2c7f10c9b76101441c7203 Mon Sep 17 00:00:00 2001 From: imarom <imarom@cisco.com> Date: Sun, 3 Jul 2016 15:38:59 +0300 Subject: slowpath features bit to avoid multiple IFs --- src/utl_yaml.cpp | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'src/utl_yaml.cpp') diff --git a/src/utl_yaml.cpp b/src/utl_yaml.cpp index 66c83ac8..8352e887 100755 --- a/src/utl_yaml.cpp +++ b/src/utl_yaml.cpp @@ -22,6 +22,8 @@ limitations under the License. */ #include <istream> +#include <fstream> +#include "common/basic_utils.h" #define INADDRSZ 4 @@ -157,6 +159,27 @@ static bool mac2uint64(const std::string &mac_str, uint64_t &mac_num) { * YAML Parser Wrapper * ***********************/ +void +YAMLParserWrapper::load(YAML::Node &root) { + std::stringstream ss; + + /* first check file exists */ + if (!utl_is_file_exists(m_filename)){ + ss << "file '" << m_filename << "' does not exists"; + throw std::runtime_error(ss.str()); + } + + std::ifstream fin(m_filename); + + try { + YAML::Parser base_parser(fin); + base_parser.GetNextDocument(root); + + } catch (const YAML::Exception &e) { + parse_err(e.what()); + } +} + bool YAMLParserWrapper::parse_bool(const YAML::Node &node, const std::string &name, bool def) { if (!node.FindValue(name)) { @@ -322,7 +345,7 @@ void YAMLParserWrapper::parse_err(const std::string &err, const YAML::Node &node) const { std::stringstream ss; - ss << "'" << m_header << "' - YAML parsing error at line " << node.GetMark().line << ": "; + ss << "'" << m_filename << "' - YAML parsing error at line " << node.GetMark().line << ": "; ss << err; throw std::runtime_error(ss.str()); @@ -332,7 +355,7 @@ void YAMLParserWrapper::parse_err(const std::string &err) const { std::stringstream ss; - ss << "'" << m_header << "' - YAML parsing error: " << err; + ss << "'" << m_filename << "' - YAML parsing error: " << err; throw std::runtime_error(ss.str()); } -- cgit