AuboCaps  0.6.0
input_validator.h
Go to the documentation of this file.
1 #ifndef AUBO_SCOPE_KEYBOARD_INPUT_VALIDATOR_H
2 #define AUBO_SCOPE_KEYBOARD_INPUT_VALIDATOR_H
3 
4 #include <string>
5 #include <functional>
6 #include <float.h>
7 
8 #include <QObject>
9 
11 
12 namespace arcs {
13 namespace aubo_scope {
14 
15 /**
16  * <p>
17  * Interface representing the input validators created by {@link
18  * InputValidationFactory}. This factory provides a set of standard input
19  * validators that can be used for validating the input entered by the user
20  * using the virtual keyboard/keypad.
21  * </p>
22  *
23  * If the standard validators available in the {@link InputValidationFactory}
24  * does not satisfy your needs, you are free to implement your own custom
25  * validator.
26  *
27  * @param <T> the (generic) type parameter for the interface representing the
28  * type of input data being validated (e.g. Integer or Double).
29  */
31 {
32  /**
33  * @param value to be validated.
34  * @return <code>true</code> if value is valid.
35  */
36  virtual bool isValid(std::string value) = 0;
37 
38  /**
39  * Returns a meaningful message in case the value is not valid.
40  *
41  * @param value the invalid value. Can be included in the message if it
42  * makes sense.
43  * @return message.
44  */
45  virtual std::string getMessage(std::string value) = 0;
46 };
47 
49 {
50  IntegerRangeValidator(int min_value, int max_value)
51  : min_value_(min_value), max_value_(max_value)
52  {
53  }
54 
55  IntegerRangeValidator(std::function<std::pair<int, int>()> range_func)
56  : range_func_(range_func)
57  {
58  }
59 
60  bool isValid(std::string value) override
61  {
62  updateValue();
63 
64  // 超出 int32 范围
65  if (value[0] == '-') {
66  if (value.size() > std::to_string(INT_MIN).size()) {
67  return false;
68  }
69  } else if (value.size() > std::to_string(INT_MAX).size()) {
70  return false;
71  }
72 
73  int64_t v = atoll(value.c_str());
74  return v >= min_value_ && v <= max_value_;
75  }
76 
77  std::string getMessage(std::string value) override
78  {
79  updateValue();
80 
81  // 超出 int32 范围
82  if (value[0] == '-') {
83  if (value.size() > std::to_string(INT_MIN).size()) {
84  return QObject::tr("Error: The value is between %1 and %2.")
85  .arg(min_value_)
86  .arg(max_value_)
87  .toStdString();
88  }
89  } else if (value.size() > std::to_string(INT_MAX).size()) {
90  return QObject::tr("Error: The value is between %1 and %2.")
91  .arg(min_value_)
92  .arg(max_value_)
93  .toStdString();
94  }
95 
96  int64_t v = atoll(value.c_str());
97  if (v < min_value_ || v > max_value_) {
98  return QObject::tr("Error: The value is between %1 and %2.")
99  .arg(min_value_)
100  .arg(max_value_)
101  .toStdString();
102  }
103  return "";
104  }
105 
106 private:
107  void updateValue()
108  {
109  if (range_func_) {
110  auto [min_value, max_value] = range_func_();
111  min_value_ = min_value;
112  max_value_ = max_value;
113  }
114 
115  if (min_value_ > max_value_) {
116  min_value_ ^= max_value_ ^= min_value_ ^= max_value_;
117  }
118  }
119 
120 private:
121  int min_value_{ INT_MIN };
122  int max_value_{ INT_MAX };
123  std::function<std::pair<int, int>()> range_func_{ nullptr };
124 };
125 
127 {
128  UIntegerRangeValidator(uint32_t min_value, uint32_t max_value)
129  : min_value_(min_value), max_value_(max_value)
130  {
131  }
132 
134  std::function<std::pair<uint32_t, uint32_t>()> range_func)
135  : range_func_(range_func)
136  {
137  }
138 
139  bool isValid(std::string value) override
140  {
141  updateValue();
142 
143  // 超出 uint32 范围
144  if (value.size() > std::to_string(UINT_MAX).size()) {
145  return false;
146  }
147 
148  uint64_t v = QString::fromStdString(value).toULongLong();
149  return v >= min_value_ && v <= max_value_;
150  }
151 
152  std::string getMessage(std::string value) override
153  {
154  updateValue();
155 
156  // 超出 uint32 范围
157  if (value.size() > std::to_string(UINT_MAX).size()) {
158  return QObject::tr("Error: The value is between %1 and %2.")
159  .arg(min_value_)
160  .arg(max_value_)
161  .toStdString();
162  }
163 
164  uint64_t v = QString::fromStdString(value).toULongLong();
165  if (v < min_value_ || v > max_value_) {
166  return QObject::tr("Error: The value is between %1 and %2.")
167  .arg(min_value_)
168  .arg(max_value_)
169  .toStdString();
170  }
171  return "";
172  }
173 
174 private:
175  void updateValue()
176  {
177  if (range_func_) {
178  auto [min_value, max_value] = range_func_();
179  min_value_ = min_value;
180  max_value_ = max_value;
181  }
182 
183  if (min_value_ > max_value_) {
184  min_value_ ^= max_value_ ^= min_value_ ^= max_value_;
185  }
186  }
187 
188 private:
189  uint32_t min_value_{ 0 };
190  uint32_t max_value_{ UINT_MAX };
191  std::function<std::pair<uint32_t, uint32_t>()> range_func_{ nullptr };
192 };
193 
195 {
196  DoubleRangeValidator(double minValue, double maxValue,
197  bool is_min_inclusive = true,
198  bool is_max_inclusive = true)
199  : min_value_(minValue), max_value_(maxValue),
200  is_min_inclusive_(is_min_inclusive),
201  is_max_inclusive_(is_max_inclusive)
202  {
203  }
204 
205  DoubleRangeValidator(std::function<std::pair<double, double>()> range_func)
206  : range_func_(range_func)
207  {
208  }
209 
211  std::function<std::tuple<double, double, bool, bool>()> range_func)
212  : range_func_with_flags_(range_func)
213  {
214  }
215 
216  bool isValid(std::string value) override
217  {
218  updateValue();
219  double val = QString::fromStdString(value).toDouble();
220 
221  bool valid = true;
222  if (is_min_inclusive_) {
223  valid &= val >= min_value_;
224  } else {
225  valid &= val > min_value_;
226  }
227 
228  if (is_max_inclusive_) {
229  valid &= val <= max_value_;
230  } else {
231  valid &= val < max_value_;
232  }
233 
234  return valid;
235  }
236 
237  std::string getMessage(std::string value) override
238  {
239  updateValue();
240  double val = QString::fromStdString(value).toDouble();
241  // double 很难超出上限 1e305,故可不考虑超出 double 范围
242  if ((is_min_inclusive_ ? val < min_value_ : val <= min_value_) ||
243  (is_max_inclusive_ ? val > max_value_ : val >= max_value_)) {
244  if (is_min_inclusive_ && is_max_inclusive_) {
245  return QObject::tr("Error: The value is between %1 and %2.")
246  .arg(min_value_, 0, 'g', 15)
247  .arg(max_value_, 0, 'g', 15)
248  .toStdString();
249  } else if (!is_min_inclusive_ && !is_max_inclusive_) {
250  return QObject::tr("Error: The value should be between %1 and "
251  "%2 (exclusive).")
252  .arg(min_value_, 0, 'g', 15)
253  .arg(max_value_, 0, 'g', 15)
254  .toStdString();
255  } else if (is_min_inclusive_ && !is_max_inclusive_) {
256  return QObject::tr("Error: The value should be greater than or "
257  "equal to %1 and less than %2.")
258  .arg(min_value_, 0, 'g', 15)
259  .arg(max_value_, 0, 'g', 15)
260  .toStdString();
261  } else {
262  return QObject::tr("Error: The value should be greater than %1 "
263  "and less than or equal to %2.")
264  .arg(min_value_, 0, 'g', 15)
265  .arg(max_value_, 0, 'g', 15)
266  .toStdString();
267  }
268  }
269 
270  return "";
271  }
272 
273 private:
274  void updateValue()
275  {
276  if (range_func_) {
277  auto [min_value, max_value] = range_func_();
278  min_value_ = min_value;
279  max_value_ = max_value;
280  is_min_inclusive_ = true;
281  is_max_inclusive_ = true;
282  } else if (range_func_with_flags_) {
283  auto [min_value, max_value, min_inclusive, max_inclusive] =
284  range_func_with_flags_();
285  min_value_ = min_value;
286  max_value_ = max_value;
287  is_min_inclusive_ = min_inclusive;
288  is_max_inclusive_ = max_inclusive;
289  }
290 
291  if (min_value_ > max_value_) {
292  double t = min_value_;
293  min_value_ = max_value_;
294  max_value_ = t;
295  }
296  }
297 
298 private:
299  double min_value_{ DBL_MIN };
300  double max_value_{ DBL_MAX };
301  std::function<std::pair<double, double>()> range_func_;
302  std::function<std::tuple<double, double, bool, bool>()>
303  range_func_with_flags_;
304  bool is_min_inclusive_{ true }; // 最小值是否闭区间
305  bool is_max_inclusive_{ true }; // 最大值是否闭区间
306 };
307 
309 {
310  StringLengthValidator(size_t min_length, size_t max_length)
311  : min_length_(min_length), max_length_(max_length)
312  {
313  }
314 
315  StringLengthValidator(std::function<std::pair<size_t, size_t>()> range_func)
316  : range_func_(range_func)
317  {
318  }
319 
320  bool isValid(std::string value) override
321  {
322  updateValue();
323 
324  auto value_size = QString::fromStdString(value).length();
325  return value_size >= min_length_ && value_size <= max_length_;
326  }
327 
328  std::string getMessage(std::string value) override
329  {
330  updateValue();
331 
332  auto value_size = QString::fromStdString(value).length();
333  if (value_size < min_length_ || value_size > max_length_) {
334  return QObject::tr(
335  "Error: The value is between %1 and %2 in length.")
336  .arg(min_length_)
337  .arg(max_length_)
338  .toStdString();
339  }
340  return "";
341  }
342 
343 private:
344  void updateValue()
345  {
346  if (range_func_) {
347  auto [min_length, max_length] = range_func_();
348  min_length_ = min_length;
349  max_length_ = max_length;
350  }
351 
352  if (min_length_ > max_length_) {
353  min_length_ ^= max_length_ ^= min_length_ ^= max_length_;
354  }
355  }
356 
357 private:
358  size_t min_length_{ 0 };
359  size_t max_length_{ ULONG_MAX };
360  std::function<std::pair<size_t, size_t>()> range_func_{ nullptr };
361 };
362 
363 } // namespace aubo_scope
364 } // namespace arcs
365 
366 #endif
std::string getMessage(std::string value) override
Returns a meaningful message in case the value is not valid.
bool isValid(std::string value) override
StringLengthValidator(size_t min_length, size_t max_length)
DoubleRangeValidator(std::function< std::tuple< double, double, bool, bool >()> range_func)
std::string getMessage(std::string value) override
Returns a meaningful message in case the value is not valid.
bool isValid(std::string value) override
bool isValid(std::string value) override
UIntegerRangeValidator(uint32_t min_value, uint32_t max_value)
DoubleRangeValidator(double minValue, double maxValue, bool is_min_inclusive=true, bool is_max_inclusive=true)
IntegerRangeValidator(std::function< std::pair< int, int >()> range_func)
virtual bool isValid(std::string value)=0
UIntegerRangeValidator(std::function< std::pair< uint32_t, uint32_t >()> range_func)
virtual std::string getMessage(std::string value)=0
Returns a meaningful message in case the value is not valid.
bool isValid(std::string value) override
std::string getMessage(std::string value) override
Returns a meaningful message in case the value is not valid.
IntegerRangeValidator(int min_value, int max_value)
std::string getMessage(std::string value) override
Returns a meaningful message in case the value is not valid.
DoubleRangeValidator(std::function< std::pair< double, double >()> range_func)
StringLengthValidator(std::function< std::pair< size_t, size_t >()> range_func)