diff options
author | Benjamin Poulain <benjamin.poulain@nokia.com> | 2010-02-23 17:45:41 (GMT) |
---|---|---|
committer | Benjamin Poulain <benjamin.poulain@nokia.com> | 2010-02-23 17:45:41 (GMT) |
commit | 615972e09981a0916422716b4f6572c6401789da (patch) | |
tree | 82203c15bceebd5426c823852ef5c85ad025e92b /src/corelib | |
parent | 60fd302e8d88b92ade59d68872c99310128c3a6c (diff) | |
parent | de4332a4728e739b37e9c7b04c021e150e096270 (diff) | |
download | Qt-615972e09981a0916422716b4f6572c6401789da.zip Qt-615972e09981a0916422716b4f6572c6401789da.tar.gz Qt-615972e09981a0916422716b4f6572c6401789da.tar.bz2 |
Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-1
Diffstat (limited to 'src/corelib')
42 files changed, 668 insertions, 253 deletions
diff --git a/src/corelib/arch/qatomic_s390.h b/src/corelib/arch/qatomic_s390.h index 21f5037..273c17b 100644 --- a/src/corelib/arch/qatomic_s390.h +++ b/src/corelib/arch/qatomic_s390.h @@ -366,11 +366,9 @@ template <typename T> Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) { #ifndef __s390x__ - return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr", - "", "bcr 15,0\n"); + return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", ""); #else - return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr", - "", "bcr 15,0\n"); + return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", ""); #endif } @@ -378,9 +376,9 @@ template <typename T> Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) { #ifndef __s390x__ - return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr", "", ""); + return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "bcr 15,0 \n"); #else - return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr", "", ""); + return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "bcr 15,0 \n"); #endif } @@ -388,11 +386,9 @@ template <typename T> Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) { #ifndef __s390x__ - return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr", - "bcr 15,0 \n", ""); + return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "bcr 15,0 \n", ""); #else - return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr", - "bcr 15,0\n", ""); + return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "bcr 15,0\n", ""); #endif } diff --git a/src/corelib/arch/qatomic_symbian.h b/src/corelib/arch/qatomic_symbian.h index f1d332f..fa4e4a9 100644 --- a/src/corelib/arch/qatomic_symbian.h +++ b/src/corelib/arch/qatomic_symbian.h @@ -42,7 +42,7 @@ #ifndef QATOMIC_SYMBIAN_H #define QATOMIC_SYMBIAN_H -#include <qglobal.h> +#include <QtCore/qglobal.h> #include <e32std.h> QT_BEGIN_HEADER diff --git a/src/corelib/arch/sparc/arch.pri b/src/corelib/arch/sparc/arch.pri index 3113dd3..9bb3a88 100644 --- a/src/corelib/arch/sparc/arch.pri +++ b/src/corelib/arch/sparc/arch.pri @@ -1,7 +1,7 @@ # # SPARC architecture # -*-64 { +*-64* { SOURCES += $$QT_ARCH_CPP/qatomic64.s } else { diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp index 445565a..4cc7912 100644 --- a/src/corelib/codecs/qsimplecodec.cpp +++ b/src/corelib/codecs/qsimplecodec.cpp @@ -681,7 +681,7 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con int u; const QChar* ucp = in; unsigned char* rp = (unsigned char *)r.data(); - const unsigned char* rmp = (const unsigned char *)reverseMap->data(); + const unsigned char* rmp = (const unsigned char *)reverseMap->constData(); int rmsize = (int) reverseMap->size(); while(i--) { diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 86845c7..ca5e658 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -79,7 +79,8 @@ # endif #endif // QT_NO_CODECS #include "qlocale.h" -#include "private/qmutexpool_p.h" +#include "qmutex.h" +#include "qhash.h" #include <stdlib.h> #include <ctype.h> @@ -172,6 +173,7 @@ static QTextCodec *createForMib(int mib) } static QList<QTextCodec*> *all = 0; +static int clearCaches = 0; // flags specifying if caches should be invalided: 0x1 codecForName, 0x2 codecForMib #ifdef Q_DEBUG_TEXTCODEC static bool destroying_is_ok = false; #endif @@ -659,13 +661,13 @@ static void setupLocaleMapper() #endif } - -static void setup() -{ #ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet(&all)); +Q_GLOBAL_STATIC_WITH_ARGS(QMutex, textCodecsMutex, (QMutex::Recursive)); #endif +// textCodecsMutex need to be locked to enter this function +static void setup() +{ if (all) return; @@ -903,8 +905,6 @@ QTextCodec::ConverterState::~ConverterState() */ /*! - \nonreentrant - Constructs a QTextCodec, and gives it the highest precedence. The QTextCodec should always be constructed on the heap (i.e. with \c new). Qt takes ownership and will delete it when the application @@ -912,6 +912,9 @@ QTextCodec::ConverterState::~ConverterState() */ QTextCodec::QTextCodec() { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); all->prepend(this); } @@ -929,8 +932,13 @@ QTextCodec::~QTextCodec() if (!destroying_is_ok) qWarning("QTextCodec::~QTextCodec: Called by application"); #endif - if (all) + if (all) { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif all->removeAll(this); + clearCaches = 0x1 | 0x2; + } } /*! @@ -951,19 +959,38 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name) if (name.isEmpty()) return 0; +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); + static QHash <QByteArray, QTextCodec *> cache; + if (clearCaches & 0x1) { + cache.clear(); + clearCaches &= ~0x1; + } + QTextCodec *codec = cache.value(name); + if (codec) + return codec; + for (int i = 0; i < all->size(); ++i) { QTextCodec *cursor = all->at(i); - if (nameMatch(cursor->name(), name)) + if (nameMatch(cursor->name(), name)) { + cache.insert(name, cursor); return cursor; + } QList<QByteArray> aliases = cursor->aliases(); - for (int i = 0; i < aliases.size(); ++i) - if (nameMatch(aliases.at(i), name)) + for (int y = 0; y < aliases.size(); ++y) + if (nameMatch(aliases.at(y), name)) { + cache.insert(name, cursor); return cursor; + } } - return createForName(name); + codec = createForName(name); + if (codec) + cache.insert(name, codec); + return codec; } @@ -973,21 +1000,39 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name) */ QTextCodec* QTextCodec::codecForMib(int mib) { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); - // Qt 3 used 1000 (mib for UCS2) as its identifier for the utf16 codec. Map - // this correctly for compatibility. - if (mib == 1000) - mib = 1015; + static QHash <int, QTextCodec *> cache; + if (clearCaches & 0x2) { + cache.clear(); + clearCaches &= ~0x2; + } + QTextCodec *codec = cache.value(mib); + if (codec) + return codec; QList<QTextCodec*>::ConstIterator i; for (int i = 0; i < all->size(); ++i) { QTextCodec *cursor = all->at(i); - if (cursor->mibEnum() == mib) + if (cursor->mibEnum() == mib) { + cache.insert(mib, cursor); return cursor; + } } - return createForMib(mib); + codec = createForMib(mib); + + // Qt 3 used 1000 (mib for UCS2) as its identifier for the utf16 codec. Map + // this correctly for compatibility. + if (!codec && mib == 1000) + return codecForMib(1015); + + if (codec) + cache.insert(mib, codec); + return codec; } /*! @@ -1001,6 +1046,9 @@ QTextCodec* QTextCodec::codecForMib(int mib) */ QList<QByteArray> QTextCodec::availableCodecs() { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); QList<QByteArray> codecs; @@ -1008,6 +1056,11 @@ QList<QByteArray> QTextCodec::availableCodecs() codecs += all->at(i)->name(); codecs += all->at(i)->aliases(); } + +#ifndef QT_NO_THREAD + locker.unlock(); +#endif + #ifndef QT_NO_TEXTCODECPLUGIN QFactoryLoader *l = loader(); QStringList keys = l->keys(); @@ -1031,11 +1084,19 @@ QList<QByteArray> QTextCodec::availableCodecs() */ QList<int> QTextCodec::availableMibs() { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); QList<int> codecs; for (int i = 0; i < all->size(); ++i) codecs += all->at(i)->mibEnum(); + +#ifndef QT_NO_THREAD + locker.unlock(); +#endif + #ifndef QT_NO_TEXTCODECPLUGIN QFactoryLoader *l = loader(); QStringList keys = l->keys(); @@ -1082,6 +1143,9 @@ QTextCodec* QTextCodec::codecForLocale() if (localeMapper) return localeMapper; +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); return localeMapper; diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h index 5012b42..e37527d 100644 --- a/src/corelib/codecs/qtextcodec.h +++ b/src/corelib/codecs/qtextcodec.h @@ -171,11 +171,6 @@ public: private: const QTextCodec *c; QTextCodec::ConverterState state; - - friend class QXmlStreamWriter; - friend class QXmlStreamWriterPrivate; - friend class QCoreXmlStreamWriter; - friend class QCoreXmlStreamWriterPrivate; }; class Q_CORE_EXPORT QTextDecoder { diff --git a/src/corelib/concurrent/qfuture.h b/src/corelib/concurrent/qfuture.h index e402335..02ae40a 100644 --- a/src/corelib/concurrent/qfuture.h +++ b/src/corelib/concurrent/qfuture.h @@ -111,7 +111,7 @@ public: { public: typedef std::bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef const T *pointer; typedef const T &reference; diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 4bffd0f..df9a463 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -35,8 +35,22 @@ symbian: { # Workaroud for problems with paging this dll MMP_RULES -= PAGED MMP_RULES *= UNPAGED - # Timezone server - LIBS += -ltzclient + + # Partial upgrade SIS file + vendorinfo = \ + "&EN" \ + "; Localised Vendor name" \ + "%{\"Nokia, Qt\"}" \ + " " \ + "; Unique Vendor name" \ + ":\"Nokia, Qt\"" \ + " " + pu_header = "; Partial upgrade package for testing QtCore changes without reinstalling everything" \ + "$${LITERAL_HASH}{\"Qt corelib\"}, (0x2001E61C), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU" + partial_upgrade.pkg_prerules = pu_header vendorinfo + partial_upgrade.sources = qtcore.dll + partial_upgrade.path = c:/sys/bin + DEPLOYMENT = partial_upgrade $$DEPLOYMENT } mmx { diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index f48c1b3..c8f836a 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1994,7 +1994,6 @@ void qt_check_pointer(const char *n, int l) qWarning("In file %s, line %d: Out of memory", n, l); } -#ifndef QT_NO_EXCEPTIONS /* \internal Allows you to throw an exception without including <new> Called internally from Q_CHECK_PTR on certain OS combinations @@ -2003,7 +2002,6 @@ void qBadAlloc() { QT_THROW(std::bad_alloc()); } -#endif /* The Q_ASSERT macro calls this function when the test fails. diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index b237659..7e7d7d8 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -864,6 +864,9 @@ typedef quint64 qulonglong; # endif #endif +#define Q_INIT_RESOURCE_EXTERN(name) \ + extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); + #define Q_INIT_RESOURCE(name) \ do { extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); \ QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); } while (0) @@ -1676,10 +1679,7 @@ Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char * #endif Q_CORE_EXPORT void qt_check_pointer(const char *, int); - -#ifndef QT_NO_EXCEPTIONS Q_CORE_EXPORT void qBadAlloc(); -#endif #ifdef QT_NO_EXCEPTIONS # if defined(QT_NO_DEBUG) diff --git a/src/corelib/global/qmalloc.cpp b/src/corelib/global/qmalloc.cpp index 43e89e3..090998c 100644 --- a/src/corelib/global/qmalloc.cpp +++ b/src/corelib/global/qmalloc.cpp @@ -124,3 +124,4 @@ void qFreeAligned(void *ptr) } QT_END_NAMESPACE + diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 35ff8e7..6ee8ae9 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1725,7 +1725,8 @@ public: enum GestureFlag { DontStartGestureOnChildren = 0x01, - ReceivePartialGestures = 0x02 + ReceivePartialGestures = 0x02, + IgnoredGesturesPropagateToParent = 0x04 }; Q_DECLARE_FLAGS(GestureFlags, GestureFlag) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 3d49d60..db910ce 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -42,6 +42,7 @@ /*! \namespace Qt \inmodule QtCore + \target Qt Namespace \brief The Qt namespace contains miscellaneous identifiers used throughout the Qt library. @@ -157,7 +158,7 @@ \value AA_MacDontSwapCtrlAndMeta On Mac OS X by default, Qt swaps the Control and Meta (Command) keys (i.e., whenever Control is pressed, Qt - sends Meta and whenever Meta is pressed Control is sent. When this + sends Meta, and whenever Meta is pressed Control is sent). When this attribute is true, Qt will not do the flip. QKeySequence::StandardShortcuts will also flip accordingly (i.e., QKeySequence::Copy will be Command+C on the keyboard regardless of the value set, though what is output for @@ -493,7 +494,7 @@ \omitvalue WordBreak \omitvalue TextForceLeftToRight \omitvalue TextForceRightToLeft - \omitvalue TextLongestVariant Always use the longest variant when computing the size of a multi-variant string + \omitvalue TextLongestVariant Always use the longest variant when computing the size of a multi-variant string. You can use as many modifier flags as you want, except that Qt::TextSingleLine and Qt::TextWordWrap cannot be combined. @@ -2115,7 +2116,7 @@ On some platforms this implies Qt::WindowSystemMenuHint for it to work. \value MacWindowToolBarButtonHint On Mac OS X adds a tool bar button (i.e., - the oblong button that is on the top right of windows that have toolbars. + the oblong button that is on the top right of windows that have toolbars). \value BypassGraphicsProxyWidget Prevents the window and its children from automatically embedding themselves into a QGraphicsProxyWidget if the diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp index 7c1887e..fc35bfa 100644 --- a/src/corelib/io/qdatastream.cpp +++ b/src/corelib/io/qdatastream.cpp @@ -157,6 +157,13 @@ QT_BEGIN_NAMESPACE data, followed by the data. Note that any encoding/decoding of the data (apart from the length quint32) must be done by you. + \section1 Reading and writing Qt collection classes + + The Qt collection classes can also be serialized to a QDataStream. + These include QList, QLinkedList, QVector, QSet, QHash, and QMap. + These classes have have stream operators declared as non-member of + the class. + \target Serializing Qt Classes \section1 Reading and writing other Qt classes. diff --git a/src/corelib/io/qdataurl.cpp b/src/corelib/io/qdataurl.cpp index 9bb896e..4e2dec2 100644 --- a/src/corelib/io/qdataurl.cpp +++ b/src/corelib/io/qdataurl.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/corelib/io/qdataurl_p.h b/src/corelib/io/qdataurl_p.h index be5b10d..57cfd75 100644 --- a/src/corelib/io/qdataurl_p.h +++ b/src/corelib/io/qdataurl_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index f5d803e..7cfdddf 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -89,8 +89,6 @@ public: QDirPrivate(const QDir *copy = 0); ~QDirPrivate(); - QString initFileEngine(const QString &file); - void updateFileLists() const; void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *) const; @@ -146,6 +144,7 @@ public: } *data; inline void setPath(const QString &p) { + detach(false); QString path = p; if ((path.endsWith(QLatin1Char('/')) || path.endsWith(QLatin1Char('\\'))) && path.length() > 1) { @@ -155,8 +154,12 @@ public: path.truncate(path.length() - 1); } + delete data->fileEngine; + data->fileEngine = QAbstractFileEngine::create(path); + // set the path to be the qt friendly version so then we can operate on it using just / - data->path = initFileEngine(path); + data->path = data->fileEngine->fileName(QAbstractFileEngine::DefaultName); + data->clear(); } inline void reset() { detach(); @@ -310,15 +313,6 @@ inline void QDirPrivate::updateFileLists() const } } -inline QString QDirPrivate::initFileEngine(const QString &path) -{ - detach(false); - data->clear(); - delete data->fileEngine; - data->fileEngine = QAbstractFileEngine::create(path); - return data->fileEngine->fileName(QAbstractFileEngine::DefaultName); -} - void QDirPrivate::detach(bool createFileEngine) { qAtomicDetach(data); diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index a7dc8fa..4740a89 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -235,7 +235,7 @@ QInotifyFileSystemWatcherEngine::QInotifyFileSystemWatcherEngine(int fd) QInotifyFileSystemWatcherEngine::~QInotifyFileSystemWatcherEngine() { - foreach (int id, pathToID.values()) + foreach (int id, pathToID) inotify_rm_watch(inotifyFd, id < 0 ? -id : id); ::close(inotifyFd); diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index f088ded..99c165e 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -109,7 +109,7 @@ QKqueueFileSystemWatcherEngine::~QKqueueFileSystemWatcherEngine() close(kqpipe[0]); close(kqpipe[1]); - foreach (int id, pathToID.values()) + foreach (int id, pathToID) ::close(id < 0 ? -id : id); } @@ -260,12 +260,22 @@ void QKqueueFileSystemWatcherEngine::run() DEBUG() << "QKqueueFileSystemWatcherEngine: processing kevent" << kev.ident << kev.filter; if (fd == kqpipe[0]) { - char c; - if (read(kqpipe[0], &c, 1) != 1) { + // read all pending data from the pipe + QByteArray ba; + ba.resize(kev.data); + if (read(kqpipe[0], ba.data(), ba.size()) != ba.size()) { perror("QKqueueFileSystemWatcherEngine: error reading from pipe"); return; } - switch (c) { + // read the command from the buffer (but break and return on 'q') + char cmd = 0; + for (int i = 0; i < ba.size(); ++i) { + cmd = ba.constData()[i]; + if (cmd == 'q') + break; + } + // handle the command + switch (cmd) { case 'q': DEBUG() << "QKqueueFileSystemWatcherEngine: thread received 'q', exiting..."; return; @@ -273,7 +283,7 @@ void QKqueueFileSystemWatcherEngine::run() DEBUG() << "QKqueueFileSystemWatcherEngine: thread received '@', continuing..."; break; default: - DEBUG() << "QKqueueFileSystemWatcherEngine: thread received unknow message" << c; + DEBUG() << "QKqueueFileSystemWatcherEngine: thread received unknow message" << cmd; break; } } else { diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index eb99f27..d8b1c03 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -1479,7 +1479,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const { //### what to do with permissions if we don't use NTFS // for now just add all permissions and what about exe missions ?? - // also qt_ntfs_permission_lookup is now not set by defualt ... should it ? + // also qt_ntfs_permission_lookup is now not set by default ... should it ? ret |= QAbstractFileEngine::ReadOtherPerm | QAbstractFileEngine::ReadGroupPerm | QAbstractFileEngine::ReadOwnerPerm | QAbstractFileEngine::ReadUserPerm | QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::WriteOwnerPerm diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index 75cde51..07d10ad 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -1002,7 +1002,7 @@ bool QProcessPrivate::waitForDeadChild() TExitCategoryName catName = symbianProcess->ExitCategory(); qDebug() << "QProcessPrivate::waitForDeadChild() dead with exitCode" << exitCode << ", crashed:" << crashed - << ", category:" << QString::fromUtf16(catName.Ptr()); + << ", category:" << QString((const QChar *)catName.Ptr()); #endif } else { QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForDeadChild() not dead!"); diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index dbf422e..b0503be 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -1006,6 +1006,9 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent, Returns the child of the model index that is stored in the given \a row and \a column. + \note This function does not work for an invalid model index which is often + used as the root index. + \sa parent(), sibling() */ @@ -1245,7 +1248,7 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent, /*! \fn QModelIndex QAbstractItemModel::parent(const QModelIndex &index) const = 0 - Returns the parent of the model item with the given \a index. If the model + Returns the parent of the model item with the given \a index. If the item has no parent, an invalid QModelIndex is returned. A common convention used in models that expose tree data structures is that diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 7c8fb3d..4755540 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -68,6 +68,14 @@ extern uint qGlobalPostedEventsCount(); # define QS_RAWINPUT 0x0400 #endif +#ifndef WM_TOUCH +# define WM_TOUCH 0x0240 +#endif +#ifndef WM_GESTURE +# define WM_GESTURE 0x0119 +# define WM_GESTURENOTIFY 0x011A +#endif + enum { WM_QT_SOCKETNOTIFIER = WM_USER, WM_QT_SENDPOSTEDEVENTS = WM_USER + 1, @@ -517,8 +525,8 @@ LRESULT CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) MSG *msg = (MSG *) lp; if (localSerialNumber != d->lastSerialNumber // if this message IS the one that triggers sendPostedEvents(), no need to post it again - && msg->hwnd != d->internalHwnd - && msg->message != WM_QT_SENDPOSTEDEVENTS) { + && (msg->hwnd != d->internalHwnd + || msg->message != WM_QT_SENDPOSTEDEVENTS)) { PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0); } } @@ -729,6 +737,9 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) && msg.message <= WM_MOUSELAST) || msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL + || msg.message == WM_TOUCH + || msg.message == WM_GESTURE + || msg.message == WM_GESTURENOTIFY || msg.message == WM_CLOSE)) { // queue user input events for later processing haveMessage = false; diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index a27e488..3324796 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1804,7 +1804,20 @@ QByteArray &QByteArray::replace(int pos, int len, const QByteArray &after) */ QByteArray &QByteArray::replace(int pos, int len, const char *after) { - int alen = qstrlen(after); + return replace(pos,len,after,qstrlen(after)); +} + +/*! \fn QByteArray &QByteArray::replace(int pos, int len, const char *after, int alen) + + \overload + + Replaces \a len bytes from index position \a pos with \a alen bytes + from the string \a after. \a after is allowed to have '\0' characters. + + \since 4.7 +*/ +QByteArray &QByteArray::replace(int pos, int len, const char *after, int alen) +{ if (len == alen && (pos + len <= d->size)) { detach(); memcpy(d->data + pos, after, len*sizeof(char)); diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index ec592f5f..0b77512 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -237,6 +237,7 @@ public: QByteArray &insert(int i, const QByteArray &a); QByteArray &remove(int index, int len); QByteArray &replace(int index, int len, const char *s); + QByteArray &replace(int index, int len, const char *s, int alen); QByteArray &replace(int index, int len, const QByteArray &s); QByteArray &replace(char before, const char *after); QByteArray &replace(char before, const QByteArray &after); diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 1f7fdb2..f767962 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -97,7 +97,7 @@ public: typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef int size_type; explicit QContiguousCache(int capacity = 0); @@ -221,22 +221,29 @@ void QContiguousCache<T>::setCapacity(int asize) x.d->alloc = asize; x.d->count = qMin(d->count, asize); x.d->offset = d->offset + d->count - x.d->count; - x.d->start = x.d->offset % x.d->alloc; - T *dest = x.p->array + (x.d->start + x.d->count-1) % x.d->alloc; - T *src = p->array + (d->start + d->count-1) % d->alloc; + if(asize) + x.d->start = x.d->offset % x.d->alloc; + else + x.d->start = 0; + int oldcount = x.d->count; - while (oldcount--) { - if (QTypeInfo<T>::isComplex) { - new (dest) T(*src); - } else { - *dest = *src; + if(oldcount) + { + T *dest = x.p->array + (x.d->start + x.d->count-1) % x.d->alloc; + T *src = p->array + (d->start + d->count-1) % d->alloc; + while (oldcount--) { + if (QTypeInfo<T>::isComplex) { + new (dest) T(*src); + } else { + *dest = *src; + } + if (dest == x.p->array) + dest = x.p->array + x.d->alloc; + dest--; + if (src == p->array) + src = p->array + d->alloc; + src--; } - if (dest == x.p->array) - dest = x.p->array + x.d->alloc; - dest--; - if (src == p->array) - src = p->array + d->alloc; - src--; } /* free old */ free(p); diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 9a361c0..c1027ed 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -75,7 +75,6 @@ #if defined(Q_OS_SYMBIAN) #include <e32std.h> -#include <tz.h> #endif QT_BEGIN_NAMESPACE @@ -3722,32 +3721,23 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) #elif defined(Q_OS_SYMBIAN) // months and days are zero index based _LIT(KUnixEpoch, "19700000:000000.000000"); + TTimeIntervalSeconds utcOffset = User::UTCOffset(); TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC); TTime epochTTime; TInt err = epochTTime.Set(KUnixEpoch); tm res; if(err == KErrNone) { TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; - TRAP(err, - RTz tz; - User::LeaveIfError(tz.Connect()); - CleanupClosePushL(tz); - res.tm_isdst = tz.IsDaylightSavingOnL(*tz.GetTimeZoneIdL(),utcTTime); - User::LeaveIfError(tz.ConvertToLocalTime(utcTTime)); - CleanupStack::PopAndDestroy(&tz)); - if (KErrNone == err) { - TDateTime localDateTime = utcTTime.DateTime(); - res.tm_sec = localDateTime.Second(); - res.tm_min = localDateTime.Minute(); - res.tm_hour = localDateTime.Hour(); - res.tm_mday = localDateTime.Day() + 1; // non-zero based index for tm struct - res.tm_mon = localDateTime.Month(); - res.tm_year = localDateTime.Year() - 1900; - // Symbian's timezone server doesn't know how to handle DST before year 1997 - if (res.tm_year < 97) - res.tm_isdst = -1; - brokenDown = &res; - } + utcTTime = utcTTime + utcOffset; + TDateTime utcDateTime = utcTTime.DateTime(); + res.tm_sec = utcDateTime.Second(); + res.tm_min = utcDateTime.Minute(); + res.tm_hour = utcDateTime.Hour(); + res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct + res.tm_mon = utcDateTime.Month(); + res.tm_year = utcDateTime.Year() - 1900; + res.tm_isdst = 0; + brokenDown = &res; } #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // use the reentrant version of localtime() where available @@ -3822,27 +3812,23 @@ static void localToUtc(QDate &date, QTime &time, int isdst) #elif defined(Q_OS_SYMBIAN) // months and days are zero index based _LIT(KUnixEpoch, "19700000:000000.000000"); + TTimeIntervalSeconds utcOffset = TTimeIntervalSeconds(0 - User::UTCOffset().Int()); TTimeIntervalSeconds tTimeIntervalSecsSince1Jan1970UTC(secsSince1Jan1970UTC); TTime epochTTime; TInt err = epochTTime.Set(KUnixEpoch); tm res; if(err == KErrNone) { - TTime localTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; - RTz tz; - if (KErrNone == tz.Connect()) { - if (KErrNone == tz.ConvertToUniversalTime(localTTime)) { - TDateTime utcDateTime = localTTime.DateTime(); - res.tm_sec = utcDateTime.Second(); - res.tm_min = utcDateTime.Minute(); - res.tm_hour = utcDateTime.Hour(); - res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct - res.tm_mon = utcDateTime.Month(); - res.tm_year = utcDateTime.Year() - 1900; - res.tm_isdst = (int)isdst; - brokenDown = &res; - } - tz.Close(); - } + TTime utcTTime = epochTTime + tTimeIntervalSecsSince1Jan1970UTC; + utcTTime = utcTTime + utcOffset; + TDateTime utcDateTime = utcTTime.DateTime(); + res.tm_sec = utcDateTime.Second(); + res.tm_min = utcDateTime.Minute(); + res.tm_hour = utcDateTime.Hour(); + res.tm_mday = utcDateTime.Day() + 1; // non-zero based index for tm struct + res.tm_mon = utcDateTime.Month(); + res.tm_year = utcDateTime.Year() - 1900; + res.tm_isdst = (int)isdst; + brokenDown = &res; } #elif !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // use the reentrant version of gmtime() where available diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 285f4c9..85a8b63 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -64,13 +64,11 @@ QT_BEGIN_NAMESPACE static uint hash(const uchar *p, int n) { uint h = 0; - uint g; while (n--) { h = (h << 4) + *p++; - g = h & 0xf0000000; - h ^= g >> 23; - h &= ~g; + h ^= (h & 0xf0000000) >> 23; + h &= 0x0fffffff; } return h; } @@ -78,13 +76,11 @@ static uint hash(const uchar *p, int n) static uint hash(const QChar *p, int n) { uint h = 0; - uint g; while (n--) { h = (h << 4) + (*p++).unicode(); - g = h & 0xf0000000; - h ^= g >> 23; - h &= ~g; + h ^= (h & 0xf0000000) >> 23; + h &= 0x0fffffff; } return h; } diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 2832ca2..f1030ae 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -330,7 +330,7 @@ public: public: typedef std::bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef T *pointer; typedef T &reference; @@ -395,7 +395,7 @@ public: public: typedef std::bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef const T *pointer; typedef const T &reference; @@ -479,7 +479,7 @@ public: // STL compatibility typedef T mapped_type; typedef Key key_type; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef int size_type; inline bool empty() const { return isEmpty(); } diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h index fe586a4..d145fe3 100644 --- a/src/corelib/tools/qlinkedlist.h +++ b/src/corelib/tools/qlinkedlist.h @@ -114,7 +114,7 @@ public: { public: typedef std::bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef T *pointer; typedef T &reference; @@ -147,7 +147,7 @@ public: { public: typedef std::bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef const T *pointer; typedef const T &reference; @@ -213,7 +213,7 @@ public: typedef const value_type *const_pointer; typedef value_type &reference; typedef const value_type &const_reference; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; #ifndef QT_NO_STL static inline QLinkedList<T> fromStdList(const std::list<T> &list) diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index ce62016..6f5bb9b 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -66,6 +66,53 @@ static int grow(int size) return x; } +/*! + * Detaches the QListData by allocating new memory for a list which will be bigger + * than the copied one and is expected to grow further. + * *idx is the desired insertion point and is clamped to the actual size of the list. + * num is the number of new elements to insert at the insertion point. + * Returns the old (shared) data, it is up to the caller to deref() and free(). + * For the new data node_copy needs to be called. + * + * \internal + */ +QListData::Data *QListData::detach_grow(int *idx, int num) +{ + Data *x = d; + int l = x->end - x->begin; + int nl = l + num; + int alloc = grow(nl); + Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + alloc * sizeof(void *))); + Q_CHECK_PTR(t); + + t->ref = 1; + t->sharable = true; + t->alloc = alloc; + // The space reservation algorithm's optimization is biased towards appending: + // Something which looks like an append will put the data at the beginning, + // while something which looks like a prepend will put it in the middle + // instead of at the end. That's based on the assumption that prepending + // is uncommon and even an initial prepend will eventually be followed by + // at least some appends. + int bg; + if (*idx < 0) { + *idx = 0; + bg = (alloc - nl) >> 1; + } else if (*idx > l) { + *idx = l; + bg = 0; + } else if (*idx < (l >> 1)) { + bg = (alloc - nl) >> 1; + } else { + bg = 0; + } + t->begin = bg; + t->end = bg + nl; + d = t; + + return x; +} + #if QT_VERSION >= 0x050000 # error "Remove QListData::detach(), it is only required for binary compatibility for 4.0.x to 4.2.x" #endif @@ -125,22 +172,23 @@ QListData::Data *QListData::detach2() } /*! - * Detaches the QListData by reallocating new memory. + * Detaches the QListData by allocating new memory for a list which possibly + * has a different size than the copied one. * Returns the old (shared) data, it is up to the caller to deref() and free() * For the new data node_copy needs to be called. * * \internal */ -QListData::Data *QListData::detach3() +QListData::Data *QListData::detach(int alloc) { Data *x = d; - Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + x->alloc * sizeof(void *))); + Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + alloc * sizeof(void *))); Q_CHECK_PTR(t); t->ref = 1; t->sharable = true; - t->alloc = x->alloc; - if (!t->alloc) { + t->alloc = alloc; + if (!alloc) { t->begin = 0; t->end = 0; } else { @@ -152,6 +200,21 @@ QListData::Data *QListData::detach3() return x; } +/*! + * Detaches the QListData by reallocating new memory. + * Returns the old (shared) data, it is up to the caller to deref() and free() + * For the new data node_copy needs to be called. + * + * \internal + */ +#if QT_VERSION >= 0x050000 +# error "Remove QListData::detach3(), it is only required for binary compatibility for 4.5.x to 4.6.x" +#endif +QListData::Data *QListData::detach3() +{ + return detach(d->alloc); +} + void QListData::realloc(int alloc) { Q_ASSERT(d->ref == 1); @@ -164,22 +227,30 @@ void QListData::realloc(int alloc) d->begin = d->end = 0; } -// ensures that enough space is available to append one element -void **QListData::append() +// ensures that enough space is available to append n elements +void **QListData::append(int n) { Q_ASSERT(d->ref == 1); - if (d->end == d->alloc) { - int n = d->end - d->begin; - if (d->begin > 2 * d->alloc / 3) { + int e = d->end; + if (e + n > d->alloc) { + int b = d->begin; + if (b - n >= 2 * d->alloc / 3) { // we have enough space. Just not at the end -> move it. - ::memcpy(d->array + n, d->array + d->begin, n * sizeof(void *)); - d->begin = n; - d->end = n * 2; + e -= b; + ::memcpy(d->array, d->array + b, e * sizeof(void *)); + d->begin = 0; } else { - realloc(grow(d->alloc + 1)); + realloc(grow(d->alloc + n)); } } - return d->array + d->end++; + d->end = e + n; + return d->array + e; +} + +// ensures that enough space is available to append one element +void **QListData::append() +{ + return append(1); } // ensures that enough space is available to append the list @@ -193,7 +264,7 @@ void **QListData::append(const QListData& l) int n = l.d->end - l.d->begin; if (n) { if (e + n > d->alloc) - realloc(grow(e + l.d->end - l.d->begin)); + realloc(grow(e + n)); ::memcpy(d->array + d->end, l.d->array + l.d->begin, n*sizeof(void*)); d->end += n; } @@ -203,15 +274,7 @@ void **QListData::append(const QListData& l) // ensures that enough space is available to append the list void **QListData::append2(const QListData& l) { - Q_ASSERT(d->ref == 1); - int e = d->end; - int n = l.d->end - l.d->begin; - if (n) { - if (e + n > d->alloc) - realloc(grow(e + n)); - d->end += n; - } - return d->array + e; + return append(l.d->end - l.d->begin); } void **QListData::prepend() @@ -237,11 +300,11 @@ void **QListData::insert(int i) Q_ASSERT(d->ref == 1); if (i <= 0) return prepend(); - if (i >= d->end - d->begin) + int size = d->end - d->begin; + if (i >= size) return append(); bool leftward = false; - int size = d->end - d->begin; if (d->begin == 0) { if (d->end == d->alloc) { @@ -647,6 +710,19 @@ void **QListData::erase(void **xi) Same as at(). */ +/*! \fn QList::reserve(int alloc) + + Reserve space for \a alloc elements. + + If \a alloc is smaller than the current size of the list, nothing will happen. + + Use this function to avoid repetetive reallocation of QList's internal + data if you can predict how many elements will be appended. + Note that the reservation applies only to the internal pointer array. + + \since 4.7 +*/ + /*! \fn void QList::append(const T &value) Inserts \a value at the end of the list. diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 1d08c41..3a29e13 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -52,6 +52,7 @@ #endif #include <new> +#include <limits.h> #include <string.h> QT_BEGIN_HEADER @@ -72,13 +73,16 @@ struct Q_CORE_EXPORT QListData { }; enum { DataHeaderSize = sizeof(Data) - sizeof(void *) }; + Data *detach(int alloc); + Data *detach_grow(int *i, int n); Data *detach(); // remove in 5.0 Data *detach2(); // remove in 5.0 - Data *detach3(); + Data *detach3(); // remove in 5.0 void realloc(int alloc); static Data shared_null; Data *d; void **erase(void **xi); + void **append(int n); void **append(); void **append(const QListData &l); void **append2(const QListData &l); // remove in 5.0 @@ -94,6 +98,25 @@ struct Q_CORE_EXPORT QListData { inline void **end() const { return d->array + d->end; } }; +////////////////////////////////////////////////////////////////////////////////// +// +// QtPodForSize and QtPodForType are internal and may change or go away any time. +// We mean it. +// +////////////////////////////////////////////////////////////////////////////////// +template <int N> struct QtPodForSize { + // This base type is rather obviously broken and cannot be made + // working due to alignment constraints. + // This doesn't matter as far as QList is concerned, as we are + // using this type only for QTypeInfo<T>::isLarge == false. + typedef struct { } Type; +}; +template <> struct QtPodForSize<1> { typedef quint8 Type; }; +template <> struct QtPodForSize<2> { typedef quint16 Type; }; +template <> struct QtPodForSize<4> { typedef quint32 Type; }; +template <> struct QtPodForSize<8> { typedef quint64 Type; }; +template <class T> struct QtPodForType : QtPodForSize<sizeof(T)> { }; + template <typename T> class QList { @@ -140,6 +163,7 @@ public: const T &operator[](int i) const; T &operator[](int i); + void reserve(int size); void append(const T &t); void append(const QList<T> &t); void prepend(const T &t); @@ -164,7 +188,7 @@ public: public: Node *i; typedef std::random_access_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef T *pointer; typedef T &reference; @@ -211,7 +235,7 @@ public: public: Node *i; typedef std::random_access_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef const T *pointer; typedef const T &reference; @@ -290,7 +314,7 @@ public: typedef const value_type *const_pointer; typedef value_type &reference; typedef const value_type &const_reference; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; #ifdef QT3_SUPPORT inline QT3_SUPPORT iterator remove(iterator pos) { return erase(pos); } @@ -331,6 +355,8 @@ public: #endif private: + Node *detach_helper_grow(int i, int n); + void detach_helper(int alloc); void detach_helper(); void free(QListData::Data *d); @@ -464,11 +490,21 @@ inline T QList<T>::takeLast() { T t = last(); removeLast(); return t; } template <typename T> +Q_OUTOFLINE_TEMPLATE void QList<T>::reserve(int alloc) +{ + if (d->alloc < alloc) { + if (d->ref != 1) + detach_helper(alloc); + else + p.realloc(alloc); + } +} + +template <typename T> Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t) { - detach(); - if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { - Node *n = reinterpret_cast<Node *>(p.append()); + if (d->ref != 1) { + Node *n = detach_helper_grow(INT_MAX, 1); QT_TRY { node_construct(n, t); } QT_CATCH(...) { @@ -476,13 +512,24 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t) QT_RETHROW; } } else { - const T cpy(t); - Node *n = reinterpret_cast<Node *>(p.append()); - QT_TRY { - node_construct(n, cpy); - } QT_CATCH(...) { - --d->end; - QT_RETHROW; + if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { + Node *n = reinterpret_cast<Node *>(p.append()); + QT_TRY { + node_construct(n, t); + } QT_CATCH(...) { + --d->end; + QT_RETHROW; + } + } else { + typedef typename QtPodForType<T>::Type PodNode; + PodNode cpy = *reinterpret_cast<const PodNode *>(&t); + Node *n = reinterpret_cast<Node *>(p.append()); + QT_TRY { + node_construct(n, *reinterpret_cast<const T *>(&cpy)); + } QT_CATCH(...) { + --d->end; + QT_RETHROW; + } } } } @@ -490,9 +537,8 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t) template <typename T> inline void QList<T>::prepend(const T &t) { - detach(); - if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { - Node *n = reinterpret_cast<Node *>(p.prepend()); + if (d->ref != 1) { + Node *n = detach_helper_grow(0, 1); QT_TRY { node_construct(n, t); } QT_CATCH(...) { @@ -500,13 +546,24 @@ inline void QList<T>::prepend(const T &t) QT_RETHROW; } } else { - const T cpy(t); - Node *n = reinterpret_cast<Node *>(p.prepend()); - QT_TRY { - node_construct(n, cpy); - } QT_CATCH(...) { - ++d->begin; - QT_RETHROW; + if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { + Node *n = reinterpret_cast<Node *>(p.prepend()); + QT_TRY { + node_construct(n, t); + } QT_CATCH(...) { + ++d->begin; + QT_RETHROW; + } + } else { + typedef typename QtPodForType<T>::Type PodNode; + PodNode cpy = *reinterpret_cast<const PodNode *>(&t); + Node *n = reinterpret_cast<Node *>(p.prepend()); + QT_TRY { + node_construct(n, *reinterpret_cast<const T *>(&cpy)); + } QT_CATCH(...) { + ++d->begin; + QT_RETHROW; + } } } } @@ -514,9 +571,8 @@ inline void QList<T>::prepend(const T &t) template <typename T> inline void QList<T>::insert(int i, const T &t) { - detach(); - if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { - Node *n = reinterpret_cast<Node *>(p.insert(i)); + if (d->ref != 1) { + Node *n = detach_helper_grow(i, 1); QT_TRY { node_construct(n, t); } QT_CATCH(...) { @@ -524,13 +580,24 @@ inline void QList<T>::insert(int i, const T &t) QT_RETHROW; } } else { - const T cpy(t); - Node *n = reinterpret_cast<Node *>(p.insert(i)); - QT_TRY { - node_construct(n, cpy); - } QT_CATCH(...) { - p.remove(i); - QT_RETHROW; + if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { + Node *n = reinterpret_cast<Node *>(p.insert(i)); + QT_TRY { + node_construct(n, t); + } QT_CATCH(...) { + p.remove(i); + QT_RETHROW; + } + } else { + typedef typename QtPodForType<T>::Type PodNode; + PodNode cpy = *reinterpret_cast<const PodNode *>(&t); + Node *n = reinterpret_cast<Node *>(p.insert(i)); + QT_TRY { + node_construct(n, *reinterpret_cast<const T *>(&cpy)); + } QT_CATCH(...) { + p.remove(i); + QT_RETHROW; + } } } } @@ -540,12 +607,7 @@ inline void QList<T>::replace(int i, const T &t) { Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::replace", "index out of range"); detach(); - if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { - reinterpret_cast<Node *>(p.at(i))->t() = t; - } else { - const T cpy(t); - reinterpret_cast<Node *>(p.at(i))->t() = cpy; - } + reinterpret_cast<Node *>(p.at(i))->t() = t; } template <typename T> @@ -575,11 +637,20 @@ Q_OUTOFLINE_TEMPLATE QList<T> QList<T>::mid(int pos, int alength) const alength = size() - pos; if (pos == 0 && alength == size()) return *this; - QList<T> cpy; if (pos + alength > size()) alength = size() - pos; - for (int i = pos; i < pos + alength; ++i) - cpy += at(i); + QList<T> cpy; + cpy.reserve(alength); + cpy.d->end = alength; + QT_TRY { + cpy.node_copy(reinterpret_cast<Node *>(cpy.p.begin()), + reinterpret_cast<Node *>(cpy.p.end()), + reinterpret_cast<Node *>(p.begin() + pos)); + } QT_CATCH(...) { + // restore the old end + cpy.d->end = 0; + QT_RETHROW; + } return cpy; } @@ -599,10 +670,40 @@ Q_OUTOFLINE_TEMPLATE T QList<T>::value(int i, const T& defaultValue) const } template <typename T> -Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper() +Q_OUTOFLINE_TEMPLATE typename QList<T>::Node *QList<T>::detach_helper_grow(int i, int c) +{ + Node *n = reinterpret_cast<Node *>(p.begin()); + QListData::Data *x = p.detach_grow(&i, c); + QT_TRY { + node_copy(reinterpret_cast<Node *>(p.begin()), + reinterpret_cast<Node *>(p.begin() + i), n); + } QT_CATCH(...) { + qFree(d); + d = x; + QT_RETHROW; + } + QT_TRY { + node_copy(reinterpret_cast<Node *>(p.begin() + i + c), + reinterpret_cast<Node *>(p.end()), n + i); + } QT_CATCH(...) { + node_destruct(reinterpret_cast<Node *>(p.begin()), + reinterpret_cast<Node *>(p.begin() + i)); + qFree(d); + d = x; + QT_RETHROW; + } + + if (!x->ref.deref()) + free(x); + + return reinterpret_cast<Node *>(p.begin() + i); +} + +template <typename T> +Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper(int alloc) { Node *n = reinterpret_cast<Node *>(p.begin()); - QListData::Data *x = p.detach3(); + QListData::Data *x = p.detach(alloc); QT_TRY { node_copy(reinterpret_cast<Node *>(p.begin()), reinterpret_cast<Node *>(p.end()), n); } QT_CATCH(...) { @@ -616,6 +717,12 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper() } template <typename T> +Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper() +{ + detach_helper(d->alloc); +} + +template <typename T> Q_OUTOFLINE_TEMPLATE QList<T>::~QList() { if (d && !d->ref.deref()) @@ -701,8 +808,9 @@ Q_OUTOFLINE_TEMPLATE typename QList<T>::iterator QList<T>::erase(typename QList< template <typename T> Q_OUTOFLINE_TEMPLATE QList<T> &QList<T>::operator+=(const QList<T> &l) { - detach(); - Node *n = reinterpret_cast<Node *>(p.append2(l.p)); + Node *n = (d->ref != 1) + ? detach_helper_grow(INT_MAX, l.size()) + : reinterpret_cast<Node *>(p.append2(l.p)); QT_TRY{ node_copy(n, reinterpret_cast<Node *>(p.end()), reinterpret_cast<Node *>(l.p.begin())); } QT_CATCH(...) { diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index ff10fa1..b4bfcaf 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -2917,7 +2917,7 @@ QDate QLocale::toDate(const QString &string, FormatType format) const #ifndef QT_NO_DATESTRING QDateTime QLocale::toDateTime(const QString &string, FormatType format) const { - return toDateTime(string, dateFormat(format)); + return toDateTime(string, dateTimeFormat(format)); } #endif diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 9ba9ca5..2e21547 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -214,7 +214,7 @@ public: public: typedef std::bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef T *pointer; typedef T &reference; @@ -282,7 +282,7 @@ public: public: typedef std::bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef const T *pointer; typedef const T &reference; @@ -385,7 +385,7 @@ public: // STL compatibility typedef Key key_type; typedef T mapped_type; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef int size_type; inline bool empty() const { return isEmpty(); } diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp index d60087f..9850ee7 100644 --- a/src/corelib/tools/qpoint.cpp +++ b/src/corelib/tools/qpoint.cpp @@ -374,7 +374,7 @@ QDebug operator<<(QDebug dbg, const QPoint &p) { QDebug operator<<(QDebug d, const QPointF &p) { d.nospace() << "QPointF(" << p.x() << ", " << p.y() << ')'; - return d; + return d.space(); } #endif diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h index 6525880..fe50d4d 100644 --- a/src/corelib/tools/qset.h +++ b/src/corelib/tools/qset.h @@ -97,7 +97,7 @@ public: public: typedef std::bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef const T *pointer; typedef const T &reference; @@ -132,7 +132,7 @@ public: public: typedef std::bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef const T *pointer; typedef const T &reference; @@ -188,11 +188,10 @@ public: typedef const value_type *const_pointer; typedef value_type &reference; typedef const value_type &const_reference; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef int size_type; inline bool empty() const { return isEmpty(); } - // comfort inline QSet<T> &operator<<(const T &value) { insert(value); return *this; } inline QSet<T> &operator|=(const QSet<T> &other) { unite(other); return *this; } @@ -292,6 +291,7 @@ template <typename T> Q_OUTOFLINE_TEMPLATE QList<T> QSet<T>::toList() const { QList<T> result; + result.reserve(size()); typename QSet<T>::const_iterator i = constBegin(); while (i != constEnd()) { result.append(*i); diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 8fbfcda..d85c248 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -132,7 +132,7 @@ namespace QtSharedPointer { typedef const value_type *const_pointer; typedef value_type &reference; typedef const value_type &const_reference; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; inline T *data() const { return value; } inline bool isNull() const { return !data(); } @@ -541,7 +541,7 @@ public: typedef const value_type *const_pointer; typedef value_type &reference; typedef const value_type &const_reference; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; } #ifndef Q_CC_NOKIAX86 @@ -653,6 +653,9 @@ public: T *value; }; +// +// operator== and operator!= +// template <class T, class X> bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) { @@ -674,7 +677,6 @@ bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2) { return ptr1 == ptr2.data(); } - template <class T, class X> bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2) { @@ -697,11 +699,54 @@ bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2) return ptr2 != ptr1; } +// +// operator- +// template <class T, class X> -Q_INLINE_TEMPLATE typename T::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) +Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) { return ptr1.data() - ptr2.data(); } +template <class T, class X> +Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, X *ptr2) +{ + return ptr1.data() - ptr2; +} +template <class T, class X> +Q_INLINE_TEMPLATE typename QSharedPointer<X>::difference_type operator-(T *ptr1, const QSharedPointer<X> &ptr2) +{ + return ptr1 - ptr2.data(); +} + +// +// operator< +// +template <class T, class X> +Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2) +{ + return ptr1.data() < ptr2.data(); +} +template <class T, class X> +Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, X *ptr2) +{ + return ptr1.data() < ptr2; +} +template <class T, class X> +Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2) +{ + return ptr1 < ptr2.data(); +} + +// +// qHash +// +template <class T> inline uint qHash(const T *key); // defined in qhash.h +template <class T> +Q_INLINE_TEMPLATE uint qHash(const QSharedPointer<T> &ptr) +{ + return QT_PREPEND_NAMESPACE(qHash)<T>(ptr.data()); +} + template <class T> Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 571a015..9431ef4 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -990,6 +990,40 @@ QString::QString(const QChar *unicode, int size) } } +/*! + \since 4.7 + + Constructs a string initialized with the characters of the QChar array + \a unicode, which must be terminated with a 0. + + QString makes a deep copy of the string data. The unicode data is copied as + is and the Byte Order Mark is preserved if present. +*/ +QString::QString(const QChar *unicode) +{ + if (!unicode) { + d = &shared_null; + d->ref.ref(); + } else { + int size = 0; + while (unicode[size] != 0) + ++size; + if (!size) { + d = &shared_empty; + d->ref.ref(); + } else { + d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar)); + Q_CHECK_PTR(d); + d->ref = 1; + d->alloc = d->size = size; + d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0; + d->data = d->array; + memcpy(d->array, unicode, size * sizeof(QChar)); + d->array[size] = '\0'; + } + } +} + /*! Constructs a string of the given \a size with every character set @@ -1767,13 +1801,14 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar } QT_TRY { - detach(); if (blen == alen) { // replace in place + detach(); for (int i = 0; i < nIndices; ++i) memcpy(d->data + indices[i], afterBuffer, alen * sizeof(QChar)); } else if (alen < blen) { // replace from front + detach(); uint to = indices[0]; if (alen) memcpy(d->data+to, after, alen*sizeof(QChar)); @@ -3887,7 +3922,7 @@ QString QString::fromUtf8(const char *str, int size) host byte order is assumed. This function is comparatively slow. - Use QString(const ushort *, int) if possible. + Use QString(const ushort *, int) or QString(const ushort *) if possible. QString makes a deep copy of the Unicode data. @@ -3980,24 +4015,74 @@ QString QString::simplified() const { if (d->size == 0) return *this; - QString result(d->size, Qt::Uninitialized); - const QChar *from = (const QChar*) d->data; - const QChar *fromend = (const QChar*) from+d->size; - int outc=0; - QChar *to = (QChar*) result.d->data; - for (;;) { - while (from!=fromend && from->isSpace()) - from++; - while (from!=fromend && !from->isSpace()) - to[outc++] = *from++; - if (from!=fromend) - to[outc++] = QLatin1Char(' '); - else + + const QChar * const start = reinterpret_cast<QChar *>(d->data); + const QChar *from = start; + const QChar *fromEnd = start + d->size; + forever { + QChar ch = *from; + if (!ch.isSpace()) break; + if (++from == fromEnd) { + // All-whitespace string + shared_empty.ref.ref(); + return QString(&shared_empty, 0); + } + } + // This loop needs no underflow check, as we already determined that + // the string contains non-whitespace. If the string has exactly one + // non-whitespace, it will be checked twice - we can live with that. + while (fromEnd[-1].isSpace()) + fromEnd--; + // The rest of the function depends on the fact that we already know + // that the last character in the source is no whitespace. + const QChar *copyFrom = from; + int copyCount; + forever { + if (++from == fromEnd) { + // Only leading and/or trailing whitespace, if any at all + return mid(copyFrom - start, from - copyFrom); + } + QChar ch = *from; + if (!ch.isSpace()) + continue; + if (ch != QLatin1Char(' ')) { + copyCount = from - copyFrom; + break; + } + ch = *++from; + if (ch.isSpace()) { + copyCount = from - copyFrom - 1; + break; + } + } + // 'from' now points at the non-trailing whitespace which made the + // string not simplified in the first place. 'copyCount' is the number + // of already simplified characters - at least one, obviously - + // without a trailing space. + QString result((fromEnd - from) + copyCount, Qt::Uninitialized); + QChar *to = reinterpret_cast<QChar *>(result.d->data); + ::memcpy(to, copyFrom, copyCount * 2); + to += copyCount; + fromEnd--; + QChar ch; + forever { + *to++ = QLatin1Char(' '); + do { + ch = *++from; + } while (ch.isSpace()); + if (from == fromEnd) + break; + do { + *to++ = ch; + ch = *++from; + if (from == fromEnd) + goto done; + } while (!ch.isSpace()); } - if (outc > 0 && to[outc-1] == QLatin1Char(' ')) - outc--; - result.truncate(outc); + done: + *to++ = ch; + result.truncate(to - reinterpret_cast<QChar *>(result.d->data)); return result; } diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 5e3b0fd..8de3c7d 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -91,7 +91,8 @@ class Q_CORE_EXPORT QString { public: inline QString(); - QString(const QChar *unicode, int size); + QString(const QChar *unicode, int size); // Qt5: don't cap size < 0 + explicit QString(const QChar *unicode); // Qt5: merge with the above QString(QChar c); QString(int size, QChar c); inline QString(const QLatin1String &latin1); @@ -595,7 +596,7 @@ private: struct Data { QBasicAtomicInt ref; int alloc, size; - ushort *data; + ushort *data; // QT5: put that after the bit field to fill alignment gap; don't use sizeof any more then ushort clean : 1; ushort simpletext : 1; ushort righttoleft : 1; diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index ddb5c7d..74661c2 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -71,7 +71,7 @@ public: private: const int m_size; - const char *m_data; + const char * const m_data; }; struct Q_CORE_EXPORT QAbstractConcatenable diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 61b22fd..c2e2485 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -164,7 +164,7 @@ public: public: T *i; typedef std::random_access_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef T *pointer; typedef T &reference; @@ -197,7 +197,7 @@ public: public: T *i; typedef std::random_access_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef T value_type; typedef const T *pointer; typedef const T &reference; @@ -261,7 +261,7 @@ public: typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; - typedef ptrdiff_t difference_type; + typedef qptrdiff difference_type; typedef iterator Iterator; typedef const_iterator ConstIterator; typedef int size_type; @@ -728,9 +728,10 @@ Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int length) const length = size() - pos; if (pos == 0 && length == size()) return *this; - QVector<T> copy; if (pos + length > size()) length = size() - pos; + QVector<T> copy; + copy.reserve(length); for (int i = pos; i < pos + length; ++i) copy += at(i); return copy; @@ -740,6 +741,7 @@ template <typename T> Q_OUTOFLINE_TEMPLATE QList<T> QVector<T>::toList() const { QList<T> result; + result.reserve(size()); for (int i = 0; i < size(); ++i) result.append(at(i)); return result; diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h index 6b911d2..ac421cf 100644 --- a/src/corelib/xml/qxmlstream_p.h +++ b/src/corelib/xml/qxmlstream_p.h @@ -54,7 +54,7 @@ #ifndef QXMLSTREAM_P_H #define QXMLSTREAM_P_H -#if defined(Q_OS_VXWORKS) && defined(ERROR) +#if defined(ERROR) # undef ERROR #endif |