cutelyst  3.9.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
validatorsize.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2017-2022 Matthias Fehring <mf@huessenbergnetz.de>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 
6 #include "validatorsize_p.h"
7 
8 using namespace Cutelyst;
9 
11  QMetaType::Type type,
12  const QVariant &size,
13  const Cutelyst::ValidatorMessages &messages,
14  const QString &defValKey)
15  : ValidatorRule(*new ValidatorSizePrivate(field, type, size, messages, defValKey))
16 {
17 }
18 
20 {
21 }
22 
24 {
25  ValidatorReturnType result;
26 
27  const QString v = value(params);
28 
29  if (!v.isEmpty()) {
30 
31  Q_D(const ValidatorSize);
32  bool ok = false;
33  bool valid = false;
34 
35  switch (d->type) {
36  case QMetaType::Short:
37  case QMetaType::Int:
38  case QMetaType::Long:
40  {
41  const qlonglong val = c->locale().toLongLong(v, &ok);
42  if (Q_UNLIKELY(!ok)) {
43  result.errorMessage = parsingError(c);
44  qCWarning(C_VALIDATOR,
45  "ValidatorSize: Failed to parse value of field %s into number at %s::%s.",
46  qPrintable(field()),
47  qPrintable(c->controllerName()),
48  qPrintable(c->actionName()));
49  } else {
50  const qlonglong size = d->extractLongLong(c, params, d->size, &ok);
51  if (Q_UNLIKELY(!ok)) {
52  result.errorMessage = validationDataError(c, 1);
53  qCWarning(C_VALIDATOR,
54  "ValidatorSize: Invalid comparison size for field %s in %s::%s.",
55  qPrintable(field()),
56  qPrintable(c->controllerName()),
57  qPrintable(c->actionName()));
58  } else {
59  if (val != size) {
60  result.errorMessage =
62  QVariantMap{{QStringLiteral("val"), val},
63  {QStringLiteral("size"), size}});
64  qCDebug(C_VALIDATOR,
65  "ValidatorSize: Validation failed for field %s in %s::%s: value is "
66  "not %lli.",
67  qPrintable(field()),
68  qPrintable(c->controllerName()),
69  qPrintable(c->actionName()),
70  size);
71  } else {
72  valid = true;
73  }
74  }
75  }
76  } break;
77  case QMetaType::UShort:
78  case QMetaType::UInt:
79  case QMetaType::ULong:
81  {
82  const qulonglong val = v.toULongLong(&ok);
83  if (Q_UNLIKELY(!ok)) {
84  result.errorMessage = parsingError(c);
85  qCWarning(C_VALIDATOR,
86  "ValidatorSize: Failed to parse value of field %s into number at %s::%s.",
87  qPrintable(field()),
88  qPrintable(c->controllerName()),
89  qPrintable(c->actionName()));
90  } else {
91  const qulonglong size = d->extractULongLong(c, params, d->size, &ok);
92  if (Q_UNLIKELY(!ok)) {
93  result.errorMessage = validationDataError(c, 1);
94  qCWarning(
95  C_VALIDATOR,
96  "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.",
97  qPrintable(field()),
98  qPrintable(c->controllerName()),
99  qPrintable(c->actionName()));
100  } else {
101  if (val != size) {
102  result.errorMessage =
103  validationError(c,
104  QVariantMap{{QStringLiteral("val"), val},
105  {QStringLiteral("size"), size}});
106  qCDebug(C_VALIDATOR,
107  "ValidatorSize: Validation failed for field %s in %s::%s: value is "
108  "not %llu.",
109  qPrintable(field()),
110  qPrintable(c->controllerName()),
111  qPrintable(c->actionName()),
112  size);
113  } else {
114  valid = true;
115  }
116  }
117  }
118  } break;
119  case QMetaType::Float:
120  case QMetaType::Double:
121  {
122  const double val = v.toDouble(&ok);
123  if (Q_UNLIKELY(!ok)) {
124  result.errorMessage = parsingError(c);
125  qCWarning(C_VALIDATOR,
126  "ValidatorSize: Failed to parse value of field %s into number at %s::%s.",
127  qPrintable(field()),
128  qPrintable(c->controllerName()),
129  qPrintable(c->actionName()));
130  } else {
131  const double size = d->extractDouble(c, params, d->size, &ok);
132  if (Q_UNLIKELY(!ok)) {
133  result.errorMessage = validationDataError(c, 1);
134  qCWarning(
135  C_VALIDATOR,
136  "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.",
137  qPrintable(field()),
138  qPrintable(c->controllerName()),
139  qPrintable(c->actionName()));
140  } else {
141  if (val != size) {
142  result.errorMessage =
143  validationError(c,
144  QVariantMap{{QStringLiteral("val"), val},
145  {QStringLiteral("size"), size}});
146  qCDebug(C_VALIDATOR,
147  "ValidatorSize: Validation failed for field %s in %s::%s: value is "
148  "not %f.",
149  qPrintable(field()),
150  qPrintable(c->controllerName()),
151  qPrintable(c->actionName()),
152  size);
153  } else {
154  valid = true;
155  }
156  }
157  }
158  } break;
159  case QMetaType::QString:
160  {
161  const qlonglong val = static_cast<qlonglong>(v.length());
162  const qlonglong size = d->extractLongLong(c, params, d->size, &ok);
163  if (Q_UNLIKELY(!ok)) {
164  result.errorMessage = validationDataError(c, 1);
165  qCWarning(C_VALIDATOR,
166  "ValidatorSize: Invalid maximum comparison value for field %s in %s::%s.",
167  qPrintable(field()),
168  qPrintable(c->controllerName()),
169  qPrintable(c->actionName()));
170  } else {
171  if (val != size) {
172  result.errorMessage = validationError(
173  c,
174  QVariantMap{{QStringLiteral("val"), val}, {QStringLiteral("size"), size}});
175  qCDebug(C_VALIDATOR,
176  "ValidatorSize: Validation failed for field %s in %s::%s: string "
177  "length is not %lli.",
178  qPrintable(field()),
179  qPrintable(c->controllerName()),
180  qPrintable(c->actionName()),
181  size);
182  } else {
183  valid = true;
184  }
185  }
186  } break;
187  default:
188  qCWarning(C_VALIDATOR,
189  "ValidatorSize: The comparison type with ID %i for field %s at %s::%s is not "
190  "supported.",
191  static_cast<int>(d->type),
192  qPrintable(field()),
193  qPrintable(c->controllerName()),
194  qPrintable(c->actionName()));
195  result.errorMessage = validationDataError(c, 0);
196  break;
197  }
198 
199  if (valid) {
200  if (d->type != QMetaType::QString) {
201  const QVariant _v = d->valueToNumber(c, v, d->type);
202  if (_v.isValid()) {
203  result.value = _v;
204  } else {
205  result.errorMessage = parsingError(c);
206  }
207  } else {
208  result.value.setValue(v);
209  }
210  }
211  } else {
212  defaultValue(c, &result, "ValidatorSize");
213  }
214 
215  return result;
216 }
217 
219 {
220  QString error;
221 
222  Q_D(const ValidatorSize);
223 
224  const QVariantMap map = errorData.toMap();
225  QString size;
226  switch (d->type) {
227  case QMetaType::Short:
228  case QMetaType::Int:
229  case QMetaType::Long:
230  case QMetaType::LongLong:
231  case QMetaType::QString:
232  size = c->locale().toString(map.value(QStringLiteral("size")).toLongLong());
233  break;
234  case QMetaType::UShort:
235  case QMetaType::UInt:
236  case QMetaType::ULong:
238  size = c->locale().toString(map.value(QStringLiteral("size")).toULongLong());
239  break;
240  case QMetaType::Float:
241  case QMetaType::Double:
242  size = c->locale().toString(map.value(QStringLiteral("size")).toDouble());
243  break;
244  default:
245  error = validationDataError(c);
246  return error;
247  }
248 
249  const QString _label = label(c);
250 
251  if (_label.isEmpty()) {
252  if (d->type == QMetaType::QString) {
253  //: %1 will be replaced by the required string size
254  error = c->translate("Cutelyst::ValidatorSize",
255  "The text must be exactly %1 characters long.")
256  .arg(size);
257  } else {
258  //: %1 will be replaced by the required size/value
259  error = c->translate("Cutelyst::ValidatorSize", "The value must be %1.").arg(size);
260  }
261  } else {
262  if (d->type == QMetaType::QString) {
263  //: %1 will be replaced by the field label, %2 will be replaced by the required string
264  //: size
265  error = c->translate("Cutelyst::ValidatorSize",
266  "The text in the “%1“ field must be exactly %2 characters long.")
267  .arg(_label, size);
268  } else {
269  //: %1 will be replaced by the field label, %2 will be replaced by the required
270  //: size/value
271  error =
272  c->translate("Cutelyst::ValidatorSize", "The value in the “%1” field must be %2.")
273  .arg(_label, size);
274  }
275  }
276 
277  return error;
278 }
279 
281 {
282  QString error;
283 
284  int field = errorData.toInt();
285  const QString _label = label(c);
286 
287  if (field == 0) {
288  Q_D(const ValidatorSize);
289  if (_label.isEmpty()) {
290  error = c->translate("Cutelyst::ValidatorSize",
291  "The comparison type with ID %1 is not supported.")
292  .arg(static_cast<int>(d->type));
293  } else {
294  error =
295  c->translate("Cutelyst::ValidatorSize",
296  "The comparison type with ID %1 for the “%2” field is not supported.")
297  .arg(QString::number(static_cast<int>(d->type)), _label);
298  }
299  } else if (field == 1) {
300  if (_label.isEmpty()) {
301  error = c->translate("Cutelyst::ValidatorSize", "The comparison value is not valid.");
302  } else {
303  //: %1 will be replaced by the field label
304  error = c->translate("Cutelyst::ValidatorSize",
305  "The comparison value for the “%1” field is not valid.")
306  .arg(_label);
307  }
308  }
309 
310  return error;
311 }
312 
314 {
315  QString error;
316  Q_UNUSED(errorData)
317  Q_D(const ValidatorSize);
318 
319  const QString _label = label(c);
320  if ((d->type == QMetaType::Float) || (d->type == QMetaType::Double)) {
321  if (_label.isEmpty()) {
322  error = c->translate("Cutelyst::ValidatorSize",
323  "Failed to parse the input value into a floating point number.");
324  } else {
325  //: %1 will be replaced by the field label
326  error = c->translate("Cutelyst::ValidatorSize",
327  "Failed to parse the input value for the “%1” field into a "
328  "floating point number.")
329  .arg(_label);
330  }
331  } else {
332  if (_label.isEmpty()) {
333  error = c->translate("Cutelyst::ValidatorSize",
334  "Failed to parse the input value into an integer number.");
335  } else {
336  //: %1 will be replaced by the field label
337  error =
338  c->translate(
339  "Cutelyst::ValidatorSize",
340  "Failed to parse the input value for the “%1” field into an integer number.")
341  .arg(_label);
342  }
343  }
344 
345  return error;
346 }
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error message if validation failed.
QString parsingError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if an error occurred while parsing input.
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
QString toString(qlonglong i) const const
Stores custom error messages and the input field label.
double toDouble(bool *ok) const const
ValidatorReturnType validate(Context *c, const ParamsMultiMap &params) const override
Performs the validation and returns the result.
The field under validation must have a size matching the given value.
Definition: validatorsize.h:47
The Cutelyst Context.
Definition: context.h:38
QString number(int n, int base)
int toInt(bool *ok) const const
~ValidatorSize() override
Deconstructs the size validator.
qlonglong toLongLong(const QString &s, bool *ok) const const
bool isEmpty() const const
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
Definition: context.cpp:490
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
Returns a generic error message for validation data errors.
QString validationDataError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if any validation data is missing or invalid.
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
Base class for all validator rules.
qulonglong toULongLong(bool *ok, int base) const const
QLocale locale() const noexcept
Definition: context.cpp:466
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
void setValue(const T &value)
QString value(const ParamsMultiMap &params) const
Returns the value of the field from the input params.
QMap< QString, QVariant > toMap() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
int length() const const
QString field() const
Returns the name of the field to validate.
bool isValid() const const
Contains the result of a single input parameter validation.
Definition: validatorrule.h:49
ValidatorSize(const QString &field, QMetaType::Type type, const QVariant &size, const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new size validator.
void defaultValue(Context *c, ValidatorReturnType *result, const char *validatorName) const
I a defValKey has been set in the constructor, this will try to get the default value from the stash ...
int size() const const
QString genericParsingError(Context *c, const QVariant &errorData) const override
Returns a generic error message for input value parsing errors.