Cutelee 6.1.0
util.cpp
1/*
2 This file is part of the Cutelee template system.
3
4 Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either version
9 2.1 of the Licence, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library. If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21#include "util.h"
22
23#include "metaenumvariable_p.h"
24#include "metatype.h"
25
26#include <QtCore/QStringList>
27#include <QDebug>
28
29#include <cfloat>
30
32{
33 return input.mid(1, input.size() - 2)
34 .replace(QStringLiteral("\\\'"), QChar::fromLatin1('\''))
35 .replace(QStringLiteral("\\\""), QChar::fromLatin1('"'))
36 .replace(QStringLiteral("\\\\"), QChar::fromLatin1('\\'));
37}
38
39bool Cutelee::variantIsTrue(const QVariant &variant)
40{
41
42 if (!variant.isValid())
43 return false;
44 switch (variant.userType()) {
45 case QMetaType::Bool: {
46 return variant.toBool();
47 }
48 case QMetaType::Int: {
49 return variant.value<int>() > 0;
50 }
51 case QMetaType::UInt: {
52 return variant.value<uint>() > 0;
53 }
55 return variant.value<qlonglong>() > 0;
56 }
58 return variant.value<qulonglong>() > 0;
59 }
60 case QMetaType::Double: {
61 return variant.value<double>() > 0;
62 }
63 case QMetaType::Float: {
64 return variant.value<float>() > 0;
65 }
66 case QMetaType::Char: {
67 return variant.value<char>() > 0;
68 }
70 auto obj = variant.value<QObject *>();
71 if (!obj)
72 return false;
73
74 if (obj->property("__true__").isValid()) {
75 return obj->property("__true__").toBool();
76 }
77 return true;
78 }
80 return !variant.value<QVariantList>().isEmpty();
81 }
83 return !variant.value<QVariantHash>().isEmpty();
84 }
86 return !variant.value<QVariantMap>().isEmpty();
87 }
88 }
89
90 return !getSafeString(variant).get().isEmpty();
91}
92
94{
95 auto sret = input;
96 sret.setSafety(Cutelee::SafeString::IsSafe);
97 return sret;
98}
99
102{
103 auto temp = input;
104 if (input.isSafe() || input.needsEscape())
105 return input;
106
107 temp.setNeedsEscape(true);
108 return temp;
109}
110
112{
113 if (input.userType() == qMetaTypeId<Cutelee::SafeString>()) {
114 return input.value<Cutelee::SafeString>();
115 } else {
116 return input.toString();
117 }
118}
119
121{
122 const auto type = input.userType();
123 return ((type == qMetaTypeId<Cutelee::SafeString>())
124 || type == QMetaType::QString);
125}
126
127static QList<int> getPrimitives()
128{
129 QList<int> primitives;
130 primitives << qMetaTypeId<Cutelee::SafeString>() << QMetaType::QString
134 return primitives;
135}
136
138{
139 static const auto primitives = getPrimitives();
140 return primitives.contains(input.userType());
141}
142
143bool Cutelee::equals(const QVariant &lhs, const QVariant &rhs)
144{
145 // TODO: Redesign...
146
147 // QVariant doesn't use operator== to compare its held data, so we do it
148 // manually instead for SafeString.
149 auto equal = false;
150 if (lhs.userType() == qMetaTypeId<Cutelee::SafeString>()) {
151 if (rhs.userType() == qMetaTypeId<Cutelee::SafeString>()) {
152 equal = (lhs.value<Cutelee::SafeString>()
153 == rhs.value<Cutelee::SafeString>());
154 } else if (rhs.userType() == QMetaType::QString) {
155 equal = (lhs.value<Cutelee::SafeString>() == rhs.toString());
156 }
157 } else if (rhs.userType() == qMetaTypeId<Cutelee::SafeString>()
158 && lhs.userType() == QMetaType::QString) {
159 equal = (rhs.value<Cutelee::SafeString>() == lhs.toString());
160 } else if (rhs.userType() == qMetaTypeId<MetaEnumVariable>()) {
161 if (lhs.userType() == qMetaTypeId<MetaEnumVariable>()) {
162 equal = (rhs.value<MetaEnumVariable>() == lhs.value<MetaEnumVariable>());
163 } else if (lhs.userType() == qMetaTypeId<int>()) {
164 equal = (rhs.value<MetaEnumVariable>() == lhs.value<int>());
165 }
166 } else if (lhs.userType() == qMetaTypeId<MetaEnumVariable>()) {
167 if (rhs.userType() == qMetaTypeId<int>()) {
168 equal = (lhs.value<MetaEnumVariable>() == rhs.value<int>());
169 }
170 } else {
171#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
172 equal = ((lhs == rhs) && (lhs.userType() == rhs.userType()));
173#else
174 equal = lhs == rhs;
175#endif
176 }
177 return equal;
178}
179
180bool Cutelee::gt(const QVariant& lhs, const QVariant& rhs)
181{
182#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
183 return lhs > rhs;
184#else
185 return QVariant::compare(lhs, rhs) == QPartialOrdering::Greater;
186#endif
187}
188
189bool Cutelee::gte(const QVariant& lhs, const QVariant& rhs)
190{
191#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
192 return lhs >= rhs;
193#else
194 return equals(lhs, rhs) || gt(lhs, rhs);
195#endif
196}
197
198bool Cutelee::lt(const QVariant &lhs, const QVariant &rhs)
199{
200#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
201 return lhs < rhs;
202#else
203 return QVariant::compare(lhs, rhs) == QPartialOrdering::Less;
204#endif
205}
206
207
208bool Cutelee::lte(const QVariant &lhs, const QVariant &rhs)
209{
210#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
211 return lhs <= rhs;
212#else
213 return equals(lhs, rhs) || lt(lhs, rhs);
214#endif
215}
216
217
218std::pair<qreal,QString> Cutelee::calcFileSize(qreal size, int unitSystem, qreal multiplier)
219{
220 std::pair<qreal,QString> ret;
221
222 int _unitSystem = unitSystem;
223
224 if ((_unitSystem != 2) && (_unitSystem != 10)) {
225 qWarning("%s", "Unrecognized file size unit system. Falling back to decimal unit system.");
226 _unitSystem = 10;
227 }
228
229 if (size == 0.0) {
230 ret.first = 0.0;
231 ret.second = QStringLiteral("bytes");
232 return ret;
233 } else if ((size == 1.0) || (size == -1.0)) {
234 ret.first = 1.0;
235 ret.second = QStringLiteral("byte");
236 return ret;
237 }
238
239 qreal _size = size * multiplier;
240
241 const bool positiveValue = (_size > 0);
242
243 if (!positiveValue) {
244 _size *= -1;
245 }
246
247 static const QStringList binaryUnits({
248 QStringLiteral("bytes"),
249 QStringLiteral("KiB"),
250 QStringLiteral("MiB"),
251 QStringLiteral("GiB"),
252 QStringLiteral("TiB"),
253 QStringLiteral("PiB"),
254 QStringLiteral("EiB"),
255 QStringLiteral("ZiB"),
256 QStringLiteral("YiB")
257 });
258
259 static const QStringList decimalUnits({
260 QStringLiteral("bytes"),
261 QStringLiteral("KB"),
262 QStringLiteral("MB"),
263 QStringLiteral("GB"),
264 QStringLiteral("TB"),
265 QStringLiteral("PB"),
266 QStringLiteral("EB"),
267 QStringLiteral("ZB"),
268 QStringLiteral("YB")
269 });
270
271 int count = 0;
272 const qreal baseVal = (_unitSystem == 10) ? 1000.0f : 1024.0f;
273#if FLT_EVAL_METHOD == 2
274 // Avoid that this is treated as long double, as the increased
275 // precision breaks the comparison below.
276 volatile qreal current = 1.0F;
277#else
278 qreal current = 1.0f;
279#endif
280 int units = decimalUnits.size();
281 while (count < units) {
282 current *= baseVal;
283 if (_size < current) {
284 break;
285 }
286 count++;
287 }
288
289 if (count >= units) {
290 count = (units - 1);
291 }
292
293 qreal devider = current/baseVal;
294 _size = _size/devider;
295
296 if (!positiveValue) {
297 _size *= -1.0;
298 }
299
300 ret.first = _size;
301 ret.second = (_unitSystem == 10) ? decimalUnits.at(count) : binaryUnits.at(count);
302
303 return ret;
304}
305
306Cutelee::SafeString Cutelee::toString(const QVariantList &list)
307{
308 QString output(QLatin1Char('['));
309 auto it = list.constBegin();
310 const auto end = list.constEnd();
311 while (it != end) {
312 const auto item = *it;
313 if (isSafeString(item)) {
314 output += QStringLiteral("u\'")
315 + static_cast<QString>(getSafeString(item).get())
316 + QLatin1Char('\'');
317 }
318 if ((item.userType() == qMetaTypeId<int>())
319 || (item.userType() == qMetaTypeId<uint>())
320 || (item.userType() == qMetaTypeId<double>())
321 || (item.userType() == qMetaTypeId<float>())
322 || (item.userType() == qMetaTypeId<long long>())
323 || (item.userType() == qMetaTypeId<unsigned long long>())) {
324 output += item.toString();
325 }
326 if (item.userType() == qMetaTypeId<QVariantList>()) {
327 output
328 += static_cast<QString>(toString(item.value<QVariantList>()).get());
329 }
330 if ((it + 1) != end)
331 output += QStringLiteral(", ");
332 ++it;
333 }
334
335 return output.append(QLatin1Char(']'));
336}
A QString wrapper class for containing whether a string is safe or needs to be escaped.
Definition safestring.h:92
const NestedString & get() const
Definition safestring.h:340
bool needsEscape() const
bool isSafe() const
@ IsSafe
The string is safe and requires no further escaping.
Definition safestring.h:98
bool equals(const QVariant &lhs, const QVariant &rhs)
Definition util.cpp:143
QString unescapeStringLiteral(const QString &input)
Definition util.cpp:31
std::pair< qreal, QString > calcFileSize(qreal size, int unitSystem=10, qreal multiplier=1.0)
Definition util.cpp:218
bool supportedOutputType(const QVariant &input)
Definition util.cpp:137
bool isSafeString(const QVariant &input)
Definition util.cpp:120
Cutelee::SafeString getSafeString(const QVariant &input)
Definition util.cpp:111
Cutelee::SafeString markSafe(const Cutelee::SafeString &input)
Definition util.cpp:93
Cutelee::SafeString markForEscaping(const Cutelee::SafeString &input)
Definition util.cpp:101
bool variantIsTrue(const QVariant &variant)
Definition util.cpp:39
QChar fromLatin1(char c)
QString mid(int position, int n) const const
QString & replace(int position, int n, QChar after)
int size() const const
bool isValid() const const
bool toBool() const const
QString toString() const const
int userType() const const
T value() const const
Utility functions used throughout Cutelee.