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 
39 bool 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  }
54  case QMetaType::LongLong: {
55  return variant.value<qlonglong>() > 0;
56  }
57  case QMetaType::ULongLong: {
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 
120 bool Cutelee::isSafeString(const QVariant &input)
121 {
122  const auto type = input.userType();
123  return ((type == qMetaTypeId<Cutelee::SafeString>())
124  || type == QMetaType::QString);
125 }
126 
127 static 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 
143 bool 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 
180 bool 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 
189 bool 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 
198 bool 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 
208 bool 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 
218 std::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 
306 Cutelee::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 }
bool variantIsTrue(const QVariant &variant)
Definition: util.cpp:39
QString & append(QChar ch)
Cutelee::SafeString markSafe(const Cutelee::SafeString &input)
Definition: util.cpp:93
int size() const const
T value() const const
bool supportedOutputType(const QVariant &input)
Definition: util.cpp:137
bool equals(const QVariant &lhs, const QVariant &rhs)
Definition: util.cpp:143
int size() const const
bool isSafeString(const QVariant &input)
Definition: util.cpp:120
Cutelee::SafeString markForEscaping(const Cutelee::SafeString &input)
Definition: util.cpp:101
QString unescapeStringLiteral(const QString &input)
Definition: util.cpp:31
QVariant property(const char *name) const const
QChar fromLatin1(char c)
bool isEmpty() const const
Utility functions used throughout Cutelee.
A QString wrapper class for containing whether a string is safe or needs to be escaped.
Definition: safestring.h:91
int userType() const const
QString mid(int position, int n) const const
bool toBool() const const
bool isValid() const const
std::pair< qreal, QString > calcFileSize(qreal size, int unitSystem=10, qreal multiplier=1.0)
Definition: util.cpp:218
bool isSafe() const
Definition: safestring.cpp:63
bool needsEscape() const
Definition: safestring.cpp:56
QString toString() const const
const NestedString & get() const
Definition: safestring.h:340
Cutelee::SafeString getSafeString(const QVariant &input)
Definition: util.cpp:111
The string is safe and requires no further escaping.
Definition: safestring.h:98