Cutelee 6.2.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 equal = lhs == rhs;
172 }
173 return equal;
174}
175
176bool Cutelee::gt(const QVariant& lhs, const QVariant& rhs)
177{
178 return QVariant::compare(lhs, rhs) == QPartialOrdering::Greater;
179}
180
181bool Cutelee::gte(const QVariant& lhs, const QVariant& rhs)
182{
183 return equals(lhs, rhs) || gt(lhs, rhs);
184}
185
186bool Cutelee::lt(const QVariant &lhs, const QVariant &rhs)
187{
188 return QVariant::compare(lhs, rhs) == QPartialOrdering::Less;
189}
190
191bool Cutelee::lte(const QVariant &lhs, const QVariant &rhs)
192{
193 return equals(lhs, rhs) || lt(lhs, rhs);
194}
195
196std::pair<qreal,QString> Cutelee::calcFileSize(qreal size, int unitSystem, qreal multiplier)
197{
198 std::pair<qreal,QString> ret;
199
200 int _unitSystem = unitSystem;
201
202 if ((_unitSystem != 2) && (_unitSystem != 10)) {
203 qWarning("%s", "Unrecognized file size unit system. Falling back to decimal unit system.");
204 _unitSystem = 10;
205 }
206
207 if (size == 0.0) {
208 ret.first = 0.0;
209 ret.second = QStringLiteral("bytes");
210 return ret;
211 } else if ((size == 1.0) || (size == -1.0)) {
212 ret.first = 1.0;
213 ret.second = QStringLiteral("byte");
214 return ret;
215 }
216
217 qreal _size = size * multiplier;
218
219 const bool positiveValue = (_size > 0);
220
221 if (!positiveValue) {
222 _size *= -1;
223 }
224
225 static const QStringList binaryUnits({
226 QStringLiteral("bytes"),
227 QStringLiteral("KiB"),
228 QStringLiteral("MiB"),
229 QStringLiteral("GiB"),
230 QStringLiteral("TiB"),
231 QStringLiteral("PiB"),
232 QStringLiteral("EiB"),
233 QStringLiteral("ZiB"),
234 QStringLiteral("YiB")
235 });
236
237 static const QStringList decimalUnits({
238 QStringLiteral("bytes"),
239 QStringLiteral("KB"),
240 QStringLiteral("MB"),
241 QStringLiteral("GB"),
242 QStringLiteral("TB"),
243 QStringLiteral("PB"),
244 QStringLiteral("EB"),
245 QStringLiteral("ZB"),
246 QStringLiteral("YB")
247 });
248
249 int count = 0;
250 const qreal baseVal = (_unitSystem == 10) ? 1000.0f : 1024.0f;
251#if FLT_EVAL_METHOD == 2
252 // Avoid that this is treated as long double, as the increased
253 // precision breaks the comparison below.
254 volatile qreal current = 1.0F;
255#else
256 qreal current = 1.0f;
257#endif
258 int units = decimalUnits.size();
259 while (count < units) {
260 current *= baseVal;
261 if (_size < current) {
262 break;
263 }
264 count++;
265 }
266
267 if (count >= units) {
268 count = (units - 1);
269 }
270
271 qreal devider = current/baseVal;
272 _size = _size/devider;
273
274 if (!positiveValue) {
275 _size *= -1.0;
276 }
277
278 ret.first = _size;
279 ret.second = (_unitSystem == 10) ? decimalUnits.at(count) : binaryUnits.at(count);
280
281 return ret;
282}
283
284Cutelee::SafeString Cutelee::toString(const QVariantList &list)
285{
286 QString output(QLatin1Char('['));
287 auto it = list.constBegin();
288 const auto end = list.constEnd();
289 while (it != end) {
290 const auto item = *it;
291 if (isSafeString(item)) {
292 output += QStringLiteral("u\'")
293 + static_cast<QString>(getSafeString(item).get())
294 + QLatin1Char('\'');
295 }
296 if ((item.userType() == qMetaTypeId<int>())
297 || (item.userType() == qMetaTypeId<uint>())
298 || (item.userType() == qMetaTypeId<double>())
299 || (item.userType() == qMetaTypeId<float>())
300 || (item.userType() == qMetaTypeId<long long>())
301 || (item.userType() == qMetaTypeId<unsigned long long>())) {
302 output += item.toString();
303 }
304 if (item.userType() == qMetaTypeId<QVariantList>()) {
305 output
306 += static_cast<QString>(toString(item.value<QVariantList>()).get());
307 }
308 if ((it + 1) != end)
309 output += QStringLiteral(", ");
310 ++it;
311 }
312
313 return output.append(QLatin1Char(']'));
314}
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:325
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:196
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(qsizetype position, qsizetype n) &&
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
qsizetype size() const const
QPartialOrdering compare(const QVariant &lhs, const QVariant &rhs)
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.