X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=bindings%2Fcxx%2FConfigKey_methods.cpp;h=7f8c201ed5a8f1e649b4f4e9a452b5c8344e1dd3;hb=b41562f6ce3ba5572d65965811e0eb1f62a4b223;hp=54fa66c181309143a5cb4c589275ed748cc94106;hpb=c23c8659b8f8c4ca60bf59f6afd12bde7a0b2383;p=libsigrok.git diff --git a/bindings/cxx/ConfigKey_methods.cpp b/bindings/cxx/ConfigKey_methods.cpp index 54fa66c1..7f8c201e 100644 --- a/bindings/cxx/ConfigKey_methods.cpp +++ b/bindings/cxx/ConfigKey_methods.cpp @@ -1,41 +1,81 @@ -const DataType *ConfigKey::get_data_type() const +#include + +const DataType *ConfigKey::data_type() const { - const struct sr_config_info *info = sr_config_info_get(id); + const struct sr_key_info *info = sr_key_info_get(SR_KEY_CONFIG, id()); if (!info) throw Error(SR_ERR_NA); return DataType::get(info->datatype); } -string ConfigKey::get_identifier() const +std::string ConfigKey::identifier() const { - const struct sr_config_info *info = sr_config_info_get(id); + const struct sr_key_info *info = sr_key_info_get(SR_KEY_CONFIG, id()); if (!info) throw Error(SR_ERR_NA); return valid_string(info->id); } -string ConfigKey::get_description() const +std::string ConfigKey::description() const { - const struct sr_config_info *info = sr_config_info_get(id); + const struct sr_key_info *info = sr_key_info_get(SR_KEY_CONFIG, id()); if (!info) throw Error(SR_ERR_NA); return valid_string(info->name); } -const ConfigKey *ConfigKey::get(string identifier) +const ConfigKey *ConfigKey::get_by_identifier(std::string identifier) { - const struct sr_config_info *info = sr_config_info_name_get(identifier.c_str()); + const struct sr_key_info *info = sr_key_info_name_get(SR_KEY_CONFIG, identifier.c_str()); if (!info) throw Error(SR_ERR_ARG); return get(info->key); } -Glib::VariantBase ConfigKey::parse_string(string value) const +#ifndef HAVE_STOI_STOD + +/* Fallback implementation of stoi and stod */ + +#include +#include +#include +#include + +static inline int stoi( const std::string& str ) +{ + char *endptr; + errno = 0; + const long ret = std::strtol(str.c_str(), &endptr, 10); + if (endptr == str.c_str()) + throw std::invalid_argument("stoi"); + else if (errno == ERANGE || + ret < std::numeric_limits::min() || + ret > std::numeric_limits::max()) + throw std::out_of_range("stoi"); + else + return ret; +} + +static inline double stod( const std::string& str ) +{ + char *endptr; + errno = 0; + const double ret = std::strtod(str.c_str(), &endptr); + if (endptr == str.c_str()) + throw std::invalid_argument("stod"); + else if (errno == ERANGE) + throw std::out_of_range("stod"); + else + return ret; +} +#endif + +Glib::VariantBase ConfigKey::parse_string(std::string value, enum sr_datatype dt) { GVariant *variant; uint64_t p, q; - switch (get_data_type()->get_id()) + switch (dt) { case SR_T_UINT64: check(sr_parse_sizestring(value.c_str(), &p)); @@ -48,7 +88,11 @@ Glib::VariantBase ConfigKey::parse_string(string value) const variant = g_variant_new_boolean(sr_parse_boolstring(value.c_str())); break; case SR_T_FLOAT: - variant = g_variant_new_double(stod(value)); + try { + variant = g_variant_new_double(stod(value)); + } catch (invalid_argument&) { + throw Error(SR_ERR_ARG); + } break; case SR_T_RATIONAL_PERIOD: check(sr_parse_period(value.c_str(), &p, &q)); @@ -59,12 +103,21 @@ Glib::VariantBase ConfigKey::parse_string(string value) const variant = g_variant_new("(tt)", p, q); break; case SR_T_INT32: - variant = g_variant_new_int32(stoi(value)); + try { + variant = g_variant_new_int32(stoi(value)); + } catch (invalid_argument&) { + throw Error(SR_ERR_ARG); + } break; default: throw Error(SR_ERR_BUG); } - return Glib::VariantBase(variant, true); + return Glib::VariantBase(variant, false); } +Glib::VariantBase ConfigKey::parse_string(std::string value) const +{ + enum sr_datatype dt = (enum sr_datatype)(data_type()->id()); + return parse_string(value, dt); +}