KDb

KDbUtils.h
1 /* This file is part of the KDE project
2  Copyright (C) 2003-2019 JarosÅ‚aw Staniek <[email protected]>
3 
4  Portions of kstandarddirs.cpp:
5  Copyright (C) 1999 Sirtaj Singh Kang <[email protected]>
6  Copyright (C) 1999,2007 Stephan Kulow <[email protected]>
7  Copyright (C) 1999 Waldo Bastian <[email protected]>
8  Copyright (C) 2009 David Faure <[email protected]>
9 
10  This program is free software; you can redistribute it and/or
11  modify it under the terms of the GNU Library General Public
12  License as published by the Free Software Foundation; either
13  version 2 of the License, or (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Library General Public License for more details.
19 
20  You should have received a copy of the GNU Library General Public License
21  along with this program; see the file COPYING. If not, write to
22  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24 */
25 
26 #ifndef KDB_TOOLS_UTILS_H
27 #define KDB_TOOLS_UTILS_H
28 
29 #include "kdb_export.h"
30 #include "config-kdb.h"
31 
32 #include <QObject>
33 #include <QDateTime>
34 #include <QMetaMethod>
35 #include <QDebug>
36 
37 namespace KDbUtils
38 {
39 
40 //! @return true if @a o has parent @a par (checks recursively)
41 KDB_EXPORT bool hasParent(QObject* par, QObject* o);
42 
43 //! @return parent object of @a o that is of type @a type or @c nullptr if no such parent
44 template<class type>
45 inline type findParent(QObject* o, const char* className = nullptr)
46 {
47  if (!o)
48  return nullptr;
49  while ((o = o->parent())) {
50  if (::qobject_cast< type >(o) && (!className || o->inherits(className)))
51  return ::qobject_cast< type >(o);
52  }
53  return nullptr;
54 }
55 
56 /**
57  * Returns the time as a string using Qt::ISODateWithMs format
58  *
59  * If milliseconds is zero then they are not appended.
60  * Works also for Qt < 5.8 which does not offer QTime::toString(Qt::ISODateWithMs).
61  *
62  * @since 3.2
63  */
64 KDB_EXPORT QString toISODateStringWithMs(const QTime &time);
65 
66 /**
67  * Returns the date/time as a string using Qt::ISODateWithMs format
68  *
69  * If milliseconds in time is zero then they are not appended.
70  * Works also for Qt < 5.8 which does not offer QDateTime::toString(Qt::ISODateWithMs).
71  *
72  * @since 3.2
73  */
74 KDB_EXPORT QString toISODateStringWithMs(const QDateTime &dateTime);
75 
76 /**
77  * Returns the time represented by the string using the Qt::ISODateWithMs format
78  *
79  * Milliseconds are optional.
80  * Works also for Qt < 5.8 which does not offer QTime::fromString(QString, Qt::ISODateWithMs).
81  *
82  * @note Equal to QTime::fromString(string, Qt::ISODate) since the Qt::ISODate mode already
83  * supports milliseconds in case of fromString().
84  *
85  * @since 3.2
86  */
87 KDB_EXPORT QTime timeFromISODateStringWithMs(const QString &string);
88 
89 /**
90  * Returns the date/time represented by the string using the Qt::ISODateWithMs format
91  *
92  * Milliseconds of time are optional.
93  * Works also for Qt < 5.8 which does not offer QDateTime::fromString(QString, Qt::ISODateWithMs).
94  *
95  * @note Equal to QDateTime::fromString(string, Qt::ISODate) since the Qt::ISODate mode already
96  * supports milliseconds in case of fromString().
97  *
98  * @since 3.2
99  */
100 KDB_EXPORT QDateTime dateTimeFromISODateStringWithMs(const QString &string);
101 
102 //! QDateTime - a hack needed because QVariant(QTime) has broken isNull()
103 KDB_EXPORT QDateTime stringToHackedQTime(const QString& s);
104 
105 /*! Serializes @a map to the array pointed by @a array.
106  KDbUtils::deserializeMap() can be used to deserialize this array back to map.
107  Does nothing if @a array is @c nullptr. */
108 KDB_EXPORT void serializeMap(const QMap<QString, QString>& map, QByteArray *array);
109 
110 /*! Serializes @a map to the string pointed by @a string.
111  KDbUtils::deserializeMap() can be used to deserialize this array back to map.
112  Does nothing if @a string is @c nullptr. */
113 KDB_EXPORT void serializeMap(const QMap<QString, QString>& map, QString *string);
114 
115 /*! @return a map deserialized from a byte array @a array.
116  @a array need to contain data previously serialized using KexiUtils::serializeMap(). */
117 KDB_EXPORT QMap<QString, QString> deserializeMap(const QByteArray& array);
118 
119 /*! @return a map deserialized from @a string.
120  @a string need to contain data previously serialized using KexiUtils::serializeMap(). */
121 KDB_EXPORT QMap<QString, QString> deserializeMap(const QString& string);
122 
123 /**
124  * Returns a valid filename converted from given string
125  *
126  * Following steps are performed:
127  * - replace \\, /, :, *, ?, ", <, >, |, \n \\t characters with a space,
128  * - simplify whitespace by removing redundant space characters using QString::simplified().
129  * - prepend '_' character if the first character is '.', so the file will not be considered hidden
130  * (since 3.2.0).
131  *
132  * @note Do not pass full paths here but only filename strings.
133  */
134 KDB_EXPORT QString stringToFileName(const QString& string);
135 
136 /*! Performs a simple @a string encryption using rot47-like algorithm.
137  Each character's unicode value is increased by 47 + i (where i is index of the character).
138  The resulting string still contains readable characters but some of them can be non-ASCII.
139  Does nothing if @a string is @c nullptr.
140  @note Do not use this for data that can be accessed by attackers! */
141 KDB_EXPORT void simpleCrypt(QString *string);
142 
143 /*! Performs a simple @a string decryption using rot47-like algorithm,
144  using opposite operations to KexiUtils::simpleCrypt().
145  @return true on success and false on failure. Failue means that one or more characters have unicode
146  numbers smaller than value of 47 + i. On failure @a string is not altered.
147  Does nothing and returns @c false if @a string is @c nullptr.
148 */
149 KDB_EXPORT bool simpleDecrypt(QString *string);
150 
151 //! @internal
152 KDB_EXPORT QString pointerToStringInternal(void* pointer, int size);
153 //! @internal
154 KDB_EXPORT void* stringToPointerInternal(const QString& string, int size);
155 
156 //! @return a pointer @a pointer safely serialized to string
157 template<class type>
158 QString pointerToString(type *pointer)
159 {
160  return pointerToStringInternal(pointer, sizeof(type*));
161 }
162 
163 //! @return a pointer of type @a type safely deserialized from @a string
164 template<class type>
165 type* stringToPointer(const QString& string)
166 {
167  return static_cast<type*>(stringToPointerInternal(string, sizeof(type*)));
168 }
169 
170 //! @return value converted to text, squeezed to reasonable length, useful for debugging
171 //! If the value is not a byte array or string, or if it's not longer than 1024 characters,
172 //! @a value is returned.
173 //! @since 3.1
174 KDB_EXPORT QVariant squeezedValue(const QVariant &value);
175 
176 //! @short Autodeleting hash
177 template <class Key, class T>
178 class AutodeletedHash : public QHash<Key, T>
179 {
180 public:
181  //! Creates autodeleting hash as a copy of @a other.
182  //! Auto-deletion is not enabled as it would cause double deletion for items.
183  //! If you enable auto-deletion on here, make sure you disable it in the @a other hash.
184  AutodeletedHash(const AutodeletedHash& other) : QHash<Key, T>(other), m_autoDelete(false) {}
185 
186  //! Creates empty autodeleting hash.
187  //! Auto-deletion is enabled by default.
188  AutodeletedHash(bool autoDelete = true) : QHash<Key, T>(), m_autoDelete(autoDelete) {}
189 
190  ~AutodeletedHash() {
191  if (m_autoDelete) {
192  qDeleteAll(*this);
193  }
194  }
195  void setAutoDelete(bool set) {
196  m_autoDelete = set;
197  }
198  bool autoDelete() const {
199  return m_autoDelete;
200  }
201  void clear() {
202  if (m_autoDelete) {
203  qDeleteAll(*this);
204  }
206  }
207  typename QHash<Key, T>::iterator erase(typename QHash<Key, T>::iterator pos) {
209  if (m_autoDelete) {
210  delete it.value();
211  it.value() = 0;
212  return it;
213  }
214  }
215  typename QHash<Key, T>::iterator insert(const Key &key, const T &value) {
216  if (m_autoDelete) {
217  T &oldValue = QHash<Key, T>::operator[](key);
218  if (oldValue && oldValue != value) { // only delete if differs
219  delete oldValue;
220  }
221  }
223  }
224  int remove(const Key &key) {
225  if (m_autoDelete) {
227  const int result = QHash<Key, T>::remove(key);
228  for (T item : values) {
229  delete item;
230  }
231  return result;
232  } else {
233  return QHash<Key, T>::remove(key);
234  }
235  }
236  // note: no need to override insertMulti(), unite(), take(), they do not replace items
237 
238 private:
239  bool m_autoDelete;
240 };
241 
242 //! @short Autodeleting list
243 template <typename T>
244 class AutodeletedList : public QList<T>
245 {
246 public:
247  //! Creates autodeleting list as a copy of @a other.
248  //! Auto-deletion is not enabled as it would cause double deletion for items.
249  //! If you enable auto-deletion on here, make sure you disable it in the @a other list.
251  : QList<T>(other), m_autoDelete(false) {}
252 
253  //! Creates empty autodeleting list.
254  //! Auto-deletion is enabled by default.
255  AutodeletedList(bool autoDelete = true) : QList<T>(), m_autoDelete(autoDelete) {}
256 
257  ~AutodeletedList() {
258  if (m_autoDelete) qDeleteAll(*this);
259  }
260  void setAutoDelete(bool set) {
261  m_autoDelete = set;
262  }
263  bool autoDelete() const {
264  return m_autoDelete;
265  }
266  void removeAt(int i) {
267  T item = QList<T>::takeAt(i); if (m_autoDelete) delete item;
268  }
269  void removeFirst() {
270  T item = QList<T>::takeFirst(); if (m_autoDelete) delete item;
271  }
272  void removeLast() {
273  T item = QList<T>::takeLast(); if (m_autoDelete) delete item;
274  }
275  void replace(int i, const T& value) {
276  T item = QList<T>::takeAt(i); insert(i, value); if (m_autoDelete) delete item;
277  }
278  void insert(int i, const T& value) {
280  }
281  typename QList<T>::iterator erase(typename QList<T>::iterator pos) {
282  T item = *pos;
283  typename QList<T>::iterator res = QList<T>::erase(pos);
284  if (m_autoDelete)
285  delete item;
286  return res;
287  }
288  typename QList<T>::iterator erase(
289  typename QList<T>::iterator afirst,
290  typename QList<T>::iterator alast) {
291  if (!m_autoDelete)
292  return QList<T>::erase(afirst, alast);
293  while (afirst != alast) {
294  T item = *afirst;
295  afirst = QList<T>::erase(afirst);
296  delete item;
297  }
298  return alast;
299  }
300  void pop_back() {
301  removeLast();
302  }
303  void pop_front() {
304  removeFirst();
305  }
306  int removeAll(const T& value) {
307  if (!m_autoDelete)
308  return QList<T>::removeAll(value);
309  typename QList<T>::iterator it(QList<T>::begin());
310  int removedCount = 0;
311  while (it != QList<T>::end()) {
312  if (*it == value) {
313  T item = *it;
314  it = QList<T>::erase(it);
315  delete item;
316  removedCount++;
317  } else
318  ++it;
319  }
320  return removedCount;
321  }
322  void clear() {
323  if (!m_autoDelete)
324  return QList<T>::clear();
325  while (!QList<T>::isEmpty()) {
326  T item = QList<T>::takeFirst();
327  delete item;
328  }
329  }
330 
331 private:
332  bool m_autoDelete;
333 };
334 
335 //! @short Case insensitive hash container supporting QString or QByteArray keys.
336 //! Keys are turned to lowercase before inserting.
337 template <typename Key, typename T>
338 class CaseInsensitiveHash : public QHash<Key, T>
339 {
340 public:
342  typename QHash<Key, T>::iterator find(const Key& key) const {
343  return QHash<Key, T>::find(key.toLower());
344  }
345  typename QHash<Key, T>::const_iterator constFind(const Key& key) const {
346  return QHash<Key, T>::constFind(key.toLower());
347  }
348  bool contains(const Key& key) const {
349  return QHash<Key, T>::contains(key.toLower());
350  }
351  int count(const Key& key) const {
352  return QHash<Key, T>::count(key.toLower());
353  }
354  typename QHash<Key, T>::iterator insert(const Key& key, const T& value) {
355  return QHash<Key, T>::insert(key.toLower(), value);
356  }
357  typename QHash<Key, T>::iterator insertMulti(const Key& key, const T& value) {
358  return QHash<Key, T>::insertMulti(key.toLower(), value);
359  }
360  const Key key(const T& value, const Key& defaultKey) const {
361  return QHash<Key, T>::key(value, defaultKey.toLower());
362  }
363  int remove(const Key& key) {
364  return QHash<Key, T>::remove(key.toLower());
365  }
366  const T take(const Key& key) {
367  return QHash<Key, T>::take(key.toLower());
368  }
369  const T value(const Key& key) const {
370  return QHash<Key, T>::value(key.toLower());
371  }
372  const T value(const Key& key, const T& defaultValue) const {
373  return QHash<Key, T>::value(key.toLower(), defaultValue);
374  }
375  QList<T> values(const Key& key) const {
376  return QHash<Key, T>::values(key.toLower());
377  }
378  T& operator[](const Key& key) {
379  return QHash<Key, T>::operator[](key.toLower());
380  }
381  const T operator[](const Key& key) const {
382  return QHash<Key, T>::operator[](key.toLower());
383  }
384 };
385 
386 //! A set created from static (0-terminated) array of raw null-terminated strings.
387 class KDB_EXPORT StaticSetOfStrings
388 {
389 public:
391  explicit StaticSetOfStrings(const char* const array[]);
393  void setStrings(const char* const array[]);
394  bool isEmpty() const;
395 
396  //! @return true if @a string can be found within set, comparison is case sensitive
397  bool contains(const QByteArray& string) const;
398 private:
399  class Private;
400  Private * const d;
401  Q_DISABLE_COPY(StaticSetOfStrings)
402 };
403 
404 /*! @return debugging string for object @a object of type @a T */
405 template <typename T>
406 QString debugString(const T& object)
407 {
408  QString result;
409  QDebug dbg(&result);
410  dbg << object;
411  return result;
412 }
413 
414 //! Used by findExe().
415 enum class FindExeOption {
416  //! No options
417  None = 0,
418  //! If set, the path returned may not have the executable bit set.
419  IgnoreExecBit = 1
420 };
421 Q_DECLARE_FLAGS(FindExeOptions, FindExeOption)
422 
423 /**
424  * Finds the executable in the system path.
425  *
426  * A valid executable must be a file and have its executable bit set.
427  *
428  * @param appname The name of the executable file for which to search.
429  * if this contains a path separator, it will be resolved
430  * according to the current working directory
431  * (shell-like behavior).
432  * @param path The path which will be searched. If this is
433  * null (default), the @c $PATH environment variable will
434  * be searched.
435  * @param options Options, see FindExeOption.
436  *
437  * @return The path of the executable. If it was not found, returns QString().
438  */
439 QString findExe(const QString& appname,
440  const QString& path = QString(),
441  FindExeOptions options = FindExeOption::None);
442 
443 //! A single property
444 //! @note This property is general-purpose and not related to Qt Properties.
445 //! @see KDbUtils::PropertySet
446 class KDB_EXPORT Property {
447 public:
448  //! Constructs a null property
449  Property();
450 
451  Property(const QVariant &aValue, const QString &aCaption);
452 
453  Property(const Property &other);
454 
455  ~Property();
456 
457  bool operator==(const Property &other) const;
458 
459  bool operator!=(const Property &other) const { return !operator==(other); }
460 
461  bool isNull() const;
462 
463  QVariant value() const;
464 
465  void setValue(const QVariant &value);
466 
467  QString caption() const;
468 
469  void setCaption(const QString &caption);
470 
471 private:
472  class Private;
473  Private * const d;
474 };
475 
476 //! A set of properties.
477 //! @note These properties are general-purpose and not related to Qt Properties.
478 //! @see KDbUtils::Property
479 class KDB_EXPORT PropertySet
480 {
481 public:
482  PropertySet();
483 
484  PropertySet(const PropertySet &other);
485 
486  ~PropertySet();
487 
488  //! Assigns @a other to this property set and returns a reference to this property set.
489  PropertySet& operator=(const PropertySet &other);
490 
491  //! @return true if this property set has exactly the same properties as @a other
492  //! @since 3.1
493  bool operator==(const PropertySet &other) const;
494 
495  //! @return true if this property differs in at least one property from @a other
496  //! @since 3.1
497  bool operator!=(const PropertySet &other) const { return !operator==(other); }
498 
499  //! Inserts property with a given @a name, @a value and @a caption.
500  //! If @a caption is empty, caption from existing property is reused.
501  //! @a name must be a valid identifier (see KDb::isIdentifier()).
502  void insert(const QByteArray &name, const QVariant &value, const QString &caption = QString());
503 
504  //! Sets caption for property @a name to @a caption.
505  //! If such property does not exist, does nothing.
506  //! @since 3.1
507  void setCaption(const QByteArray &name, const QString &caption);
508 
509  //! Sets value for property @a name to @a value.
510  //! If such property does not exist, does nothing.
511  //! @since 3.1
512  void setValue(const QByteArray &name, const QVariant &value);
513 
514  //! Removes property with a given @a name.
515  void remove(const QByteArray &name);
516 
517  //! @return property with a given @a name.
518  //! If not found, a null Property is returned (Property::isNull).
519  Property property(const QByteArray &name) const;
520 
521  //! @return a list of property names.
522  QList<QByteArray> names() const;
523 
524 private:
525  class Private;
526  Private * const d;
527 };
528 
529 } // KDbUtils
530 
531 #endif //KDB_TOOLS_UTILS_H
const T value(const Key &key) const const
AutodeletedList(const AutodeletedList &other)
Creates autodeleting list as a copy of other.
Definition: KDbUtils.h:250
Autodeleting list.
Definition: KDbUtils.h:244
int count() const const
QHash::iterator erase(QHash::iterator pos)
int removeAll(const T &value)
AutodeletedList(bool autoDelete=true)
Creates empty autodeleting list.
Definition: KDbUtils.h:255
Case insensitive hash container supporting QString or QByteArray keys.
Definition: KDbUtils.h:338
T takeAt(int i)
A set created from static (0-terminated) array of raw null-terminated strings.
Definition: KDbUtils.h:387
AutodeletedHash(bool autoDelete=true)
Creates empty autodeleting hash.
Definition: KDbUtils.h:188
QHash::iterator find(const Key &key)
void clear()
bool inherits(const char *className) const const
QHash::iterator insert(const Key &key, const T &value)
T take(const Key &key)
A set of properties.
Definition: KDbUtils.h:479
AutodeletedHash(const AutodeletedHash &other)
Creates autodeleting hash as a copy of other.
Definition: KDbUtils.h:184
T takeFirst()
A single property.
Definition: KDbUtils.h:446
const Key key(const T &value) const const
QHash::iterator insertMulti(const Key &key, const T &value)
Autodeleting hash.
Definition: KDbUtils.h:178
QHash::const_iterator constFind(const Key &key) const const
void insert(int i, const T &value)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
bool operator!=(const PropertySet &other) const
Definition: KDbUtils.h:497
QList< T > values() const const
QList::iterator erase(QList::iterator pos)
int remove(const Key &key)
void clear()
T & operator[](const Key &key)
bool contains(const Key &key) const const
T takeLast()
QObject * parent() const const
T value(int i) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Oct 6 2022 04:04:38 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.