diff options
Diffstat (limited to 'src/qt3support/tools')
44 files changed, 10941 insertions, 0 deletions
diff --git a/src/qt3support/tools/q3asciicache.h b/src/qt3support/tools/q3asciicache.h new file mode 100644 index 0000000..1e10bff --- /dev/null +++ b/src/qt3support/tools/q3asciicache.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3ASCIICACHE_H +#define Q3ASCIICACHE_H + +#include <Qt3Support/q3gcache.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3AsciiCache +#ifdef qdoc + : public Q3PtrCollection +#else + : public Q3GCache +#endif +{ +public: + Q3AsciiCache(const Q3AsciiCache<type> &c) : Q3GCache(c) {} + Q3AsciiCache(int maxCost=100, int size=17, bool caseSensitive=true, + bool copyKeys=true) + : Q3GCache(maxCost, size, AsciiKey, caseSensitive, copyKeys) {} + ~Q3AsciiCache() { clear(); } + Q3AsciiCache<type> &operator=(const Q3AsciiCache<type> &c) + { return (Q3AsciiCache<type>&)Q3GCache::operator=(c); } + int maxCost() const { return Q3GCache::maxCost(); } + int totalCost() const { return Q3GCache::totalCost(); } + void setMaxCost(int m) { Q3GCache::setMaxCost(m); } + uint count() const { return Q3GCache::count(); } + uint size() const { return Q3GCache::size(); } + bool isEmpty() const { return Q3GCache::count() == 0; } + void clear() { Q3GCache::clear(); } + bool insert(const char *k, const type *d, int c=1, int p=0) + { return Q3GCache::insert_other(k,(Item)d,c,p);} + bool remove(const char *k) + { return Q3GCache::remove_other(k); } + type *take(const char *k) + { return (type *)Q3GCache::take_other(k); } + type *find(const char *k, bool ref=true) const + { return (type *)Q3GCache::find_other(k,ref);} + type *operator[](const char *k) const + { return (type *)Q3GCache::find_other(k);} + void statistics() const { Q3GCache::statistics(); } +private: + void deleteItem(Item d); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3AsciiCache<void>::deleteItem(Q3PtrCollection::Item) +{ +} +#endif + +template<class type> inline void Q3AsciiCache<type>::deleteItem(Q3PtrCollection::Item d) +{ + if (del_item) delete (type *)d; +} + + +template<class type> +class Q3AsciiCacheIterator : public Q3GCacheIterator +{ +public: + Q3AsciiCacheIterator(const Q3AsciiCache<type> &c):Q3GCacheIterator((Q3GCache &)c) {} + Q3AsciiCacheIterator(const Q3AsciiCacheIterator<type> &ci) + : Q3GCacheIterator((Q3GCacheIterator &)ci) {} + Q3AsciiCacheIterator<type> &operator=(const Q3AsciiCacheIterator<type>&ci) + { return (Q3AsciiCacheIterator<type>&)Q3GCacheIterator::operator=(ci); } + uint count() const { return Q3GCacheIterator::count(); } + bool isEmpty() const { return Q3GCacheIterator::count() == 0; } + bool atFirst() const { return Q3GCacheIterator::atFirst(); } + bool atLast() const { return Q3GCacheIterator::atLast(); } + type *toFirst() { return (type *)Q3GCacheIterator::toFirst(); } + type *toLast() { return (type *)Q3GCacheIterator::toLast(); } + operator type *() const { return (type *)Q3GCacheIterator::get(); } + type *current() const { return (type *)Q3GCacheIterator::get(); } + const char *currentKey() const { return Q3GCacheIterator::getKeyAscii(); } + type *operator()() { return (type *)Q3GCacheIterator::operator()();} + type *operator++() { return (type *)Q3GCacheIterator::operator++(); } + type *operator+=(uint j) { return (type *)Q3GCacheIterator::operator+=(j);} + type *operator--() { return (type *)Q3GCacheIterator::operator--(); } + type *operator-=(uint j) { return (type *)Q3GCacheIterator::operator-=(j);} +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3ASCIICACHE_H diff --git a/src/qt3support/tools/q3asciidict.h b/src/qt3support/tools/q3asciidict.h new file mode 100644 index 0000000..4a304ac --- /dev/null +++ b/src/qt3support/tools/q3asciidict.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3ASCIIDICT_H +#define Q3ASCIIDICT_H + +#include <Qt3Support/q3gdict.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3AsciiDict +#ifdef qdoc + : public Q3PtrCollection +#else + : public Q3GDict +#endif +{ +public: + Q3AsciiDict(int size=17, bool caseSensitive=true, bool copyKeys=true) + : Q3GDict(size,AsciiKey,caseSensitive,copyKeys) {} + Q3AsciiDict(const Q3AsciiDict<type> &d) : Q3GDict(d) {} + ~Q3AsciiDict() { clear(); } + Q3AsciiDict<type> &operator=(const Q3AsciiDict<type> &d) + { return (Q3AsciiDict<type>&)Q3GDict::operator=(d); } + uint count() const { return Q3GDict::count(); } + uint size() const { return Q3GDict::size(); } + bool isEmpty() const { return Q3GDict::count() == 0; } + + void insert(const char *k, const type *d) + { Q3GDict::look_ascii(k,(Item)d,1); } + void replace(const char *k, const type *d) + { Q3GDict::look_ascii(k,(Item)d,2); } + bool remove(const char *k) { return Q3GDict::remove_ascii(k); } + type *take(const char *k) { return (type *)Q3GDict::take_ascii(k); } + type *find(const char *k) const + { return (type *)((Q3GDict*)this)->Q3GDict::look_ascii(k,0,0); } + type *operator[](const char *k) const + { return (type *)((Q3GDict*)this)->Q3GDict::look_ascii(k,0,0); } + + void clear() { Q3GDict::clear(); } + void resize(uint n) { Q3GDict::resize(n); } + void statistics() const { Q3GDict::statistics(); } + +#ifdef qdoc +protected: + virtual QDataStream& read(QDataStream &, Q3PtrCollection::Item &); + virtual QDataStream& write(QDataStream &, Q3PtrCollection::Item) const; +#endif + +private: + void deleteItem(Item d); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3AsciiDict<void>::deleteItem(Q3PtrCollection::Item) +{ +} +#endif + +template<class type> inline void Q3AsciiDict<type>::deleteItem(Q3PtrCollection::Item d) +{ + if (del_item) delete (type *)d; +} + +template<class type> +class Q3AsciiDictIterator : public Q3GDictIterator +{ +public: + Q3AsciiDictIterator(const Q3AsciiDict<type> &d) + : Q3GDictIterator((Q3GDict &)d) {} + ~Q3AsciiDictIterator() {} + uint count() const { return dict->count(); } + bool isEmpty() const { return dict->count() == 0; } + type *toFirst() { return (type *)Q3GDictIterator::toFirst(); } + operator type *() const { return (type *)Q3GDictIterator::get(); } + type *current() const { return (type *)Q3GDictIterator::get(); } + const char *currentKey() const { return Q3GDictIterator::getKeyAscii(); } + type *operator()() { return (type *)Q3GDictIterator::operator()(); } + type *operator++() { return (type *)Q3GDictIterator::operator++(); } + type *operator+=(uint j) { return (type *)Q3GDictIterator::operator+=(j);} +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3ASCIIDICT_H diff --git a/src/qt3support/tools/q3cache.h b/src/qt3support/tools/q3cache.h new file mode 100644 index 0000000..64f67c4 --- /dev/null +++ b/src/qt3support/tools/q3cache.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3CACHE_H +#define Q3CACHE_H + +#include <Qt3Support/q3gcache.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3Cache +#ifdef qdoc + : public Q3PtrCollection +#else + : public Q3GCache +#endif +{ +public: + Q3Cache(const Q3Cache<type> &c) : Q3GCache(c) {} + Q3Cache(int maxCost=100, int size=17, bool caseSensitive=true) + : Q3GCache(maxCost, size, StringKey, caseSensitive, false) {} + ~Q3Cache() { clear(); } + Q3Cache<type> &operator=(const Q3Cache<type> &c) + { return (Q3Cache<type>&)Q3GCache::operator=(c); } + int maxCost() const { return Q3GCache::maxCost(); } + int totalCost() const { return Q3GCache::totalCost(); } + void setMaxCost(int m) { Q3GCache::setMaxCost(m); } + uint count() const { return Q3GCache::count(); } + uint size() const { return Q3GCache::size(); } + bool isEmpty() const { return Q3GCache::count() == 0; } + void clear() { Q3GCache::clear(); } + bool insert(const QString &k, const type *d, int c=1, int p=0) + { return Q3GCache::insert_string(k,(Item)d,c,p);} + bool remove(const QString &k) + { return Q3GCache::remove_string(k); } + type *take(const QString &k) + { return (type *)Q3GCache::take_string(k); } + type *find(const QString &k, bool ref=true) const + { return (type *)Q3GCache::find_string(k,ref);} + type *operator[](const QString &k) const + { return (type *)Q3GCache::find_string(k);} + void statistics() const { Q3GCache::statistics(); } +private: + void deleteItem(Item d); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3Cache<void>::deleteItem(Q3PtrCollection::Item) +{ +} +#endif + +template<class type> inline void Q3Cache<type>::deleteItem(Q3PtrCollection::Item d) +{ + if (del_item) delete (type *)d; +} + +template<class type> +class Q3CacheIterator : public Q3GCacheIterator +{ +public: + Q3CacheIterator(const Q3Cache<type> &c):Q3GCacheIterator((Q3GCache &)c) {} + Q3CacheIterator(const Q3CacheIterator<type> &ci) + : Q3GCacheIterator((Q3GCacheIterator &)ci) {} + Q3CacheIterator<type> &operator=(const Q3CacheIterator<type>&ci) + { return (Q3CacheIterator<type>&)Q3GCacheIterator::operator=(ci); } + uint count() const { return Q3GCacheIterator::count(); } + bool isEmpty() const { return Q3GCacheIterator::count() == 0; } + bool atFirst() const { return Q3GCacheIterator::atFirst(); } + bool atLast() const { return Q3GCacheIterator::atLast(); } + type *toFirst() { return (type *)Q3GCacheIterator::toFirst(); } + type *toLast() { return (type *)Q3GCacheIterator::toLast(); } + operator type *() const { return (type *)Q3GCacheIterator::get(); } + type *current() const { return (type *)Q3GCacheIterator::get(); } + QString currentKey() const{ return Q3GCacheIterator::getKeyString(); } + type *operator()() { return (type *)Q3GCacheIterator::operator()();} + type *operator++() { return (type *)Q3GCacheIterator::operator++(); } + type *operator+=(uint j) { return (type *)Q3GCacheIterator::operator+=(j);} + type *operator--() { return (type *)Q3GCacheIterator::operator--(); } + type *operator-=(uint j) { return (type *)Q3GCacheIterator::operator-=(j);} +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3CACHE_H diff --git a/src/qt3support/tools/q3cleanuphandler.h b/src/qt3support/tools/q3cleanuphandler.h new file mode 100644 index 0000000..c249ae9 --- /dev/null +++ b/src/qt3support/tools/q3cleanuphandler.h @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3CLEANUPHANDLER_H +#define Q3CLEANUPHANDLER_H + +#include <QtCore/qlist.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class T> +class Q3CleanupHandler +{ + QListData p; +public: + inline Q3CleanupHandler() + { p.d = 0; } + ~Q3CleanupHandler() + { + if (p.d) { + for (int i = 0; i < p.size(); ++i) { + T** t = static_cast<T**>(*p.at(i)); + delete *t; + *t = 0; + } + qFree(p.d); + p.d = 0; + } + } + + T* add(T **object) + { + if (!p.d) { + p.d = &QListData::shared_null; + p.d->ref.ref(); + p.detach(); + } + *p.prepend() = object; + return *object; + } + void remove(T **object) + { + if (p.d) + for (int i = 0; i < p.size(); ++i) + if (*p.at(i) == object) + p.remove(i--); + } +}; + +template<class T> +class Q3SingleCleanupHandler +{ + T **object; +public: + inline Q3SingleCleanupHandler() + : object(0) {} + inline ~Q3SingleCleanupHandler() + { if (object) { delete *object; *object = 0; } } + inline T* set(T **o) + { object = o; return *object; } + inline void reset() { object = 0; } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif //Q3CLEANUPHANDLER_H diff --git a/src/qt3support/tools/q3cstring.cpp b/src/qt3support/tools/q3cstring.cpp new file mode 100644 index 0000000..aa7f345 --- /dev/null +++ b/src/qt3support/tools/q3cstring.cpp @@ -0,0 +1,1050 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3cstring.h" +#include "qregexp.h" +#include "qdatastream.h" + +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> +#include <ctype.h> +#include <limits.h> + +QT_BEGIN_NAMESPACE + +/***************************************************************************** + Q3CString member functions + *****************************************************************************/ + +/*! + \class Q3CString + \reentrant + \brief The Q3CString class provides an abstraction of the classic C + zero-terminated char array (char *). + + \compat + + Q3CString tries to behave like a more convenient \c{const char *}. + The price of doing this is that some algorithms will perform + badly. For example, append() is O(length()) since it scans for a + null terminator. Although you might use Q3CString for text that is + never exposed to the user, for most purposes, and especially for + user-visible text, you should use QString. QString provides + implicit sharing, Unicode and other internationalization support, + and is well optimized. + + Note that for the Q3CString methods that take a \c{const char *} + parameter the \c{const char *} must either be 0 (null) or not-null + and '\0' (NUL byte) terminated; otherwise the results are + undefined. + + A Q3CString that has not been assigned to anything is \e null, i.e. + both the length and the data pointer is 0. A Q3CString that + references the empty string ("", a single '\0' char) is \e empty. + Both null and empty Q3CStrings are legal parameters to the methods. + Assigning \c{const char *} 0 to Q3CString produces a null Q3CString. + + The length() function returns the length of the string; resize() + resizes the string and truncate() truncates the string. A string + can be filled with a character using fill(). Strings can be left + or right padded with characters using leftJustify() and + rightJustify(). Characters, strings and regular expressions can be + searched for using find() and findRev(), and counted using + contains(). + + Strings and characters can be inserted with insert() and appended + with append(). A string can be prepended with prepend(). + Characters can be removed from the string with remove() and + replaced with replace(). + + Portions of a string can be extracted using left(), right() and + mid(). Whitespace can be removed using stripWhiteSpace() and + simplifyWhiteSpace(). Strings can be converted to uppercase or + lowercase with upper() and lower() respectively. + + Strings that contain numbers can be converted to numbers with + toShort(), toInt(), toLong(), toULong(), toFloat() and toDouble(). + Numbers can be converted to strings with setNum(). + + Many operators are overloaded to work with Q3CStrings. Q3CString + also supports some more obscure functions, e.g. sprintf(), + setStr() and setExpand(). + + \sidebar Note on Character Comparisons + + In Q3CString the notion of uppercase and lowercase and of which + character is greater than or less than another character is locale + dependent. This affects functions which support a case insensitive + option or which compare or lowercase or uppercase their arguments. + Case insensitive operations and comparisons will be accurate if + both strings contain only ASCII characters. (If \c $LC_CTYPE is + set, most Unix systems do "the right thing".) Functions that this + affects include contains(), find(), findRev(), \l operator<(), \l + operator<=(), \l operator>(), \l operator>=(), lower() and + upper(). + + This issue does not apply to \l{QString}s since they represent + characters using Unicode. + \endsidebar + + Performance note: The Q3CString methods for QRegExp searching are + implemented by converting the Q3CString to a QString and performing + the search on that. This implies a deep copy of the Q3CString data. + If you are going to perform many QRegExp searches on a large + Q3CString, you will get better performance by converting the + Q3CString to a QString yourself, and then searching in the QString. +*/ + +/*! + \fn Q3CString Q3CString::left(uint len) const + + \internal +*/ + +/*! + \fn Q3CString Q3CString::right(uint len) const + + \internal +*/ + +/*! + \fn Q3CString Q3CString::mid(uint index, uint len) const + + \internal +*/ + +/*! + \fn Q3CString Q3CString::lower() const + + Use QByteArray::toLower() instead. +*/ + +/*! + \fn Q3CString Q3CString::upper() const + + Use QByteArray::toUpper() instead. +*/ + +/*! + \fn Q3CString Q3CString::stripWhiteSpace() const + + Use QByteArray::trimmed() instead. +*/ + +/*! + \fn Q3CString Q3CString::simplifyWhiteSpace() const + + Use QByteArray::simplified() instead. +*/ + +/*! + \fn Q3CString& Q3CString::insert(uint index, const char *c) + + \internal +*/ + +/*! + \fn Q3CString& Q3CString::insert(uint index, char c) + + \internal +*/ + +/*! + \fn Q3CString& Q3CString::prepend(const char *c) + + \internal +*/ + +/*! + \fn Q3CString& Q3CString::remove(uint index, uint len) + + \internal +*/ + +/*! + \fn Q3CString& Q3CString::replace(uint index, uint len, const char *c) + + \internal +*/ + +/*! + \fn Q3CString& Q3CString::replace(char c, const Q3CString &after) + + \internal +*/ + +/*! + \fn Q3CString& Q3CString::replace(char c, const char *after) + + \internal +*/ + +/*! + \fn Q3CString& Q3CString::replace(const Q3CString &b, const Q3CString &a) + + \internal +*/ + +/*! + \fn Q3CString& Q3CString::replace(const char *b, const char *a) + + \internal +*/ + +/*! + \fn Q3CString& Q3CString::replace(char b, char a) + + \internal +*/ + +/*! + \fn Q3CString::Q3CString() + + Constructs a null string. + + \sa isNull() +*/ + +/*! + \fn Q3CString::Q3CString(const QByteArray &ba) + + Constructs a copy of \a ba. +*/ + +/*! + \fn Q3CString::Q3CString(const Q3CString &s) + + Constructs a shallow copy \a s. +*/ + +/*! \fn Q3CString::Q3CString(int size) + Constructs a string with room for \a size characters, including + the '\0'-terminator. Makes a null string if \a size == 0. + + If \a size \> 0, then the first and last characters in the string + are initialized to '\0'. All other characters are uninitialized. + + \sa resize(), isNull() +*/ + +/*! \fn Q3CString::Q3CString(const char *str) + Constructs a string that is a deep copy of \a str. + + If \a str is 0 a null string is created. + + \sa isNull() +*/ + + +/*! \fn Q3CString::Q3CString(const char *str, uint maxsize) + + Constructs a string that is a deep copy of \a str. The copy will + be at most \a maxsize bytes long including the '\0'-terminator. + + Example: + \snippet doc/src/snippets/code/src_qt3support_tools_q3cstring.cpp 0 + + If \a str contains a 0 byte within the first \a maxsize bytes, the + resulting Q3CString will be terminated by this 0. If \a str is 0 a + null string is created. + + \sa isNull() +*/ + +/*! + \fn Q3CString &Q3CString::operator=(const QByteArray &ba) + + Assigns byte array \a ba to this Q3CString. +*/ + +/*! + \fn Q3CString &Q3CString::operator=(const Q3CString &s) + + Assigns a shallow copy of \a s to this string and returns a + reference to this string. +*/ + +/*! + \fn Q3CString &Q3CString::operator=(const char *str) + \overload + + Assigns a deep copy of \a str to this string and returns a + reference to this string. + + If \a str is 0 a null string is created. + + \sa isNull() +*/ + +/* + \fn bool Q3CString::isNull() const + + Returns true if the string is null, i.e. if data() == 0; otherwise + returns false. A null string is also an empty string. + + Example: + \snippet doc/src/snippets/code/src.qt3support.tools.q3cstring.cpp 1 + + \sa isEmpty(), length(), size() +*/ + +/* + \fn bool Q3CString::isEmpty() const + + Returns true if the string is empty, i.e. if length() == 0; + otherwise returns false. An empty string is not always a null + string. + + See example in isNull(). + + \sa isNull(), length(), size() +*/ + +/* + \fn uint Q3CString::length() const + + Returns the length of the string, excluding the '\0'-terminator. + Equivalent to calling \c strlen(data()). + + Null strings and empty strings have zero length. + + \sa size(), isNull(), isEmpty() +*/ + +/* + \fn bool Q3CString::truncate(uint pos) + + Truncates the string at position \a pos. + + Equivalent to calling \c resize(pos+1). + + Example: + \snippet doc/src/snippets/code/src.qt3support.tools.q3cstring.cpp 2 + + \sa resize() +*/ + + + +/*! + Implemented as a call to the native vsprintf() (see the manual for + your C library). + + If the string is shorter than 256 characters, this sprintf() calls + resize(256) to decrease the chance of memory corruption. The + string is resized back to its actual length before sprintf() + returns. + + Example: + \snippet doc/src/snippets/code/src_qt3support_tools_q3cstring.cpp 3 + + \warning All vsprintf() implementations will write past the end of + the target string (*this) if the \a format specification and + arguments happen to be longer than the target string, and some + will also fail if the target string is longer than some arbitrary + implementation limit. + + Giving user-supplied arguments to sprintf() is risky: Sooner or + later someone will paste a huge line into your application. +*/ + +Q3CString &Q3CString::sprintf(const char *format, ...) +{ + detach(); + va_list ap; + va_start(ap, format); + if (size() < 256) + resize(256); // make string big enough + qvsnprintf(data(), size(), format, ap); + resize(qstrlen(constData())); + va_end(ap); + return *this; +} + + + +/*! + \fn Q3CString Q3CString::copy() const + + Returns a deep copy of this string. +*/ + + +/*! + Returns a string of length \a width (plus one for the terminating + '\0') that contains this string padded with the \a fill character. + + If the length of the string exceeds \a width and \a truncate is + false (the default), then the returned string is a copy of the + string. If the length of the string exceeds \a width and \a + truncate is true, then the returned string is a left(\a width). + + Example: + \snippet doc/src/snippets/code/src_qt3support_tools_q3cstring.cpp 4 + + \sa rightJustify() +*/ + +Q3CString Q3CString::leftJustify(uint width, char fill, bool truncate) const +{ + Q3CString result; + int len = qstrlen(constData()); + int padlen = width - len; + if (padlen > 0) { + result.resize(len+padlen); + memcpy(result.data(), constData(), len); + memset(result.data()+len, fill, padlen); + } else { + if (truncate) + result = left(width); + else + result = *this; + } + return result; +} + +/*! + Returns a string of length \a width (plus one for the terminating + '\0') that contains zero or more of the \a fill character followed + by this string. + + If the length of the string exceeds \a width and \a truncate is + false (the default), then the returned string is a copy of the + string. If the length of the string exceeds \a width and \a + truncate is true, then the returned string is a left(\a width). + + Example: + \snippet doc/src/snippets/code/src_qt3support_tools_q3cstring.cpp 5 + + \sa leftJustify() +*/ + +Q3CString Q3CString::rightJustify(uint width, char fill, bool truncate) const +{ + Q3CString result; + int len = qstrlen(constData()); + int padlen = width - len; + if (padlen > 0) { + result.resize(len+padlen); + memset(result.data(), fill, padlen); + memcpy(result.data()+padlen, constData(), len); + } else { + if (truncate) + result = left(width); + else + result = *this; + } + return result; +} + +/*! + Returns the string converted to a \c long value. + + If \a ok is not 0: *\a ok is set to false if the string is not a + number, or if it has trailing garbage; otherwise *\a ok is set to + true. +*/ + +long Q3CString::toLong(bool *ok) const +{ + const char *p = constData(); + long val=0; + const long max_mult = 214748364; + bool is_ok = false; + int neg = 0; + if (!p) + goto bye; + while (isspace((uchar) *p)) // skip leading space + p++; + if (*p == '-') { + p++; + neg = 1; + } else if (*p == '+') { + p++; + } + if (!isdigit((uchar) *p)) + goto bye; + while (isdigit((uchar) *p)) { + if (val > max_mult || (val == max_mult && (*p-'0') > 7+neg)) + goto bye; + val = 10*val + (*p++ - '0'); + } + if (neg) + val = -val; + while (isspace((uchar) *p)) // skip trailing space + p++; + if (*p == '\0') + is_ok = true; +bye: + if (ok) + *ok = is_ok; + return is_ok ? val : 0; +} + +/*! + Returns the string converted to an \c{unsigned long} value. + + If \a ok is not 0: *\a ok is set to false if the string is not a + number, or if it has trailing garbage; otherwise *\a ok is set to + true. +*/ + +ulong Q3CString::toULong(bool *ok) const +{ + const char *p = constData(); + ulong val=0; + const ulong max_mult = 429496729; + bool is_ok = false; + if (!p) + goto bye; + while (isspace((uchar) *p)) // skip leading space + p++; + if (*p == '+') + p++; + if (!isdigit((uchar) *p)) + goto bye; + while (isdigit((uchar) *p)) { + if (val > max_mult || (val == max_mult && (*p-'0') > 5)) + goto bye; + val = 10*val + (*p++ - '0'); + } + while (isspace((uchar) *p)) // skip trailing space + p++; + if (*p == '\0') + is_ok = true; +bye: + if (ok) + *ok = is_ok; + return is_ok ? val : 0; +} + +/*! + Returns the string converted to a \c{short} value. + + If \a ok is not 0: *\a ok is set to false if the string is not a + number, is out of range, or if it has trailing garbage; otherwise + *\a ok is set to true. +*/ + +short Q3CString::toShort(bool *ok) const +{ + long v = toLong(ok); + if (ok && *ok && (v < -32768 || v > 32767)) + *ok = false; + return (short)v; +} + +/*! + Returns the string converted to an \c{unsigned short} value. + + If \a ok is not 0: *\a ok is set to false if the string is not a + number, is out of range, or if it has trailing garbage; otherwise + *\a ok is set to true. +*/ + +ushort Q3CString::toUShort(bool *ok) const +{ + ulong v = toULong(ok); + if (ok && *ok && (v > 65535)) + *ok = false; + return (ushort)v; +} + + +/*! + Returns the string converted to a \c{int} value. + + If \a ok is not 0: *\a ok is set to false if the string is not a + number, or if it has trailing garbage; otherwise *\a ok is set to + true. +*/ + +int Q3CString::toInt(bool *ok) const +{ + return (int)toLong(ok); +} + +/*! + Returns the string converted to an \c{unsigned int} value. + + If \a ok is not 0: *\a ok is set to false if the string is not a + number, or if it has trailing garbage; otherwise *\a ok is set to + true. +*/ + +uint Q3CString::toUInt(bool *ok) const +{ + return (uint)toULong(ok); +} + +/*! + Returns the string converted to a \c{double} value. + + If \a ok is not 0: *\a ok is set to false if the string is not a + number, or if it has trailing garbage; otherwise *\a ok is set to + true. +*/ + +double Q3CString::toDouble(bool *ok) const +{ + char *end; + double val = strtod(constData() ? constData() : "", &end); + if (ok) + *ok = (constData() && *constData() && (end == 0 || *end == '\0')); + return val; +} + +/*! + Returns the string converted to a \c{float} value. + + If \a ok is not 0: *\a ok is set to false if the string is not a + number, or if it has trailing garbage; otherwise *\a ok is set to + true. +*/ + +float Q3CString::toFloat(bool *ok) const +{ + return (float)toDouble(ok); +} + + +/*! \fn Q3CString &Q3CString::setStr(const char *str) + Makes a deep copy of \a str. Returns a reference to the string. +*/ + +/*! + \overload + + Sets the string to the string representation of the number \a n + and returns a reference to the string. +*/ + +Q3CString &Q3CString::setNum(long n) +{ + data(); + char buf[20]; + register char *p = &buf[19]; + bool neg; + if (n < 0) { + neg = true; + n = -n; + } else { + neg = false; + } + *p = '\0'; + do { + *--p = ((int)(n%10)) + '0'; + n /= 10; + } while (n); + if (neg) + *--p = '-'; + *this = p; + return *this; +} + +/*! + \overload + + Sets the string to the string representation of the number \a n + and returns a reference to the string. +*/ + +Q3CString &Q3CString::setNum(ulong n) +{ + data(); + char buf[20]; + register char *p = &buf[19]; + *p = '\0'; + do { + *--p = ((int)(n%10)) + '0'; + n /= 10; + } while (n); + *this = p; + return *this; +} + +/*! + \fn Q3CString &Q3CString::setNum(int n) + \overload + + Sets the string to the string representation of the number \a n + and returns a reference to the string. +*/ + +/*! + \fn Q3CString &Q3CString::setNum(uint n) + \overload + + Sets the string to the string representation of the number \a n + and returns a reference to the string. +*/ + +/*! + \fn Q3CString &Q3CString::setNum(short n) + \overload + + Sets the string to the string representation of the number \a n + and returns a reference to the string. +*/ + +/*! + \fn Q3CString &Q3CString::setNum(ushort n) + \overload + + Sets the string to the string representation of the number \a n + and returns a reference to the string. +*/ + +/*! + Sets the string to the string representation of the number \a n + and returns a reference to the string. + + The format of the string representation is specified by the format + character \a f, and the precision (number of digits after the + decimal point) is specified with \a prec. + + The valid formats for \a f are 'e', 'E', 'f', 'g' and 'G'. The + formats are the same as for sprintf(); they are explained in \l + QString::arg(). +*/ + +Q3CString &Q3CString::setNum(double n, char f, int prec) +{ +#ifndef QT_NO_DEBUG + if (!(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G')) + qWarning("Q3CString::setNum: Invalid format char '%c'", f); +#endif + char format[20]; + register char *fs = format; // generate format string + *fs++ = '%'; // "%.<prec>l<f>" + if (prec > 99) + prec = 99; + *fs++ = '.'; + if (prec >= 10) { + *fs++ = prec / 10 + '0'; + *fs++ = prec % 10 + '0'; + } else { + *fs++ = prec + '0'; + } + *fs++ = 'l'; + *fs++ = f; + *fs = '\0'; + return sprintf(format, n); +} + +/*! \fn Q3CString &Q3CString::setNum(float n, char f, int prec) + \overload +*/ + +/*! + Sets the character at position \a index to \a c and expands the + string if necessary, padding with spaces. + + Returns false if \a index was out of range and the string could + not be expanded; otherwise returns true. +*/ + +bool Q3CString::setExpand(uint index, char c) +{ + uint oldlen = length(); + if (index >= oldlen) { + resize(index+1); + if (index > oldlen) + memset(data() + oldlen, ' ', index - oldlen); + } + *(data() + index) = c; + return true; +} + + +/* + \fn Q3CString::operator const char *() const + + Returns the string data. +*/ + + +/*! + \fn Q3CString& Q3CString::append(const char *str) + + Appends string \a str to the string and returns a reference to the + string. Equivalent to operator+=(). +*/ + + + +#ifndef QT_NO_DATASTREAM +/*! \fn QDataStream &operator<<(QDataStream &s, const Q3CString &str) + \relates Q3CString + + Writes string \a str to the stream \a s. + + \sa \link datastreamformat.html Format of the QDataStream operators \endlink +*/ +QDataStream &operator<<(QDataStream &d, const Q3CString &s) +{ + if (d.version() >= QDataStream::Qt_4_0) + return operator<<(d, static_cast<const QByteArray &>(s)); + + // we need to add a NUL to keep compatibility with Qt 3's QByteArray + QByteArray copy = s; + copy.append('\0'); + return operator<<(d, copy); +} + +/*! + \fn QDataStream &operator>>(QDataStream &s, Q3CString &str) + \relates Q3CString + + Reads a string into \a str from the stream \a s. + + \sa \link datastreamformat.html Format of the QDataStream operators \endlink +*/ +QDataStream &operator>>(QDataStream &d, Q3CString &s) { + operator>>(d, static_cast<QByteArray &>(s)); + if (d.version() < QDataStream::Qt_4_0 && s.endsWith('\0')) + s.chop(1); // ending NUL + return d; +} +#endif + +/***************************************************************************** + Documentation for related functions + *****************************************************************************/ + +/*! + \fn bool operator==(const Q3CString &s1, const Q3CString &s2) + + \relates Q3CString + + Returns true if \a s1 and \a s2 are equal; otherwise returns false. + + Equivalent to qstrcmp(\a s1, \a s2) == 0. +*/ + +/*! + \fn bool operator==(const Q3CString &s1, const char *s2) + \overload + + \relates Q3CString + + Returns true if \a s1 and \a s2 are equal; otherwise returns false. + + Equivalent to qstrcmp(\a s1, \a s2) == 0. +*/ + +/*! + \fn bool operator==(const char *s1, const Q3CString &s2) + \overload + + \relates Q3CString + + Returns true if \a s1 and \a s2 are equal; otherwise returns false. + + Equivalent to qstrcmp(\a s1, \a s2) == 0. +*/ + +/*! + \fn bool operator!=(const Q3CString &s1, const Q3CString &s2) + + \relates Q3CString + + Returns true if \a s1 and \a s2 are different; otherwise returns false. + + Equivalent to qstrcmp(\a s1, \a s2) != 0. +*/ + +/*! + \fn bool operator!=(const Q3CString &s1, const char *s2) + \overload + + \relates Q3CString + + Returns true if \a s1 and \a s2 are different; otherwise returns false. + + Equivalent to qstrcmp(\a s1, \a s2) != 0. +*/ + +/*! + \fn bool operator!=(const char *s1, const Q3CString &s2) + \overload + + \relates Q3CString + + Returns true if \a s1 and \a s2 are different; otherwise returns false. + + Equivalent to qstrcmp(\a s1, \a s2) != 0. +*/ + +/*! + \fn bool operator<(const Q3CString &s1, const char *s2) + + \relates Q3CString + + Returns true if \a s1 is less than \a s2; otherwise returns false. + + Equivalent to qstrcmp(\a s1, \a s2) \< 0. +*/ + +/*! + \fn bool operator<(const char *s1, const Q3CString &s2) + \overload + + \relates Q3CString + + Returns true if \a s1 is less than \a s2; otherwise returns false. + + Equivalent to qstrcmp(\a s1, \a s2) \< 0. +*/ + +/*! + \fn bool operator<=(const Q3CString &s1, const char *s2) + + \relates Q3CString + + Returns true if \a s1 is less than or equal to \a s2; otherwise + returns false. + + Equivalent to qstrcmp(\a s1, \a s2) \<= 0. +*/ + +/*! + \fn bool operator<=(const char *s1, const Q3CString &s2) + \overload + + \relates Q3CString + + Returns true if \a s1 is less than or equal to \a s2; otherwise + returns false. + + Equivalent to qstrcmp(\a s1, \a s2) \<= 0. +*/ + +/*! + \fn bool operator>(const Q3CString &s1, const char *s2) + + \relates Q3CString + + Returns true if \a s1 is greater than \a s2; otherwise returns false. + + Equivalent to qstrcmp(\a s1, \a s2) \> 0. +*/ + +/*! + \fn bool operator>(const char *s1, const Q3CString &s2) + \overload + + \relates Q3CString + + Returns true if \a s1 is greater than \a s2; otherwise returns false. + + Equivalent to qstrcmp(\a s1, \a s2) \> 0. +*/ + +/*! + \fn bool operator>=(const Q3CString &s1, const char *s2) + + \relates Q3CString + + Returns true if \a s1 is greater than or equal to \a s2; otherwise + returns false. + + Equivalent to qstrcmp(\a s1, \a s2) \>= 0. +*/ + +/*! + \fn bool operator>=(const char *s1, const Q3CString &s2) + \overload + + \relates Q3CString + + Returns true if \a s1 is greater than or equal to \a s2; otherwise + returns false. + + Equivalent to qstrcmp(\a s1, \a s2) \>= 0. +*/ + +/*! + \fn const Q3CString operator+(const Q3CString &s1, const Q3CString &s2) + + \relates Q3CString + + Returns a string which consists of the concatenation of \a s1 and + \a s2. +*/ + +/*! + \fn const Q3CString operator+(const Q3CString &s1, const char *s2) + \overload + + \relates Q3CString + + Returns a string which consists of the concatenation of \a s1 and \a s2. +*/ + +/*! + \fn const Q3CString operator+(const char *s1, const Q3CString &s2) + \overload + + \relates Q3CString + + Returns a string which consists of the concatenation of \a s1 and \a s2. +*/ + +/*! + \fn const Q3CString operator+(const Q3CString &s, char c) + \overload + + \relates Q3CString + + Returns a string which consists of the concatenation of \a s and \a c. +*/ + +/*! + \fn const Q3CString operator+(char c, const Q3CString &s) + \overload + + \relates Q3CString + Returns a string which consists of the concatenation of \a c and \a s. +*/ + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3cstring.h b/src/qt3support/tools/q3cstring.h new file mode 100644 index 0000000..c1897aa --- /dev/null +++ b/src/qt3support/tools/q3cstring.h @@ -0,0 +1,273 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3CSTRING_H +#define Q3CSTRING_H + +#include <QtCore/qbytearray.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +/***************************************************************************** + QCString class + *****************************************************************************/ + +class QRegExp; + +class Q_COMPAT_EXPORT Q3CString : public QByteArray +{ +public: + Q3CString() {} + Q3CString(int size) : QByteArray(size, '\0') {} + Q3CString(const Q3CString &s) : QByteArray(s) {} + Q3CString(const QByteArray &ba) : QByteArray(ba) {} + Q3CString(const char *str) : QByteArray(str) {} + Q3CString(const char *str, uint maxlen) : QByteArray(str, qMin(qstrlen(str), maxlen - 1)) {} + + Q3CString &operator=(const Q3CString &s) { + QByteArray::operator=(s); return *this; + } + Q3CString &operator=(const char *str) { + QByteArray::operator=(str); return *this; + } + Q3CString &operator=(const QByteArray &ba) { + QByteArray::operator=(ba); return *this; + } + + Q3CString copy() const { return *this; } + Q3CString &sprintf(const char *format, ...); + + Q3CString left(uint len) const { return QByteArray::left(len); } + Q3CString right(uint len) const { return QByteArray::right(len); } + Q3CString mid(uint index, uint len=0xffffffff) const { return QByteArray::mid(index, len); } + + Q3CString leftJustify(uint width, char fill=' ', bool trunc=false)const; + Q3CString rightJustify(uint width, char fill=' ',bool trunc=false)const; + + Q3CString lower() const { return QByteArray::toLower(); } + Q3CString upper() const { return QByteArray::toUpper(); } + + Q3CString stripWhiteSpace() const { return QByteArray::trimmed(); } + Q3CString simplifyWhiteSpace() const { return QByteArray::simplified(); } + + Q3CString &insert(uint index, const char *c) { QByteArray::insert(index, c); return *this; } + Q3CString &insert(uint index, char c) { QByteArray::insert(index, c); return *this; } + Q3CString &append(const char *c) { QByteArray::append(c); return *this; } + Q3CString &prepend(const char *c) { QByteArray::prepend(c); return *this; } + Q3CString &remove(uint index, uint len) { QByteArray::remove(index, len); return *this; } + Q3CString &replace(uint index, uint len, const char *c) + { QByteArray::replace(index, len, c); return *this; } + Q3CString &replace(char c, const Q3CString &after) { return replace(c, after.constData()); } + Q3CString &replace(char c, const char *after) { QByteArray::replace(c, after); return *this; } + Q3CString &replace(const Q3CString &b, const Q3CString &a) + { return replace(b.constData(), a.constData()); } + Q3CString &replace(const char *b, const char *a) { QByteArray::replace(b, a); return *this; } + Q3CString &replace(char b, char a) { QByteArray::replace(b, a); return *this; } + + short toShort(bool *ok=0) const; + ushort toUShort(bool *ok=0) const; + int toInt(bool *ok=0) const; + uint toUInt(bool *ok=0) const; + long toLong(bool *ok=0) const; + ulong toULong(bool *ok=0) const; + float toFloat(bool *ok=0) const; + double toDouble(bool *ok=0) const; + + Q3CString &setStr(const char *s) { *this = s; return *this; } + Q3CString &setNum(short); + Q3CString &setNum(ushort); + Q3CString &setNum(int); + Q3CString &setNum(uint); + Q3CString &setNum(long); + Q3CString &setNum(ulong); + Q3CString &setNum(float, char f='g', int prec=6); + Q3CString &setNum(double, char f='g', int prec=6); + + bool setExpand(uint index, char c); + +}; + + +/***************************************************************************** + Q3CString stream functions + *****************************************************************************/ +#ifndef QT_NO_DATASTREAM +Q_COMPAT_EXPORT QDataStream &operator<<(QDataStream &d, const Q3CString &s); +Q_COMPAT_EXPORT QDataStream &operator>>(QDataStream &d, Q3CString &s); +#endif + +/***************************************************************************** + Q3CString inline functions + *****************************************************************************/ + +inline Q3CString &Q3CString::setNum(short n) +{ return setNum(long(n)); } + +inline Q3CString &Q3CString::setNum(ushort n) +{ return setNum(ulong(n)); } + +inline Q3CString &Q3CString::setNum(int n) +{ return setNum(long(n)); } + +inline Q3CString &Q3CString::setNum(uint n) +{ return setNum(ulong(n)); } + +inline Q3CString &Q3CString::setNum(float n, char f, int prec) +{ return setNum(double(n),f,prec); } + +/***************************************************************************** + Q3CString non-member operators + *****************************************************************************/ + +Q_COMPAT_EXPORT inline bool operator==(const Q3CString &s1, const Q3CString &s2) +{ return qstrcmp(s1, s2) == 0; } + +Q_COMPAT_EXPORT inline bool operator==(const Q3CString &s1, const char *s2) +{ return qstrcmp(s1, s2) == 0; } + +Q_COMPAT_EXPORT inline bool operator==(const char *s1, const Q3CString &s2) +{ return qstrcmp(s1, s2) == 0; } + +Q_COMPAT_EXPORT inline bool operator!=(const Q3CString &s1, const Q3CString &s2) +{ return qstrcmp(s1, s2) != 0; } + +Q_COMPAT_EXPORT inline bool operator!=(const Q3CString &s1, const char *s2) +{ return qstrcmp(s1, s2) != 0; } + +Q_COMPAT_EXPORT inline bool operator!=(const char *s1, const Q3CString &s2) +{ return qstrcmp(s1, s2) != 0; } + +Q_COMPAT_EXPORT inline bool operator<(const Q3CString &s1, const Q3CString& s2) +{ return qstrcmp(s1, s2) < 0; } + +Q_COMPAT_EXPORT inline bool operator<(const Q3CString &s1, const char *s2) +{ return qstrcmp(s1, s2) < 0; } + +Q_COMPAT_EXPORT inline bool operator<(const char *s1, const Q3CString &s2) +{ return qstrcmp(s1, s2) < 0; } + +Q_COMPAT_EXPORT inline bool operator<=(const Q3CString &s1, const Q3CString &s2) +{ return qstrcmp(s1, s2) <= 0; } + +Q_COMPAT_EXPORT inline bool operator<=(const Q3CString &s1, const char *s2) +{ return qstrcmp(s1, s2) <= 0; } + +Q_COMPAT_EXPORT inline bool operator<=(const char *s1, const Q3CString &s2) +{ return qstrcmp(s1, s2) <= 0; } + +Q_COMPAT_EXPORT inline bool operator>(const Q3CString &s1, const Q3CString &s2) +{ return qstrcmp(s1, s2) > 0; } + +Q_COMPAT_EXPORT inline bool operator>(const Q3CString &s1, const char *s2) +{ return qstrcmp(s1, s2) > 0; } + +Q_COMPAT_EXPORT inline bool operator>(const char *s1, const Q3CString &s2) +{ return qstrcmp(s1, s2) > 0; } + +Q_COMPAT_EXPORT inline bool operator>=(const Q3CString &s1, const Q3CString& s2) +{ return qstrcmp(s1, s2) >= 0; } + +Q_COMPAT_EXPORT inline bool operator>=(const Q3CString &s1, const char *s2) +{ return qstrcmp(s1, s2) >= 0; } + +Q_COMPAT_EXPORT inline bool operator>=(const char *s1, const Q3CString &s2) +{ return qstrcmp(s1, s2) >= 0; } + +Q_COMPAT_EXPORT inline const Q3CString operator+(const Q3CString &s1, + const Q3CString &s2) +{ + Q3CString tmp(s1); + tmp += s2; + return tmp; +} +Q_COMPAT_EXPORT inline const Q3CString operator+(const Q3CString &s1, + const QByteArray &s2) +{ + QByteArray tmp(s1); + tmp += s2; + return tmp; +} +Q_COMPAT_EXPORT inline const Q3CString operator+(const QByteArray &s1, + const Q3CString &s2) +{ + QByteArray tmp(s1); + tmp += s2; + return tmp; +} + +Q_COMPAT_EXPORT inline const Q3CString operator+(const Q3CString &s1, const char *s2) +{ + Q3CString tmp(s1); + tmp += s2; + return tmp; +} + +Q_COMPAT_EXPORT inline const Q3CString operator+(const char *s1, const Q3CString &s2) +{ + Q3CString tmp(s1); + tmp += s2; + return tmp; +} + +Q_COMPAT_EXPORT inline const Q3CString operator+(const Q3CString &s1, char c2) +{ + Q3CString tmp(s1); + tmp += c2; + return tmp; +} + +Q_COMPAT_EXPORT inline const Q3CString operator+(char c1, const Q3CString &s2) +{ + Q3CString tmp; + tmp += c1; + tmp += s2; + return tmp; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3CSTRING_H diff --git a/src/qt3support/tools/q3deepcopy.cpp b/src/qt3support/tools/q3deepcopy.cpp new file mode 100644 index 0000000..c026021 --- /dev/null +++ b/src/qt3support/tools/q3deepcopy.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3deepcopy.h" + +QT_BEGIN_NAMESPACE + +/*! + \class Q3DeepCopy + \brief The Q3DeepCopy class is a template class which ensures that + implicitly shared and explicitly shared classes reference unique + data. + + \reentrant + + \compat + + Normally, shared copies reference the same data to optimize memory + use and for maximum speed. In the example below, \c s1, \c s2, \c + s3, \c s4 and \c s5 share data. + + \snippet doc/src/snippets/code/src_qt3support_tools_q3deepcopy.cpp 0 + + Q3DeepCopy can be used several ways to ensure that an object + references unique, unshared data. In the example below, \c s1, \c + s2 and \c s5 share data, while neither \c s3 nor \c s4 share data. + \snippet doc/src/snippets/code/src_qt3support_tools_q3deepcopy.cpp 1 + + In the example below, \c s1, \c s2 and \c s5 share data, and \c s3 + and \c s4 share data. + \snippet doc/src/snippets/code/src_qt3support_tools_q3deepcopy.cpp 2 + + Q3DeepCopy can also provide safety in multithreaded applications + that use shared classes. In the example below, the variable \c + global_string is used safely since the data contained in \c + global_string is always a deep copy. This ensures that all threads + get a unique copy of the data, and that any assignments to \c + global_string will result in a deep copy. + + \snippet doc/src/snippets/code/src_qt3support_tools_q3deepcopy.cpp 3 + + \warning It is the application developer's responsibility to + protect the object shared across multiple threads. + + The examples above use QString, which is an implicitly shared + class. The behavior of Q3DeepCopy is the same when using explicitly + shared classes like QByteArray. + + Currently, Q3DeepCopy works with the following classes: + \list + \i QMemArray (including subclasses like QByteArray and QCString) + \i QMap + \i QString + \i QValueList (including subclasses like QStringList and QValueStack) + \i QValueVector + \endlist + + \sa \link threads.html Thread Support in Qt \endlink +*/ + +/*! + \fn Q3DeepCopy::Q3DeepCopy() + + Constructs an empty instance of type \e T. +*/ + +/*! + \fn Q3DeepCopy::Q3DeepCopy( const T &t ) + + Constructs a deep copy of \a t. +*/ + +/*! + \fn Q3DeepCopy<T>& Q3DeepCopy::operator=( const T &t ) + + Assigns a deep copy of \a t. +*/ + +/*! + \fn Q3DeepCopy::operator T () + + Returns a deep copy of the encapsulated data. +*/ + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3deepcopy.h b/src/qt3support/tools/q3deepcopy.h new file mode 100644 index 0000000..1b6d13f --- /dev/null +++ b/src/qt3support/tools/q3deepcopy.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DEEPCOPY_H +#define Q3DEEPCOPY_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template <class T> +class Q3DeepCopy +{ +public: + inline Q3DeepCopy() + { + } + + inline Q3DeepCopy(const T &t) + : deepcopy(t) + { + deepcopy.detach(); + } + + inline Q3DeepCopy<T> &operator=(const T &t) + { + deepcopy = t; + deepcopy.detach(); + return *this; + } + + inline operator T () + { + T tmp = deepcopy; + tmp.detach(); + return tmp; + } + +private: + T deepcopy; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3DEEPCOPY_H diff --git a/src/qt3support/tools/q3dict.h b/src/qt3support/tools/q3dict.h new file mode 100644 index 0000000..23f7048 --- /dev/null +++ b/src/qt3support/tools/q3dict.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3DICT_H +#define Q3DICT_H + +#include <Qt3Support/q3gdict.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3Dict +#ifdef qdoc + : public Q3PtrCollection +#else + : public Q3GDict +#endif +{ +public: + Q3Dict(int size = 17, bool caseSensitive = true) + : Q3GDict(size, StringKey, caseSensitive, false) { } + Q3Dict(const Q3Dict<type> &d) : Q3GDict(d) { } + ~Q3Dict() { clear(); } + Q3Dict<type> &operator=(const Q3Dict<type> &d) + { return (Q3Dict<type>&)Q3GDict::operator=(d); } + uint count() const { return Q3GDict::count(); } + uint size() const { return Q3GDict::size(); } + bool isEmpty() const { return Q3GDict::count() == 0; } + + void insert(const QString &k, const type *d) + { Q3GDict::look_string(k,(Item)d,1); } + void replace(const QString &k, const type *d) + { Q3GDict::look_string(k,(Item)d,2); } + bool remove(const QString &k) { return Q3GDict::remove_string(k); } + type *take(const QString &k) { return (type *)Q3GDict::take_string(k); } + type *find(const QString &k) const + { return (type *)((Q3GDict*)this)->Q3GDict::look_string(k,0,0); } + type *operator[](const QString &k) const + { return (type *)((Q3GDict*)this)->Q3GDict::look_string(k,0,0); } + + void clear() { Q3GDict::clear(); } + void resize(uint n) { Q3GDict::resize(n); } + void statistics() const { Q3GDict::statistics(); } + +#ifdef qdoc +protected: + virtual QDataStream& read(QDataStream &, Q3PtrCollection::Item &); + virtual QDataStream& write(QDataStream &, Q3PtrCollection::Item) const; +#endif + +private: + void deleteItem(Item d); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3Dict<void>::deleteItem(Item) +{ +} +#endif + +template<class type> inline void Q3Dict<type>::deleteItem(Q3PtrCollection::Item d) +{ + if (del_item) delete (type *)d; +} + +template<class type> +class Q3DictIterator : public Q3GDictIterator +{ +public: + Q3DictIterator(const Q3Dict<type> &d) : Q3GDictIterator((Q3GDict &)d) { } + ~Q3DictIterator() {} + uint count() const { return dict->count(); } + bool isEmpty() const { return dict->count() == 0; } + type *toFirst() { return (type *)Q3GDictIterator::toFirst(); } + operator type *() const { return (type *)Q3GDictIterator::get(); } + type *operator*() { return (type *)Q3GDictIterator::get(); } + type *current() const { return (type *)Q3GDictIterator::get(); } + QString currentKey() const{ return Q3GDictIterator::getKeyString(); } + type *operator()() { return (type *)Q3GDictIterator::operator()(); } + type *operator++() { return (type *)Q3GDictIterator::operator++(); } + type *operator+=(uint j) { return (type *)Q3GDictIterator::operator+=(j); } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3DICT_H diff --git a/src/qt3support/tools/q3garray.cpp b/src/qt3support/tools/q3garray.cpp new file mode 100644 index 0000000..66e41e1 --- /dev/null +++ b/src/qt3support/tools/q3garray.cpp @@ -0,0 +1,797 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qglobal.h" +#if defined(Q_CC_BOR) + // needed for qsort() because of a std namespace problem on Borland +# include "qplatformdefs.h" +#elif defined(Q_WS_WIN) + // needed for bsearch on some platforms +# include "qt_windows.h" +#endif + +#define Q3GARRAY_CPP +#include "q3garray.h" +#include <stdlib.h> +#include <string.h> + +#ifndef QT_NO_THREAD +# include "private/qmutexpool_p.h" +#endif + +#if defined(Q_OS_WINCE) +# include "qfunctions_wince.h" +#endif +QT_BEGIN_NAMESPACE + +/* + If USE_MALLOC isn't defined, we use new[] and delete[] to allocate + memory. The documentation for QMemArray<T>::assign() explicitly + mentions that the array is freed using free(), so don't mess around + with USE_MALLOC unless you know what you're doing. +*/ +#define USE_MALLOC + +#undef NEW +#undef DELETE + +#if defined(USE_MALLOC) +#define NEW(type,size) ((type*)malloc(size*sizeof(type))) +#define DELETE(array) (free((char*)array)) +#else +#define NEW(type,size) (new type[size]) +#define DELETE(array) (delete[] array) +#define DONT_USE_REALLOC // comment to use realloc() +#endif + +/*! + \class Q3GArray + \reentrant + \brief The Q3GArray class is an internal class for implementing the QMemArray class. + + \internal + + Q3GArray is a strictly internal class that acts as base class for the + QMemArray template array. + + It contains an array of bytes and has no notion of an array element. +*/ + + +/*! + Constructs a null array. +*/ + +Q3GArray::Q3GArray() +{ + shd = newData(); + Q_CHECK_PTR(shd); +} + +/*! + Dummy constructor; does not allocate any data. + + This constructor does not initialize any array data so subclasses + must do it. The intention is to make the code more efficient. +*/ + +Q3GArray::Q3GArray(int, int) +{ +} + +/*! + Constructs an array with room for \a size bytes. +*/ + +Q3GArray::Q3GArray(int size) +{ + if (size < 0) { +#if defined(QT_CHECK_RANGE) + qWarning("Q3GArray: Cannot allocate array with negative length"); +#endif + size = 0; + } + shd = newData(); + Q_CHECK_PTR(shd); + if (size == 0) // zero length + return; + shd->data = NEW(char,size); + Q_CHECK_PTR(shd->data); + shd->len = +#ifdef QT_Q3GARRAY_SPEED_OPTIM + shd->maxl = +#endif + size; +} + +/*! + Constructs a shallow copy of \a a. +*/ + +Q3GArray::Q3GArray(const Q3GArray &a) +{ + shd = a.shd; + shd->ref(); +} + +/*! + Dereferences the array data and deletes it if this was the last + reference. +*/ + +Q3GArray::~Q3GArray() +{ + if (shd && shd->deref()) { // delete when last reference + if (shd->data) // is lost + DELETE(shd->data); + deleteData(shd); + shd = 0; + } +} + + +/*! + \fn Q3GArray &Q3GArray::operator=(const Q3GArray &a) + + Assigns a shallow copy of \a a to this array and returns a reference to + this array. Equivalent to assign(). +*/ + +/*! + \fn void Q3GArray::detach() + + Detaches this array from shared array data. +*/ + +/*! + \fn char *Q3GArray::data() const + + Returns a pointer to the actual array data. +*/ + +/*! + \fn uint Q3GArray::nrefs() const + + Returns the reference count. +*/ + +/*! + \fn uint Q3GArray::size() const + + Returns the size of the array, in bytes. +*/ + + +/*! + Returns true if this array is equal to \a a, otherwise false. + The comparison is bitwise, of course. +*/ + +bool Q3GArray::isEqual(const Q3GArray &a) const +{ + if (size() != a.size()) // different size + return false; + if (data() == a.data()) // has same data + return true; + return (size() ? memcmp(data(), a.data(), size()) : 0) == 0; +} + + +/*! + Resizes the array to \a newsize bytes. \a optim is either + MemOptim (the default) or SpeedOptim. +*/ +bool Q3GArray::resize(uint newsize, Optimization optim) +{ +#ifndef QT_Q3GARRAY_SPEED_OPTIM + Q_UNUSED(optim); +#endif + + if (newsize == shd->len +#ifdef QT_Q3GARRAY_SPEED_OPTIM + && newsize == shd->maxl +#endif + ) // nothing to do + return true; + if (newsize == 0) { // remove array + if (shd->data) + DELETE(shd->data); + shd->data = 0; + shd->len = 0; +#ifdef QT_Q3GARRAY_SPEED_OPTIM + shd->maxl = 0; +#endif + return true; + } + + uint newmaxl = newsize; +#ifdef QT_Q3GARRAY_SPEED_OPTIM + if (optim == SpeedOptim) { + if (newsize <= shd->maxl && + (newsize * 4 > shd->maxl || shd->maxl <= 4)) { + shd->len = newsize; + return true; + } + newmaxl = 4; + while (newmaxl < newsize) + newmaxl *= 2; + // try to spare some memory + if (newmaxl >= 1024 * 1024 && newsize <= newmaxl - (newmaxl >> 2)) + newmaxl -= newmaxl >> 2; + } + shd->maxl = newmaxl; +#endif + + if (shd->data) { // existing data +#if defined(DONT_USE_REALLOC) + char *newdata = NEW(char,newsize); // manual realloc + memcpy(newdata, shd->data, QMIN(shd->len,newmaxl)); + DELETE(shd->data); + shd->data = newdata; +#else + shd->data = (char *)realloc(shd->data, newmaxl); +#endif + } else { + shd->data = NEW(char,newmaxl); + } + if (!shd->data) // no memory + return false; + shd->len = newsize; + return true; +} + +/*!\overload +*/ +bool Q3GArray::resize(uint newsize) +{ + return resize(newsize, MemOptim); +} + + +/*! + Fills the array with the repeated occurrences of \a d, which is + \a sz bytes long. + If \a len is specified as different from -1, then the array will be + resized to \a len*sz before it is filled. + + Returns true if successful, or false if the memory cannot be allocated + (only when \a len != -1). + + \sa resize() +*/ + +bool Q3GArray::fill(const char *d, int len, uint sz) +{ + if (len < 0) + len = shd->len/sz; // default: use array length + else if (!resize(len*sz)) + return false; + if (sz == 1) // 8 bit elements + memset(data(), *d, len); + else if (sz == 4) { // 32 bit elements + register Q_INT32 *x = (Q_INT32*)data(); + Q_INT32 v = *((Q_INT32*)d); + while (len--) + *x++ = v; + } else if (sz == 2) { // 16 bit elements + register Q_INT16 *x = (Q_INT16*)data(); + Q_INT16 v = *((Q_INT16*)d); + while (len--) + *x++ = v; + } else { // any other size elements + register char *x = data(); + while (len--) { // more complicated + memcpy(x, d, sz); + x += sz; + } + } + return true; +} + +/*! + \overload + Shallow copy. Dereference the current array and references the data + contained in \a a instead. Returns a reference to this array. + \sa operator=() +*/ + +Q3GArray &Q3GArray::assign(const Q3GArray &a) +{ + a.shd->ref(); // avoid 'a = a' + if (shd->deref()) { // delete when last reference + if (shd->data) // is lost + DELETE(shd->data); + deleteData(shd); + } + shd = a.shd; + return *this; +} + +/*! + Shallow copy. Dereference the current array and references the + array data \a d, which contains \a len bytes. + Returns a reference to this array. + + Do not delete \a d later, because Q3GArray takes care of that. +*/ + +Q3GArray &Q3GArray::assign(const char *d, uint len) +{ + if (shd->count > 1) { // disconnect this + shd->count--; + shd = newData(); + Q_CHECK_PTR(shd); + } else { + if (shd->data) + DELETE(shd->data); + } + shd->data = (char *)d; + shd->len = +#ifdef QT_Q3GARRAY_SPEED_OPTIM + shd->maxl = +#endif + len; + return *this; +} + +/*! + Deep copy. Dereference the current array and obtains a copy of the data + contained in \a a instead. Returns a reference to this array. + \sa assign(), operator=() +*/ + +Q3GArray &Q3GArray::duplicate(const Q3GArray &a) +{ + if (a.shd == shd) { // a.duplicate(a) ! + if (shd->count > 1) { + shd->count--; + register array_data *n = newData(); + Q_CHECK_PTR(n); + if ((n->len=shd->len)) { + n->data = NEW(char,n->len); + Q_CHECK_PTR(n->data); + if (n->data) + memcpy(n->data, shd->data, n->len); + } else { + n->data = 0; + } + shd = n; + } + return *this; + } + char *oldptr = 0; + if (shd->count > 1) { // disconnect this + shd->count--; + shd = newData(); + Q_CHECK_PTR(shd); + } else { // delete after copy was made + oldptr = shd->data; + } + if (a.shd->len) { // duplicate data + shd->data = NEW(char,a.shd->len); + Q_CHECK_PTR(shd->data); + if (shd->data) + memcpy(shd->data, a.shd->data, a.shd->len); + } else { + shd->data = 0; + } + shd->len = +#ifdef QT_Q3GARRAY_SPEED_OPTIM + shd->maxl = +#endif + a.shd->len; + if (oldptr) + DELETE(oldptr); + return *this; +} + +/*! + \overload + Deep copy. Dereferences the current array and obtains a copy of + \a len characters from array data \a d instead. Returns a reference + to this array. + \sa assign(), operator=() +*/ + +Q3GArray &Q3GArray::duplicate(const char *d, uint len) +{ + char *data; + if (d == 0 || len == 0) { + data = 0; + len = 0; + } else { + if (shd->count == 1 && shd->len == len) { + if (shd->data != d) // avoid self-assignment + memcpy(shd->data, d, len); // use same buffer + return *this; + } + data = NEW(char,len); + Q_CHECK_PTR(data); + memcpy(data, d, len); + } + if (shd->count > 1) { // detach + shd->count--; + shd = newData(); + Q_CHECK_PTR(shd); + } else { // just a single reference + if (shd->data) + DELETE(shd->data); + } + shd->data = data; + shd->len = +#ifdef QT_Q3GARRAY_SPEED_OPTIM + shd->maxl = +#endif + len; + return *this; +} + +/*! + Resizes this array to \a len bytes and copies the \a len bytes at + address \a d into it. + + \warning This function disregards the reference count mechanism. If + other Q3GArrays reference the same data as this, all will be updated. +*/ + +void Q3GArray::store(const char *d, uint len) +{ // store, but not deref + resize(len); + memcpy(shd->data, d, len); +} + + +/*! + \fn array_data *Q3GArray::sharedBlock() const + + Returns a pointer to the shared array block. + + \warning + + Do not use this function. Using it is begging for trouble. We dare + not remove it, for fear of breaking code, but we \e strongly + discourage new use of it. +*/ + +/*! + \fn void Q3GArray::setSharedBlock(array_data *p) + + Sets the shared array block to \a p. + + \warning + + Do not use this function. Using it is begging for trouble. We dare + not remove it, for fear of breaking code, but we \e strongly + discourage new use of it. +*/ + + +/*! + Sets raw data and returns a reference to the array. + + Dereferences the current array and sets the new array data to \a d and + the new array size to \a len. Do not attempt to resize or re-assign the + array data when raw data has been set. + Call resetRawData(d,len) to reset the array. + + Setting raw data is useful because it sets QMemArray data without + allocating memory or copying data. + + Example of intended use: + \snippet doc/src/snippets/code/src_qt3support_tools_q3garray.cpp 0 + + Example of misuse (do not do this): + \snippet doc/src/snippets/code/src_qt3support_tools_q3garray.cpp 1 + + \warning If you do not call resetRawData(), Q3GArray will attempt to + deallocate or reallocate the raw data, which might not be too good. + Be careful. +*/ + +Q3GArray &Q3GArray::setRawData(const char *d, uint len) +{ + duplicate(0, 0); // set null data + shd->data = (char *)d; + shd->len = len; + return *this; +} + +/*! + Resets raw data. + + The arguments must be the data, \a d, and length \a len, that were + passed to setRawData(). This is for consistency checking. +*/ + +void Q3GArray::resetRawData(const char *d, uint len) +{ + if (d != shd->data || len != shd->len) { +#if defined(QT_CHECK_STATE) + qWarning("Q3GArray::resetRawData: Inconsistent arguments"); +#endif + return; + } + shd->data = 0; + shd->len = 0; +} + + +/*! + Finds the first occurrence of \a d in the array from position \a index, + where \a sz is the size of the \a d element. + + Note that \a index is given in units of \a sz, not bytes. + + This function only compares whole cells, not bytes. +*/ + +int Q3GArray::find(const char *d, uint index, uint sz) const +{ + index *= sz; + if (index >= shd->len) { +#if defined(QT_CHECK_RANGE) + qWarning("Q3GArray::find: Index %d out of range", index/sz); +#endif + return -1; + } + register uint i; + uint ii; + switch (sz) { + case 1: { // 8 bit elements + register char *x = data() + index; + char v = *d; + for (i=index; i<shd->len; i++) { + if (*x++ == v) + break; + } + ii = i; + } + break; + case 2: { // 16 bit elements + register Q_INT16 *x = (Q_INT16*)(data() + index); + Q_INT16 v = *((Q_INT16*)d); + for (i=index; i<shd->len; i+=2) { + if (*x++ == v) + break; + } + ii = i/2; + } + break; + case 4: { // 32 bit elements + register Q_INT32 *x = (Q_INT32*)(data() + index); + Q_INT32 v = *((Q_INT32*)d); + for (i=index; i<shd->len; i+=4) { + if (*x++ == v) + break; + } + ii = i/4; + } + break; + default: { // any size elements + for (i=index; i<shd->len; i+=sz) { + if (memcmp(d, &shd->data[i], sz) == 0) + break; + } + ii = i/sz; + } + break; + } + return i<shd->len ? (int)ii : -1; +} + +/*! + Returns the number of occurrences of \a d in the array, where \a sz is + the size of the \a d element. + + This function only compares whole cells, not bytes. +*/ + +int Q3GArray::contains(const char *d, uint sz) const +{ + register uint i = shd->len; + int count = 0; + switch (sz) { + case 1: { // 8 bit elements + register char *x = data(); + char v = *d; + while (i--) { + if (*x++ == v) + count++; + } + } + break; + case 2: { // 16 bit elements + register Q_INT16 *x = (Q_INT16*)data(); + Q_INT16 v = *((Q_INT16*)d); + i /= 2; + while (i--) { + if (*x++ == v) + count++; + } + } + break; + case 4: { // 32 bit elements + register Q_INT32 *x = (Q_INT32*)data(); + Q_INT32 v = *((Q_INT32*)d); + i /= 4; + while (i--) { + if (*x++ == v) + count++; + } + } + break; + default: { // any size elements + for (i=0; i<shd->len; i+=sz) { + if (memcmp(d, &shd->data[i], sz) == 0) + count++; + } + } + break; + } + return count; +} + +static int cmp_item_size = 0; + +#if defined(Q_C_CALLBACKS) +extern "C" { +#endif + +#ifdef Q_OS_WINCE +static int __cdecl cmp_arr(const void *n1, const void *n2) +#else +static int cmp_arr(const void *n1, const void *n2) +#endif +{ + return (n1 && n2) ? memcmp(n1, n2, cmp_item_size) + : (n1 ? 1 : (n2 ? -1 : 0)); + // ### Qt 3.0: Add a virtual compareItems() method and call that instead +} + +#if defined(Q_C_CALLBACKS) +} +#endif + +/*! + Sorts the first \a sz items of the array. +*/ + +void Q3GArray::sort(uint sz) +{ + int numItems = size() / sz; + if (numItems < 2) + return; + +#ifndef QT_NO_THREAD + QMutexLocker locker(QMutexPool::globalInstanceGet(&cmp_item_size)); +#endif + + cmp_item_size = sz; + qsort(shd->data, numItems, sz, cmp_arr); +} + +/*! + Binary search; assumes that \a d is a sorted array of size \a sz. +*/ + +int Q3GArray::bsearch(const char *d, uint sz) const +{ + int numItems = size() / sz; + if (!numItems) + return -1; + +#ifndef QT_NO_THREAD + QMutexLocker locker(QMutexPool::globalInstanceGet(&cmp_item_size)); +#endif + + cmp_item_size = sz; + char* r = (char*)::bsearch(d, shd->data, numItems, sz, cmp_arr); + if (!r) + return -1; + while((r >= shd->data + sz) && (cmp_arr(r - sz, d) == 0)) + r -= sz; // search to first of equal elements; bsearch is undef + return (int)((r - shd->data) / sz); +} + + +/*! + \fn char *Q3GArray::at(uint index) const + + Returns a pointer to the byte at offset \a index in the array. +*/ + +/*! + Expand the array if necessary, and copies (the first part of) its + contents from the \a index * \a sz bytes at \a d. + + Returns true if the operation succeeds, false if it runs out of + memory. + + \warning This function disregards the reference count mechanism. If + other Q3GArrays reference the same data as this, all will be changed. +*/ + +bool Q3GArray::setExpand(uint index, const char *d, uint sz) +{ + index *= sz; + if (index >= shd->len) { + if (!resize(index+sz)) // no memory + return false; + } + memcpy(data() + index, d, sz); + return true; +} + + +/*! + Prints a warning message if at() or [] is given a bad index. +*/ + +void Q3GArray::msg_index(uint index) +{ +#if defined(QT_CHECK_RANGE) + qWarning("Q3GArray::at: Absolute index %d out of range", index); +#else + Q_UNUSED(index) +#endif +} + + +/*! + Returns a new shared array block. +*/ + +Q3GArray::array_data * Q3GArray::newData() +{ + return new array_data; +} + + +/*! + Deletes the shared array block \a p. +*/ + +void Q3GArray::deleteData(array_data *p) +{ + delete p; +} + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3garray.h b/src/qt3support/tools/q3garray.h new file mode 100644 index 0000000..5b09203 --- /dev/null +++ b/src/qt3support/tools/q3garray.h @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3GARRAY_H +#define Q3GARRAY_H + +#include <Qt3Support/q3shared.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +class Q_COMPAT_EXPORT Q3GArray // generic array +{ + friend class QBuffer; +public: + // do not use this, even though this is public + struct array_data : public Q3Shared { // shared array + array_data():data(0),len(0) +#ifdef QT_QGARRAY_SPEED_OPTIM + ,maxl(0) +#endif + {} + char *data; // actual array data + uint len; +#ifdef QT_QGARRAY_SPEED_OPTIM + uint maxl; +#endif + }; + Q3GArray(); + enum Optimization { MemOptim, SpeedOptim }; +protected: + Q3GArray(int, int); // dummy; does not alloc + Q3GArray(int size); // allocate 'size' bytes + Q3GArray(const Q3GArray &a); // shallow copy + virtual ~Q3GArray(); + + Q3GArray &operator=(const Q3GArray &a) { return assign(a); } + + virtual void detach() { duplicate(*this); } + + // ### Qt 4.0: maybe provide two versions of data(), at(), etc. + char *data() const { return shd->data; } + uint nrefs() const { return shd->count; } + uint size() const { return shd->len; } + bool isEqual(const Q3GArray &a) const; + + bool resize(uint newsize, Optimization optim); + bool resize(uint newsize); + + bool fill(const char *d, int len, uint sz); + + Q3GArray &assign(const Q3GArray &a); + Q3GArray &assign(const char *d, uint len); + Q3GArray &duplicate(const Q3GArray &a); + Q3GArray &duplicate(const char *d, uint len); + void store(const char *d, uint len); + + array_data *sharedBlock() const { return shd; } + void setSharedBlock(array_data *p) { shd=(array_data*)p; } + + Q3GArray &setRawData(const char *d, uint len); + void resetRawData(const char *d, uint len); + + int find(const char *d, uint index, uint sz) const; + int contains(const char *d, uint sz) const; + + void sort(uint sz); + int bsearch(const char *d, uint sz) const; + + char *at(uint index) const; + + bool setExpand(uint index, const char *d, uint sz); + +protected: + virtual array_data *newData(); + virtual void deleteData(array_data *p); + +private: + static void msg_index(uint); + array_data *shd; +}; + + +inline char *Q3GArray::at(uint index) const +{ +#if defined(QT_CHECK_RANGE) + if (index >= size()) { + msg_index(index); + index = 0; + } +#endif + return &shd->data[index]; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3GARRAY_H diff --git a/src/qt3support/tools/q3gcache.cpp b/src/qt3support/tools/q3gcache.cpp new file mode 100644 index 0000000..446bc42 --- /dev/null +++ b/src/qt3support/tools/q3gcache.cpp @@ -0,0 +1,867 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3gcache.h" +#include "q3ptrlist.h" +#include "q3dict.h" +#include "qstring.h" + +QT_BEGIN_NAMESPACE + +/*! + \class Q3GCache + \reentrant + \brief The Q3GCache class is an internal class for implementing Q3Cache + template classes. + + \internal + + Q3GCache is a strictly internal class that acts as a base class for the + \link collection.html collection classes\endlink Q3Cache and QIntCache. +*/ + + +/***************************************************************************** + Q3GCacheItem class (internal cache item) + *****************************************************************************/ + +struct Q3CacheItem +{ + Q3CacheItem(void *k, Q3PtrCollection::Item d, int c, short p) + : priority(p), skipPriority(p), cost(c), key(k), data(d), node(0) {} + short priority; + short skipPriority; + int cost; + void *key; + Q3PtrCollection::Item data; + Q3LNode *node; +}; + + +/***************************************************************************** + Q3CList class (internal list of cache items) + *****************************************************************************/ + +class Q3CList : private Q3PtrList<Q3CacheItem> +{ +friend class Q3GCacheIterator; +friend class Q3CListIt; +public: + Q3CList() {} + ~Q3CList(); + + void insert(Q3CacheItem *); // insert according to priority + void insert(int, Q3CacheItem *); + void take(Q3CacheItem *); + void reference(Q3CacheItem *); + + void setAutoDelete(bool del) { Q3PtrCollection::setAutoDelete(del); } + + bool removeFirst() { return Q3PtrList<Q3CacheItem>::removeFirst(); } + bool removeLast() { return Q3PtrList<Q3CacheItem>::removeLast(); } + + Q3CacheItem *first() { return Q3PtrList<Q3CacheItem>::first(); } + Q3CacheItem *last() { return Q3PtrList<Q3CacheItem>::last(); } + Q3CacheItem *prev() { return Q3PtrList<Q3CacheItem>::prev(); } + Q3CacheItem *next() { return Q3PtrList<Q3CacheItem>::next(); } + +#if defined(QT_DEBUG) + int inserts; // variables for statistics + int insertCosts; + int insertMisses; + int finds; + int hits; + int hitCosts; + int dumps; + int dumpCosts; +#endif +}; + + +Q3CList::~Q3CList() +{ +#if defined(QT_DEBUG) + Q_ASSERT(count() == 0); +#endif +} + + +void Q3CList::insert(Q3CacheItem *ci) +{ + Q3CacheItem *item = first(); + while(item && item->skipPriority > ci->priority) { + item->skipPriority--; + item = next(); + } + if (item) + Q3PtrList<Q3CacheItem>::insert(at(), ci); + else + append(ci); +#if defined(QT_DEBUG) + Q_ASSERT(ci->node == 0); +#endif + ci->node = currentNode(); +} + +inline void Q3CList::insert(int i, Q3CacheItem *ci) +{ + Q3PtrList<Q3CacheItem>::insert(i, ci); +#if defined(QT_DEBUG) + Q_ASSERT(ci->node == 0); +#endif + ci->node = currentNode(); +} + + +void Q3CList::take(Q3CacheItem *ci) +{ + if (ci) { +#if defined(QT_DEBUG) + Q_ASSERT(ci->node != 0); +#endif + takeNode(ci->node); + ci->node = 0; + } +} + + +inline void Q3CList::reference(Q3CacheItem *ci) +{ +#if defined(QT_DEBUG) + Q_ASSERT(ci != 0 && ci->node != 0); +#endif + ci->skipPriority = ci->priority; + relinkNode(ci->node); // relink as first item +} + + +class Q3CListIt: public Q3PtrListIterator<Q3CacheItem> +{ +public: + Q3CListIt(const Q3CList *p): Q3PtrListIterator<Q3CacheItem>(*p) {} + Q3CListIt(const Q3CListIt *p): Q3PtrListIterator<Q3CacheItem>(*p) {} +}; + + +/***************************************************************************** + Q3CDict class (internal dictionary of cache items) + *****************************************************************************/ + +// +// Since we need to decide if the dictionary should use an int or const +// char * key (the "bool trivial" argument in the constructor below) +// we cannot use the macro/template dict, but inherit directly from Q3GDict. +// + +class Q3CDict : public Q3GDict +{ +public: + Q3CDict(uint size, uint kt, bool caseSensitive, bool copyKeys) + : Q3GDict(size, (KeyType)kt, caseSensitive, copyKeys) {} + ~Q3CDict(); + + void clear() { Q3GDict::clear(); } + + Q3CacheItem *find_string(const QString &key) const + { return (Q3CacheItem*)((Q3CDict*)this)->look_string(key, 0, 0); } + Q3CacheItem *find_ascii(const char *key) const + { return (Q3CacheItem*)((Q3CDict*)this)->look_ascii(key, 0, 0); } + Q3CacheItem *find_int(long key) const + { return (Q3CacheItem*)((Q3CDict*)this)->look_int(key, 0, 0); } + + Q3CacheItem *take_string(const QString &key) + { return (Q3CacheItem*)Q3GDict::take_string(key); } + Q3CacheItem *take_ascii(const char *key) + { return (Q3CacheItem*)Q3GDict::take_ascii(key); } + Q3CacheItem *take_int(long key) + { return (Q3CacheItem*)Q3GDict::take_int(key); } + + bool insert_string(const QString &key, const Q3CacheItem *ci) + { return Q3GDict::look_string(key,(Item)ci,1)!=0;} + bool insert_ascii(const char *key, const Q3CacheItem *ci) + { return Q3GDict::look_ascii(key,(Item)ci,1)!=0;} + bool insert_int(long key, const Q3CacheItem *ci) + { return Q3GDict::look_int(key,(Item)ci,1)!=0;} + + bool remove_string(Q3CacheItem *item) + { return Q3GDict::remove_string(*((QString*)(item->key)),item); } + bool remove_ascii(Q3CacheItem *item) + { return Q3GDict::remove_ascii((const char *)item->key,item); } + bool remove_int(Q3CacheItem *item) + { return Q3GDict::remove_int((long)item->key,item);} + + void statistics() { Q3GDict::statistics(); } + +private: + void deleteItem(void *item) + { if (del_item) { Q3CacheItem *d = (Q3CacheItem*)item; delete d; } } +}; + +inline Q3CDict::~Q3CDict() +{ + clear(); +} + +/***************************************************************************** + Q3GDict member functions + *****************************************************************************/ + +/*! + Constructs a cache. + The maximum cost of the cache is given by \a maxCost and the size by \a + size. The key type is \a kt which may be \c StringKey, \c AsciiKey, + \c IntKey or \c PtrKey. The case-sensitivity of lookups is set with + \a caseSensitive. Keys are copied if \a copyKeys is true. +*/ + +Q3GCache::Q3GCache(int maxCost, uint size, KeyType kt, bool caseSensitive, + bool copyKeys) +{ + keytype = kt; + lruList = new Q3CList; + Q_CHECK_PTR(lruList); + lruList->setAutoDelete(true); + copyk = ((keytype == AsciiKey) && copyKeys); + dict = new Q3CDict(size, kt, caseSensitive, false); + Q_CHECK_PTR(dict); + mCost = maxCost; + tCost = 0; +#if defined(QT_DEBUG) + lruList->inserts = 0; + lruList->insertCosts = 0; + lruList->insertMisses = 0; + lruList->finds = 0; + lruList->hits = 0; + lruList->hitCosts = 0; + lruList->dumps = 0; + lruList->dumpCosts = 0; +#endif +} + +/*! + Cannot copy a cache. +*/ + +Q3GCache::Q3GCache(const Q3GCache &) + : Q3PtrCollection() +{ +#if defined(QT_CHECK_NULL) + qFatal("Q3GCache::Q3GCache(Q3GCache &): Cannot copy a cache"); +#endif +} + +/*! + Removes all items from the cache and destroys it. +*/ + +Q3GCache::~Q3GCache() +{ + clear(); + delete dict; + delete lruList; +} + +/*! + Cannot assign a cache. +*/ + +Q3GCache &Q3GCache::operator=(const Q3GCache &) +{ +#if defined(QT_CHECK_NULL) + qFatal("Q3GCache::operator=: Cannot copy a cache"); +#endif + return *this; +} + + +/*! + Returns the number of items in the cache. +*/ + +uint Q3GCache::count() const +{ + return dict->count(); +} + +/*! + Returns the size of the hash array. +*/ + +uint Q3GCache::size() const +{ + return dict->size(); +} + +/*! + \fn int Q3GCache::maxCost() const + + Returns the maximum cache cost. +*/ + +/*! + \fn int Q3GCache::totalCost() const + + Returns the total cache cost. +*/ + +/*! + Sets the maximum cache cost to \a maxCost. +*/ + +void Q3GCache::setMaxCost(int maxCost) +{ + if (maxCost < tCost) { + if (!makeRoomFor(tCost - maxCost)) // remove excess cost + return; + } + mCost = maxCost; +} + + +/*! + Inserts an item with data \a data into the cache using key \a key. + The item has cost \a cost and priority \a priority. + + \warning If this function returns false, you must delete \a data + yourself. Additionally, be very careful about using \a data after + calling this function, as any other insertions into the cache, from + anywhere in the application, or within Qt itself, could cause the + data to be discarded from the cache, and the pointer to become + invalid. +*/ + +bool Q3GCache::insert_string(const QString &key, Q3PtrCollection::Item data, + int cost, int priority) +{ + if (tCost + cost > mCost) { + if (!makeRoomFor(tCost + cost - mCost, priority)) { +#if defined(QT_DEBUG) + lruList->insertMisses++; +#endif + return false; + } + } +#if defined(QT_DEBUG) + Q_ASSERT(keytype == StringKey); + lruList->inserts++; + lruList->insertCosts += cost; +#endif + if (priority < -32768) + priority = -32768; + else if (priority > 32767) + priority = 32677; + Q3CacheItem *ci = new Q3CacheItem(new QString(key), newItem(data), + cost, (short)priority); + Q_CHECK_PTR(ci); + lruList->insert(0, ci); + dict->insert_string(key, ci); + tCost += cost; + return true; +} + +bool Q3GCache::insert_other(const char *key, Q3PtrCollection::Item data, + int cost, int priority) +{ + if (tCost + cost > mCost) { + if (!makeRoomFor(tCost + cost - mCost, priority)) { +#if defined(QT_DEBUG) + lruList->insertMisses++; +#endif + return false; + } + } +#if defined(QT_DEBUG) + Q_ASSERT(keytype != StringKey); + lruList->inserts++; + lruList->insertCosts += cost; +#endif + if (keytype == AsciiKey && copyk) + key = qstrdup(key); + if (priority < -32768) + priority = -32768; + else if (priority > 32767) + priority = 32677; + Q3CacheItem *ci = new Q3CacheItem((void*)key, newItem(data), cost, + (short)priority); + Q_CHECK_PTR(ci); + lruList->insert(0, ci); + if (keytype == AsciiKey) + dict->insert_ascii(key, ci); + else + dict->insert_int((long)key, ci); + tCost += cost; + return true; +} + + +/*! + Removes the item with key \a key from the cache. Returns true if the + item was removed; otherwise returns false. +*/ + +bool Q3GCache::remove_string(const QString &key) +{ + Item d = take_string(key); + if (d) + deleteItem(d); + return d != 0; +} + +bool Q3GCache::remove_other(const char *key) +{ + Item d = take_other(key); + if (d) + deleteItem(d); + return d != 0; +} + + +/*! + Takes the item with key \a key out of the cache. The item is not + deleted. If no item has this \a key 0 is returned. +*/ + +Q3PtrCollection::Item Q3GCache::take_string(const QString &key) +{ + Q3CacheItem *ci = dict->take_string(key); // take from dict + Item d; + if (ci) { + d = ci->data; + tCost -= ci->cost; + lruList->take(ci); // take from list + delete (QString*)ci->key; + delete ci; + } else { + d = 0; + } + return d; +} + +/*! + Takes the item with key \a key out of the cache. The item is not + deleted. If no item has this \a key 0 is returned. +*/ + +Q3PtrCollection::Item Q3GCache::take_other(const char *key) +{ + Q3CacheItem *ci; + if (keytype == AsciiKey) + ci = dict->take_ascii(key); + else + ci = dict->take_int((long)key); + Item d; + if (ci) { + d = ci->data; + tCost -= ci->cost; + lruList->take(ci); // take from list + if (copyk) + delete [] (char *)ci->key; + delete ci; + } else { + d = 0; + } + return d; +} + + +/*! + Clears the cache. +*/ + +void Q3GCache::clear() +{ + Q3CacheItem *ci; + while ((ci = lruList->first())) { + switch (keytype) { + case StringKey: + dict->remove_string(ci); + delete (QString*)ci->key; + break; + case AsciiKey: + dict->remove_ascii(ci); + if (copyk) + delete [] (char*)ci->key; + break; + case IntKey: + dict->remove_int(ci); + break; + case PtrKey: // unused + break; + } + deleteItem(ci->data); // delete data + lruList->removeFirst(); // remove from list + } + tCost = 0; +} + + +/*! + Finds an item for \a key in the cache and adds a reference if \a ref is true. +*/ + +Q3PtrCollection::Item Q3GCache::find_string(const QString &key, bool ref) const +{ + Q3CacheItem *ci = dict->find_string(key); +#if defined(QT_DEBUG) + lruList->finds++; +#endif + if (ci) { +#if defined(QT_DEBUG) + lruList->hits++; + lruList->hitCosts += ci->cost; +#endif + if (ref) + lruList->reference(ci); + return ci->data; + } + return 0; +} + + +/*! + Finds an item for \a key in the cache and adds a reference if \a ref is true. +*/ + +Q3PtrCollection::Item Q3GCache::find_other(const char *key, bool ref) const +{ + Q3CacheItem *ci = keytype == AsciiKey ? dict->find_ascii(key) + : dict->find_int((long)key); +#if defined(QT_DEBUG) + lruList->finds++; +#endif + if (ci) { +#if defined(QT_DEBUG) + lruList->hits++; + lruList->hitCosts += ci->cost; +#endif + if (ref) + lruList->reference(ci); + return ci->data; + } + return 0; +} + + +/*! + Allocates cache space for one or more items. +*/ + +bool Q3GCache::makeRoomFor(int cost, int priority) +{ + if (cost > mCost) // cannot make room for more + return false; // than maximum cost + if (priority == -1) + priority = 32767; + register Q3CacheItem *ci = lruList->last(); + int cntCost = 0; + int dumps = 0; // number of items to dump + while (cntCost < cost && ci && ci->skipPriority <= priority) { + cntCost += ci->cost; + ci = lruList->prev(); + dumps++; + } + if (cntCost < cost) // can enough cost be dumped? + return false; // no +#if defined(QT_DEBUG) + Q_ASSERT(dumps > 0); +#endif + while (dumps--) { + ci = lruList->last(); +#if defined(QT_DEBUG) + lruList->dumps++; + lruList->dumpCosts += ci->cost; +#endif + switch (keytype) { + case StringKey: + dict->remove_string(ci); + delete (QString*)ci->key; + break; + case AsciiKey: + dict->remove_ascii(ci); + if (copyk) + delete [] (char *)ci->key; + break; + case IntKey: + dict->remove_int(ci); + break; + case PtrKey: // unused + break; + } + deleteItem(ci->data); // delete data + lruList->removeLast(); // remove from list + } + tCost -= cntCost; + return true; +} + + +/*! + Outputs debug statistics. +*/ + +void Q3GCache::statistics() const +{ +#if defined(QT_DEBUG) + QString line; + line.fill(QLatin1Char('*'), 80); + qDebug("%s", line.ascii()); + qDebug("CACHE STATISTICS:"); + qDebug("cache contains %d item%s, with a total cost of %d", + count(), count() != 1 ? "s" : "", tCost); + qDebug("maximum cost is %d, cache is %d%% full.", + mCost, (200*tCost + mCost) / (mCost*2)); + qDebug("find() has been called %d time%s", + lruList->finds, lruList->finds != 1 ? "s" : ""); + qDebug("%d of these were hits, items found had a total cost of %d.", + lruList->hits,lruList->hitCosts); + qDebug("%d item%s %s been inserted with a total cost of %d.", + lruList->inserts,lruList->inserts != 1 ? "s" : "", + lruList->inserts != 1 ? "have" : "has", lruList->insertCosts); + qDebug("%d item%s %s too large or had too low priority to be inserted.", + lruList->insertMisses, lruList->insertMisses != 1 ? "s" : "", + lruList->insertMisses != 1 ? "were" : "was"); + qDebug("%d item%s %s been thrown away with a total cost of %d.", + lruList->dumps, lruList->dumps != 1 ? "s" : "", + lruList->dumps != 1 ? "have" : "has", lruList->dumpCosts); + qDebug("Statistics from internal dictionary class:"); + dict->statistics(); + qDebug("%s", line.ascii()); +#endif +} + + +/***************************************************************************** + Q3GCacheIterator member functions + *****************************************************************************/ + +/*! + \class Q3GCacheIterator + \reentrant + \brief The Q3GCacheIterator class is an internal class for implementing Q3CacheIterator and + QIntCacheIterator. + + \internal + + Q3GCacheIterator is a strictly internal class that does the heavy work for + Q3CacheIterator and QIntCacheIterator. +*/ + +/*! + Constructs an iterator that operates on the cache \a c. +*/ + +Q3GCacheIterator::Q3GCacheIterator(const Q3GCache &c) +{ + it = new Q3CListIt(c.lruList); +#if defined(QT_DEBUG) + Q_ASSERT(it != 0); +#endif +} + +/*! + Constructs an iterator that operates on the same cache as \a ci. +*/ + +Q3GCacheIterator::Q3GCacheIterator(const Q3GCacheIterator &ci) +{ + it = new Q3CListIt(ci.it); +#if defined(QT_DEBUG) + Q_ASSERT(it != 0); +#endif +} + +/*! + Destroys the iterator. +*/ + +Q3GCacheIterator::~Q3GCacheIterator() +{ + delete it; +} + +/*! + Assigns the iterator \a ci to this cache iterator. +*/ + +Q3GCacheIterator &Q3GCacheIterator::operator=(const Q3GCacheIterator &ci) +{ + *it = *ci.it; + return *this; +} + +/*! + Returns the number of items in the cache. +*/ + +uint Q3GCacheIterator::count() const +{ + return it->count(); +} + +/*! + Returns true if the iterator points to the first item. +*/ + +bool Q3GCacheIterator::atFirst() const +{ + return it->atFirst(); +} + +/*! + Returns true if the iterator points to the last item. +*/ + +bool Q3GCacheIterator::atLast() const +{ + return it->atLast(); +} + +/*! + Sets the list iterator to point to the first item in the cache. +*/ + +Q3PtrCollection::Item Q3GCacheIterator::toFirst() +{ + Q3CacheItem *item = it->toFirst(); + return item ? item->data : 0; +} + +/*! + Sets the list iterator to point to the last item in the cache. +*/ + +Q3PtrCollection::Item Q3GCacheIterator::toLast() +{ + Q3CacheItem *item = it->toLast(); + return item ? item->data : 0; +} + +/*! + Returns the current item. +*/ + +Q3PtrCollection::Item Q3GCacheIterator::get() const +{ + Q3CacheItem *item = it->current(); + return item ? item->data : 0; +} + +/*! + Returns the key of the current item. +*/ + +QString Q3GCacheIterator::getKeyString() const +{ + Q3CacheItem *item = it->current(); + return item ? *((QString*)item->key) : QString(); +} + +/*! + Returns the key of the current item, as a \0-terminated C string. +*/ + +const char *Q3GCacheIterator::getKeyAscii() const +{ + Q3CacheItem *item = it->current(); + return item ? (const char *)item->key : 0; +} + +/*! + Returns the key of the current item, as a long. +*/ + +long Q3GCacheIterator::getKeyInt() const +{ + Q3CacheItem *item = it->current(); + return item ? (long)item->key : 0; +} + +/*! + Moves to the next item (postfix). +*/ + +Q3PtrCollection::Item Q3GCacheIterator::operator()() +{ + Q3CacheItem *item = it->operator()(); + return item ? item->data : 0; +} + +/*! + Moves to the next item (prefix). +*/ + +Q3PtrCollection::Item Q3GCacheIterator::operator++() +{ + Q3CacheItem *item = it->operator++(); + return item ? item->data : 0; +} + +/*! + Moves \a jump positions forward. +*/ + +Q3PtrCollection::Item Q3GCacheIterator::operator+=(uint jump) +{ + Q3CacheItem *item = it->operator+=(jump); + return item ? item->data : 0; +} + +/*! + Moves to the previous item (prefix). +*/ + +Q3PtrCollection::Item Q3GCacheIterator::operator--() +{ + Q3CacheItem *item = it->operator--(); + return item ? item->data : 0; +} + +/*! + Moves \a jump positions backward. +*/ + +Q3PtrCollection::Item Q3GCacheIterator::operator-=(uint jump) +{ + Q3CacheItem *item = it->operator-=(jump); + return item ? item->data : 0; +} + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3gcache.h b/src/qt3support/tools/q3gcache.h new file mode 100644 index 0000000..dcb9822 --- /dev/null +++ b/src/qt3support/tools/q3gcache.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3GCACHE_H +#define Q3GCACHE_H + +#include <Qt3Support/q3ptrcollection.h> +#include <Qt3Support/q3glist.h> +#include <Qt3Support/q3gdict.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +class Q3CList; // internal classes +class Q3CListIt; +class Q3CDict; + +class Q_COMPAT_EXPORT Q3GCache : public Q3PtrCollection // generic LRU cache +{ +friend class Q3GCacheIterator; +protected: + enum KeyType { StringKey, AsciiKey, IntKey, PtrKey }; + // identical to Q3GDict's, but PtrKey is not used at the moment + + Q3GCache(int maxCost, uint size, KeyType kt, bool caseSensitive, + bool copyKeys); + Q3GCache(const Q3GCache &); // not allowed, calls fatal() + ~Q3GCache(); + Q3GCache &operator=(const Q3GCache &); // not allowed, calls fatal() + + uint count() const; + uint size() const; + int maxCost() const { return mCost; } + int totalCost() const { return tCost; } + void setMaxCost(int maxCost); + void clear(); + + bool insert_string(const QString &key, Q3PtrCollection::Item, + int cost, int priority); + bool insert_other(const char *key, Q3PtrCollection::Item, + int cost, int priority); + bool remove_string(const QString &key); + bool remove_other(const char *key); + Q3PtrCollection::Item take_string(const QString &key); + Q3PtrCollection::Item take_other(const char *key); + + Q3PtrCollection::Item find_string(const QString &key, bool ref=true) const; + Q3PtrCollection::Item find_other(const char *key, bool ref=true) const; + + void statistics() const; + +private: + bool makeRoomFor(int cost, int priority = -1); + KeyType keytype; + Q3CList *lruList; + Q3CDict *dict; + int mCost; + int tCost; + bool copyk; +}; + + +class Q_COMPAT_EXPORT Q3GCacheIterator // generic cache iterator +{ +protected: + Q3GCacheIterator(const Q3GCache &); + Q3GCacheIterator(const Q3GCacheIterator &); + ~Q3GCacheIterator(); + Q3GCacheIterator &operator=(const Q3GCacheIterator &); + + uint count() const; + bool atFirst() const; + bool atLast() const; + Q3PtrCollection::Item toFirst(); + Q3PtrCollection::Item toLast(); + + Q3PtrCollection::Item get() const; + QString getKeyString() const; + const char *getKeyAscii() const; + long getKeyInt() const; + + Q3PtrCollection::Item operator()(); + Q3PtrCollection::Item operator++(); + Q3PtrCollection::Item operator+=(uint); + Q3PtrCollection::Item operator--(); + Q3PtrCollection::Item operator-=(uint); + +protected: + Q3CListIt *it; // iterator on cache list +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3GCACHE_H diff --git a/src/qt3support/tools/q3gdict.cpp b/src/qt3support/tools/q3gdict.cpp new file mode 100644 index 0000000..6a21f81 --- /dev/null +++ b/src/qt3support/tools/q3gdict.cpp @@ -0,0 +1,1154 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3gdict.h" +#include "q3ptrlist.h" +#include "qstring.h" +#include "qdatastream.h" +#include <ctype.h> + +QT_BEGIN_NAMESPACE + +/*! + \class Q3GDict + \reentrant + \brief The Q3GDict class is an internal class for implementing QDict template classes. + + \internal + + Q3GDict is a strictly internal class that acts as a base class for the + \link collection.html collection classes\endlink QDict and QIntDict. + + Q3GDict has some virtual functions that can be reimplemented to customize + the subclasses. + \list + \i read() reads a collection/dictionary item from a QDataStream. + \i write() writes a collection/dictionary item to a QDataStream. + \endlist + Normally, you do not have to reimplement any of these functions. +*/ + +static const int op_find = 0; +static const int op_insert = 1; +static const int op_replace = 2; + + +class Q3GDItList : public Q3PtrList<Q3GDictIterator> +{ +public: + Q3GDItList() : Q3PtrList<Q3GDictIterator>() {} + Q3GDItList(const Q3GDItList &list) : Q3PtrList<Q3GDictIterator>(list) {} + ~Q3GDItList() { clear(); } + Q3GDItList &operator=(const Q3GDItList &list) + { return (Q3GDItList&)Q3PtrList<Q3GDictIterator>::operator=(list); } +}; + + +/***************************************************************************** + Default implementation of special and virtual functions + *****************************************************************************/ + +/*! + Returns the hash key for \a key, when key is a string. +*/ + +int Q3GDict::hashKeyString(const QString &key) +{ +#if defined(QT_CHECK_NULL) + if (key.isNull()) + qWarning("Q3GDict::hashKeyString: Invalid null key"); +#endif + int i; + register uint h=0; + uint g; + const QChar *p = key.unicode(); + if (cases) { // case sensitive + for (i=0; i<(int)key.length(); i++) { + h = (h<<4) + p[i].cell(); + if ((g = h & 0xf0000000)) + h ^= g >> 24; + h &= ~g; + } + } else { // case insensitive + for (i=0; i<(int)key.length(); i++) { + h = (h<<4) + p[i].lower().cell(); + if ((g = h & 0xf0000000)) + h ^= g >> 24; + h &= ~g; + } + } + int index = h; + if (index < 0) // adjust index to table size + index = -index; + return index; +} + +/*! + Returns the hash key for \a key, which is a C string. +*/ + +int Q3GDict::hashKeyAscii(const char *key) +{ +#if defined(QT_CHECK_NULL) + if (key == 0) + qWarning("Q3GDict::hashAsciiKey: Invalid null key"); +#endif + register const char *k = key; + register uint h=0; + uint g; + if (cases) { // case sensitive + while (*k) { + h = (h<<4) + *k++; + if ((g = h & 0xf0000000)) + h ^= g >> 24; + h &= ~g; + } + } else { // case insensitive + while (*k) { + h = (h<<4) + tolower((uchar) *k); + if ((g = h & 0xf0000000)) + h ^= g >> 24; + h &= ~g; + k++; + } + } + int index = h; + if (index < 0) // adjust index to table size + index = -index; + return index; +} + +#ifndef QT_NO_DATASTREAM + +/*! + \overload + Reads a collection/dictionary item from the stream \a s and returns a + reference to the stream. + + The default implementation sets \a item to 0. + + \sa write() +*/ + +QDataStream& Q3GDict::read(QDataStream &s, Q3PtrCollection::Item &item) +{ + item = 0; + return s; +} + +/*! + \overload + Writes a collection/dictionary item to the stream \a s and returns a + reference to the stream. + + \sa read() +*/ + +QDataStream& Q3GDict::write(QDataStream &s, Q3PtrCollection::Item) const +{ + return s; +} +#endif //QT_NO_DATASTREAM + +/***************************************************************************** + Q3GDict member functions + *****************************************************************************/ + +/*! + Constructs a dictionary. + + \a len is the initial size of the dictionary. + The key type is \a kt which may be \c StringKey, \c AsciiKey, + \c IntKey or \c PtrKey. The case-sensitivity of lookups is set with + \a caseSensitive. Keys are copied if \a copyKeys is true. +*/ + +Q3GDict::Q3GDict(uint len, KeyType kt, bool caseSensitive, bool copyKeys) +{ + init(len, kt, caseSensitive, copyKeys); +} + + +void Q3GDict::init(uint len, KeyType kt, bool caseSensitive, bool copyKeys) +{ + vlen = len ? len : 17; + vec = new Q3BaseBucket *[ vlen ]; + + Q_CHECK_PTR(vec); + memset((char*)vec, 0, vlen*sizeof(Q3BaseBucket*)); + numItems = 0; + iterators = 0; + // The caseSensitive and copyKey options don't make sense for + // all dict types. + switch ((keytype = (uint)kt)) { + case StringKey: + cases = caseSensitive; + copyk = false; + break; + case AsciiKey: + cases = caseSensitive; + copyk = copyKeys; + break; + default: + cases = false; + copyk = false; + break; + } +} + + +/*! + Constructs a copy of \a dict. +*/ + +Q3GDict::Q3GDict(const Q3GDict & dict) + : Q3PtrCollection(dict) +{ + init(dict.vlen, (KeyType)dict.keytype, dict.cases, dict.copyk); + Q3GDictIterator it(dict); + while (it.get()) { // copy from other dict + switch (keytype) { + case StringKey: + look_string(it.getKeyString(), it.get(), op_insert); + break; + case AsciiKey: + look_ascii(it.getKeyAscii(), it.get(), op_insert); + break; + case IntKey: + look_int(it.getKeyInt(), it.get(), op_insert); + break; + case PtrKey: + look_ptr(it.getKeyPtr(), it.get(), op_insert); + break; + } + ++it; + } +} + + +/*! + Removes all items from the dictionary and destroys it. +*/ + +Q3GDict::~Q3GDict() +{ + clear(); // delete everything + delete [] vec; + if (!iterators) // no iterators for this dict + return; + Q3GDictIterator *i = iterators->first(); + while (i) { // notify all iterators that + i->dict = 0; // this dict is deleted + i = iterators->next(); + } + delete iterators; +} + + +/*! + Assigns \a dict to this dictionary. +*/ + +Q3GDict &Q3GDict::operator=(const Q3GDict &dict) +{ + if (&dict == this) + return *this; + clear(); + Q3GDictIterator it(dict); + while (it.get()) { // copy from other dict + switch (keytype) { + case StringKey: + look_string(it.getKeyString(), it.get(), op_insert); + break; + case AsciiKey: + look_ascii(it.getKeyAscii(), it.get(), op_insert); + break; + case IntKey: + look_int(it.getKeyInt(), it.get(), op_insert); + break; + case PtrKey: + look_ptr(it.getKeyPtr(), it.get(), op_insert); + break; + } + ++it; + } + return *this; +} + +/*! + \fn uint Q3GDict::count() const + + Returns the number of items in the dictionary. +*/ + +/*! + \fn uint Q3GDict::size() const + + Returns the size of the hash array. +*/ + +/*! + The do-it-all function; \a op is one of op_find, op_insert, op_replace. + The key is \a key and the item is \a d. +*/ + +Q3PtrCollection::Item Q3GDict::look_string(const QString &key, Q3PtrCollection::Item d, + int op) +{ + Q3StringBucket *n = 0; + int index = hashKeyString(key) % vlen; + if (op == op_find) { // find + if (cases) { + n = (Q3StringBucket*)vec[index]; + while(n != 0) { + if (key == n->getKey()) + return n->getData(); // item found + n = (Q3StringBucket*)n->getNext(); + } + } else { + QString k = key.lower(); + n = (Q3StringBucket*)vec[index]; + while(n != 0) { + if (k == n->getKey().lower()) + return n->getData(); // item found + n = (Q3StringBucket*)n->getNext(); + } + } + return 0; // not found + } + if (op == op_replace) { // replace + if (vec[index] != 0) // maybe something there + remove_string(key); + } + // op_insert or op_replace + n = new Q3StringBucket(key,newItem(d),vec[index]); + Q_CHECK_PTR(n); +#if defined(QT_CHECK_NULL) + if (n->getData() == 0) + qWarning("QDict: Cannot insert null item"); +#endif + vec[index] = n; + numItems++; + return n->getData(); +} + +Q3PtrCollection::Item Q3GDict::look_ascii(const char *key, Q3PtrCollection::Item d, int op) +{ + Q3AsciiBucket *n; + int index = hashKeyAscii(key) % vlen; + if (op == op_find) { // find + if (cases) { + for (n=(Q3AsciiBucket*)vec[index]; n; + n=(Q3AsciiBucket*)n->getNext()) { + if (qstrcmp(n->getKey(),key) == 0) + return n->getData(); // item found + } + } else { + for (n=(Q3AsciiBucket*)vec[index]; n; + n=(Q3AsciiBucket*)n->getNext()) { + if (qstricmp(n->getKey(),key) == 0) + return n->getData(); // item found + } + } + return 0; // not found + } + if (op == op_replace) { // replace + if (vec[index] != 0) // maybe something there + remove_ascii(key); + } + // op_insert or op_replace + n = new Q3AsciiBucket(copyk ? qstrdup(key) : key,newItem(d),vec[index]); + Q_CHECK_PTR(n); +#if defined(QT_CHECK_NULL) + if (n->getData() == 0) + qWarning("QAsciiDict: Cannot insert null item"); +#endif + vec[index] = n; + numItems++; + return n->getData(); +} + +Q3PtrCollection::Item Q3GDict::look_int(long key, Q3PtrCollection::Item d, int op) +{ + Q3IntBucket *n; + int index = (int)((ulong)key % vlen); // simple hash + if (op == op_find) { // find + for (n=(Q3IntBucket*)vec[index]; n; + n=(Q3IntBucket*)n->getNext()) { + if (n->getKey() == key) + return n->getData(); // item found + } + return 0; // not found + } + if (op == op_replace) { // replace + if (vec[index] != 0) // maybe something there + remove_int(key); + } + // op_insert or op_replace + n = new Q3IntBucket(key,newItem(d),vec[index]); + Q_CHECK_PTR(n); +#if defined(QT_CHECK_NULL) + if (n->getData() == 0) + qWarning("QIntDict: Cannot insert null item"); +#endif + vec[index] = n; + numItems++; + return n->getData(); +} + +Q3PtrCollection::Item Q3GDict::look_ptr(void *key, Q3PtrCollection::Item d, int op) +{ + Q3PtrBucket *n; + int index = (int)((ulong)key % vlen); // simple hash + if (op == op_find) { // find + for (n=(Q3PtrBucket*)vec[index]; n; + n=(Q3PtrBucket*)n->getNext()) { + if (n->getKey() == key) + return n->getData(); // item found + } + return 0; // not found + } + if (op == op_replace) { // replace + if (vec[index] != 0) // maybe something there + remove_ptr(key); + } + // op_insert or op_replace + n = new Q3PtrBucket(key,newItem(d),vec[index]); + Q_CHECK_PTR(n); +#if defined(QT_CHECK_NULL) + if (n->getData() == 0) + qWarning("Q3PtrDict: Cannot insert null item"); +#endif + vec[index] = n; + numItems++; + return n->getData(); +} + + +/*! + Changes the size of the hashtable to \a newsize. + The contents of the dictionary are preserved, + but all iterators on the dictionary become invalid. +*/ +void Q3GDict::resize(uint newsize) +{ + // Save old information + Q3BaseBucket **old_vec = vec; + uint old_vlen = vlen; + bool old_copyk = copyk; + + vec = new Q3BaseBucket *[vlen = newsize]; + Q_CHECK_PTR(vec); + memset((char*)vec, 0, vlen*sizeof(Q3BaseBucket*)); + numItems = 0; + copyk = false; + + // Reinsert every item from vec, deleting vec as we go + for (uint index = 0; index < old_vlen; index++) { + switch (keytype) { + case StringKey: + { + Q3StringBucket *n=(Q3StringBucket *)old_vec[index]; + while (n) { + look_string(n->getKey(), n->getData(), op_insert); + Q3StringBucket *t=(Q3StringBucket *)n->getNext(); + delete n; + n = t; + } + } + break; + case AsciiKey: + { + Q3AsciiBucket *n=(Q3AsciiBucket *)old_vec[index]; + while (n) { + look_ascii(n->getKey(), n->getData(), op_insert); + Q3AsciiBucket *t=(Q3AsciiBucket *)n->getNext(); + delete n; + n = t; + } + } + break; + case IntKey: + { + Q3IntBucket *n=(Q3IntBucket *)old_vec[index]; + while (n) { + look_int(n->getKey(), n->getData(), op_insert); + Q3IntBucket *t=(Q3IntBucket *)n->getNext(); + delete n; + n = t; + } + } + break; + case PtrKey: + { + Q3PtrBucket *n=(Q3PtrBucket *)old_vec[index]; + while (n) { + look_ptr(n->getKey(), n->getData(), op_insert); + Q3PtrBucket *t=(Q3PtrBucket *)n->getNext(); + delete n; + n = t; + } + } + break; + } + } + delete [] old_vec; + + // Restore state + copyk = old_copyk; + + // Invalidate all iterators, since order is lost + if (iterators && iterators->count()) { + Q3GDictIterator *i = iterators->first(); + while (i) { + i->toFirst(); + i = iterators->next(); + } + } +} + +/*! + Unlinks the bucket with the specified key (and specified data pointer, + if it is set). +*/ + +void Q3GDict::unlink_common(int index, Q3BaseBucket *node, Q3BaseBucket *prev) +{ + if (iterators && iterators->count()) { // update iterators + Q3GDictIterator *i = iterators->first(); + while (i) { // invalidate all iterators + if (i->curNode == node) // referring to pending node + i->operator++(); + i = iterators->next(); + } + } + if (prev) // unlink node + prev->setNext(node->getNext()); + else + vec[index] = node->getNext(); + numItems--; +} + +Q3StringBucket *Q3GDict::unlink_string(const QString &key, Q3PtrCollection::Item d) +{ + if (numItems == 0) // nothing in dictionary + return 0; + Q3StringBucket *n; + Q3StringBucket *prev = 0; + int index = hashKeyString(key) % vlen; + if (cases) { + for (n=(Q3StringBucket*)vec[index]; n; + n=(Q3StringBucket*)n->getNext()) { + bool found = (key == n->getKey()); + if (found && d) + found = (n->getData() == d); + if (found) { + unlink_common(index,n,prev); + return n; + } + prev = n; + } + } else { + QString k = key.lower(); + for (n=(Q3StringBucket*)vec[index]; n; + n=(Q3StringBucket*)n->getNext()) { + bool found = (k == n->getKey().lower()); + if (found && d) + found = (n->getData() == d); + if (found) { + unlink_common(index,n,prev); + return n; + } + prev = n; + } + } + return 0; +} + +Q3AsciiBucket *Q3GDict::unlink_ascii(const char *key, Q3PtrCollection::Item d) +{ + if (numItems == 0) // nothing in dictionary + return 0; + Q3AsciiBucket *n; + Q3AsciiBucket *prev = 0; + int index = hashKeyAscii(key) % vlen; + for (n=(Q3AsciiBucket *)vec[index]; n; n=(Q3AsciiBucket *)n->getNext()) { + bool found = (cases ? qstrcmp(n->getKey(),key) + : qstricmp(n->getKey(),key)) == 0; + if (found && d) + found = (n->getData() == d); + if (found) { + unlink_common(index,n,prev); + return n; + } + prev = n; + } + return 0; +} + +Q3IntBucket *Q3GDict::unlink_int(long key, Q3PtrCollection::Item d) +{ + if (numItems == 0) // nothing in dictionary + return 0; + Q3IntBucket *n; + Q3IntBucket *prev = 0; + int index = (int)((ulong)key % vlen); + for (n=(Q3IntBucket *)vec[index]; n; n=(Q3IntBucket *)n->getNext()) { + bool found = (n->getKey() == key); + if (found && d) + found = (n->getData() == d); + if (found) { + unlink_common(index,n,prev); + return n; + } + prev = n; + } + return 0; +} + +Q3PtrBucket *Q3GDict::unlink_ptr(void *key, Q3PtrCollection::Item d) +{ + if (numItems == 0) // nothing in dictionary + return 0; + Q3PtrBucket *n; + Q3PtrBucket *prev = 0; + int index = (int)((ulong)key % vlen); + for (n=(Q3PtrBucket *)vec[index]; n; n=(Q3PtrBucket *)n->getNext()) { + bool found = (n->getKey() == key); + if (found && d) + found = (n->getData() == d); + if (found) { + unlink_common(index,n,prev); + return n; + } + prev = n; + } + return 0; +} + + +/*! + Removes the item with the specified \a key. If \a item is not null, + the remove will match the \a item as well (used to remove an + item when several items have the same key). +*/ + +bool Q3GDict::remove_string(const QString &key, Q3PtrCollection::Item item) +{ + Q3StringBucket *n = unlink_string(key, item); + if (n) { + deleteItem(n->getData()); + delete n; + return true; + } else { + return false; + } +} + +bool Q3GDict::remove_ascii(const char *key, Q3PtrCollection::Item item) +{ + Q3AsciiBucket *n = unlink_ascii(key, item); + if (n) { + if (copyk) + delete [] (char *)n->getKey(); + deleteItem(n->getData()); + delete n; + } + return n != 0; +} + +bool Q3GDict::remove_int(long key, Q3PtrCollection::Item item) +{ + Q3IntBucket *n = unlink_int(key, item); + if (n) { + deleteItem(n->getData()); + delete n; + } + return n != 0; +} + +bool Q3GDict::remove_ptr(void *key, Q3PtrCollection::Item item) +{ + Q3PtrBucket *n = unlink_ptr(key, item); + if (n) { + deleteItem(n->getData()); + delete n; + } + return n != 0; +} + +Q3PtrCollection::Item Q3GDict::take_string(const QString &key) +{ + Q3StringBucket *n = unlink_string(key); + Item d; + if (n) { + d = n->getData(); + delete n; + } else { + d = 0; + } + return d; +} + +Q3PtrCollection::Item Q3GDict::take_ascii(const char *key) +{ + Q3AsciiBucket *n = unlink_ascii(key); + Item d; + if (n) { + if (copyk) + delete [] (char *)n->getKey(); + d = n->getData(); + delete n; + } else { + d = 0; + } + return d; +} + +Q3PtrCollection::Item Q3GDict::take_int(long key) +{ + Q3IntBucket *n = unlink_int(key); + Item d; + if (n) { + d = n->getData(); + delete n; + } else { + d = 0; + } + return d; +} + +Q3PtrCollection::Item Q3GDict::take_ptr(void *key) +{ + Q3PtrBucket *n = unlink_ptr(key); + Item d; + if (n) { + d = n->getData(); + delete n; + } else { + d = 0; + } + return d; +} + +/*! + Removes all items from the dictionary. +*/ +void Q3GDict::clear() +{ + if (!numItems) + return; + numItems = 0; // disable remove() function + for (uint j=0; j<vlen; j++) { // destroy hash table + if (vec[j]) { + switch (keytype) { + case StringKey: + { + Q3StringBucket *n=(Q3StringBucket *)vec[j]; + while (n) { + Q3StringBucket *next = (Q3StringBucket*)n->getNext(); + deleteItem(n->getData()); + delete n; + n = next; + } + } + break; + case AsciiKey: + { + Q3AsciiBucket *n=(Q3AsciiBucket *)vec[j]; + while (n) { + Q3AsciiBucket *next = (Q3AsciiBucket*)n->getNext(); + if (copyk) + delete [] (char *)n->getKey(); + deleteItem(n->getData()); + delete n; + n = next; + } + } + break; + case IntKey: + { + Q3IntBucket *n=(Q3IntBucket *)vec[j]; + while (n) { + Q3IntBucket *next = (Q3IntBucket*)n->getNext(); + deleteItem(n->getData()); + delete n; + n = next; + } + } + break; + case PtrKey: + { + Q3PtrBucket *n=(Q3PtrBucket *)vec[j]; + while (n) { + Q3PtrBucket *next = (Q3PtrBucket*)n->getNext(); + deleteItem(n->getData()); + delete n; + n = next; + } + } + break; + } + vec[j] = 0; // detach list of buckets + } + } + if (iterators && iterators->count()) { // invalidate all iterators + Q3GDictIterator *i = iterators->first(); + while (i) { + i->curNode = 0; + i = iterators->next(); + } + } +} + +/*! + Outputs debug statistics. +*/ +void Q3GDict::statistics() const +{ +#if defined(QT_DEBUG) + QString line; + line.fill(QLatin1Char('-'), 60); + double real, ideal; + qDebug("%s", line.ascii()); + qDebug("DICTIONARY STATISTICS:"); + if (count() == 0) { + qDebug("Empty!"); + qDebug("%s", line.ascii()); + return; + } + real = 0.0; + ideal = (float)count()/(2.0*size())*(count()+2.0*size()-1); + uint i = 0; + while (i<size()) { + Q3BaseBucket *n = vec[i]; + int b = 0; + while (n) { // count number of buckets + b++; + n = n->getNext(); + } + real = real + (double)b * ((double)b+1.0)/2.0; + char buf[80], *pbuf; + if (b > 78) + b = 78; + pbuf = buf; + while (b--) + *pbuf++ = '*'; + *pbuf = '\0'; + qDebug("%s", buf); + i++; + } + qDebug("Array size = %d", size()); + qDebug("# items = %d", count()); + qDebug("Real dist = %g", real); + qDebug("Rand dist = %g", ideal); + qDebug("Real/Rand = %g", real/ideal); + qDebug("%s", line.ascii()); +#endif // QT_DEBUG +} + + +/***************************************************************************** + Q3GDict stream functions + *****************************************************************************/ +#ifndef QT_NO_DATASTREAM +QDataStream &operator>>(QDataStream &s, Q3GDict &dict) +{ + return dict.read(s); +} + +QDataStream &operator<<(QDataStream &s, const Q3GDict &dict) +{ + return dict.write(s); +} + +#if defined(Q_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001) +#pragma message disable narrowptr +#endif + +/*! + Reads a dictionary from the stream \a s. +*/ + +QDataStream &Q3GDict::read(QDataStream &s) +{ + uint num; + s >> num; // read number of items + clear(); // clear dict + while (num--) { // read all items + Item d; + switch (keytype) { + case StringKey: + { + QString k; + s >> k; + read(s, d); + look_string(k, d, op_insert); + } + break; + case AsciiKey: + { + char *k; + s >> k; + read(s, d); + look_ascii(k, d, op_insert); + if (copyk) + delete [] k; + } + break; + case IntKey: + { + Q_UINT32 k; + s >> k; + read(s, d); + look_int(k, d, op_insert); + } + break; + case PtrKey: + { + Q_UINT32 k; + s >> k; + read(s, d); + // ### cannot insert 0 - this renders the thing + // useless since all pointers are written as 0, + // but hey, serializing pointers? can it be done + // at all, ever? + if (k) + look_ptr((void *)(ulong)k, d, op_insert); + } + break; + } + } + return s; +} + +/*! + Writes the dictionary to the stream \a s. +*/ + +QDataStream& Q3GDict::write(QDataStream &s) const +{ + s << count(); // write number of items + uint i = 0; + while (i<size()) { + Q3BaseBucket *n = vec[i]; + while (n) { // write all buckets + switch (keytype) { + case StringKey: + s << ((Q3StringBucket*)n)->getKey(); + break; + case AsciiKey: + s << ((Q3AsciiBucket*)n)->getKey(); + break; + case IntKey: + s << (Q_UINT32)((Q3IntBucket*)n)->getKey(); + break; + case PtrKey: + s << (Q_UINT32)0; // ### cannot serialize a pointer + break; + } + write(s, n->getData()); // write data + n = n->getNext(); + } + i++; + } + return s; +} +#endif //QT_NO_DATASTREAM + +/***************************************************************************** + Q3GDictIterator member functions + *****************************************************************************/ + +/*! + \class Q3GDictIterator + \reentrant + \brief The Q3GDictIterator class is an internal class for implementing QDictIterator and QIntDictIterator. + + \internal + + Q3GDictIterator is a strictly internal class that does the heavy work for + QDictIterator and QIntDictIterator. +*/ + +/*! + Constructs an iterator that operates on the dictionary \a d. +*/ + +Q3GDictIterator::Q3GDictIterator(const Q3GDict &d) +{ + dict = (Q3GDict *)&d; // get reference to dict + toFirst(); // set to first noe + if (!dict->iterators) { + dict->iterators = new Q3GDItList; // create iterator list + Q_CHECK_PTR(dict->iterators); + } + dict->iterators->append(this); // attach iterator to dict +} + +/*! + Constructs a copy of the iterator \a it. +*/ + +Q3GDictIterator::Q3GDictIterator(const Q3GDictIterator &it) +{ + dict = it.dict; + curNode = it.curNode; + curIndex = it.curIndex; + if (dict) + dict->iterators->append(this); // attach iterator to dict +} + +/*! + Assigns a copy of the iterator \a it and returns a reference to this + iterator. +*/ + +Q3GDictIterator &Q3GDictIterator::operator=(const Q3GDictIterator &it) +{ + if (dict) // detach from old dict + dict->iterators->removeRef(this); + dict = it.dict; + curNode = it.curNode; + curIndex = it.curIndex; + if (dict) + dict->iterators->append(this); // attach to new list + return *this; +} + +/*! + Destroys the iterator. +*/ + +Q3GDictIterator::~Q3GDictIterator() +{ + if (dict) // detach iterator from dict + dict->iterators->removeRef(this); +} + + +/*! + Sets the iterator to point to the first item in the dictionary. +*/ + +Q3PtrCollection::Item Q3GDictIterator::toFirst() +{ + if (!dict) { +#if defined(QT_CHECK_NULL) + qWarning("Q3GDictIterator::toFirst: Dictionary has been deleted"); +#endif + return 0; + } + if (dict->count() == 0) { // empty dictionary + curNode = 0; + return 0; + } + register uint i = 0; + register Q3BaseBucket **v = dict->vec; + while (!(*v++)) + i++; + curNode = dict->vec[i]; + curIndex = i; + return curNode->getData(); +} + + +/*! + Moves to the next item (postfix). +*/ + +Q3PtrCollection::Item Q3GDictIterator::operator()() +{ + if (!dict) { +#if defined(QT_CHECK_NULL) + qWarning("Q3GDictIterator::operator(): Dictionary has been deleted"); +#endif + return 0; + } + if (!curNode) + return 0; + Q3PtrCollection::Item d = curNode->getData(); + this->operator++(); + return d; +} + +/*! + Moves to the next item (prefix). +*/ + +Q3PtrCollection::Item Q3GDictIterator::operator++() +{ + if (!dict) { +#if defined(QT_CHECK_NULL) + qWarning("Q3GDictIterator::operator++: Dictionary has been deleted"); +#endif + return 0; + } + if (!curNode) + return 0; + curNode = curNode->getNext(); + if (!curNode) { // no next bucket + register uint i = curIndex + 1; // look from next vec element + register Q3BaseBucket **v = &dict->vec[i]; + while (i < dict->size() && !(*v++)) + i++; + if (i == dict->size()) { // nothing found + curNode = 0; + return 0; + } + curNode = dict->vec[i]; + curIndex = i; + } + return curNode->getData(); +} + +/*! + Moves \a jumps positions forward. +*/ + +Q3PtrCollection::Item Q3GDictIterator::operator+=(uint jumps) +{ + while (curNode && jumps--) + operator++(); + return curNode ? curNode->getData() : 0; +} + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3gdict.h b/src/qt3support/tools/q3gdict.h new file mode 100644 index 0000000..079c322 --- /dev/null +++ b/src/qt3support/tools/q3gdict.h @@ -0,0 +1,233 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3GDICT_H +#define Q3GDICT_H + +#include <Qt3Support/q3ptrcollection.h> +#include <QtCore/qstring.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +class Q3GDictIterator; +class Q3GDItList; + + +class Q3BaseBucket // internal dict node +{ +public: + Q3PtrCollection::Item getData() { return data; } + Q3PtrCollection::Item setData( Q3PtrCollection::Item d ) { return data = d; } + Q3BaseBucket *getNext() { return next; } + void setNext( Q3BaseBucket *n) { next = n; } +protected: + Q3BaseBucket( Q3PtrCollection::Item d, Q3BaseBucket *n ) : data(d), next(n) {} + Q3PtrCollection::Item data; + Q3BaseBucket *next; +}; + +class Q3StringBucket : public Q3BaseBucket +{ +public: + Q3StringBucket( const QString &k, Q3PtrCollection::Item d, Q3BaseBucket *n ) + : Q3BaseBucket(d,n), key(k) {} + const QString &getKey() const { return key; } +private: + QString key; +}; + +class Q3AsciiBucket : public Q3BaseBucket +{ +public: + Q3AsciiBucket( const char *k, Q3PtrCollection::Item d, Q3BaseBucket *n ) + : Q3BaseBucket(d,n), key(k) {} + const char *getKey() const { return key; } +private: + const char *key; +}; + +class Q3IntBucket : public Q3BaseBucket +{ +public: + Q3IntBucket( long k, Q3PtrCollection::Item d, Q3BaseBucket *n ) + : Q3BaseBucket(d,n), key(k) {} + long getKey() const { return key; } +private: + long key; +}; + +class Q3PtrBucket : public Q3BaseBucket +{ +public: + Q3PtrBucket( void *k, Q3PtrCollection::Item d, Q3BaseBucket *n ) + : Q3BaseBucket(d,n), key(k) {} + void *getKey() const { return key; } +private: + void *key; +}; + + +class Q_COMPAT_EXPORT Q3GDict : public Q3PtrCollection // generic dictionary class +{ +public: + uint count() const { return numItems; } + uint size() const { return vlen; } + Q3PtrCollection::Item look_string( const QString& key, Q3PtrCollection::Item, + int ); + Q3PtrCollection::Item look_ascii( const char *key, Q3PtrCollection::Item, int ); + Q3PtrCollection::Item look_int( long key, Q3PtrCollection::Item, int ); + Q3PtrCollection::Item look_ptr( void *key, Q3PtrCollection::Item, int ); +#ifndef QT_NO_DATASTREAM + QDataStream &read( QDataStream & ); + QDataStream &write( QDataStream & ) const; +#endif +protected: + enum KeyType { StringKey, AsciiKey, IntKey, PtrKey }; + + Q3GDict( uint len, KeyType kt, bool cs, bool ck ); + Q3GDict( const Q3GDict & ); + ~Q3GDict(); + + Q3GDict &operator=( const Q3GDict & ); + + bool remove_string( const QString &key, Q3PtrCollection::Item item=0 ); + bool remove_ascii( const char *key, Q3PtrCollection::Item item=0 ); + bool remove_int( long key, Q3PtrCollection::Item item=0 ); + bool remove_ptr( void *key, Q3PtrCollection::Item item=0 ); + Q3PtrCollection::Item take_string( const QString &key ); + Q3PtrCollection::Item take_ascii( const char *key ); + Q3PtrCollection::Item take_int( long key ); + Q3PtrCollection::Item take_ptr( void *key ); + + void clear(); + void resize( uint ); + + int hashKeyString( const QString & ); + int hashKeyAscii( const char * ); + + void statistics() const; + +#ifndef QT_NO_DATASTREAM + virtual QDataStream &read( QDataStream &, Q3PtrCollection::Item & ); + virtual QDataStream &write( QDataStream &, Q3PtrCollection::Item ) const; +#endif +private: + Q3BaseBucket **vec; + uint vlen; + uint numItems; + uint keytype : 2; + uint cases : 1; + uint copyk : 1; + Q3GDItList *iterators; + void unlink_common( int, Q3BaseBucket *, Q3BaseBucket * ); + Q3StringBucket *unlink_string( const QString &, + Q3PtrCollection::Item item = 0 ); + Q3AsciiBucket *unlink_ascii( const char *, Q3PtrCollection::Item item = 0 ); + Q3IntBucket *unlink_int( long, Q3PtrCollection::Item item = 0 ); + Q3PtrBucket *unlink_ptr( void *, Q3PtrCollection::Item item = 0 ); + void init( uint, KeyType, bool, bool ); + friend class Q3GDictIterator; +}; + + +class Q_COMPAT_EXPORT Q3GDictIterator // generic dictionary iterator +{ +friend class Q3GDict; +public: + Q3GDictIterator( const Q3GDict & ); + Q3GDictIterator( const Q3GDictIterator & ); + Q3GDictIterator &operator=( const Q3GDictIterator & ); + ~Q3GDictIterator(); + + Q3PtrCollection::Item toFirst(); + + Q3PtrCollection::Item get() const; + QString getKeyString() const; + const char *getKeyAscii() const; + long getKeyInt() const; + void *getKeyPtr() const; + + Q3PtrCollection::Item operator()(); + Q3PtrCollection::Item operator++(); + Q3PtrCollection::Item operator+=(uint); + +protected: + Q3GDict *dict; + +private: + Q3BaseBucket *curNode; + uint curIndex; +}; + +inline Q3PtrCollection::Item Q3GDictIterator::get() const +{ + return curNode ? curNode->getData() : 0; +} + +inline QString Q3GDictIterator::getKeyString() const +{ + return curNode ? ((Q3StringBucket*)curNode)->getKey() : QString(); +} + +inline const char *Q3GDictIterator::getKeyAscii() const +{ + return curNode ? ((Q3AsciiBucket*)curNode)->getKey() : 0; +} + +inline long Q3GDictIterator::getKeyInt() const +{ + return curNode ? ((Q3IntBucket*)curNode)->getKey() : 0; +} + +inline void *Q3GDictIterator::getKeyPtr() const +{ + return curNode ? ((Q3PtrBucket*)curNode)->getKey() : 0; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3GDICT_H diff --git a/src/qt3support/tools/q3glist.cpp b/src/qt3support/tools/q3glist.cpp new file mode 100644 index 0000000..50ff2c9 --- /dev/null +++ b/src/qt3support/tools/q3glist.cpp @@ -0,0 +1,1270 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3glist.h" +#include "q3gvector.h" +#include "qdatastream.h" +#include "q3valuelist.h" + +QT_BEGIN_NAMESPACE + +/*! + \class Q3LNode + \reentrant + \brief The Q3LNode class is an internal class for the Q3PtrList template collection. + + \internal + + Q3LNode is a doubly-linked list node. It has three pointers: + \list 1 + \i Pointer to the previous node. + \i Pointer to the next node. + \i Pointer to the actual data. + \endlist + + It might sometimes be practical to have direct access to the list nodes + in a Q3PtrList, but it is seldom required. + + Be very careful if you want to access the list nodes. The heap can + easily get corrupted if you make a mistake. + + \sa Q3PtrList::currentNode(), Q3PtrList::removeNode(), Q3PtrList::takeNode() +*/ + +/*! + \fn Q3PtrCollection::Item Q3LNode::getData() + Returns a pointer (\c void*) to the actual data in the list node. +*/ + + +/*! + \class Q3GList + \reentrant + \brief The Q3GList class is an internal class for implementing Qt collection classes. + + \internal + + Q3GList is a strictly internal class that acts as a base class for + several collection classes; Q3PtrList, Q3PtrQueue and Q3PtrStack. + + Q3GList has some virtual functions that can be reimplemented to + customize the subclasses, namely compareItems(), read() and + write. Normally, you do not have to reimplement any of these + functions. If you still want to reimplement them, see the QStrList + class (qstrlist.h) for an example. +*/ + + +/* Internal helper class for Q3GList. Contains some optimization for + the typically case where only one iterators is activre on the list. + */ +class Q3GListIteratorList +{ +public: + Q3GListIteratorList() + : list(0), iterator(0) { + } + ~Q3GListIteratorList() { + notifyClear( true ); + delete list; + } + + void add( Q3GListIterator* i ) { + if ( !iterator ) { + iterator = i; + } else if ( list ) { + list->push_front( i ); + } else { + list = new Q3ValueList<Q3GListIterator*>; + list->push_front( i ); + } + } + + void remove( Q3GListIterator* i ) { + if ( iterator == i ) { + iterator = 0; + } else if ( list ) { + list->remove( i ); + if ( list->isEmpty() ) { + delete list; + list = 0; + } + } + } + + void notifyClear( bool zeroList ) { + if ( iterator ) { + if ( zeroList ) + iterator->list = 0; + iterator->curNode = 0; + } + if ( list ) { + for ( Q3ValueList<Q3GListIterator*>::Iterator i = list->begin(); i != list->end(); ++i ) { + if ( zeroList ) + (*i)->list = 0; + (*i)->curNode = 0; + } + } + } + + void notifyRemove( Q3LNode* n, Q3LNode* curNode ) { + if ( iterator ) { + if ( iterator->curNode == n ) + iterator->curNode = curNode; + } + if ( list ) { + for ( Q3ValueList<Q3GListIterator*>::Iterator i = list->begin(); i != list->end(); ++i ) { + if ( (*i)->curNode == n ) + (*i)->curNode = curNode; + } + } + } + +private: + Q3ValueList<Q3GListIterator*>* list; + Q3GListIterator* iterator; +}; + + + +/***************************************************************************** + Default implementation of virtual functions + *****************************************************************************/ + +/*! + Documented as Q3PtrList::compareItems(). + + Compares \a item1 with \a item2. +*/ +int Q3GList::compareItems( Q3PtrCollection::Item item1, Q3PtrCollection::Item item2 ) +{ + return item1 != item2; // compare pointers +} + +#ifndef QT_NO_DATASTREAM +/*! + \overload + Reads a collection/list item from the stream \a s and returns a reference + to the stream. + + The default implementation sets \a item to 0. + + \sa write() +*/ + +QDataStream &Q3GList::read( QDataStream &s, Q3PtrCollection::Item &item ) +{ + item = 0; + return s; +} + +/*! + \overload + Writes a collection/list item to the stream \a s and + returns a reference to the stream. + + The default implementation does nothing. + + \sa read() +*/ + +QDataStream &Q3GList::write( QDataStream &s, Q3PtrCollection::Item ) const +{ + return s; +} +#endif // QT_NO_DATASTREAM + +/***************************************************************************** + Q3GList member functions + *****************************************************************************/ + +/*! + Constructs an empty list. +*/ + +Q3GList::Q3GList() +{ + firstNode = lastNode = curNode = 0; // initialize list + numNodes = 0; + curIndex = -1; + iterators = 0; // initialize iterator list +} + +/*! + Constructs a copy of \a list. +*/ + +Q3GList::Q3GList( const Q3GList & list ) + : Q3PtrCollection( list ) +{ + firstNode = lastNode = curNode = 0; // initialize list + numNodes = 0; + curIndex = -1; + iterators = 0; // initialize iterator list + Q3LNode *n = list.firstNode; + while ( n ) { // copy all items from list + append( n->data ); + n = n->next; + } +} + +/*! + Removes all items from the list and destroys the list. +*/ + +Q3GList::~Q3GList() +{ + clear(); + delete iterators; + // Workaround for GCC 2.7.* bug. Compiler constructs 'static' Q3GList + // instances twice on the same address and therefore tries to destruct + // twice on the same address! This is insane but let's try not to crash + // here. + iterators = 0; +} + + +/*! + Assigns \a list to this list. +*/ + +Q3GList& Q3GList::operator=( const Q3GList &list ) +{ + if ( &list == this ) + return *this; + + clear(); + if ( list.count() > 0 ) { + Q3LNode *n = list.firstNode; + while ( n ) { // copy all items from list + append( n->data ); + n = n->next; + } + curNode = firstNode; + curIndex = 0; + } + return *this; +} + +/*! + Compares this list with \a list. Returns true if the lists + contain the same data, otherwise false. +*/ + +bool Q3GList::operator==( const Q3GList &list ) const +{ + if ( count() != list.count() ) + return false; + + if ( count() == 0 ) + return true; + + Q3LNode *n1 = firstNode; + Q3LNode *n2 = list.firstNode; + while ( n1 && n2 ) { + // should be mutable + if ( ( (Q3GList*)this )->compareItems( n1->data, n2->data ) != 0 ) + return false; + n1 = n1->next; + n2 = n2->next; + } + + return true; +} + +/*! + \fn uint Q3GList::count() const + + Returns the number of items in the list. +*/ + + +/*! + Returns the node at position \a index. Sets this node to current. +*/ + +Q3LNode *Q3GList::locate( uint index ) +{ + if ( index == (uint)curIndex ) // current node ? + return curNode; + if ( !curNode && firstNode ) { // set current node + curNode = firstNode; + curIndex = 0; + } + register Q3LNode *node; + int distance = index - curIndex; // node distance to cur node + bool forward; // direction to traverse + + if ( index >= numNodes ) + return 0; + + if ( distance < 0 ) + distance = -distance; + if ( (uint)distance < index && (uint)distance < numNodes - index ) { + node = curNode; // start from current node + forward = index > (uint)curIndex; + } else if ( index < numNodes - index ) { // start from first node + node = firstNode; + distance = index; + forward = true; + } else { // start from last node + node = lastNode; + distance = numNodes - index - 1; + if ( distance < 0 ) + distance = 0; + forward = false; + } + if ( forward ) { // now run through nodes + while ( distance-- ) + node = node->next; + } else { + while ( distance-- ) + node = node->prev; + } + curIndex = index; // must update index + return curNode = node; +} + + +/*! + Inserts item \a d at its sorted position in the list. +*/ + +void Q3GList::inSort( Q3PtrCollection::Item d ) +{ + int index = 0; + register Q3LNode *n = firstNode; + while ( n && compareItems(n->data,d) < 0 ){ // find position in list + n = n->next; + index++; + } + insertAt( index, d ); +} + + +/*! + Inserts item \a d at the start of the list. +*/ + +void Q3GList::prepend( Q3PtrCollection::Item d ) +{ + register Q3LNode *n = new Q3LNode( newItem(d) ); + Q_CHECK_PTR( n ); + n->prev = 0; + if ( (n->next = firstNode) ) // list is not empty + firstNode->prev = n; + else // initialize list + lastNode = n; + firstNode = curNode = n; // curNode affected + numNodes++; + curIndex = 0; +} + + +/*! + Inserts item \a d at the end of the list. +*/ + +void Q3GList::append( Q3PtrCollection::Item d ) +{ + register Q3LNode *n = new Q3LNode( newItem(d) ); + Q_CHECK_PTR( n ); + n->next = 0; + if ( (n->prev = lastNode) ) // list is not empty + lastNode->next = n; + else // initialize list + firstNode = n; + lastNode = curNode = n; // curNode affected + curIndex = numNodes; + numNodes++; +} + + +/*! + Inserts item \a d at position \a index in the list. +*/ + +bool Q3GList::insertAt( uint index, Q3PtrCollection::Item d ) +{ + if ( index == 0 ) { + prepend( d ); + return true; + } else if ( index == numNodes ) { + append( d ); + return true; + } + Q3LNode *nextNode = locate( index ); + if ( !nextNode ) + return false; + Q3LNode *prevNode = nextNode->prev; + register Q3LNode *n = new Q3LNode( newItem(d) ); + Q_CHECK_PTR( n ); + nextNode->prev = n; + prevNode->next = n; + n->prev = prevNode; // link new node into list + n->next = nextNode; + curNode = n; // curIndex set by locate() + numNodes++; + return true; +} + + +/*! + Relinks node \a n and makes it the first node in the list. +*/ + +void Q3GList::relinkNode( Q3LNode *n ) +{ + if ( n == firstNode ) // already first + return; + curNode = n; + unlink(); + n->prev = 0; + if ( (n->next = firstNode) ) // list is not empty + firstNode->prev = n; + else // initialize list + lastNode = n; + firstNode = curNode = n; // curNode affected + numNodes++; + curIndex = 0; +} + + +/*! + Unlinks the current list node and returns a pointer to this node. +*/ + +Q3LNode *Q3GList::unlink() +{ + if ( curNode == 0 ) // null current node + return 0; + register Q3LNode *n = curNode; // unlink this node + if ( n == firstNode ) { // removing first node ? + if ( (firstNode = n->next) ) { + firstNode->prev = 0; + } else { + lastNode = curNode = 0; // list becomes empty + curIndex = -1; + } + } else { + if ( n == lastNode ) { // removing last node ? + lastNode = n->prev; + lastNode->next = 0; + } else { // neither last nor first node + n->prev->next = n->next; + n->next->prev = n->prev; + } + } + + if ( n->next ) { // change current node + curNode = n->next; + } else if ( n->prev ) { + curNode = n->prev; + curIndex--; + } + + if ( iterators ) + iterators->notifyRemove( n, curNode ); + numNodes--; + return n; +} + + +/*! + Removes the node \a n from the list. +*/ + +bool Q3GList::removeNode( Q3LNode *n ) +{ +#if defined(QT_CHECK_NULL) + if ( n == 0 || (n->prev && n->prev->next != n) || + (n->next && n->next->prev != n) ) { + qWarning( "Q3GList::removeNode: Corrupted node" ); + return false; + } +#endif + curNode = n; + unlink(); // unlink node + deleteItem( n->data ); // deallocate this node + delete n; + curNode = firstNode; + curIndex = curNode ? 0 : -1; + return true; +} + +/*! + Removes the item \a d from the list. Uses compareItems() to find the item. + + If \a d is 0, removes the current item. +*/ + +bool Q3GList::remove( Q3PtrCollection::Item d ) +{ + if ( d && find(d) == -1 ) + return false; + Q3LNode *n = unlink(); + if ( !n ) + return false; + deleteItem( n->data ); + delete n; + return true; +} + +/*! + Removes the item \a d from the list. +*/ + +bool Q3GList::removeRef( Q3PtrCollection::Item d ) +{ + if ( findRef(d) == -1 ) + return false; + Q3LNode *n = unlink(); + if ( !n ) + return false; + deleteItem( n->data ); + delete n; + return true; +} + +/*! + \fn bool Q3GList::removeFirst() + + Removes the first item in the list. +*/ + +/*! + \fn bool Q3GList::removeLast() + + Removes the last item in the list. +*/ + +/*! + Removes the item at position \a index from the list. +*/ + +bool Q3GList::removeAt( uint index ) +{ + if ( !locate(index) ) + return false; + Q3LNode *n = unlink(); + if ( !n ) + return false; + deleteItem( n->data ); + delete n; + return true; +} + + +/*! + Replaces the item at index \a index with \a d. +*/ +bool Q3GList::replaceAt( uint index, Q3PtrCollection::Item d ) +{ + Q3LNode *n = locate( index ); + if ( !n ) + return false; + if ( n->data != d ) { + deleteItem( n->data ); + n->data = newItem( d ); + } + return true; +} + + + +/*! + Takes the node \a n out of the list. +*/ + +Q3PtrCollection::Item Q3GList::takeNode( Q3LNode *n ) +{ +#if defined(QT_CHECK_NULL) + if ( n == 0 || (n->prev && n->prev->next != n) || + (n->next && n->next->prev != n) ) { + qWarning( "Q3GList::takeNode: Corrupted node" ); + return 0; + } +#endif + curNode = n; + unlink(); // unlink node + Item d = n->data; + delete n; // delete the node, not data + curNode = firstNode; + curIndex = curNode ? 0 : -1; + return d; +} + +/*! + Takes the current item out of the list. +*/ + +Q3PtrCollection::Item Q3GList::take() +{ + Q3LNode *n = unlink(); // unlink node + Item d = n ? n->data : 0; + delete n; // delete node, keep contents + return d; +} + +/*! + Takes the item at position \a index out of the list. +*/ + +Q3PtrCollection::Item Q3GList::takeAt( uint index ) +{ + if ( !locate(index) ) + return 0; + Q3LNode *n = unlink(); // unlink node + Item d = n ? n->data : 0; + delete n; // delete node, keep contents + return d; +} + +/*! + Takes the first item out of the list. +*/ + +Q3PtrCollection::Item Q3GList::takeFirst() +{ + first(); + Q3LNode *n = unlink(); // unlink node + Item d = n ? n->data : 0; + delete n; + return d; +} + +/*! + Takes the last item out of the list. +*/ + +Q3PtrCollection::Item Q3GList::takeLast() +{ + last(); + Q3LNode *n = unlink(); // unlink node + Item d = n ? n->data : 0; + delete n; + return d; +} + + +/*! + Removes all items from the list. +*/ + +void Q3GList::clear() +{ + register Q3LNode *n = firstNode; + + firstNode = lastNode = curNode = 0; // initialize list + numNodes = 0; + curIndex = -1; + + if ( iterators ) + iterators->notifyClear( false ); + + Q3LNode *prevNode; + while ( n ) { // for all nodes ... + deleteItem( n->data ); // deallocate data + prevNode = n; + n = n->next; + delete prevNode; // deallocate node + } +} + + +/*! + Finds item \a d in the list. If \a fromStart is true the search + begins at the first node; otherwise it begins at the current node. +*/ + +int Q3GList::findRef( Q3PtrCollection::Item d, bool fromStart ) +{ + register Q3LNode *n; + int index; + if ( fromStart ) { // start from first node + n = firstNode; + index = 0; + } else { // start from current node + n = curNode; + index = curIndex; + } + while ( n && n->data != d ) { // find exact match + n = n->next; + index++; + } + curNode = n; + curIndex = n ? index : -1; + return curIndex; // return position of item +} + +/*! + Finds item \a d in the list using compareItems(). If \a fromStart is + true the search begins at the first node; otherwise it begins at the + current node. +*/ + +int Q3GList::find( Q3PtrCollection::Item d, bool fromStart ) +{ + register Q3LNode *n; + int index; + if ( fromStart ) { // start from first node + n = firstNode; + index = 0; + } else { // start from current node + n = curNode; + index = curIndex; + } + while ( n && compareItems(n->data,d) ){ // find equal match + n = n->next; + index++; + } + curNode = n; + curIndex = n ? index : -1; + return curIndex; // return position of item +} + + +/*! + Counts the number item \a d occurs in the list. +*/ + +uint Q3GList::containsRef( Q3PtrCollection::Item d ) const +{ + register Q3LNode *n = firstNode; + uint count = 0; + while ( n ) { // for all nodes... + if ( n->data == d ) // count # exact matches + count++; + n = n->next; + } + return count; +} + +/*! + Counts the number of times item \a d occurs in the list. Uses + compareItems(). +*/ + +uint Q3GList::contains( Q3PtrCollection::Item d ) const +{ + register Q3LNode *n = firstNode; + uint count = 0; + Q3GList *that = (Q3GList*)this; // mutable for compareItems() + while ( n ) { // for all nodes... + if ( !that->compareItems(n->data,d) ) // count # equal matches + count++; + n = n->next; + } + return count; +} + + +/*! + \fn Q3PtrCollection::Item Q3GList::at( uint index ) + \overload + + Sets the item at position \a index to the current item. +*/ + +/*! + \fn int Q3GList::at() const + + Returns the current index. +*/ + +/*! + \fn Q3LNode *Q3GList::currentNode() const + + Returns the current node. +*/ + +/*! + \fn Q3PtrCollection::Item Q3GList::get() const + + Returns the current item. +*/ + +/*! + \fn Q3PtrCollection::Item Q3GList::cfirst() const + + Returns the first item in the list. +*/ + +/*! + \fn Q3PtrCollection::Item Q3GList::clast() const + + Returns the last item in the list. +*/ + + +/*! + Returns the first list item. Sets this to current. +*/ + +Q3PtrCollection::Item Q3GList::first() +{ + if ( firstNode ) { + curIndex = 0; + return (curNode=firstNode)->data; + } + return 0; +} + +/*! + Returns the last list item. Sets this to current. +*/ + +Q3PtrCollection::Item Q3GList::last() +{ + if ( lastNode ) { + curIndex = numNodes-1; + return (curNode=lastNode)->data; + } + return 0; +} + +/*! + Returns the next list item (after current). Sets this to current. +*/ + +Q3PtrCollection::Item Q3GList::next() +{ + if ( curNode ) { + if ( curNode->next ) { + curIndex++; + curNode = curNode->next; + return curNode->data; + } + curIndex = -1; + curNode = 0; + } + return 0; +} + +/*! + Returns the previous list item (before current). Sets this to current. +*/ + +Q3PtrCollection::Item Q3GList::prev() +{ + if ( curNode ) { + if ( curNode->prev ) { + curIndex--; + curNode = curNode->prev; + return curNode->data; + } + curIndex = -1; + curNode = 0; + } + return 0; +} + + +/*! + Converts the list to a vector, \a vector. +*/ + +void Q3GList::toVector( Q3GVector *vector ) const +{ + vector->clear(); + if ( !vector->resize( count() ) ) + return; + register Q3LNode *n = firstNode; + uint i = 0; + while ( n ) { + vector->insert( i, n->data ); + n = n->next; + i++; + } +} + +void Q3GList::heapSortPushDown( Q3PtrCollection::Item* heap, int first, int last ) +{ + int r = first; + while( r <= last/2 ) { + // Node r has only one child ? + if ( last == 2*r ) { + // Need for swapping ? + if ( compareItems( heap[r], heap[ 2*r ] ) > 0 ) { + Q3PtrCollection::Item tmp = heap[r]; + heap[ r ] = heap[ 2*r ]; + heap[ 2*r ] = tmp; + } + // That's it ... + r = last; + } else { + // Node has two children + if ( compareItems( heap[r], heap[ 2*r ] ) > 0 && + compareItems( heap[ 2*r ], heap[ 2*r+1 ] ) <= 0 ) { + // Swap with left child + Q3PtrCollection::Item tmp = heap[r]; + heap[ r ] = heap[ 2*r ]; + heap[ 2*r ] = tmp; + r *= 2; + } else if ( compareItems( heap[r], heap[ 2*r+1 ] ) > 0 && + compareItems( heap[ 2*r+1 ], heap[ 2*r ] ) < 0 ) { + // Swap with right child + Q3PtrCollection::Item tmp = heap[r]; + heap[ r ] = heap[ 2*r+1 ]; + heap[ 2*r+1 ] = tmp; + r = 2*r+1; + } else { + // We are done + r = last; + } + } + } +} + + +/*! Sorts the list by the result of the virtual compareItems() function. + + The Heap-Sort algorithm is used for sorting. It sorts n items with + O(n*log n) compares. This is the asymptotic optimal solution of the + sorting problem. +*/ + +void Q3GList::sort() +{ + uint n = count(); + if ( n < 2 ) + return; + + // Create the heap + Q3PtrCollection::Item* realheap = new Q3PtrCollection::Item[ n ]; + // Wow, what a fake. But I want the heap to be indexed as 1...n + Q3PtrCollection::Item* heap = realheap - 1; + int size = 0; + Q3LNode* insert = firstNode; + for( ; insert != 0; insert = insert->next ) { + heap[++size] = insert->data; + int i = size; + while( i > 1 && compareItems( heap[i], heap[ i / 2 ] ) < 0 ) { + Q3PtrCollection::Item tmp = heap[ i ]; + heap[ i ] = heap[ i/2 ]; + heap[ i/2 ] = tmp; + i /= 2; + } + } + + insert = firstNode; + // Now do the sorting + for ( int i = n; i > 0; i-- ) { + insert->data = heap[1]; + insert = insert->next; + if ( i > 1 ) { + heap[1] = heap[i]; + heapSortPushDown( heap, 1, i - 1 ); + } + } + + delete [] realheap; +} + + +/***************************************************************************** + Q3GList stream functions + *****************************************************************************/ + +#ifndef QT_NO_DATASTREAM +QDataStream &operator>>( QDataStream &s, Q3GList &list ) +{ // read list + return list.read( s ); +} + +QDataStream &operator<<( QDataStream &s, const Q3GList &list ) +{ // write list + return list.write( s ); +} + +/*! + Reads a list from the stream \a s. +*/ + +QDataStream &Q3GList::read( QDataStream &s ) +{ + uint num; + s >> num; // read number of items + clear(); // clear list + while ( num-- ) { // read all items + Item d; + read( s, d ); + Q_CHECK_PTR( d ); + if ( !d ) // no memory + break; + Q3LNode *n = new Q3LNode( d ); + Q_CHECK_PTR( n ); + if ( !n ) // no memory + break; + n->next = 0; + if ( (n->prev = lastNode) ) // list is not empty + lastNode->next = n; + else // initialize list + firstNode = n; + lastNode = n; + numNodes++; + } + curNode = firstNode; + curIndex = curNode ? 0 : -1; + return s; +} + +/*! + Writes the list to the stream \a s. +*/ + +QDataStream &Q3GList::write( QDataStream &s ) const +{ + s << count(); // write number of items + Q3LNode *n = firstNode; + while ( n ) { // write all items + write( s, n->data ); + n = n->next; + } + return s; +} + +#endif // QT_NO_DATASTREAM + + + +/*! \internal + */ +Q3LNode* Q3GList::erase( Q3LNode* it ) +{ + Q3LNode* n = it; + it = it->next; + removeNode( n ); + return it; +} + + +/***************************************************************************** + Q3GListIterator member functions + *****************************************************************************/ + +/*! + \class Q3GListIterator + \reentrant + \brief The Q3GListIterator class is an internal class for implementing Q3PtrListIterator. + + \internal + + Q3GListIterator is a strictly internal class that does the heavy work for + Q3PtrListIterator. +*/ + +/*! + \internal + Constructs an iterator that operates on the list \a l. +*/ + +Q3GListIterator::Q3GListIterator( const Q3GList &l ) +{ + list = (Q3GList *)&l; // get reference to list + curNode = list->firstNode; // set to first node + if ( !list->iterators ) { + list->iterators = new Q3GListIteratorList; // create iterator list + Q_CHECK_PTR( list->iterators ); + } + list->iterators->add( this ); // attach iterator to list +} + +/*! + \internal + Constructs a copy of the iterator \a it. +*/ + +Q3GListIterator::Q3GListIterator( const Q3GListIterator &it ) +{ + list = it.list; + curNode = it.curNode; + if ( list ) + list->iterators->add( this ); // attach iterator to list +} + +/*! + \internal + Assigns a copy of the iterator \a it and returns a reference to this + iterator. +*/ + +Q3GListIterator &Q3GListIterator::operator=( const Q3GListIterator &it ) +{ + if ( list ) // detach from old list + list->iterators->remove( this ); + list = it.list; + curNode = it.curNode; + if ( list ) + list->iterators->add( this ); // attach to new list + return *this; +} + +/*! + \internal + Destroys the iterator. +*/ + +Q3GListIterator::~Q3GListIterator() +{ + if ( list ) // detach iterator from list + list->iterators->remove(this); +} + + +/*! + \fn bool Q3GListIterator::atFirst() const + \internal + Returns true if the iterator points to the first item, otherwise false. +*/ + +/*! + \fn bool Q3GListIterator::atLast() const + \internal + Returns true if the iterator points to the last item, otherwise false. +*/ + + +/*! + \internal + Sets the list iterator to point to the first item in the list. +*/ + +Q3PtrCollection::Item Q3GListIterator::toFirst() +{ + if ( !list ) { +#if defined(QT_CHECK_NULL) + qWarning( "Q3GListIterator::toFirst: List has been deleted" ); +#endif + return 0; + } + return list->firstNode ? (curNode = list->firstNode)->getData() : 0; +} + +/*! + \internal + Sets the list iterator to point to the last item in the list. +*/ + +Q3PtrCollection::Item Q3GListIterator::toLast() +{ + if ( !list ) { +#if defined(QT_CHECK_NULL) + qWarning( "Q3GListIterator::toLast: List has been deleted" ); +#endif + return 0; + } + return list->lastNode ? (curNode = list->lastNode)->getData() : 0; +} + + +/*! + \fn Q3PtrCollection::Item Q3GListIterator::get() const + \internal + Returns the iterator item. +*/ + + +/*! + \internal + Moves to the next item (postfix). +*/ + +Q3PtrCollection::Item Q3GListIterator::operator()() +{ + if ( !curNode ) + return 0; + Q3PtrCollection::Item d = curNode->getData(); + curNode = curNode->next; + return d; +} + +/*! + \internal + Moves to the next item (prefix). +*/ + +Q3PtrCollection::Item Q3GListIterator::operator++() +{ + if ( !curNode ) + return 0; + curNode = curNode->next; + return curNode ? curNode->getData() : 0; +} + +/*! + \internal + Moves \a jumps positions forward. +*/ + +Q3PtrCollection::Item Q3GListIterator::operator+=( uint jumps ) +{ + while ( curNode && jumps-- ) + curNode = curNode->next; + return curNode ? curNode->getData() : 0; +} + +/*! + \internal + Moves to the previous item (prefix). +*/ + +Q3PtrCollection::Item Q3GListIterator::operator--() +{ + if ( !curNode ) + return 0; + curNode = curNode->prev; + return curNode ? curNode->getData() : 0; +} + +/*! + \internal + Moves \a jumps positions backward. +*/ + +Q3PtrCollection::Item Q3GListIterator::operator-=( uint jumps ) +{ + while ( curNode && jumps-- ) + curNode = curNode->prev; + return curNode ? curNode->getData() : 0; +} + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3glist.h b/src/qt3support/tools/q3glist.h new file mode 100644 index 0000000..5415838 --- /dev/null +++ b/src/qt3support/tools/q3glist.h @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3GLIST_H +#define Q3GLIST_H + +#include <Qt3Support/q3ptrcollection.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +class Q_COMPAT_EXPORT Q3LNode +{ +friend class Q3GList; +friend class Q3GListIterator; +friend class Q3GListStdIterator; +public: + Q3PtrCollection::Item getData() { return data; } +private: + Q3PtrCollection::Item data; + Q3LNode *prev; + Q3LNode *next; + Q3LNode( Q3PtrCollection::Item d ) { data = d; } +}; + +class Q3GListIteratorList; // internal helper class + +class Q_COMPAT_EXPORT Q3GList : public Q3PtrCollection // doubly linked generic list +{ +friend class Q3GListIterator; +friend class Q3GListIteratorList; +friend class Q3GVector; // needed by Q3GVector::toList +public: + uint count() const; // return number of nodes + +#ifndef QT_NO_DATASTREAM + QDataStream &read( QDataStream & ); // read list from stream + QDataStream &write( QDataStream & ) const; // write list to stream +#endif +protected: + Q3GList(); // create empty list + Q3GList( const Q3GList & ); // make copy of other list + virtual ~Q3GList(); + + Q3GList &operator=( const Q3GList & ); // assign from other list + bool operator==( const Q3GList& ) const; + + void inSort( Q3PtrCollection::Item ); // add item sorted in list + void append( Q3PtrCollection::Item ); // add item at end of list + bool insertAt( uint index, Q3PtrCollection::Item ); // add item at i'th position + void relinkNode( Q3LNode * ); // relink as first item + bool removeNode( Q3LNode * ); // remove node + bool remove( Q3PtrCollection::Item = 0 ); // remove item (0=current) + bool removeRef( Q3PtrCollection::Item = 0 ); // remove item (0=current) + bool removeFirst(); // remove first item + bool removeLast(); // remove last item + bool removeAt( uint ); // remove item at i'th position + bool replaceAt( uint, Q3PtrCollection::Item ); // replace item at position i with item + Q3PtrCollection::Item takeNode( Q3LNode * ); // take out node + Q3PtrCollection::Item take(); // take out current item + Q3PtrCollection::Item takeAt( uint index ); // take out item at i'th pos + Q3PtrCollection::Item takeFirst(); // take out first item + Q3PtrCollection::Item takeLast(); // take out last item + + void sort(); // sort all items; + void clear(); // remove all items + + int findRef( Q3PtrCollection::Item, bool = true ); // find exact item in list + int find( Q3PtrCollection::Item, bool = true ); // find equal item in list + + uint containsRef( Q3PtrCollection::Item ) const; // get number of exact matches + uint contains( Q3PtrCollection::Item ) const; // get number of equal matches + + Q3PtrCollection::Item at( uint index ); // access item at i'th pos + int at() const; // get current index + Q3LNode *currentNode() const; // get current node + + Q3PtrCollection::Item get() const; // get current item + + Q3PtrCollection::Item cfirst() const; // get ptr to first list item + Q3PtrCollection::Item clast() const; // get ptr to last list item + Q3PtrCollection::Item first(); // set first item in list curr + Q3PtrCollection::Item last(); // set last item in list curr + Q3PtrCollection::Item next(); // set next item in list curr + Q3PtrCollection::Item prev(); // set prev item in list curr + + void toVector( Q3GVector * ) const; // put items in vector + + virtual int compareItems( Q3PtrCollection::Item, Q3PtrCollection::Item ); + +#ifndef QT_NO_DATASTREAM + virtual QDataStream &read( QDataStream &, Q3PtrCollection::Item & ); + virtual QDataStream &write( QDataStream &, Q3PtrCollection::Item ) const; +#endif + + Q3LNode* begin() const { return firstNode; } + Q3LNode* end() const { return 0; } + Q3LNode* erase( Q3LNode* it ); + +private: + void prepend( Q3PtrCollection::Item ); // add item at start of list + + void heapSortPushDown( Q3PtrCollection::Item* heap, int first, int last ); + + Q3LNode *firstNode; // first node + Q3LNode *lastNode; // last node + Q3LNode *curNode; // current node + int curIndex; // current index + uint numNodes; // number of nodes + Q3GListIteratorList *iterators; // list of iterators + + Q3LNode *locate( uint ); // get node at i'th pos + Q3LNode *unlink(); // unlink node +}; + + +inline uint Q3GList::count() const +{ + return numNodes; +} + +inline bool Q3GList::removeFirst() +{ + first(); + return remove(); +} + +inline bool Q3GList::removeLast() +{ + last(); + return remove(); +} + +inline int Q3GList::at() const +{ + return curIndex; +} + +inline Q3PtrCollection::Item Q3GList::at( uint index ) +{ + Q3LNode *n = locate( index ); + return n ? n->data : 0; +} + +inline Q3LNode *Q3GList::currentNode() const +{ + return curNode; +} + +inline Q3PtrCollection::Item Q3GList::get() const +{ + return curNode ? curNode->data : 0; +} + +inline Q3PtrCollection::Item Q3GList::cfirst() const +{ + return firstNode ? firstNode->data : 0; +} + +inline Q3PtrCollection::Item Q3GList::clast() const +{ + return lastNode ? lastNode->data : 0; +} + + +/***************************************************************************** + Q3GList stream functions + *****************************************************************************/ + +#ifndef QT_NO_DATASTREAM +Q_COMPAT_EXPORT QDataStream &operator>>( QDataStream &, Q3GList & ); +Q_COMPAT_EXPORT QDataStream &operator<<( QDataStream &, const Q3GList & ); +#endif + +/***************************************************************************** + Q3GListIterator class + *****************************************************************************/ + +class Q_COMPAT_EXPORT Q3GListIterator // Q3GList iterator +{ +friend class Q3GList; +friend class Q3GListIteratorList; +protected: + Q3GListIterator( const Q3GList & ); + Q3GListIterator( const Q3GListIterator & ); + Q3GListIterator &operator=( const Q3GListIterator & ); + ~Q3GListIterator(); + + bool atFirst() const; // test if at first item + bool atLast() const; // test if at last item + Q3PtrCollection::Item toFirst(); // move to first item + Q3PtrCollection::Item toLast(); // move to last item + + Q3PtrCollection::Item get() const; // get current item + Q3PtrCollection::Item operator()(); // get current and move to next + Q3PtrCollection::Item operator++(); // move to next item (prefix) + Q3PtrCollection::Item operator+=(uint); // move n positions forward + Q3PtrCollection::Item operator--(); // move to prev item (prefix) + Q3PtrCollection::Item operator-=(uint); // move n positions backward + +protected: + Q3GList *list; // reference to list + +private: + Q3LNode *curNode; // current node in list +}; + + +inline bool Q3GListIterator::atFirst() const +{ + return curNode == list->firstNode; +} + +inline bool Q3GListIterator::atLast() const +{ + return curNode == list->lastNode; +} + +inline Q3PtrCollection::Item Q3GListIterator::get() const +{ + return curNode ? curNode->data : 0; +} + +class Q_COMPAT_EXPORT Q3GListStdIterator +{ +public: + inline Q3GListStdIterator( Q3LNode* n ) : node( n ){} + inline operator Q3LNode* () { return node; } +protected: + inline Q3LNode *next() { return node->next; } + Q3LNode *node; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3GLIST_H diff --git a/src/qt3support/tools/q3gvector.cpp b/src/qt3support/tools/q3gvector.cpp new file mode 100644 index 0000000..5da08b5 --- /dev/null +++ b/src/qt3support/tools/q3gvector.cpp @@ -0,0 +1,597 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qglobal.h" +#if defined(Q_CC_BOR) +// needed for qsort() because of a std namespace problem on Borland +#include "qplatformdefs.h" +#endif + +#define Q3GVECTOR_CPP +#include "q3gvector.h" +#include "q3glist.h" +#include "qstring.h" +#include "qdatastream.h" +#include <stdlib.h> + +#ifndef QT_NO_THREAD +# include "private/qmutexpool_p.h" +#endif + +QT_BEGIN_NAMESPACE + +#define USE_MALLOC // comment to use new/delete + +#undef NEW +#undef DELETE + +#if defined(USE_MALLOC) +#define NEW(type,size) ((type*)malloc(size*sizeof(type))) +#define DELETE(array) (free((char*)array)) +#else +#define NEW(type,size) (new type[size]) +#define DELETE(array) (delete[] array) +#define DONT_USE_REALLOC // comment to use realloc() +#endif + +/*! + \class Q3GVector + \reentrant + + \brief The Q3GVector class is an internal class for implementing Qt + collection classes. + + \internal + + Q3GVector is an internal class that acts as a base class for the + Q3PtrVector collection class. + + Q3GVector has some virtual functions that may be reimplemented in + subclasses to customize behavior. + + \list + \i compareItems() compares two collection/vector items. + \i read() reads a collection/vector item from a QDataStream. + \i write() writes a collection/vector item to a QDataStream. + \endlist +*/ + +/***************************************************************************** + Default implementation of virtual functions + *****************************************************************************/ + +/*! + This virtual function compares two list items. + + Returns: + <ul> + <li> 0 if \a d1 == \a d2 + <li> non-zero if \a d1 != \a d2 + </ul> + + This function returns \e int rather than \e bool so that + reimplementations can return one of three values and use it to sort + by: + <ul> + <li> 0 if \a d1 == \a d2 + <li> \> 0 (positive integer) if \a d1 \> \a d2 + <li> \< 0 (negative integer) if \a d1 \< \a d2 + </ul> + + The Q3PtrVector::sort() and Q3PtrVector::bsearch() functions require that + compareItems() is implemented as described here. + + This function should not modify the vector because some const + functions call compareItems(). +*/ + +int Q3GVector::compareItems( Item d1, Item d2 ) +{ + return d1 != d2; // compare pointers +} + +#ifndef QT_NO_DATASTREAM +/*! + Reads a collection/vector item from the stream \a s and returns a reference + to the stream. + + The default implementation sets \a d to 0. + + \sa write() +*/ + +QDataStream &Q3GVector::read( QDataStream &s, Item &d ) +{ // read item from stream + d = 0; + return s; +} + +/*! + Writes a collection/vector item to the stream \a s and returns a reference + to the stream. + + The default implementation does nothing. + + \sa read() +*/ + +QDataStream &Q3GVector::write( QDataStream &s, Item ) const +{ // write item to stream + return s; +} +#endif // QT_NO_DATASTREAM + +/***************************************************************************** + Q3GVector member functions + *****************************************************************************/ + +Q3GVector::Q3GVector() // create empty vector +{ + vec = 0; + len = numItems = 0; +} + +Q3GVector::Q3GVector( uint size ) // create vectors with nullptrs +{ + len = size; + numItems = 0; + if ( len == 0 ) { // zero length + vec = 0; + return; + } + vec = NEW(Item,len); + Q_CHECK_PTR( vec ); + memset( (void*)vec, 0, len*sizeof(Item) ); // fill with nulls +} + +Q3GVector::Q3GVector( const Q3GVector &a ) // make copy of other vector + : Q3PtrCollection( a ) +{ + len = a.len; + numItems = a.numItems; + if ( len == 0 ) { + vec = 0; + return; + } + vec = NEW( Item, len ); + Q_CHECK_PTR( vec ); + for ( uint i = 0; i < len; i++ ) { + if ( a.vec[i] ) { + vec[i] = newItem( a.vec[i] ); + Q_CHECK_PTR( vec[i] ); + } else { + vec[i] = 0; + } + } +} + +Q3GVector::~Q3GVector() +{ + clear(); +} + +Q3GVector& Q3GVector::operator=( const Q3GVector &v ) +{ + if ( &v == this ) + return *this; + + clear(); + len = v.len; + numItems = v.numItems; + if ( len == 0 ) { + vec = 0; + return *this; + } + vec = NEW( Item, len ); + Q_CHECK_PTR( vec ); + for ( uint i = 0; i < len; i++ ) { + if ( v.vec[i] ) { + vec[i] = newItem( v.vec[i] ); + Q_CHECK_PTR( vec[i] ); + } else { + vec[i] = 0; + } + } + return *this; +} + + +bool Q3GVector::insert( uint index, Item d ) // insert item at index +{ +#if defined(QT_CHECK_RANGE) + if ( index >= len ) { // range error + qWarning( "Q3GVector::insert: Index %d out of range", index ); + return false; + } +#endif + if ( vec[index] ) { // remove old item + deleteItem( vec[index] ); + numItems--; + } + if ( d ) { + vec[index] = newItem( d ); + Q_CHECK_PTR( vec[index] ); + numItems++; + return vec[index] != 0; + } else { + vec[index] = 0; // reset item + } + return true; +} + +bool Q3GVector::remove( uint index ) // remove item at index +{ +#if defined(QT_CHECK_RANGE) + if ( index >= len ) { // range error + qWarning( "Q3GVector::remove: Index %d out of range", index ); + return false; + } +#endif + if ( vec[index] ) { // valid item + deleteItem( vec[index] ); // delete it + vec[index] = 0; // reset pointer + numItems--; + } + return true; +} + +Q3PtrCollection::Item Q3GVector::take( uint index ) // take out item +{ +#if defined(QT_CHECK_RANGE) + if ( index >= len ) { // range error + qWarning( "Q3GVector::take: Index %d out of range", index ); + return 0; + } +#endif + Item d = vec[index]; // don't delete item + if ( d ) + numItems--; + vec[index] = 0; + return d; +} + +void Q3GVector::clear() // clear vector +{ + if ( vec ) { + for ( uint i=0; i<len; i++ ) { // delete each item + if ( vec[i] ) + deleteItem( vec[i] ); + } + DELETE(vec); + vec = 0; + len = numItems = 0; + } +} + +bool Q3GVector::resize( uint newsize ) // resize array +{ + if ( newsize == len ) // nothing to do + return true; + if ( vec ) { // existing data + if ( newsize < len ) { // shrink vector + uint i = newsize; + while ( i < len ) { // delete lost items + if ( vec[i] ) { + deleteItem( vec[i] ); + numItems--; + } + i++; + } + } + if ( newsize == 0 ) { // vector becomes empty + DELETE(vec); + vec = 0; + len = numItems = 0; + return true; + } +#if defined(DONT_USE_REALLOC) + if ( newsize == 0 ) { + DELETE(vec); + vec = 0; + return false; + } + Item *newvec = NEW(Item,newsize); // manual realloc + memcpy( newvec, vec, (len < newsize ? len : newsize)*sizeof(Item) ); + DELETE(vec); + vec = newvec; +#else + vec = (Item*)realloc( (char *)vec, newsize*sizeof(Item) ); +#endif + } else { // create new vector + vec = NEW(Item,newsize); + len = numItems = 0; + } + Q_CHECK_PTR( vec ); + if ( !vec ) // no memory + return false; + if ( newsize > len ) // init extra space added + memset( (void*)&vec[len], 0, (newsize-len)*sizeof(Item) ); + len = newsize; + return true; +} + + +bool Q3GVector::fill( Item d, int flen ) // resize and fill vector +{ + if ( flen < 0 ) + flen = len; // default: use vector length + else if ( !resize( flen ) ) + return false; + for ( uint i=0; i<(uint)flen; i++ ) // insert d at every index + insert( i, d ); + return true; +} + + +static Q3GVector *sort_vec=0; // current sort vector + + +#if defined(Q_C_CALLBACKS) +extern "C" { +#endif + +#ifdef Q_OS_WINCE +static int _cdecl cmp_vec( const void *n1, const void *n2 ) +#else +static int cmp_vec( const void *n1, const void *n2 ) +#endif +{ + return sort_vec->compareItems( *((Q3PtrCollection::Item*)n1), *((Q3PtrCollection::Item*)n2) ); +} + +#if defined(Q_C_CALLBACKS) +} +#endif + + +void Q3GVector::sort() // sort vector +{ + if ( count() == 0 ) // no elements + return; + register Item *start = &vec[0]; + register Item *end = &vec[len-1]; + Item tmp; + for (;;) { // put all zero elements behind + while ( start < end && *start != 0 ) + start++; + while ( end > start && *end == 0 ) + end--; + if ( start < end ) { + tmp = *start; + *start = *end; + *end = tmp; + } else { + break; + } + } + +#ifndef QT_NO_THREAD + QMutexLocker locker(QMutexPool::globalInstanceGet(&sort_vec)); +#endif + + sort_vec = (Q3GVector*)this; + qsort( vec, count(), sizeof(Item), cmp_vec ); + sort_vec = 0; +} + +int Q3GVector::bsearch( Item d ) const // binary search; when sorted +{ + if ( !len ) + return -1; + if ( !d ) { +#if defined(QT_CHECK_NULL) + qWarning( "Q3GVector::bsearch: Cannot search for null object" ); +#endif + return -1; + } + int n1 = 0; + int n2 = len - 1; + int mid = 0; + bool found = false; + while ( n1 <= n2 ) { + int res; + mid = (n1 + n2)/2; + if ( vec[mid] == 0 ) // null item greater + res = -1; + else + res = ((Q3GVector*)this)->compareItems( d, vec[mid] ); + if ( res < 0 ) + n2 = mid - 1; + else if ( res > 0 ) + n1 = mid + 1; + else { // found it + found = true; + break; + } + } + if ( !found ) + return -1; + // search to first of equal items + while ( (mid - 1 >= 0) && !((Q3GVector*)this)->compareItems(d, vec[mid-1]) ) + mid--; + return mid; +} + +int Q3GVector::findRef( Item d, uint index) const // find exact item in vector +{ +#if defined(QT_CHECK_RANGE) + if ( index > len ) { // range error + qWarning( "Q3GVector::findRef: Index %d out of range", index ); + return -1; + } +#endif + for ( uint i=index; i<len; i++ ) { + if ( vec[i] == d ) + return i; + } + return -1; +} + +int Q3GVector::find( Item d, uint index ) const // find equal item in vector +{ +#if defined(QT_CHECK_RANGE) + if ( index >= len ) { // range error + qWarning( "Q3GVector::find: Index %d out of range", index ); + return -1; + } +#endif + for ( uint i=index; i<len; i++ ) { + if ( vec[i] == 0 && d == 0 ) // found null item + return i; + if ( vec[i] && ((Q3GVector*)this)->compareItems( vec[i], d ) == 0 ) + return i; + } + return -1; +} + +uint Q3GVector::containsRef( Item d ) const // get number of exact matches +{ + uint count = 0; + for ( uint i=0; i<len; i++ ) { + if ( vec[i] == d ) + count++; + } + return count; +} + +uint Q3GVector::contains( Item d ) const // get number of equal matches +{ + uint count = 0; + for ( uint i=0; i<len; i++ ) { + if ( vec[i] == 0 && d == 0 ) // count null items + count++; + if ( vec[i] && ((Q3GVector*)this)->compareItems( vec[i], d ) == 0 ) + count++; + } + return count; +} + +bool Q3GVector::insertExpand( uint index, Item d )// insert and grow if necessary +{ + if ( index >= len ) { + if ( !resize( index+1 ) ) // no memory + return false; + } + insert( index, d ); + return true; +} + +void Q3GVector::toList( Q3GList *list ) const // store items in list +{ + list->clear(); + for ( uint i=0; i<len; i++ ) { + if ( vec[i] ) + list->append( vec[i] ); + } +} + + +void Q3GVector::warningIndexRange( uint i ) +{ +#if defined(QT_CHECK_RANGE) + qWarning( "Q3GVector::operator[]: Index %d out of range", i ); +#else + Q_UNUSED( i ) +#endif +} + + +/***************************************************************************** + Q3GVector stream functions + *****************************************************************************/ +#ifndef QT_NO_DATASTREAM +QDataStream &operator>>( QDataStream &s, Q3GVector &vec ) +{ // read vector + return vec.read( s ); +} + +QDataStream &operator<<( QDataStream &s, const Q3GVector &vec ) +{ // write vector + return vec.write( s ); +} + +QDataStream &Q3GVector::read( QDataStream &s ) // read vector from stream +{ + uint num; + s >> num; // read number of items + clear(); // clear vector + resize( num ); + for (uint i=0; i<num; i++) { // read all items + Item d; + read( s, d ); + Q_CHECK_PTR( d ); + if ( !d ) // no memory + break; + vec[i] = d; + } + return s; +} + +QDataStream &Q3GVector::write( QDataStream &s ) const +{ // write vector to stream + uint num = count(); + s << num; // number of items to write + num = size(); + for (uint i=0; i<num; i++) { // write non-null items + if ( vec[i] ) + write( s, vec[i] ); + } + return s; +} + +/* Returns whether v equals this vector or not */ + +bool Q3GVector::operator==( const Q3GVector &v ) const +{ + if ( size() != v.size() ) + return false; + if ( count() != v.count() ) + return false; + for ( int i = 0; i < (int)size(); ++i ) { + if ( ( (Q3GVector*)this )->compareItems( at( i ), v.at( i ) ) != 0 ) + return false; + } + return true; +} + +#endif // QT_NO_DATASTREAM + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3gvector.h b/src/qt3support/tools/q3gvector.h new file mode 100644 index 0000000..8d0f3ac --- /dev/null +++ b/src/qt3support/tools/q3gvector.h @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3GVECTOR_H +#define Q3GVECTOR_H + +#include <Qt3Support/q3ptrcollection.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +class Q_COMPAT_EXPORT Q3GVector : public Q3PtrCollection // generic vector +{ +friend class Q3GList; // needed by Q3GList::toVector +public: +#ifndef QT_NO_DATASTREAM + QDataStream &read( QDataStream & ); // read vector from stream + QDataStream &write( QDataStream & ) const; // write vector to stream +#endif + virtual int compareItems( Item, Item ); + +protected: + Q3GVector(); // create empty vector + Q3GVector( uint size ); // create vector with nullptrs + Q3GVector( const Q3GVector &v ); // make copy of other vector + ~Q3GVector(); + + Q3GVector &operator=( const Q3GVector &v ); // assign from other vector + bool operator==( const Q3GVector &v ) const; + + Item *data() const { return vec; } + uint size() const { return len; } + uint count() const { return numItems; } + + bool insert( uint index, Item ); // insert item at index + bool remove( uint index ); // remove item + Item take( uint index ); // take out item + + void clear(); // clear vector + bool resize( uint newsize ); // resize vector + + bool fill( Item, int flen ); // resize and fill vector + + void sort(); // sort vector + int bsearch( Item ) const; // binary search (when sorted) + + int findRef( Item, uint index ) const; // find exact item in vector + int find( Item, uint index ) const; // find equal item in vector + uint containsRef( Item ) const; // get number of exact matches + uint contains( Item ) const; // get number of equal matches + + Item at( uint index ) const // return indexed item + { +#if defined(QT_CHECK_RANGE) + if ( index >= len ) + warningIndexRange( index ); +#endif + return vec[index]; + } + + bool insertExpand( uint index, Item ); // insert, expand if necessary + + void toList( Q3GList * ) const; // put items in list + +#ifndef QT_NO_DATASTREAM + virtual QDataStream &read( QDataStream &, Item & ); + virtual QDataStream &write( QDataStream &, Item ) const; +#endif +private: + Item *vec; + uint len; + uint numItems; + + static void warningIndexRange( uint ); +}; + + +/***************************************************************************** + Q3GVector stream functions + *****************************************************************************/ + +#ifndef QT_NO_DATASTREAM +Q_COMPAT_EXPORT QDataStream &operator>>( QDataStream &, Q3GVector & ); +Q_COMPAT_EXPORT QDataStream &operator<<( QDataStream &, const Q3GVector & ); +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3GVECTOR_H diff --git a/src/qt3support/tools/q3intcache.h b/src/qt3support/tools/q3intcache.h new file mode 100644 index 0000000..72cbf75 --- /dev/null +++ b/src/qt3support/tools/q3intcache.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3INTCACHE_H +#define Q3INTCACHE_H + +#include <Qt3Support/q3gcache.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3IntCache +#ifdef qdoc + : public Q3PtrCollection +#else + : public Q3GCache +#endif +{ +public: + Q3IntCache( const Q3IntCache<type> &c ) : Q3GCache(c) {} + Q3IntCache( int maxCost=100, int size=17 ) + : Q3GCache( maxCost, size, IntKey, false, false ) {} + ~Q3IntCache() { clear(); } + Q3IntCache<type> &operator=( const Q3IntCache<type> &c ) + { return (Q3IntCache<type>&)Q3GCache::operator=(c); } + int maxCost() const { return Q3GCache::maxCost(); } + int totalCost() const { return Q3GCache::totalCost(); } + void setMaxCost( int m) { Q3GCache::setMaxCost(m); } + uint count() const { return Q3GCache::count(); } + uint size() const { return Q3GCache::size(); } + bool isEmpty() const { return Q3GCache::count() == 0; } + bool insert( long k, const type *d, int c=1, int p=0 ) + { return Q3GCache::insert_other((const char*)k,(Item)d,c,p); } + bool remove( long k ) + { return Q3GCache::remove_other((const char*)k); } + type *take( long k ) + { return (type *)Q3GCache::take_other((const char*)k);} + void clear() { Q3GCache::clear(); } + type *find( long k, bool ref=true ) const + { return (type *)Q3GCache::find_other( (const char*)k,ref);} + type *operator[]( long k ) const + { return (type *)Q3GCache::find_other( (const char*)k); } + void statistics() const { Q3GCache::statistics(); } +private: + void deleteItem( Item d ); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3IntCache<void>::deleteItem( Q3PtrCollection::Item ) +{ +} +#endif + +template<class type> inline void Q3IntCache<type>::deleteItem( Q3PtrCollection::Item d ) +{ + if ( del_item ) delete (type *)d; +} + +template<class type> +class Q3IntCacheIterator : public Q3GCacheIterator +{ +public: + Q3IntCacheIterator( const Q3IntCache<type> &c ) + : Q3GCacheIterator( (Q3GCache &)c ) {} + Q3IntCacheIterator( const Q3IntCacheIterator<type> &ci ) + : Q3GCacheIterator((Q3GCacheIterator &)ci) {} + Q3IntCacheIterator<type> &operator=( const Q3IntCacheIterator<type>&ci ) + { return ( Q3IntCacheIterator<type>&)Q3GCacheIterator::operator=( ci );} + uint count() const { return Q3GCacheIterator::count(); } + bool isEmpty() const { return Q3GCacheIterator::count() == 0; } + bool atFirst() const { return Q3GCacheIterator::atFirst(); } + bool atLast() const { return Q3GCacheIterator::atLast(); } + type *toFirst() { return (type *)Q3GCacheIterator::toFirst(); } + type *toLast() { return (type *)Q3GCacheIterator::toLast(); } + operator type *() const { return (type *)Q3GCacheIterator::get(); } + type *current() const { return (type *)Q3GCacheIterator::get(); } + long currentKey() const { return (long)Q3GCacheIterator::getKeyInt();} + type *operator()() { return (type *)Q3GCacheIterator::operator()();} + type *operator++() { return (type *)Q3GCacheIterator::operator++(); } + type *operator+=(uint j) { return (type *)Q3GCacheIterator::operator+=(j);} + type *operator--() { return (type *)Q3GCacheIterator::operator--(); } + type *operator-=(uint j) { return (type *)Q3GCacheIterator::operator-=(j);} +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3INTCACHE_H diff --git a/src/qt3support/tools/q3intdict.h b/src/qt3support/tools/q3intdict.h new file mode 100644 index 0000000..d91162c --- /dev/null +++ b/src/qt3support/tools/q3intdict.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3INTDICT_H +#define Q3INTDICT_H + +#include <Qt3Support/q3gdict.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3IntDict +#ifdef qdoc + : public Q3PtrCollection +#else + : public Q3GDict +#endif +{ +public: + Q3IntDict(int size=17) : Q3GDict(size,IntKey,0,0) {} + Q3IntDict( const Q3IntDict<type> &d ) : Q3GDict(d) {} + ~Q3IntDict() { clear(); } + Q3IntDict<type> &operator=(const Q3IntDict<type> &d) + { return (Q3IntDict<type>&)Q3GDict::operator=(d); } + uint count() const { return Q3GDict::count(); } + uint size() const { return Q3GDict::size(); } + bool isEmpty() const { return Q3GDict::count() == 0; } + void insert( long k, const type *d ) + { Q3GDict::look_int(k,(Item)d,1); } + void replace( long k, const type *d ) + { Q3GDict::look_int(k,(Item)d,2); } + bool remove( long k ) { return Q3GDict::remove_int(k); } + type *take( long k ) { return (type*)Q3GDict::take_int(k); } + type *find( long k ) const + { return (type *)((Q3GDict*)this)->Q3GDict::look_int(k,0,0); } + type *operator[]( long k ) const + { return (type *)((Q3GDict*)this)->Q3GDict::look_int(k,0,0); } + void clear() { Q3GDict::clear(); } + void resize( uint n ) { Q3GDict::resize(n); } + void statistics() const { Q3GDict::statistics(); } + +#ifdef qdoc +protected: + virtual QDataStream& read( QDataStream &, Q3PtrCollection::Item & ); + virtual QDataStream& write( QDataStream &, Q3PtrCollection::Item ) const; +#endif + +private: + void deleteItem( Item d ); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3IntDict<void>::deleteItem( Q3PtrCollection::Item ) +{ +} +#endif + +template<class type> inline void Q3IntDict<type>::deleteItem( Q3PtrCollection::Item d ) +{ + if ( del_item ) delete (type*)d; +} + +template<class type> +class Q3IntDictIterator : public Q3GDictIterator +{ +public: + Q3IntDictIterator(const Q3IntDict<type> &d) :Q3GDictIterator((Q3GDict &)d) {} + ~Q3IntDictIterator() {} + uint count() const { return dict->count(); } + bool isEmpty() const { return dict->count() == 0; } + type *toFirst() { return (type *)Q3GDictIterator::toFirst(); } + operator type *() const { return (type *)Q3GDictIterator::get(); } + type *current() const { return (type *)Q3GDictIterator::get(); } + long currentKey() const { return Q3GDictIterator::getKeyInt(); } + type *operator()() { return (type *)Q3GDictIterator::operator()(); } + type *operator++() { return (type *)Q3GDictIterator::operator++(); } + type *operator+=(uint j) { return (type *)Q3GDictIterator::operator+=(j);} +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3INTDICT_H diff --git a/src/qt3support/tools/q3memarray.h b/src/qt3support/tools/q3memarray.h new file mode 100644 index 0000000..4152a7b --- /dev/null +++ b/src/qt3support/tools/q3memarray.h @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3MEMARRAY_H +#define Q3MEMARRAY_H + +#include <Qt3Support/q3garray.h> +#include <QtCore/qvector.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3MemArray : public Q3GArray +{ +public: + typedef type* Iterator; + typedef const type* ConstIterator; + typedef type ValueType; + +protected: + Q3MemArray(int, int) : Q3GArray(0, 0) {} + +public: + Q3MemArray() {} + Q3MemArray(int size) : Q3GArray(size*sizeof(type)) {} + Q3MemArray(const Q3MemArray<type> &a) : Q3GArray(a) {} + Q3MemArray(const QVector<type> &vector); + ~Q3MemArray() {} + Q3MemArray<type> &operator=(const Q3MemArray<type> &a) + { return (Q3MemArray<type>&)Q3GArray::assign(a); } + type *data() const { return (type *)Q3GArray::data(); } + uint nrefs() const { return Q3GArray::nrefs(); } + uint size() const { return Q3GArray::size()/sizeof(type); } + uint count() const { return size(); } + bool isEmpty() const { return Q3GArray::size() == 0; } + bool isNull() const { return Q3GArray::data() == 0; } + bool resize(uint size) { return Q3GArray::resize(size*sizeof(type)); } + bool resize(uint size, Optimization optim) { return Q3GArray::resize(size*sizeof(type), optim); } + bool truncate(uint pos) { return Q3GArray::resize(pos*sizeof(type)); } + bool fill(const type &d, int size = -1) + { return Q3GArray::fill((char*)&d,size,sizeof(type)); } + void detach() { Q3GArray::detach(); } + Q3MemArray<type> copy() const + { Q3MemArray<type> tmp; return tmp.duplicate(*this); } + Q3MemArray<type>& assign(const Q3MemArray<type>& a) + { return (Q3MemArray<type>&)Q3GArray::assign(a); } + Q3MemArray<type>& assign(const type *a, uint n) + { return (Q3MemArray<type>&)Q3GArray::assign((char*)a,n*sizeof(type)); } + Q3MemArray<type>& duplicate(const Q3MemArray<type>& a) + { return (Q3MemArray<type>&)Q3GArray::duplicate(a); } + Q3MemArray<type>& duplicate(const type *a, uint n) + { return (Q3MemArray<type>&)Q3GArray::duplicate((char*)a,n*sizeof(type)); } + Q3MemArray<type>& setRawData(const type *a, uint n) + { return (Q3MemArray<type>&)Q3GArray::setRawData((char*)a, + n*sizeof(type)); } + void resetRawData(const type *a, uint n) + { Q3GArray::resetRawData((char*)a,n*sizeof(type)); } + int find(const type &d, uint i=0) const + { return Q3GArray::find((char*)&d,i,sizeof(type)); } + int contains(const type &d) const + { return Q3GArray::contains((char*)&d,sizeof(type)); } + void sort() { Q3GArray::sort(sizeof(type)); } + int bsearch(const type &d) const + { return Q3GArray::bsearch((const char*)&d,sizeof(type)); } + // ### Qt 4.0: maybe provide uint overload as work-around for MSVC bug + type& operator[](int i) const + { return (type &)(*(type *)Q3GArray::at(i*sizeof(type))); } + type& at(uint i) const + { return (type &)(*(type *)Q3GArray::at(i*sizeof(type))); } + operator const type*() const { return (const type *)Q3GArray::data(); } + bool operator==(const Q3MemArray<type> &a) const { return isEqual(a); } + bool operator!=(const Q3MemArray<type> &a) const { return !isEqual(a); } + Iterator begin() { return data(); } + Iterator end() { return data() + size(); } + ConstIterator begin() const { return data(); } + ConstIterator end() const { return data() + size(); } + + operator QVector<type>() const; +}; + +template<class type> +Q_OUTOFLINE_TEMPLATE Q3MemArray<type>::Q3MemArray(const QVector<type> &vector) + : Q3GArray(vector.size()*sizeof(type)) +{ + for (int i = 0; i < vector.size(); ++i) + at(i) = vector.at(i); +} + +template<class type> +Q_OUTOFLINE_TEMPLATE Q3MemArray<type>::operator QVector<type>() const +{ + QVector<type> vector; + for (int i = 0; i < size(); ++i) + vector.append(at(i)); + return vector; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3MEMARRAY_H diff --git a/src/qt3support/tools/q3objectdict.h b/src/qt3support/tools/q3objectdict.h new file mode 100644 index 0000000..46ca741 --- /dev/null +++ b/src/qt3support/tools/q3objectdict.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3OBJECTDICT_H +#define Q3OBJECTDICT_H + +#include <QtCore/qmetaobject.h> +#include <Qt3Support/q3asciidict.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +// +// The object dictionary is a collection of QMetaObjects +// + +class Q3ObjectDictionary : public Q3AsciiDict<QMetaObject> +{ +public: + Q3ObjectDictionary(int size=17,bool cs=true,bool ck=true) + : Q3AsciiDict<QMetaObject>(size,cs,ck) {} + Q3ObjectDictionary( const Q3ObjectDictionary &dict ) + : Q3AsciiDict<QMetaObject>(dict) {} + ~Q3ObjectDictionary() { clear(); } + Q3ObjectDictionary &operator=(const Q3ObjectDictionary &dict) + { return (Q3ObjectDictionary&)Q3AsciiDict<QMetaObject>::operator=(dict);} +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3OBJECTDICT_H diff --git a/src/qt3support/tools/q3ptrcollection.cpp b/src/qt3support/tools/q3ptrcollection.cpp new file mode 100644 index 0000000..1d00a64 --- /dev/null +++ b/src/qt3support/tools/q3ptrcollection.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3ptrcollection.h" + +QT_BEGIN_NAMESPACE + +/*! + \class Q3PtrCollection + \reentrant + \brief The Q3PtrCollection class is the base class of most pointer-based Qt collections. + + \compat + + The Q3PtrCollection class is an abstract base class for the Qt + collection classes QDict, Q3PtrList, + etc. + + A Q3PtrCollection only knows about the number of objects in the + collection and the deletion strategy (see setAutoDelete()). + + A collection is implemented using the \c Item (generic collection + item) type, which is a \c void*. The template classes that create + the real collections cast the \c Item to the required type. +*/ + + +/*! + \typedef Q3PtrCollection::Item + + This type is the generic "item" in a Q3PtrCollection. +*/ + + +/*! + \fn Q3PtrCollection::Q3PtrCollection() + + Constructs a collection. The constructor is protected because + Q3PtrCollection is an abstract class. +*/ + +/*! + \fn Q3PtrCollection::Q3PtrCollection( const Q3PtrCollection & source ) + + Constructs a copy of \a source with autoDelete() set to false. The + constructor is protected because Q3PtrCollection is an abstract + class. + + Note that if \a source has autoDelete turned on, copying it will + risk memory leaks, reading freed memory, or both. +*/ + +/*! + \fn Q3PtrCollection::~Q3PtrCollection() + + Destroys the collection. The destructor is protected because + Q3PtrCollection is an abstract class. +*/ + + +/*! + \fn bool Q3PtrCollection::autoDelete() const + + Returns the setting of the auto-delete option. The default is false. + + \sa setAutoDelete() +*/ + +/*! + \fn void Q3PtrCollection::setAutoDelete( bool enable ) + + Sets the collection to auto-delete its contents if \a enable is + true and to never delete them if \a enable is false. + + If auto-deleting is turned on, all the items in a collection are + deleted when the collection itself is deleted. This is convenient + if the collection has the only pointer to the items. + + The default setting is false, for safety. If you turn it on, be + careful about copying the collection - you might find yourself + with two collections deleting the same items. + + Note that the auto-delete setting may also affect other functions + in subclasses. For example, a subclass that has a remove() + function will remove the item from its data structure, and if + auto-delete is enabled, will also delete the item. + + \sa autoDelete() +*/ + + +/*! + \fn virtual uint Q3PtrCollection::count() const + + Returns the number of objects in the collection. +*/ + +/*! + \fn virtual void Q3PtrCollection::clear() + + Removes all objects from the collection. The objects will be + deleted if auto-delete has been enabled. + + \sa setAutoDelete() +*/ + +/*! + \fn void Q3PtrCollection::deleteItem( Item d ) + + Reimplement this function if you want to be able to delete items. + + Deletes an item that is about to be removed from the collection. + + This function has to reimplemented in the collection template + classes, and should \e only delete item \a d if auto-delete has + been enabled. + + \warning If you reimplement this function you must also + reimplement the destructor and call the virtual function clear() + from your destructor. This is due to the way virtual functions and + destructors work in C++: Virtual functions in derived classes + cannot be called from a destructor. If you do not do this, your + deleteItem() function will not be called when the container is + destroyed. + + \sa newItem(), setAutoDelete() +*/ + +/*! + Virtual function that creates a copy of an object that is about to + be inserted into the collection. + + The default implementation returns the \a d pointer, i.e. no copy + is made. + + This function is seldom reimplemented in the collection template + classes. It is not common practice to make a copy of something + that is being inserted. + + \sa deleteItem() +*/ + +Q3PtrCollection::Item Q3PtrCollection::newItem(Item d) +{ + return d; // just return reference +} + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3ptrcollection.h b/src/qt3support/tools/q3ptrcollection.h new file mode 100644 index 0000000..4c8071d --- /dev/null +++ b/src/qt3support/tools/q3ptrcollection.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3PTRCOLLECTION_H +#define Q3PTRCOLLECTION_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +class Q3GVector; +class Q3GList; +class Q3GDict; + +class Q_COMPAT_EXPORT Q3PtrCollection // inherited by all collections +{ +public: + bool autoDelete() const { return del_item; } + void setAutoDelete(bool enable) { del_item = enable; } + + virtual uint count() const = 0; + virtual void clear() = 0; // delete all objects + + typedef void *Item; // generic collection item + +protected: + Q3PtrCollection() { del_item = false; } // no deletion of objects + Q3PtrCollection(const Q3PtrCollection &) { del_item = false; } + virtual ~Q3PtrCollection() {} + + bool del_item; // default false + + virtual Item newItem(Item); // create object + virtual void deleteItem(Item) = 0; // delete object +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3PTRCOLLECTION_H diff --git a/src/qt3support/tools/q3ptrdict.h b/src/qt3support/tools/q3ptrdict.h new file mode 100644 index 0000000..f162e7c --- /dev/null +++ b/src/qt3support/tools/q3ptrdict.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3PTRDICT_H +#define Q3PTRDICT_H + +#include <Qt3Support/q3gdict.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3PtrDict +#ifdef qdoc + : public Q3PtrCollection +#else + : public Q3GDict +#endif +{ +public: + Q3PtrDict(int size=17) : Q3GDict(size,PtrKey,0,0) {} + Q3PtrDict( const Q3PtrDict<type> &d ) : Q3GDict(d) {} + ~Q3PtrDict() { clear(); } + Q3PtrDict<type> &operator=(const Q3PtrDict<type> &d) + { return (Q3PtrDict<type>&)Q3GDict::operator=(d); } + uint count() const { return Q3GDict::count(); } + uint size() const { return Q3GDict::size(); } + bool isEmpty() const { return Q3GDict::count() == 0; } + void insert( void *k, const type *d ) + { Q3GDict::look_ptr(k,(Item)d,1); } + void replace( void *k, const type *d ) + { Q3GDict::look_ptr(k,(Item)d,2); } + bool remove( void *k ) { return Q3GDict::remove_ptr(k); } + type *take( void *k ) { return (type*)Q3GDict::take_ptr(k); } + type *find( void *k ) const + { return (type *)((Q3GDict*)this)->Q3GDict::look_ptr(k,0,0); } + type *operator[]( void *k ) const + { return (type *)((Q3GDict*)this)->Q3GDict::look_ptr(k,0,0); } + void clear() { Q3GDict::clear(); } + void resize( uint n ) { Q3GDict::resize(n); } + void statistics() const { Q3GDict::statistics(); } + +#ifdef qdoc +protected: + virtual QDataStream& read( QDataStream &, Q3PtrCollection::Item & ); + virtual QDataStream& write( QDataStream &, Q3PtrCollection::Item ) const; +#endif + +private: + void deleteItem( Item d ); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3PtrDict<void>::deleteItem( Q3PtrCollection::Item ) +{ +} +#endif + +template<class type> +inline void Q3PtrDict<type>::deleteItem( Q3PtrCollection::Item d ) +{ + if ( del_item ) delete (type *)d; +} + +template<class type> +class Q3PtrDictIterator : public Q3GDictIterator +{ +public: + Q3PtrDictIterator(const Q3PtrDict<type> &d) :Q3GDictIterator((Q3GDict &)d) {} + ~Q3PtrDictIterator() {} + uint count() const { return dict->count(); } + bool isEmpty() const { return dict->count() == 0; } + type *toFirst() { return (type *)Q3GDictIterator::toFirst(); } + operator type *() const { return (type *)Q3GDictIterator::get(); } + type *current() const { return (type *)Q3GDictIterator::get(); } + void *currentKey() const { return Q3GDictIterator::getKeyPtr(); } + type *operator()() { return (type *)Q3GDictIterator::operator()(); } + type *operator++() { return (type *)Q3GDictIterator::operator++(); } + type *operator+=(uint j) { return (type *)Q3GDictIterator::operator+=(j);} +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3PTRDICT_H diff --git a/src/qt3support/tools/q3ptrlist.h b/src/qt3support/tools/q3ptrlist.h new file mode 100644 index 0000000..ffad698 --- /dev/null +++ b/src/qt3support/tools/q3ptrlist.h @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3PTRLIST_H +#define Q3PTRLIST_H + +#include <Qt3Support/q3glist.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3PtrListStdIterator : public Q3GListStdIterator +{ +public: + inline Q3PtrListStdIterator( Q3LNode* n ): Q3GListStdIterator(n) {} + type *operator*() { return node ? (type *)node->getData() : 0; } + inline Q3PtrListStdIterator<type> operator++() + { node = next(); return *this; } + inline Q3PtrListStdIterator<type> operator++(int) + { Q3LNode* n = node; node = next(); return Q3PtrListStdIterator<type>( n ); } + inline bool operator==( const Q3PtrListStdIterator<type>& it ) const { return node == it.node; } + inline bool operator!=( const Q3PtrListStdIterator<type>& it ) const { return node != it.node; } +}; + + +template<class type> +class Q3PtrList +#ifdef qdoc + : public Q3PtrCollection +#else + : public Q3GList +#endif +{ +public: + + Q3PtrList() {} + Q3PtrList( const Q3PtrList<type> &l ) : Q3GList(l) {} + ~Q3PtrList() { clear(); } + Q3PtrList<type> &operator=(const Q3PtrList<type> &l) + { return (Q3PtrList<type>&)Q3GList::operator=(l); } + bool operator==( const Q3PtrList<type> &list ) const + { return Q3GList::operator==( list ); } + bool operator!=( const Q3PtrList<type> &list ) const + { return !Q3GList::operator==( list ); } + uint count() const { return Q3GList::count(); } + bool isEmpty() const { return Q3GList::count() == 0; } + bool insert( uint i, const type *d){ return Q3GList::insertAt(i,(Q3PtrCollection::Item)d); } + void inSort( const type *d ) { Q3GList::inSort((Q3PtrCollection::Item)d); } + void prepend( const type *d ) { Q3GList::insertAt(0,(Q3PtrCollection::Item)d); } + void append( const type *d ) { Q3GList::append((Q3PtrCollection::Item)d); } + bool remove( uint i ) { return Q3GList::removeAt(i); } + bool remove() { return Q3GList::remove((Q3PtrCollection::Item)0); } + bool remove( const type *d ) { return Q3GList::remove((Q3PtrCollection::Item)d); } + bool removeRef( const type *d ) { return Q3GList::removeRef((Q3PtrCollection::Item)d); } + void removeNode( Q3LNode *n ) { Q3GList::removeNode(n); } + bool removeFirst() { return Q3GList::removeFirst(); } + bool removeLast() { return Q3GList::removeLast(); } + type *take( uint i ) { return (type *)Q3GList::takeAt(i); } + type *take() { return (type *)Q3GList::take(); } + type *takeNode( Q3LNode *n ) { return (type *)Q3GList::takeNode(n); } + void clear() { Q3GList::clear(); } + void sort() { Q3GList::sort(); } + int find( const type *d ) { return Q3GList::find((Q3PtrCollection::Item)d); } + int findNext( const type *d ) { return Q3GList::find((Q3PtrCollection::Item)d,false); } + int findRef( const type *d ) { return Q3GList::findRef((Q3PtrCollection::Item)d); } + int findNextRef( const type *d ){ return Q3GList::findRef((Q3PtrCollection::Item)d,false);} + uint contains( const type *d ) const { return Q3GList::contains((Q3PtrCollection::Item)d); } + uint containsRef( const type *d ) const + { return Q3GList::containsRef((Q3PtrCollection::Item)d); } + bool replace( uint i, const type *d ) { return Q3GList::replaceAt( i, (Q3PtrCollection::Item)d ); } + type *at( uint i ) { return (type *)Q3GList::at(i); } + int at() const { return Q3GList::at(); } + type *current() const { return (type *)Q3GList::get(); } + Q3LNode *currentNode() const { return Q3GList::currentNode(); } + type *getFirst() const { return (type *)Q3GList::cfirst(); } + type *getLast() const { return (type *)Q3GList::clast(); } + type *first() { return (type *)Q3GList::first(); } + type *last() { return (type *)Q3GList::last(); } + type *next() { return (type *)Q3GList::next(); } + type *prev() { return (type *)Q3GList::prev(); } + void toVector( Q3GVector *vec )const{ Q3GList::toVector(vec); } + + + // standard iterators + typedef Q3PtrListStdIterator<type> Iterator; + typedef Q3PtrListStdIterator<type> ConstIterator; + inline Iterator begin() { return Q3GList::begin(); } + inline ConstIterator begin() const { return Q3GList::begin(); } + inline ConstIterator constBegin() const { return Q3GList::begin(); } + inline Iterator end() { return Q3GList::end(); } + inline ConstIterator end() const { return Q3GList::end(); } + inline ConstIterator constEnd() const { return Q3GList::end(); } + inline Iterator erase( Iterator it ) { return Q3GList::erase( it ); } + // stl syntax compatibility + typedef Iterator iterator; + typedef ConstIterator const_iterator; + + +#ifdef qdoc +protected: + virtual int compareItems( Q3PtrCollection::Item, Q3PtrCollection::Item ); + virtual QDataStream& read( QDataStream&, Q3PtrCollection::Item& ); + virtual QDataStream& write( QDataStream&, Q3PtrCollection::Item ) const; +#endif + +private: + void deleteItem( Item d ); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3PtrList<void>::deleteItem( Q3PtrCollection::Item ) +{ +} +#endif + +template<class type> inline void Q3PtrList<type>::deleteItem( Q3PtrCollection::Item d ) +{ + if ( del_item ) delete (type *)d; +} + +template<class type> +class Q3PtrListIterator : public Q3GListIterator +{ +public: + Q3PtrListIterator(const Q3PtrList<type> &l) :Q3GListIterator((Q3GList &)l) {} + ~Q3PtrListIterator() {} + uint count() const { return list->count(); } + bool isEmpty() const { return list->count() == 0; } + bool atFirst() const { return Q3GListIterator::atFirst(); } + bool atLast() const { return Q3GListIterator::atLast(); } + type *toFirst() { return (type *)Q3GListIterator::toFirst(); } + type *toLast() { return (type *)Q3GListIterator::toLast(); } + operator type *() const { return (type *)Q3GListIterator::get(); } + type *operator*() { return (type *)Q3GListIterator::get(); } + + // No good, since Q3PtrList<char> (ie. QStrList fails... + // + // MSVC++ gives warning + // Sunpro C++ 4.1 gives error + // type *operator->() { return (type *)Q3GListIterator::get(); } + + type *current() const { return (type *)Q3GListIterator::get(); } + type *operator()() { return (type *)Q3GListIterator::operator()();} + type *operator++() { return (type *)Q3GListIterator::operator++(); } + type *operator+=(uint j) { return (type *)Q3GListIterator::operator+=(j);} + type *operator--() { return (type *)Q3GListIterator::operator--(); } + type *operator-=(uint j) { return (type *)Q3GListIterator::operator-=(j);} + Q3PtrListIterator<type>& operator=(const Q3PtrListIterator<type>&it) + { Q3GListIterator::operator=(it); return *this; } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3PTRLIST_H diff --git a/src/qt3support/tools/q3ptrqueue.h b/src/qt3support/tools/q3ptrqueue.h new file mode 100644 index 0000000..bb3210c --- /dev/null +++ b/src/qt3support/tools/q3ptrqueue.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3PTRQUEUE_H +#define Q3PTRQUEUE_H + +#include <Qt3Support/q3glist.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3PtrQueue : protected Q3GList +{ +public: + Q3PtrQueue() {} + Q3PtrQueue( const Q3PtrQueue<type> &q ) : Q3GList(q) {} + ~Q3PtrQueue() { clear(); } + Q3PtrQueue<type>& operator=(const Q3PtrQueue<type> &q) + { return (Q3PtrQueue<type>&)Q3GList::operator=(q); } + bool autoDelete() const { return Q3PtrCollection::autoDelete(); } + void setAutoDelete( bool del ) { Q3PtrCollection::setAutoDelete(del); } + uint count() const { return Q3GList::count(); } + bool isEmpty() const { return Q3GList::count() == 0; } + void enqueue( const type *d ) { Q3GList::append(Item(d)); } + type *dequeue() { return (type *)Q3GList::takeFirst();} + bool remove() { return Q3GList::removeFirst(); } + void clear() { Q3GList::clear(); } + type *head() const { return (type *)Q3GList::cfirst(); } + operator type *() const { return (type *)Q3GList::cfirst(); } + type *current() const { return (type *)Q3GList::cfirst(); } + +#ifdef qdoc +protected: + virtual QDataStream& read( QDataStream&, Q3PtrCollection::Item& ); + virtual QDataStream& write( QDataStream&, Q3PtrCollection::Item ) const; +#endif + +private: + void deleteItem( Item d ); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3PtrQueue<void>::deleteItem( Q3PtrCollection::Item ) +{ +} +#endif + +template<class type> inline void Q3PtrQueue<type>::deleteItem( Q3PtrCollection::Item d ) +{ + if ( del_item ) delete (type *)d; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3PTRQUEUE_H diff --git a/src/qt3support/tools/q3ptrstack.h b/src/qt3support/tools/q3ptrstack.h new file mode 100644 index 0000000..f303003 --- /dev/null +++ b/src/qt3support/tools/q3ptrstack.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3PTRSTACK_H +#define Q3PTRSTACK_H + +#include <Qt3Support/q3glist.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3PtrStack : protected Q3GList +{ +public: + Q3PtrStack() { } + Q3PtrStack( const Q3PtrStack<type> &s ) : Q3GList( s ) { } + ~Q3PtrStack() { clear(); } + Q3PtrStack<type> &operator=(const Q3PtrStack<type> &s) + { return (Q3PtrStack<type>&)Q3GList::operator=(s); } + bool autoDelete() const { return Q3PtrCollection::autoDelete(); } + void setAutoDelete( bool del ) { Q3PtrCollection::setAutoDelete(del); } + uint count() const { return Q3GList::count(); } + bool isEmpty() const { return Q3GList::count() == 0; } + void push( const type *d ) { Q3GList::insertAt(0,Item(d)); } + type *pop() { return (type *)Q3GList::takeFirst(); } + bool remove() { return Q3GList::removeFirst(); } + void clear() { Q3GList::clear(); } + type *top() const { return (type *)Q3GList::cfirst(); } + operator type *() const { return (type *)Q3GList::cfirst(); } + type *current() const { return (type *)Q3GList::cfirst(); } + +#ifdef qdoc +protected: + virtual QDataStream& read( QDataStream&, Q3PtrCollection::Item& ); + virtual QDataStream& write( QDataStream&, Q3PtrCollection::Item ) const; +#endif + +private: + void deleteItem( Item d ); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3PtrStack<void>::deleteItem( Q3PtrCollection::Item ) +{ +} +#endif + +template<class type> inline void Q3PtrStack<type>::deleteItem( Q3PtrCollection::Item d ) +{ + if ( del_item ) delete (type *)d; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3PTRSTACK_H diff --git a/src/qt3support/tools/q3ptrvector.h b/src/qt3support/tools/q3ptrvector.h new file mode 100644 index 0000000..85cf372 --- /dev/null +++ b/src/qt3support/tools/q3ptrvector.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3PTRVECTOR_H +#define Q3PTRVECTOR_H + +#include <Qt3Support/q3gvector.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3PtrVector +#ifdef qdoc + : public Q3PtrCollection +#else + : public Q3GVector +#endif +{ +public: + Q3PtrVector() { } + Q3PtrVector( uint size ) : Q3GVector(size) { } + Q3PtrVector( const Q3PtrVector<type> &v ) : Q3GVector( v ) { } + ~Q3PtrVector() { clear(); } + Q3PtrVector<type> &operator=(const Q3PtrVector<type> &v) + { return (Q3PtrVector<type>&)Q3GVector::operator=(v); } + bool operator==( const Q3PtrVector<type> &v ) const { return Q3GVector::operator==(v); } + type **data() const { return (type **)Q3GVector::data(); } + uint size() const { return Q3GVector::size(); } + uint count() const { return Q3GVector::count(); } + bool isEmpty() const { return Q3GVector::count() == 0; } + bool isNull() const { return Q3GVector::size() == 0; } + bool resize( uint size ) { return Q3GVector::resize(size); } + bool insert( uint i, const type *d){ return Q3GVector::insert(i,(Item)d); } + bool remove( uint i ) { return Q3GVector::remove(i); } + type *take( uint i ) { return (type *)Q3GVector::take(i); } + void clear() { Q3GVector::clear(); } + bool fill( const type *d, int size=-1 ) + { return Q3GVector::fill((Item)d,size);} + void sort() { Q3GVector::sort(); } + int bsearch( const type *d ) const{ return Q3GVector::bsearch((Item)d); } + int findRef( const type *d, uint i=0 ) const + { return Q3GVector::findRef((Item)d,i);} + int find( const type *d, uint i= 0 ) const + { return Q3GVector::find((Item)d,i); } + uint containsRef( const type *d ) const + { return Q3GVector::containsRef((Item)d); } + uint contains( const type *d ) const + { return Q3GVector::contains((Item)d); } + type *operator[]( int i ) const { return (type *)Q3GVector::at(i); } + type *at( uint i ) const { return (type *)Q3GVector::at(i); } + void toList( Q3GList *list ) const { Q3GVector::toList(list); } + +#ifdef qdoc +protected: + virtual int compareItems( Q3PtrCollection::Item d1, Q3PtrCollection::Item d2 ); + virtual QDataStream& read( QDataStream &s, Q3PtrCollection::Item &d ); + virtual QDataStream& write( QDataStream &s, Q3PtrCollection::Item d ) const; +#endif + +private: + void deleteItem( Item d ); +}; + +#if !defined(Q_BROKEN_TEMPLATE_SPECIALIZATION) +template<> inline void Q3PtrVector<void>::deleteItem( Q3PtrCollection::Item ) +{ +} +#endif + +template<class type> inline void Q3PtrVector<type>::deleteItem( Q3PtrCollection::Item d ) +{ + if ( del_item ) delete (type *)d; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3PTRVECTOR_H diff --git a/src/qt3support/tools/q3semaphore.cpp b/src/qt3support/tools/q3semaphore.cpp new file mode 100644 index 0000000..7fc39d7 --- /dev/null +++ b/src/qt3support/tools/q3semaphore.cpp @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3semaphore.h" + +#include "qmutex.h" +#include "qwaitcondition.h" + +QT_BEGIN_NAMESPACE + +/*! + \class Q3Semaphore + \threadsafe + \brief The Q3Semaphore class provides a robust integer semaphore. + + \compat + + A Q3Semaphore can be used to serialize thread execution, in a + similar way to a QMutex. A semaphore differs from a mutex, in + that a semaphore can be accessed by more than one thread at a + time. + + For example, suppose we have an application that stores data in a + large tree structure. The application creates 10 threads + (commonly called a thread pool) to perform searches on the tree. + When the application searches the tree for some piece of data, it + uses one thread per base node to do the searching. A semaphore + could be used to make sure that two threads don't try to search + the same branch of the tree at the same time. + + A non-computing example of a semaphore would be dining at a + restaurant. A semaphore is initialized to have a maximum count + equal to the number of chairs in the restaurant. As people + arrive, they want a seat. As seats are filled, the semaphore is + accessed, once per person. As people leave, the access is + released, allowing more people to enter. If a party of 10 people + want to be seated, but there are only 9 seats, those 10 people + will wait, but a party of 4 people would be seated (taking the + available seats to 5, making the party of 10 people wait longer). + + When a semaphore is created it is given a number which is the + maximum number of concurrent accesses it will permit. This amount + may be changed using operator++(), operator--(), operator+=() and + operator-=(). The number of accesses allowed is retrieved with + available(), and the total number with total(). Note that the + incrementing functions will block if there aren't enough available + accesses. Use tryAccess() if you want to acquire accesses without + blocking. +*/ + +#ifdef max +#undef max +#endif + +class Q3SemaphorePrivate { +public: + Q3SemaphorePrivate(int); + + QMutex mutex; + QWaitCondition cond; + + int value, max; +}; + + +Q3SemaphorePrivate::Q3SemaphorePrivate(int m) + : value(0), max(m) +{ +} + + +/*! + Creates a new semaphore. The semaphore can be concurrently + accessed at most \a maxcount times. +*/ +Q3Semaphore::Q3Semaphore(int maxcount) +{ + d = new Q3SemaphorePrivate(maxcount); +} + + +/*! + Destroys the semaphore. + + \warning If you destroy a semaphore that has accesses in use the + resultant behavior is undefined. +*/ +Q3Semaphore::~Q3Semaphore() +{ + delete d; +} + + +/*! + Postfix ++ operator. + + Try to get access to the semaphore. If \l available() == 0, this + call will block until it can get access, i.e. until available() \> + 0. +*/ +int Q3Semaphore::operator++(int) +{ + QMutexLocker locker(&d->mutex); + while (d->value >= d->max) + d->cond.wait(locker.mutex()); + + ++d->value; + if (d->value > d->max) + d->value = d->max; + + return d->value; +} + + +/*! + Postfix -- operator. + + Release access of the semaphore. This wakes all threads waiting + for access to the semaphore. +*/ +int Q3Semaphore::operator--(int) +{ + QMutexLocker locker(&d->mutex); + + --d->value; + if (d->value < 0) + d->value = 0; + + d->cond.wakeAll(); + + return d->value; +} + + +/*! + Try to get access to the semaphore. If \l available() \< \a n, this + call will block until it can get all the accesses it wants, i.e. + until available() \>= \a n. +*/ +int Q3Semaphore::operator+=(int n) +{ + QMutexLocker locker(&d->mutex); + + if (n < 0 || n > d->max) { + qWarning("Q3Semaphore::operator+=: parameter %d out of range", n); + n = n < 0 ? 0 : d->max; + } + + while (d->value + n > d->max) + d->cond.wait(locker.mutex()); + + d->value += n; + + return d->value; +} + + +/*! + Release \a n accesses to the semaphore. +*/ +int Q3Semaphore::operator-=(int n) +{ + QMutexLocker locker(&d->mutex); + + if (n < 0 || n > d->value) { + qWarning("Q3Semaphore::operator-=: parameter %d out of range", n); + n = n < 0 ? 0 : d->value; + } + + d->value -= n; + d->cond.wakeAll(); + + return d->value; +} + + +/*! + Returns the number of accesses currently available to the + semaphore. +*/ +int Q3Semaphore::available() const +{ + QMutexLocker locker(&d->mutex); + return d->max - d->value; +} + + +/*! + Returns the total number of accesses to the semaphore. +*/ +int Q3Semaphore::total() const +{ + QMutexLocker locker(&d->mutex); + return d->max; +} + + +/*! + Try to get access to the semaphore. If \l available() \< \a n, this + function will return false immediately. If \l available() \>= \a n, + this function will take \a n accesses and return true. This + function does \e not block. +*/ +bool Q3Semaphore::tryAccess(int n) +{ + QMutexLocker locker(&d->mutex); + + if (d->value + n > d->max) + return false; + + d->value += n; + + return true; +} + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3semaphore.h b/src/qt3support/tools/q3semaphore.h new file mode 100644 index 0000000..ea643bd --- /dev/null +++ b/src/qt3support/tools/q3semaphore.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3SEMAPHORE_H +#define Q3SEMAPHORE_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +class Q3SemaphorePrivate; + +class Q_COMPAT_EXPORT Q3Semaphore +{ +public: + Q3Semaphore(int); + virtual ~Q3Semaphore(); + + int available() const; + int total() const; + + // postfix operators + int operator++(int); + int operator--(int); + + int operator+=(int); + int operator-=(int); + + bool tryAccess(int); + +private: + Q_DISABLE_COPY(Q3Semaphore) + + Q3SemaphorePrivate *d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3SEMAPHORE_H diff --git a/src/qt3support/tools/q3shared.cpp b/src/qt3support/tools/q3shared.cpp new file mode 100644 index 0000000..fc9d060 --- /dev/null +++ b/src/qt3support/tools/q3shared.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3shared.h" + +QT_BEGIN_NAMESPACE + +/*! + \class Q3Shared + \brief The Q3Shared class is used internally for implementing shared classes. + \compat + + Use QSharedData and QSharedDataPointer instead. +*/ + +/*! + \fn Q3Shared::Q3Shared() + + Constructs a Q3Shared object with a reference count of 1. +*/ + +/*! + \fn void Q3Shared::ref() + + Increments the reference count. +*/ + +/*! + \fn bool Q3Shared::deref() + Decrements the reference count and returns true if + any references remain. +*/ + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3shared.h b/src/qt3support/tools/q3shared.h new file mode 100644 index 0000000..59bf808 --- /dev/null +++ b/src/qt3support/tools/q3shared.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3SHARED_H +#define Q3SHARED_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +struct Q_COMPAT_EXPORT Q3Shared +{ + Q3Shared() : count( 1 ) { } + void ref() { count++; } + bool deref() { return !--count; } + uint count; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3SHARED_H diff --git a/src/qt3support/tools/q3signal.cpp b/src/qt3support/tools/q3signal.cpp new file mode 100644 index 0000000..7d555b4 --- /dev/null +++ b/src/qt3support/tools/q3signal.cpp @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "q3signal.h" +#include "qmetaobject.h" +#include "qpointer.h" +#include "q3cstring.h" + +QT_BEGIN_NAMESPACE + +/*! + \class Q3Signal + \brief The Q3Signal class can be used to send signals for classes + that don't inherit QObject. + + \compat + + If you want to send signals from a class that does not inherit + QObject, you can create an internal Q3Signal object to emit the + signal. You must also provide a function that connects the signal + to an outside object slot. This is how we used to implement + signals in Qt 3's QMenuData class, which was not a QObject. In Qt + 4, menus contain actions, which are QObjects. + + In general, we recommend inheriting QObject instead. QObject + provides much more functionality. + + You can set a single QVariant parameter for the signal with + setValue(). + + Note that QObject is a \e private base class of Q3Signal, i.e. you + cannot call any QObject member functions from a Q3Signal object. + + Example: + \snippet doc/src/snippets/code/src_qt3support_tools_q3signal.cpp 0 +*/ + +/*! + Constructs a signal object called \a name, with the parent object + \a parent. These arguments are passed directly to QObject. +*/ + +Q3Signal::Q3Signal(QObject *parent, const char *name) + : QObject(parent, name) +{ +#ifndef QT_NO_VARIANT + val = 0; +#endif +} + +/*! + Destroys the signal. All connections are removed, as is the case + with all QObjects. +*/ +Q3Signal::~Q3Signal() +{ +} +#ifndef QT_NO_VARIANT +// Returns true if it matches ".+(.*int.*" +static inline bool intSignature(const char *member) +{ + Q3CString s(member); + int p = s.find('('); + return p > 0 && p < s.findRev("int"); +} +#endif +/*! + Connects the signal to \a member in object \a receiver. + Returns true if the connection is successful. + + \sa disconnect(), QObject::connect() +*/ + +bool Q3Signal::connect(const QObject *receiver, const char *member) +{ +#ifndef QT_NO_VARIANT + if (intSignature(member)) +#endif + return QObject::connect((QObject *)this, SIGNAL(intSignal(int)), receiver, member); +#ifndef QT_NO_VARIANT + return QObject::connect((QObject *)this, SIGNAL(signal(QVariant)), + receiver, member); +#endif +} + +/*! + Disonnects the signal from \a member in object \a receiver. + Returns true if the connection existed and the disconnect + was successful. + + \sa connect(), QObject::disconnect() +*/ + +bool Q3Signal::disconnect(const QObject *receiver, const char *member) +{ + if (!member) + return QObject::disconnect((QObject *)this, 0, receiver, member); +#ifndef QT_NO_VARIANT + if (intSignature(member)) +#endif + return QObject::disconnect((QObject *)this, SIGNAL(intSignal(int)), receiver, member); +#ifndef QT_NO_VARIANT + return QObject::disconnect((QObject *)this, SIGNAL(signal(QVariant)), + receiver, member); +#endif +} + + +/*! + \fn bool Q3Signal::isBlocked() const + \obsolete + Returns true if the signal is blocked, or false if it is not blocked. + + The signal is not blocked by default. + + \sa block(), QObject::signalsBlocked() +*/ + +/*! + \fn void Q3Signal::block(bool b) + \obsolete + Blocks the signal if \a b is true, or unblocks the signal if \a b is false. + + An activated signal disappears into hyperspace if it is blocked. + + \sa isBlocked(), activate(), QObject::blockSignals() +*/ + + +/*! + \fn void Q3Signal::activate() + + Emits the signal. If the platform supports QVariant and a + parameter has been set with setValue(), this value is passed in + the signal. +*/ +void Q3Signal::activate() +{ +#ifndef QT_NO_VARIANT + /* Create this Q3GuardedPtr on this, if we get destroyed after the intSignal (but before the variant signal) + we cannot just emit the signal (because val has been destroyed already) */ + QPointer<Q3Signal> me = this; + if(me) + emit intSignal(val.toInt()); + if(me) + emit signal(val); +#else + emit intSignal(0); +#endif +} + +#ifndef QT_NO_VARIANT +/*! + Sets the signal's parameter to \a value +*/ +void Q3Signal::setValue(const QVariant &value) +{ + val = value; +} + +/*! + Returns the signal's parameter +*/ +QVariant Q3Signal::value() const +{ + return val; +} +/*! \fn void Q3Signal::signal(const QVariant &) + \internal +*/ +/*! \fn void Q3Signal::intSignal(int) + \internal +*/ + +/*! \obsolete */ +void Q3Signal::setParameter(int value) +{ + val = value; +} + +/*! \obsolete */ +int Q3Signal::parameter() const +{ + return val.toInt(); +} +#endif //QT_NO_VARIANT + +QT_END_NAMESPACE diff --git a/src/qt3support/tools/q3signal.h b/src/qt3support/tools/q3signal.h new file mode 100644 index 0000000..a28b6fb --- /dev/null +++ b/src/qt3support/tools/q3signal.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3SIGNAL_H +#define Q3SIGNAL_H + +#include <QtCore/qvariant.h> +#include <QtCore/qobject.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +class Q_COMPAT_EXPORT Q3Signal : public QObject +{ + Q_OBJECT + +public: + Q3Signal(QObject *parent=0, const char *name=0); + ~Q3Signal(); + + bool connect(const QObject *receiver, const char *member); + bool disconnect(const QObject *receiver, const char *member=0); + + void activate(); + + bool isBlocked() const { return QObject::signalsBlocked(); } + void block(bool b) { QObject::blockSignals(b); } +#ifndef QT_NO_VARIANT + void setParameter(int value); + int parameter() const; +#endif + +#ifndef QT_NO_VARIANT + void setValue(const QVariant &value); + QVariant value() const; +#endif +Q_SIGNALS: +#ifndef QT_NO_VARIANT + void signal(const QVariant&); +#endif + void intSignal(int); + +private: + Q_DISABLE_COPY(Q3Signal) + +#ifndef QT_NO_VARIANT + QVariant val; +#endif + +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3SIGNAL_H diff --git a/src/qt3support/tools/q3sortedlist.h b/src/qt3support/tools/q3sortedlist.h new file mode 100644 index 0000000..d5347b4 --- /dev/null +++ b/src/qt3support/tools/q3sortedlist.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3SORTEDLIST_H +#define Q3SORTEDLIST_H + +#include <Qt3Support/q3ptrlist.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class type> +class Q3SortedList : public Q3PtrList<type> +{ +public: + Q3SortedList() {} + Q3SortedList( const Q3SortedList<type> &l ) : Q3PtrList<type>(l) {} + ~Q3SortedList() { this->clear(); } + Q3SortedList<type> &operator=(const Q3SortedList<type> &l) + { return (Q3SortedList<type>&)Q3PtrList<type>::operator=(l); } + + virtual int compareItems( Q3PtrCollection::Item s1, Q3PtrCollection::Item s2 ) + { if ( *((type*)s1) == *((type*)s2) ) return 0; return ( *((type*)s1) < *((type*)s2) ? -1 : 1 ); } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3SORTEDLIST_H diff --git a/src/qt3support/tools/q3strlist.h b/src/qt3support/tools/q3strlist.h new file mode 100644 index 0000000..5a020c7 --- /dev/null +++ b/src/qt3support/tools/q3strlist.h @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3STRLIST_H +#define Q3STRLIST_H + +#include <QtCore/qstring.h> +#include <Qt3Support/q3ptrlist.h> +#include <QtCore/qdatastream.h> +#include <QtCore/qlist.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +#if defined(qdoc) +class Q3StrListIterator : public Q3PtrListIterator<char> +{ +}; +#else +typedef Q3PtrListIterator<char> Q3StrListIterator; +#endif + +class Q_COMPAT_EXPORT Q3StrList : public Q3PtrList<char> +{ +public: + Q3StrList( bool deepCopies=true ) { dc = deepCopies; del_item = deepCopies; } + Q3StrList( const Q3StrList & ); + ~Q3StrList() { clear(); } + Q3StrList& operator=( const Q3StrList & ); + Q3StrList(const QList<QByteArray> &list) { + for (int i = 0; i < list.size(); ++i) + append(list.at(i).constData()); + } + + Q3StrList &operator =(const QList<QByteArray> &list) { + clear(); + for (int i = 0; i < list.size(); ++i) + append(list.at(i).constData()); + return *this; + } + + operator QList<QByteArray>() const { + QList<QByteArray> list; + for (Q3PtrListStdIterator<char> it = begin(); it != end(); ++it) + list.append(QByteArray(*it)); + return list; + } + +private: + Q3PtrCollection::Item newItem( Q3PtrCollection::Item d ) { return dc ? qstrdup( (const char*)d ) : d; } + void deleteItem( Q3PtrCollection::Item d ) { if ( del_item ) delete[] (char*)d; } + int compareItems( Q3PtrCollection::Item s1, Q3PtrCollection::Item s2 ) { return qstrcmp((const char*)s1, + (const char*)s2); } +#ifndef QT_NO_DATASTREAM + QDataStream &read( QDataStream &s, Q3PtrCollection::Item &d ) + { s >> (char *&)d; return s; } + QDataStream &write( QDataStream &s, Q3PtrCollection::Item d ) const + { return s << (const char *)d; } +#endif + bool dc; +}; + + +class Q_COMPAT_EXPORT Q3StrIList : public Q3StrList // case insensitive string list +{ +public: + Q3StrIList( bool deepCopies=true ) : Q3StrList( deepCopies ) {} + ~Q3StrIList() { clear(); } +private: + int compareItems( Q3PtrCollection::Item s1, Q3PtrCollection::Item s2 ) + { return qstricmp((const char*)s1, + (const char*)s2); } +}; + + +inline Q3StrList & Q3StrList::operator=( const Q3StrList &strList ) +{ + clear(); + dc = strList.dc; + del_item = dc; + Q3PtrList<char>::operator=( strList ); + return *this; +} + +inline Q3StrList::Q3StrList( const Q3StrList &strList ) + : Q3PtrList<char>( strList ) +{ + dc = false; + operator=( strList ); +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3STRLIST_H diff --git a/src/qt3support/tools/q3strvec.h b/src/qt3support/tools/q3strvec.h new file mode 100644 index 0000000..0ce9cbd --- /dev/null +++ b/src/qt3support/tools/q3strvec.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3STRVEC_H +#define Q3STRVEC_H + +#include <QtCore/qstring.h> +#include <Qt3Support/q3ptrvector.h> +#include <QtCore/qdatastream.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +class Q3StrVec : public Q3PtrVector<char> +{ +public: + Q3StrVec() { dc = true; } + Q3StrVec( uint size, bool deepc = true ) : Q3PtrVector<char>(size) {dc=deepc;} + ~Q3StrVec() { clear(); } +private: + Item newItem( Item d ) { return dc ? qstrdup( (const char*)d ) : d; } + void deleteItem( Item d ) { if ( dc ) delete[] (char*)d; } + int compareItems( Item s1, Item s2 ) + { return qstrcmp((const char*)s1, + (const char*)s2); } +#ifndef QT_NO_DATASTREAM + QDataStream &read( QDataStream &s, Item &d ) + { s >> (char *&)d; return s; } + QDataStream &write( QDataStream &s, Item d ) const + { return s << (const char*)d; } +#endif + bool dc; +}; + + +class Q3StrIVec : public Q3StrVec // case insensitive string vec +{ +public: + Q3StrIVec() {} + Q3StrIVec( uint size, bool dc = true ) : Q3StrVec( size, dc ) {} + ~Q3StrIVec() { clear(); } +private: + int compareItems( Item s1, Item s2 ) + { return qstricmp((const char*)s1, + (const char*)s2); } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3STRVEC_H diff --git a/src/qt3support/tools/q3tl.h b/src/qt3support/tools/q3tl.h new file mode 100644 index 0000000..418f81c --- /dev/null +++ b/src/qt3support/tools/q3tl.h @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3TL_H +#define Q3TL_H + +#include <QtCore/qalgorithms.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template <typename T, typename LessThan> +Q_OUTOFLINE_TEMPLATE void qHeapSortPushDown(T *heap, int first, int last, LessThan lessThan) +{ + int r = first; + while (r <= last / 2) { + if (last == 2 * r) { + // node r has only one child + if (lessThan(heap[2 * r], heap[r])) + qSwap(heap[r], heap[2 * r]); + r = last; + } else { + // node r has two children + if (lessThan(heap[2 * r], heap[r]) && !lessThan(heap[2 * r + 1], heap[2 * r])) { + // swap with left child + qSwap(heap[r], heap[2 * r]); + r *= 2; + } else if (lessThan(heap[2 * r + 1], heap[r]) + && lessThan(heap[2 * r + 1], heap[2 * r])) { + // swap with right child + qSwap(heap[r], heap[2 * r + 1]); + r = 2 * r + 1; + } else { + r = last; + } + } + } +} + +template <typename BiIterator, typename T, typename LessThan> +Q_OUTOFLINE_TEMPLATE void qHeapSortHelper(BiIterator begin, BiIterator end, const T & /* dummy */, LessThan lessThan) +{ + BiIterator it = begin; + uint n = 0; + while (it != end) { + ++n; + ++it; + } + if (n == 0) + return; + + // Create the heap + BiIterator insert = begin; + T *realheap = new T[n]; + T *heap = realheap - 1; + int size = 0; + for(; insert != end; ++insert) { + heap[++size] = *insert; + int i = size; + while (i > 1 && lessThan(heap[i], heap[i / 2])) { + qSwap(heap[i], heap[i / 2]); + i /= 2; + } + } + + // Now do the sorting + for (int i = n; i > 0; i--) { + *begin++ = heap[1]; + if (i > 1) { + heap[1] = heap[i]; + qHeapSortPushDown(heap, 1, i - 1, lessThan); + } + } + + delete[] realheap; +} + +template <typename BiIterator, typename T> +inline void qHeapSortHelper(BiIterator begin, BiIterator end, const T &dummy) +{ + qHeapSortHelper(begin, end, dummy, qLess<T>()); +} + +template <typename BiIterator, typename LessThan> +inline void qHeapSort(BiIterator begin, BiIterator end, LessThan lessThan) +{ + if (begin != end) + qHeapSortHelper(begin, end, *begin, lessThan); +} + +template <typename BiIterator> +inline void qHeapSort(BiIterator begin, BiIterator end) +{ + if (begin != end) + qHeapSortHelper(begin, end, *begin); +} + +template <typename Container> +inline void qHeapSort(Container &c) +{ +#ifdef Q_CC_BOR + // Work around Borland 5.5 optimizer bug + c.detach(); +#endif + if (!c.empty()) + qHeapSortHelper(c.begin(), c.end(), *c.begin()); +} + + +template <typename BiIterator, typename LessThan> +void qBubbleSort(BiIterator begin, BiIterator end, LessThan lessThan) +{ + // Goto last element; + BiIterator last = end; + + // empty list + if (begin == end) + return; + + --last; + // only one element ? + if (last == begin) + return; + + // So we have at least two elements in here + while (begin != last) { + bool swapped = false; + BiIterator swapPos = begin; + BiIterator x = end; + BiIterator y = x; + y--; + do { + --x; + --y; + if (lessThan(*x, *y)) { + swapped = true; + qSwap(*x, *y); + swapPos = y; + } + } while (y != begin); + if (!swapped) + return; + begin = swapPos; + ++begin; + } +} + +template <typename BiIterator, typename T> +void qBubbleSortHelper(BiIterator begin, BiIterator end, T) +{ + qBubbleSort(begin, end, qLess<T>()); +} + +template <typename BiIterator> +void qBubbleSort(BiIterator begin, BiIterator end) +{ + if (begin != end) + qBubbleSortHelper(begin, end, *begin); +} + +template <typename Container> +inline void qBubbleSort(Container &c) +{ + qBubbleSort(c.begin(), c.end()); +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3TL_H diff --git a/src/qt3support/tools/q3valuelist.h b/src/qt3support/tools/q3valuelist.h new file mode 100644 index 0000000..0803525 --- /dev/null +++ b/src/qt3support/tools/q3valuelist.h @@ -0,0 +1,238 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3VALUELIST_H +#define Q3VALUELIST_H + +#include <QtCore/qalgorithms.h> +#include <QtCore/qdatastream.h> +#include <QtCore/qlinkedlist.h> +#include <QtCore/qlist.h> + +#ifndef QT_NO_STL +#include <iterator> +#include <list> +#endif + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template <typename T> +class Q3ValueListIterator : public QLinkedList<T>::iterator +{ +public: + inline Q3ValueListIterator() : + QLinkedList<T>::iterator() {} + inline Q3ValueListIterator(const Q3ValueListIterator &o) : + QLinkedList<T>::iterator(o) {} + inline Q3ValueListIterator(const typename QLinkedList<T>::iterator &o) : + QLinkedList<T>::iterator(o) {} +}; + +template <typename T> +class Q3ValueListConstIterator : public QLinkedList<T>::const_iterator +{ +public: + inline Q3ValueListConstIterator() {} + inline Q3ValueListConstIterator(const Q3ValueListConstIterator &o) : + QLinkedList<T>::const_iterator(o) {} + inline Q3ValueListConstIterator(const typename QLinkedList<T>::const_iterator &o) : + QLinkedList<T>::const_iterator(o) {} + inline Q3ValueListConstIterator(const typename QLinkedList<T>::iterator &o) : + QLinkedList<T>::const_iterator(o) {} +}; + +template <typename T> +class Q3ValueList : public QLinkedList<T> +{ +public: + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; +#ifndef QT_NO_STL + typedef ptrdiff_t difference_type; +#else + typedef int difference_type; +#endif + + typedef Q3ValueListIterator<T> Iterator; + typedef Q3ValueListConstIterator<T> ConstIterator; + typedef Q3ValueListIterator<T> iterator; + typedef Q3ValueListConstIterator<T> const_iterator; + typedef typename QLinkedList<T>::size_type size_type; + + /** + * API + */ + Q3ValueList() {} + Q3ValueList(const Q3ValueList<T>& l) : QLinkedList<T>(l) {} + Q3ValueList(const QLinkedList<T>& l) : QLinkedList<T>(l) {} + Q3ValueList(const QList<T>& l) + { + for (int i = 0; i < l.size(); ++i) append(l.at(i)); + } +#ifndef QT_NO_STL + Q3ValueList(const std::list<T>& l) + { + qCopy(l.begin(), l.end(), std::back_inserter(*this)); + } +#endif + ~Q3ValueList() {} + + Q3ValueList<T>& operator= (const Q3ValueList<T>& l) + { + QLinkedList<T>::operator=(l); + return *this; + } + Q3ValueList<T>& operator= (const QList<T>& l) + { + this->clear(); + for (int i = 0; i < l.size(); ++i) append(l.at(i)); + return *this; + } +#ifndef QT_NO_STL + Q3ValueList<T>& operator= (const std::list<T>& l) + { + this->detach(); + qCopy(l.begin(), l.end(), std::back_inserter(*this)); + return *this; + } + bool operator== (const std::list<T>& l) const + { + if (this->size() != l.size()) + return false; + typename Q3ValueList<T>::const_iterator it2 = this->begin(); +#if !defined(Q_CC_MIPS) + typename +#endif + std::list<T>::const_iterator it = l.begin(); + for (; it2 != this->end(); ++it2, ++it) + if (!((*it2) == (*it))) + return false; + return true; + } +#endif + bool operator== (const Q3ValueList<T>& l) const { return QLinkedList<T>::operator==(l); } + bool operator!= (const Q3ValueList<T>& l) const { return QLinkedList<T>::operator!=(l); } + + operator QList<T>() const { + QList<T> list; + for (typename Q3ValueList<T>::const_iterator it = QLinkedList<T>::constBegin(); + it != QLinkedList<T>::constEnd(); ++it) + list.append(*it); + return list; + } + + inline Q3ValueList<T>& operator<< (const T& x) { append(x); return *this; } + + void insert(typename Q3ValueList<T>::Iterator pos, + typename Q3ValueList<T>::size_type n, + const T& x); + + typename Q3ValueList<T>::Iterator insert(typename Q3ValueList<T>::Iterator pos, + const T& x) + { return QLinkedList<T>::insert(pos, x); } + typename Q3ValueList<T>::Iterator remove(typename Q3ValueList<T>::Iterator pos) + { return QLinkedList<T>::erase(pos); } + int remove(const T &value) + { return QLinkedList<T>::removeAll(value); } + + inline Q3ValueList<T> operator+ (const Q3ValueList<T>& l) const + { return static_cast<Q3ValueList<T> >(QLinkedList<T>::operator+(l)); } + inline Q3ValueList<T>& operator+= (const Q3ValueList<T>& l) + { QLinkedList<T>::operator+=(l); return *this; } + + typename Q3ValueList<T>::Iterator fromLast() + { return (this->isEmpty() ? this->end() : --this->end()); } + typename Q3ValueList<T>::ConstIterator fromLast() const + { return (this->isEmpty() ? this->end() : --this->end()); } + + typename Q3ValueList<T>::Iterator append(const T& x) + { QLinkedList<T>::append(x); return --this->end(); } + typename Q3ValueList<T>::Iterator prepend(const T& x) + { QLinkedList<T>::prepend(x); return this->begin(); } + + typename Q3ValueList<T>::Iterator at(typename Q3ValueList<T>::size_type i) + { Q_ASSERT(i < this->size()); this->detach(); return this->begin()+i; } + typename Q3ValueList<T>::ConstIterator at(typename Q3ValueList<T>::size_type i) const + { Q_ASSERT(i < this->size()); return this->begin()+i; } + typename Q3ValueList<T>::size_type contains(const T& x) const + { return QLinkedList<T>::count(x); } + + Q3ValueList<T>& operator+= (const T& x) { append(x); return *this; } + + T& operator[] (typename Q3ValueList<T>::size_type i) { return *at(i); } + const T& operator[] (typename Q3ValueList<T>::size_type i) const { return *at(i); } + +}; + +template <typename T> +Q_OUTOFLINE_TEMPLATE void Q3ValueList<T>::insert(typename Q3ValueList<T>::Iterator pos, + typename Q3ValueList<T>::size_type n, const T& x) +{ + for (; n > 0; --n) + this->insert(pos, x); +} + +#ifndef QT_NO_DATASTREAM +template <typename T> +Q_OUTOFLINE_TEMPLATE QDataStream& operator>>(QDataStream& s, Q3ValueList<T>& l) +{ + return operator>>(s, static_cast<QLinkedList<T> &>(l)); +} + +template <typename T> +Q_OUTOFLINE_TEMPLATE QDataStream& operator<<(QDataStream& s, const Q3ValueList<T>& l) +{ + return operator<<(s, static_cast<const QLinkedList<T> &>(l)); +} +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3VALUELIST_H diff --git a/src/qt3support/tools/q3valuestack.h b/src/qt3support/tools/q3valuestack.h new file mode 100644 index 0000000..a3d6a98 --- /dev/null +++ b/src/qt3support/tools/q3valuestack.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3VALUESTACK_H +#define Q3VALUESTACK_H + +#include <Qt3Support/q3valuelist.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template<class T> +class Q3ValueStack : public Q3ValueList<T> +{ +public: + Q3ValueStack() {} + ~Q3ValueStack() {} + void push(const T& val) { this->append(val); } + T pop() + { + T elem(this->last()); + if (!this->isEmpty()) + this->remove(this->fromLast()); + return elem; + } + T& top() { return this->last(); } + const T& top() const { return this->last(); } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3VALUESTACK_H diff --git a/src/qt3support/tools/q3valuevector.h b/src/qt3support/tools/q3valuevector.h new file mode 100644 index 0000000..92eab43 --- /dev/null +++ b/src/qt3support/tools/q3valuevector.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt3Support module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef Q3VALUEVECTOR_H +#define Q3VALUEVECTOR_H + +#include <QtCore/qvector.h> + +#ifndef QT_NO_STL +#include <vector> +#endif + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Qt3SupportLight) + +template <typename T> +class Q3ValueVector : public QVector<T> +{ +public: + inline Q3ValueVector() : QVector<T>() {} + inline Q3ValueVector(const Q3ValueVector<T>& v) : QVector<T>(v) {} + inline Q3ValueVector(typename QVector<T>::size_type n, + const T& val = T()) : QVector<T>(n, val) {} + +#ifndef QT_NO_STL + inline Q3ValueVector(const std::vector<T>& v) : QVector<T>() + { this->resize(v.size()); qCopy(v.begin(), v.end(), this->begin()); } +#endif + + Q3ValueVector<T>& operator= (const Q3ValueVector<T>& v) + { QVector<T>::operator=(v); return *this; } + +#ifndef QT_NO_STL + Q3ValueVector<T>& operator= (const std::vector<T>& v) + { + this->clear(); + this->resize(v.size()); + qCopy(v.begin(), v.end(), this->begin()); + return *this; + } +#endif + + void resize(int n, const T& val = T()) + { + if (n < this->size()) + erase(this->begin() + n, this->end()); + else + insert(this->end(), n - this->size(), val); + } + + + T& at(int i, bool* ok = 0) + { + this->detach(); + if (ok) + *ok = (i >= 0 && i < this->size()); + return *(this->begin() + i); + } + + const T&at(int i, bool* ok = 0) const + { + if (ok) + *ok = (i >= 0 && i < this->size()); + return *(this->begin() + i); + } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // Q3VALUEVECTOR_H diff --git a/src/qt3support/tools/tools.pri b/src/qt3support/tools/tools.pri new file mode 100644 index 0000000..fa31220 --- /dev/null +++ b/src/qt3support/tools/tools.pri @@ -0,0 +1,44 @@ +# Qt compat module + +HEADERS += tools/q3asciicache.h \ + tools/q3asciidict.h \ + tools/q3signal.h \ + tools/q3cleanuphandler.h \ + tools/q3cstring.h \ + tools/q3deepcopy.h \ + tools/q3dict.h \ + tools/q3garray.h \ + tools/q3gcache.h \ + tools/q3gdict.h \ + tools/q3glist.h \ + tools/q3gvector.h \ + tools/q3intcache.h \ + tools/q3intdict.h \ + tools/q3memarray.h \ + tools/q3objectdict.h \ + tools/q3ptrcollection.h \ + tools/q3ptrdict.h \ + tools/q3ptrlist.h \ + tools/q3ptrqueue.h \ + tools/q3ptrstack.h \ + tools/q3ptrvector.h \ + tools/q3semaphore.h \ + tools/q3shared.h \ + tools/q3sortedlist.h \ + tools/q3strlist.h \ + tools/q3strvec.h \ + tools/q3tl.h \ + tools/q3valuelist.h \ + tools/q3valuestack.h \ + tools/q3valuevector.h + +SOURCES += tools/q3cstring.cpp \ + tools/q3signal.cpp \ + tools/q3garray.cpp \ + tools/q3gcache.cpp \ + tools/q3gdict.cpp \ + tools/q3glist.cpp \ + tools/q3gvector.cpp \ + tools/q3semaphore.cpp \ + tools/q3shared.cpp \ + tools/q3ptrcollection.cpp |