6#include "validatorfilesize_p.h"
18 const QString &defValKey)
19 :
ValidatorRule(*new ValidatorFileSizePrivate(field, option, min, max, messages, defValKey))
29 const QLocale &locale,
34 const QString str =
value.simplified();
37 bool decimalPointFound =
false;
38 const QString decimalPoint(locale.decimalPoint());
41 bool byteSignFound =
false;
42 ValidatorFileSizePrivate::StartsWith startsWith{ValidatorFileSizePrivate::StartsWith::NotSet};
44 for (
const QChar &ch : str) {
46 const char16_t uc = ch.toUpper().unicode();
47 if (((uc >= ValidatorRulePrivate::ascii_0) && (uc <= ValidatorRulePrivate::ascii_9)) ||
48 (ch == decimalPoint)) {
49 if (startsWith == ValidatorFileSizePrivate::StartsWith::NotSet) {
50 startsWith = ValidatorFileSizePrivate::StartsWith::DigitPart;
52 if (ch == decimalPoint) {
53 if (decimalPointFound) {
54 qCDebug(C_VALIDATOR).nospace()
55 <<
"ValidatorFileSize: Validation failed for " <<
value <<
": "
56 <<
"two decimal seperators in a row";
60 decimalPointFound =
true;
63 if ((symbolPart.isEmpty() &&
64 (startsWith == ValidatorFileSizePrivate::StartsWith::DigitPart)) ||
65 (!symbolPart.isEmpty() &&
66 (startsWith == ValidatorFileSizePrivate::StartsWith::SymbolPart))) {
69 qCDebug(C_VALIDATOR).nospace()
70 <<
"ValidatorFileSize: Validation failed for " <<
value <<
": "
71 <<
"symbol inside digit part";
75 }
else if ((uc != ValidatorRulePrivate::asciiTab) &&
76 (uc != ValidatorRulePrivate::asciiSpace)) {
78 if (startsWith == ValidatorFileSizePrivate::StartsWith::NotSet) {
79 startsWith = ValidatorFileSizePrivate::StartsWith::SymbolPart;
81 if ((digitPart.isEmpty() &&
82 (startsWith == ValidatorFileSizePrivate::StartsWith::SymbolPart)) ||
83 (!digitPart.isEmpty() &&
84 (startsWith == ValidatorFileSizePrivate::StartsWith::DigitPart))) {
86 case ValidatorFileSizePrivate::ascii_K:
90 qCDebug(C_VALIDATOR).nospace()
91 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
92 <<
"unit symbol K already found";
95 symbolPart.append(ch);
98 case ValidatorFileSizePrivate::ascii_M:
100 if (multiplier > 0) {
102 qCDebug(C_VALIDATOR).nospace()
103 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
104 <<
"unit symbol M already found";
107 symbolPart.append(ch);
110 case ValidatorFileSizePrivate::ascii_G:
112 if (multiplier > 0) {
114 qCDebug(C_VALIDATOR).nospace()
115 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
116 <<
"unit symbol G already found";
119 symbolPart.append(ch);
122 case ValidatorFileSizePrivate::ascii_T:
124 if (multiplier > 0) {
126 qCDebug(C_VALIDATOR).nospace()
127 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
128 <<
"unit symbol T already found";
131 symbolPart.append(ch);
134 case ValidatorFileSizePrivate::ascii_P:
136 if (multiplier > 0) {
138 qCDebug(C_VALIDATOR).nospace()
139 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
140 <<
"unit symbol P already found";
143 symbolPart.append(ch);
146 case ValidatorFileSizePrivate::ascii_E:
148 if (multiplier > 0) {
150 qCDebug(C_VALIDATOR).nospace()
151 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
152 <<
"unit symbol E already found";
155 symbolPart.append(ch);
158 case ValidatorRulePrivate::ascii_Z:
160 if (multiplier > 0) {
162 qCDebug(C_VALIDATOR).nospace()
163 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
164 <<
"unit symbol Z already found";
167 symbolPart.append(ch);
170 case ValidatorFileSizePrivate::ascii_Y:
172 if (multiplier > 0) {
174 qCDebug(C_VALIDATOR).nospace()
175 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
176 <<
"unit symbol Y already found";
179 symbolPart.append(ch);
182 case ValidatorFileSizePrivate::ascii_I:
184 if ((multiplier == 0) || binary) {
186 qCDebug(C_VALIDATOR).nospace()
187 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
188 <<
"binary indicator I already found or no unit symbol given "
192 symbolPart.append(ch);
195 case ValidatorFileSizePrivate::ascii_B:
199 qCDebug(C_VALIDATOR).nospace()
200 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
201 <<
"byte symbol B already found";
203 byteSignFound =
true;
204 symbolPart.append(ch);
207 case ValidatorRulePrivate::asciiTab:
208 case ValidatorRulePrivate::asciiSpace:
212 qCDebug(C_VALIDATOR).nospace()
213 <<
"ValdatorFileSize: Validation failed for " <<
value <<
": "
214 <<
"invalid character in symbol part";
239 double size = locale.toDouble(digitPart, &ok);
243 if (multiplier > 0) {
245 binary ? std::exp2(multiplier * 10) : std::pow(10.0, multiplier * 3);
248 if ((min >= 1.0) && (size < min)) {
251 if ((max >= 1.0) && (size > max)) {
254 if (valid && fileSize) {
269 const QString v =
value(params);
276 if (d->min.isValid()) {
277 min = d->extractDouble(c, params, d->min, &ok);
279 qCWarning(C_VALIDATOR).noquote()
280 <<
debugString(c) <<
"Invalid minimum size comparison data";
285 if (ok && d->max.isValid()) {
286 max = d->extractDouble(c, params, d->max, &ok);
288 qCWarning(C_VALIDATOR).noquote()
289 <<
debugString(c) <<
"Invalid maximum size comparison data";
297 if (size <
static_cast<double>(std::numeric_limits<qulonglong>::max())) {
298 result.
value.setValue<qulonglong>(
static_cast<qulonglong
>(size + 0.5));
300 result.
value.setValue(size);
304 qCWarning(C_VALIDATOR).noquote()
305 <<
debugString(c) << v <<
"is not a valid data size string";
321 const QString _label =
label(c);
322 if (d->min.isValid() || d->max.isValid()) {
323 if (_label.isEmpty()) {
324 error = c->
translate(
"Cutelyst::ValidatorFileSize",
325 "Invalid file size or file size not within the allowed limits.");
327 error = c->
translate(
"Cutelyst::ValidatorFileSize",
328 "The value in the “%1” field is either not a valid file size or "
329 "not within the allowed limits.")
333 if (_label.isEmpty()) {
334 error = c->
translate(
"Cutelyst::ValidatorFileSize",
"Invalid file size.");
336 error = c->
translate(
"Cutelyst::ValidatorFileSize",
337 "The “%1” field does not contain a valid file size.")
349 const QString _label =
label(c);
351 const int sizeType = errorData.toInt();
354 if (_label.isEmpty()) {
355 error = c->
translate(
"Cutelyst::ValidatorFileSize",
356 "The minimum file size comparison value is not valid.");
359 "Cutelyst::ValidatorFileSize",
360 "The minimum file size comparison value for the “%1” field is not valid.")
364 if (_label.isEmpty()) {
365 error = c->
translate(
"Cutelyst::ValidatorFileSize",
366 "The maximum file size comparison value is not valid.");
369 "Cutelyst::ValidatorFileSize",
370 "The maximum file size comparison value for the “%1” field is not valid.")
382 c->
locale().textDirection() == Qt::LeftToRight
383 ? QStringLiteral(
"^\\d+[,.٫]?\\d*\\s*[KkMmGgTt]?[Ii]?[Bb]?")
384 : QStringLiteral(
"[KkMmGgTt]?[Ii]?[Bb]?\\s*\\d+[,.٫]?\\d*"));
QLocale locale() const noexcept
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
void setStash(const QString &key, const QVariant &value)
Checks if the input field contains a valid file size string like 1.5 GB.
~ValidatorFileSize() override
Deconstructs the file size validator.
QString genericValidationDataError(Context *c, const QVariant &errorData) const override
Returns a generic error messages if validation data is missing or invalid.
Option
Options for ValidatorFileSize.
QString genericValidationError(Context *c, const QVariant &errorData=QVariant()) const override
Returns a generic error message if validation failed.
static void inputPattern(Context *c, const QString &stashKey=QStringLiteral("fileSizePattern"))
Puts an HTML input pattern for file sizes into the stash.
ValidatorFileSize(const QString &field, Option option=NoOption, const QVariant &min=QVariant(), const QVariant &max=QVariant(), const ValidatorMessages &messages=ValidatorMessages(), const QString &defValKey=QString())
Constructs a new file size validator.
Base class for all validator rules.
QString label(Context *c) const
Returns the human readable field label used for generic error messages.
void defaultValue(Context *c, ValidatorReturnType *result) const
I a defValKey has been set in the constructor, this will try to get the default value from the stash ...
QString value(const ParamsMultiMap ¶ms) const
Returns the value of the field from the input params.
QString validationDataError(Context *c, const QVariant &errorData=QVariant()) const
Returns an error message if any validation data is missing or invalid.
QString validationError(Context *c, const QVariant &errorData=QVariant()) const
Returns a descriptive error message if validation failed.
QString debugString(Context *c) const
Returns a string that can be used for debug output if validation fails.
static bool validate(const QString &value, double min=-1, double max=-1, Option option=NoOption, const QLocale &locale=QLocale(), double *fileSize=nullptr)
Returns true if value is a valid file size string.
The Cutelyst namespace holds all public Cutelyst API.
QMultiMap< QString, QString > ParamsMultiMap
Stores custom error messages and the input field label.
Contains the result of a single input parameter validation.