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  : min_value_(minValue), max_value_(maxValue)
198  {
199  }
200 
201  DoubleRangeValidator(std::function<std::pair<double, double>()> range_func)
202  : range_func_(range_func)
203  {
204  }
205 
206  bool isValid(std::string value) override
207  {
208  updateValue();
209 
210  // double 很难超出上限 1e305,故可不考虑超出 double 范围
211  return QString::fromStdString(value).toDouble() >= min_value_ &&
212  QString::fromStdString(value).toDouble() <= max_value_;
213  }
214 
215  std::string getMessage(std::string value) override
216  {
217  updateValue();
218 
219  // double 很难超出上限 1e305,故可不考虑超出 double 范围
220  if (QString::fromStdString(value).toDouble() < min_value_ ||
221  QString::fromStdString(value).toDouble() > max_value_) {
222  return QObject::tr("Error: The value is between %1 and %2.")
223  .arg(min_value_, 0, 'g', 15)
224  .arg(max_value_, 0, 'g', 15)
225  .toStdString();
226  }
227  return "";
228  }
229 
230 private:
231  void updateValue()
232  {
233  if (range_func_) {
234  auto [min_value, max_value] = range_func_();
235  min_value_ = min_value;
236  max_value_ = max_value;
237  }
238 
239  if (min_value_ > max_value_) {
240  double t = min_value_;
241  min_value_ = max_value_;
242  max_value_ = t;
243  }
244  }
245 
246 private:
247  double min_value_{ DBL_MIN };
248  double max_value_{ DBL_MAX };
249  std::function<std::pair<double, double>()> range_func_{ nullptr };
250 };
251 
253 {
254  StringLengthValidator(size_t min_length, size_t max_length)
255  : min_length_(min_length), max_length_(max_length)
256  {
257  }
258 
259  StringLengthValidator(std::function<std::pair<size_t, size_t>()> range_func)
260  : range_func_(range_func)
261  {
262  }
263 
264  bool isValid(std::string value) override
265  {
266  updateValue();
267 
268  auto value_size = QString::fromStdString(value).length();
269  return value_size >= min_length_ && value_size <= max_length_;
270  }
271 
272  std::string getMessage(std::string value) override
273  {
274  updateValue();
275 
276  auto value_size = QString::fromStdString(value).length();
277  if (value_size < min_length_ || value_size > max_length_) {
278  return QObject::tr(
279  "Error: The value is between %1 and %2 in length.")
280  .arg(min_length_)
281  .arg(max_length_)
282  .toStdString();
283  }
284  return "";
285  }
286 
287 private:
288  void updateValue()
289  {
290  if (range_func_) {
291  auto [min_length, max_length] = range_func_();
292  min_length_ = min_length;
293  max_length_ = max_length;
294  }
295 
296  if (min_length_ > max_length_) {
297  min_length_ ^= max_length_ ^= min_length_ ^= max_length_;
298  }
299  }
300 
301 private:
302  size_t min_length_{ 0 };
303  size_t max_length_{ ULONG_MAX };
304  std::function<std::pair<size_t, size_t>()> range_func_{ nullptr };
305 };
306 
307 } // namespace aubo_scope
308 } // namespace arcs
309 
310 #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)
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)
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
DoubleRangeValidator(double minValue, double maxValue)
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)