]> sigrok.org Git - libsigrok.git/blame - bindings/cxx/ConfigKey_methods.cpp
output/csv: use intermediate time_t var, silence compiler warning
[libsigrok.git] / bindings / cxx / ConfigKey_methods.cpp
CommitLineData
1e95832b
GS
1#include <config.h>
2
3b161085 3const DataType *ConfigKey::data_type() const
c23c8659 4{
21d1bec6 5 const struct sr_key_info *info = sr_key_info_get(SR_KEY_CONFIG, id());
c23c8659
ML
6 if (!info)
7 throw Error(SR_ERR_NA);
8 return DataType::get(info->datatype);
9}
10
6c6dd732 11std::string ConfigKey::identifier() const
c23c8659 12{
21d1bec6 13 const struct sr_key_info *info = sr_key_info_get(SR_KEY_CONFIG, id());
c23c8659
ML
14 if (!info)
15 throw Error(SR_ERR_NA);
16 return valid_string(info->id);
17}
18
6c6dd732 19std::string ConfigKey::description() const
c23c8659 20{
21d1bec6 21 const struct sr_key_info *info = sr_key_info_get(SR_KEY_CONFIG, id());
c23c8659
ML
22 if (!info)
23 throw Error(SR_ERR_NA);
24 return valid_string(info->name);
25}
26
6c6dd732 27const ConfigKey *ConfigKey::get_by_identifier(std::string identifier)
c23c8659 28{
2fb60e23 29 const struct sr_key_info *info = sr_key_info_name_get(SR_KEY_CONFIG, identifier.c_str());
c23c8659
ML
30 if (!info)
31 throw Error(SR_ERR_ARG);
32 return get(info->key);
33}
34
d92de05a
MC
35#ifndef HAVE_STOI_STOD
36
37/* Fallback implementation of stoi and stod */
38
39#include <cstdlib>
40#include <cerrno>
41#include <stdexcept>
42#include <limits>
43
44static inline int stoi( const std::string& str )
45{
46 char *endptr;
47 errno = 0;
48 const long ret = std::strtol(str.c_str(), &endptr, 10);
49 if (endptr == str.c_str())
50 throw std::invalid_argument("stoi");
51 else if (errno == ERANGE ||
52 ret < std::numeric_limits<int>::min() ||
53 ret > std::numeric_limits<int>::max())
54 throw std::out_of_range("stoi");
55 else
56 return ret;
57}
58
59static inline double stod( const std::string& str )
60{
61 char *endptr;
62 errno = 0;
63 const double ret = std::strtod(str.c_str(), &endptr);
64 if (endptr == str.c_str())
65 throw std::invalid_argument("stod");
66 else if (errno == ERANGE)
67 throw std::out_of_range("stod");
68 else
69 return ret;
70}
71#endif
72
f806de18
GS
73#ifndef HAVE_STOUL
74
75/* Fallback implementation of stoul. */
76
77#include <cerrno>
78#include <cstdlib>
79#include <limits>
80#include <stdexcept>
81
82static inline unsigned long stoul(const std::string &str)
83{
84 char *endptr;
85 unsigned long ret;
86 errno = 0;
87 ret = std::strtoul(str.c_str(), &endptr, 10);
88 if (endptr == str.c_str())
89 throw std::invalid_argument("stoul");
90 /*
91 * TODO Convert to a larger/wider intermediate data type?
92 * Because after conversion into the very target type, the
93 * range check is assumed to be ineffective.
94 */
95 if (errno == ERANGE ||
96 ret < std::numeric_limits<unsigned long>::min() ||
97 ret > std::numeric_limits<unsigned long>::max())
98 throw std::out_of_range("stoul");
99 return ret;
100}
101#endif
102
0db1b189
MH
103// Conversion from text to uint32_t, including a range check.
104// This is sigrok specific, _not_ part of any C++ standard library.
105static uint32_t stou32(const std::string &str)
106{
107 unsigned long ret;
108 errno = 0;
109 ret = stoul(str);
110 if (errno == ERANGE)
111 throw std::out_of_range("stou32");
112 if (ret > std::numeric_limits<uint32_t>::max())
113 throw std::out_of_range("stou32");
114 return ret;
115}
116
6c6dd732 117Glib::VariantBase ConfigKey::parse_string(std::string value, enum sr_datatype dt)
c23c8659
ML
118{
119 GVariant *variant;
120 uint64_t p, q;
121
61a6d983 122 switch (dt)
c23c8659
ML
123 {
124 case SR_T_UINT64:
125 check(sr_parse_sizestring(value.c_str(), &p));
126 variant = g_variant_new_uint64(p);
127 break;
128 case SR_T_STRING:
129 variant = g_variant_new_string(value.c_str());
130 break;
131 case SR_T_BOOL:
132 variant = g_variant_new_boolean(sr_parse_boolstring(value.c_str()));
133 break;
134 case SR_T_FLOAT:
4aa9a1e5
ML
135 try {
136 variant = g_variant_new_double(stod(value));
0875f11d 137 } catch (invalid_argument&) {
4aa9a1e5
ML
138 throw Error(SR_ERR_ARG);
139 }
c23c8659
ML
140 break;
141 case SR_T_RATIONAL_PERIOD:
142 check(sr_parse_period(value.c_str(), &p, &q));
143 variant = g_variant_new("(tt)", p, q);
144 break;
145 case SR_T_RATIONAL_VOLT:
146 check(sr_parse_voltage(value.c_str(), &p, &q));
147 variant = g_variant_new("(tt)", p, q);
148 break;
149 case SR_T_INT32:
4aa9a1e5
ML
150 try {
151 variant = g_variant_new_int32(stoi(value));
0875f11d 152 } catch (invalid_argument&) {
4aa9a1e5
ML
153 throw Error(SR_ERR_ARG);
154 }
c23c8659 155 break;
0db1b189
MH
156 case SR_T_UINT32:
157 try {
158 variant = g_variant_new_uint32(stou32(value));
159 } catch (invalid_argument&) {
160 throw Error(SR_ERR_ARG);
161 }
162 break;
c23c8659
ML
163 default:
164 throw Error(SR_ERR_BUG);
165 }
166
7009a392 167 return Glib::VariantBase(variant, false);
c23c8659
ML
168}
169
6c6dd732 170Glib::VariantBase ConfigKey::parse_string(std::string value) const
61a6d983
GS
171{
172 enum sr_datatype dt = (enum sr_datatype)(data_type()->id());
173 return parse_string(value, dt);
174}