diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-09-10 18:04:39 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2010-09-10 18:04:39 (GMT) |
commit | b3981fd1f7b82742857c613af6dfbe41b5493577 (patch) | |
tree | 957b84d8f1792f9e5a43c879274469c4f07168ea /src/corelib | |
parent | e0ef11578048620b3f107b7a357fed3aade0d21e (diff) | |
parent | 72cc21e597f2d77ea1be3c1a3f7df36d8909d2fc (diff) | |
download | Qt-b3981fd1f7b82742857c613af6dfbe41b5493577.zip Qt-b3981fd1f7b82742857c613af6dfbe41b5493577.tar.gz Qt-b3981fd1f7b82742857c613af6dfbe41b5493577.tar.bz2 |
Merge remote branch 'origin/4.7' into qt-master-from-4.7
Conflicts:
bin/syncqt
demos/declarative/snake/content/snake.js
demos/declarative/snake/snake.qml
doc/src/development/qmake-manual.qdoc
src/corelib/plugin/plugin.pri
src/gui/kernel/qapplication_win.cpp
src/gui/kernel/qdesktopwidget_win.cpp
src/gui/painting/qdrawhelper.cpp
tests/auto/qdir/tst_qdir.cpp
tools/qdoc3/test/assistant.qdocconf
tools/qdoc3/test/designer.qdocconf
tools/qdoc3/test/linguist.qdocconf
Diffstat (limited to 'src/corelib')
25 files changed, 941 insertions, 655 deletions
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index 2505e72..260ed59 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -19,7 +19,7 @@ INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global # Only used on platforms with CONFIG += precompile_header PRECOMPILED_HEADER = global/qt_pch.h -linux*:!static { +linux*:!static:!linux-armcc:!linux-gcce { QMAKE_LFLAGS += -Wl,-e,qt_core_boilerplate prog=$$quote(if (/program interpreter: (.*)]/) { print $1; }) DEFINES += ELF_INTERPRETER=\\\"$$system(readelf -l /bin/ls | perl -n -e \'$$prog\')\\\" diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index a0779c9..957abbf 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -66,6 +66,8 @@ QT_END_NAMESPACE QT_BEGIN_NAMESPACE +extern void qDumpCPUFeatures(); // in qsimd.cpp + #ifndef QT_NO_SETTINGS struct QLibrarySettings @@ -500,7 +502,6 @@ QT_END_NAMESPACE extern const char qt_core_interpreter[] __attribute__((section(".interp"))) = ELF_INTERPRETER; -extern void qDumpCPUFeatures(); // in qsimd.cpp extern "C" void qt_core_boilerplate(); void qt_core_boilerplate() { @@ -526,7 +527,7 @@ void qt_core_boilerplate() qt_configure_libraries_path_str + 12, qt_configure_headers_path_str + 12); -// qDumpCPUFeatures(); + QT_PREPEND_NAMESPACE(qDumpCPUFeatures)(); #ifdef QT_EVAL extern void qt_core_eval_init(uint); diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 0eb8965..f6f4b19 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -82,20 +82,69 @@ static QString driveSpec(const QString &path) //************* QDirPrivate class QDirPrivate + : public QSharedData { - friend struct QScopedPointerDeleter<QDirPrivate>; - public: - QDirPrivate(const QDir *copy = 0); - ~QDirPrivate(); - - void updateFileLists() const; - void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *) const; + QDirPrivate(const QString &path, + const QStringList &nameFilters_ = QStringList(), + QDir::SortFlags sort_ = QDir::SortFlags(QDir::Name | QDir::IgnoreCase), + QDir::Filters filters_ = QDir::AllEntries) + : QSharedData() + , nameFilters(nameFilters_) + , sort(sort_) + , filters(filters_) +#ifdef QT3_SUPPORT + , filterSepChar(0) + , matchAllDirs(false) +#endif + , fileListsInitialized(false) + { + setPath(path.isEmpty() ? QString::fromLatin1(".") : path); + + bool empty = nameFilters.isEmpty(); + if (!empty) { + empty = true; + for (int i = 0; i < nameFilters.size(); ++i) { + if (!nameFilters.at(i).isEmpty()) { + empty = false; + break; + } + } + } + if (empty) + nameFilters = QStringList(QString::fromLatin1("*")); + } + QDirPrivate(const QDirPrivate ©) + : QSharedData(copy) + , path(copy.path) + , nameFilters(copy.nameFilters) + , sort(copy.sort) + , filters(copy.filters) #ifdef QT3_SUPPORT - QChar filterSepChar; - bool matchAllDirs; + , filterSepChar(copy.filterSepChar) + , matchAllDirs(copy.matchAllDirs) #endif + , fileListsInitialized(false) + { + } + + bool exists() const + { + const QAbstractFileEngine::FileFlags info = + fileEngine->fileFlags(QAbstractFileEngine::DirectoryType + | QAbstractFileEngine::ExistsFlag + | QAbstractFileEngine::Refresh); + if (!(info & QAbstractFileEngine::DirectoryType)) + return false; + return info & QAbstractFileEngine::ExistsFlag; + } + + void initFileEngine(); + void initFileLists() const; + + static void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *); + static inline QChar getFilterSepChar(const QString &nameFilter) { QChar sep(QLatin1Char(';')); @@ -104,7 +153,9 @@ public: sep = QChar(QLatin1Char(' ')); return sep; } - static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0) { + + static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0) + { if (sep == 0) sep = getFilterSepChar(nameFilter); QStringList ret = nameFilter.split(sep); @@ -113,80 +164,46 @@ public: return ret; } - struct Data { - inline Data() - : ref(1), fileEngine(0), listsDirty(1) - {} - inline Data(const Data ©) - : ref(1), path(copy.path), nameFilters(copy.nameFilters), sort(copy.sort), - filters(copy.filters), fileEngine(0), listsDirty(1) - {} - inline ~Data() - { delete fileEngine; } - - inline void clear() { - listsDirty = 1; - files.clear(); - fileInfos.clear(); - } - mutable QAtomicInt ref; - - QString path; - QStringList nameFilters; - QDir::SortFlags sort; - QDir::Filters filters; - - mutable QAbstractFileEngine *fileEngine; - - mutable uint listsDirty : 1; - mutable QStringList files; - mutable QFileInfoList fileInfos; - } *data; - inline void setPath(const QString &p) + inline void setPath(QString p) { - detach(false); - QString path = p; - if ((path.endsWith(QLatin1Char('/')) || path.endsWith(QLatin1Char('\\'))) - && path.length() > 1) { + if ((p.endsWith(QLatin1Char('/')) || p.endsWith(QLatin1Char('\\'))) + && p.length() > 1) { #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - if (!(path.length() == 3 && path.at(1) == QLatin1Char(':'))) + if (!(p.length() == 3 && p.at(1) == QLatin1Char(':'))) #endif - path.truncate(path.length() - 1); + p.truncate(p.length() - 1); } - delete data->fileEngine; - data->fileEngine = QAbstractFileEngine::create(path); + path = p; + initFileEngine(); // set the path to be the qt friendly version so then we can operate on it using just / - data->path = data->fileEngine->fileName(QAbstractFileEngine::DefaultName); - data->clear(); + path = fileEngine->fileName(QAbstractFileEngine::DefaultName); + clearFileLists(); } - inline void reset() { - detach(); - data->clear(); + + inline void clearFileLists() { + fileListsInitialized = false; + files.clear(); + fileInfos.clear(); } - void detach(bool createFileEngine = true); -}; -QDirPrivate::QDirPrivate(const QDir *copy) + QString path; + QStringList nameFilters; + QDir::SortFlags sort; + QDir::Filters filters; + #ifdef QT3_SUPPORT - : filterSepChar(0), matchAllDirs(false) + QChar filterSepChar; + bool matchAllDirs; #endif -{ - if (copy) { - copy->d_func()->data->ref.ref(); - data = copy->d_func()->data; - } else { - data = new QDirPrivate::Data; - } -} -QDirPrivate::~QDirPrivate() -{ - if (!data->ref.deref()) - delete data; - data = 0; -} + QScopedPointer<QAbstractFileEngine> fileEngine; + + mutable bool fileListsInitialized; + mutable QStringList files; + mutable QFileInfoList fileInfos; +}; /* For sorting */ struct QDirSortItem @@ -269,7 +286,7 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt } inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, - QStringList *names, QFileInfoList *infos) const + QStringList *names, QFileInfoList *infos) { // names and infos are always empty lists or 0 here int n = l.size(); @@ -299,28 +316,23 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, } } -inline void QDirPrivate::updateFileLists() const +inline void QDirPrivate::initFileLists() const { - if (data->listsDirty) { + if (!fileListsInitialized) { QFileInfoList l; - QDirIterator it(data->path, data->nameFilters, data->filters); + QDirIterator it(path, nameFilters, filters); while (it.hasNext()) { it.next(); l.append(it.fileInfo()); } - sortFileList(data->sort, l, &data->files, &data->fileInfos); - data->listsDirty = 0; + sortFileList(sort, l, &files, &fileInfos); + fileListsInitialized = true; } } -void QDirPrivate::detach(bool createFileEngine) +inline void QDirPrivate::initFileEngine() { - qAtomicDetach(data); - if (createFileEngine) { - QAbstractFileEngine *newFileEngine = QAbstractFileEngine::create(data->path); - delete data->fileEngine; - data->fileEngine = newFileEngine; - } + fileEngine.reset(QAbstractFileEngine::create(path)); } /*! @@ -504,13 +516,8 @@ void QDirPrivate::detach(bool createFileEngine) \sa currentPath() */ -QDir::QDir(const QString &path) : d_ptr(new QDirPrivate) +QDir::QDir(const QString &path) : d_ptr(new QDirPrivate(path)) { - Q_D(QDir); - d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); - d->data->nameFilters = QStringList(QString::fromLatin1("*")); - d->data->filters = AllEntries; - d->data->sort = SortFlags(Name | IgnoreCase); } /*! @@ -532,25 +539,9 @@ QDir::QDir(const QString &path) : d_ptr(new QDirPrivate) \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting() */ QDir::QDir(const QString &path, const QString &nameFilter, - SortFlags sort, Filters filters) : d_ptr(new QDirPrivate) -{ - Q_D(QDir); - d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path); - d->data->nameFilters = QDir::nameFiltersFromString(nameFilter); - bool empty = d->data->nameFilters.isEmpty(); - if (!empty) { - empty = true; - for (int i = 0; i < d->data->nameFilters.size(); ++i) { - if (!d->data->nameFilters.at(i).isEmpty()) { - empty = false; - break; - } - } - } - if (empty) - d->data->nameFilters = QStringList(QString::fromLatin1("*")); - d->data->sort = sort; - d->data->filters = filters; + SortFlags sort, Filters filters) + : d_ptr(new QDirPrivate(path, QDir::nameFiltersFromString(nameFilter), sort, filters)) +{ } /*! @@ -559,7 +550,8 @@ QDir::QDir(const QString &path, const QString &nameFilter, \sa operator=() */ -QDir::QDir(const QDir &dir) : d_ptr(new QDirPrivate(&dir)) +QDir::QDir(const QDir &dir) + : d_ptr(dir.d_ptr) { } @@ -589,8 +581,7 @@ QDir::~QDir() */ void QDir::setPath(const QString &path) { - Q_D(QDir); - d->setPath(path); + d_ptr->setPath(path); } /*! @@ -605,8 +596,8 @@ void QDir::setPath(const QString &path) */ QString QDir::path() const { - Q_D(const QDir); - return d->data->path; + const QDirPrivate* d = d_ptr.constData(); + return d->path; } /*! @@ -619,8 +610,8 @@ QString QDir::path() const */ QString QDir::absolutePath() const { - Q_D(const QDir); - QString ret = d->data->path; + const QDirPrivate* d = d_ptr.constData(); + QString ret = d->path; if (QDir::isRelativePath(ret)) ret = absoluteFilePath(QString::fromLatin1("")); return cleanPath(ret); @@ -644,11 +635,7 @@ QString QDir::absolutePath() const */ QString QDir::canonicalPath() const { - Q_D(const QDir); - - if (!d->data->fileEngine) - return QLatin1String(""); - return cleanPath(d->data->fileEngine->fileName(QAbstractFileEngine::CanonicalName)); + return cleanPath(d_ptr->fileEngine->fileName(QAbstractFileEngine::CanonicalName)); } /*! @@ -664,11 +651,11 @@ QString QDir::canonicalPath() const */ QString QDir::dirName() const { - Q_D(const QDir); - int pos = d->data->path.lastIndexOf(QLatin1Char('/')); + const QDirPrivate* d = d_ptr.constData(); + int pos = d->path.lastIndexOf(QLatin1Char('/')); if (pos == -1) - return d->data->path; - return d->data->path.mid(pos + 1); + return d->path; + return d->path.mid(pos + 1); } /*! @@ -682,11 +669,11 @@ QString QDir::dirName() const */ QString QDir::filePath(const QString &fileName) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (isAbsolutePath(fileName)) return QString(fileName); - QString ret = d->data->path; + QString ret = d->path; if (!fileName.isEmpty()) { if (!ret.isEmpty() && ret[(int)ret.length()-1] != QLatin1Char('/') && fileName[0] != QLatin1Char('/')) ret += QLatin1Char('/'); @@ -705,21 +692,19 @@ QString QDir::filePath(const QString &fileName) const */ QString QDir::absoluteFilePath(const QString &fileName) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (isAbsolutePath(fileName)) return fileName; - if (!d->data->fileEngine) - return fileName; QString ret; #ifndef QT_NO_FSFILEENGINE - if (isRelativePath(d->data->path)) //get pwd + if (isRelativePath(d->path)) //get pwd ret = QFSFileEngine::currentPath(fileName); #endif - if (!d->data->path.isEmpty() && d->data->path != QLatin1String(".")) { + if (!d->path.isEmpty() && d->path != QLatin1String(".")) { if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) ret += QLatin1Char('/'); - ret += d->data->path; + ret += d->path; } if (!fileName.isEmpty()) { if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/'))) @@ -869,11 +854,12 @@ QString QDir::fromNativeSeparators(const QString &pathName) */ bool QDir::cd(const QString &dirName) { - Q_D(QDir); + // Don't detach just yet. + const QDirPrivate * const d = d_ptr.constData(); if (dirName.isEmpty() || dirName == QLatin1String(".")) return true; - QString newPath = d->data->path; + QString newPath = d->path; if (isAbsolutePath(dirName)) { newPath = cleanPath(dirName); } else { @@ -886,7 +872,7 @@ bool QDir::cd(const QString &dirName) newPath += dirName; if (dirName.indexOf(QLatin1Char('/')) >= 0 - || d->data->path == QLatin1String(".") + || d->path == QLatin1String(".") || dirName == QLatin1String("..")) { newPath = cleanPath(newPath); /* @@ -903,12 +889,13 @@ bool QDir::cd(const QString &dirName) } } - QDir dir(*this); - dir.setPath(newPath); - if (!dir.exists()) + QScopedPointer<QDirPrivate> dir(new QDirPrivate(*d_ptr.constData())); + dir->setPath(newPath); + + if (!dir->exists()) return false; - *this = dir; + d_ptr = dir.take(); return true; } @@ -932,9 +919,8 @@ bool QDir::cdUp() */ QStringList QDir::nameFilters() const { - Q_D(const QDir); - - return d->data->nameFilters; + const QDirPrivate* d = d_ptr.constData(); + return d->nameFilters; } /*! @@ -954,10 +940,11 @@ QStringList QDir::nameFilters() const */ void QDir::setNameFilters(const QStringList &nameFilters) { - Q_D(QDir); + QDirPrivate* d = d_ptr.data(); + d->initFileEngine(); + d->clearFileLists(); - d->reset(); - d->data->nameFilters = nameFilters; + d->nameFilters = nameFilters; } /*! @@ -1060,9 +1047,8 @@ QStringList QDir::searchPaths(const QString &prefix) */ QDir::Filters QDir::filter() const { - Q_D(const QDir); - - return d->data->filters; + const QDirPrivate* d = d_ptr.constData(); + return d->filters; } /*! @@ -1143,10 +1129,11 @@ QDir::Filters QDir::filter() const */ void QDir::setFilter(Filters filters) { - Q_D(QDir); + QDirPrivate* d = d_ptr.data(); + d->initFileEngine(); + d->clearFileLists(); - d->reset(); - d->data->filters = filters; + d->filters = filters; } /*! @@ -1156,9 +1143,8 @@ void QDir::setFilter(Filters filters) */ QDir::SortFlags QDir::sorting() const { - Q_D(const QDir); - - return d->data->sort; + const QDirPrivate* d = d_ptr.constData(); + return d->sort; } /*! @@ -1201,10 +1187,11 @@ QDir::SortFlags QDir::sorting() const */ void QDir::setSorting(SortFlags sort) { - Q_D(QDir); + QDirPrivate* d = d_ptr.data(); + d->initFileEngine(); + d->clearFileLists(); - d->reset(); - d->data->sort = sort; + d->sort = sort; } /*! @@ -1216,10 +1203,9 @@ void QDir::setSorting(SortFlags sort) */ uint QDir::count() const { - Q_D(const QDir); - - d->updateFileLists(); - return d->data->files.count(); + const QDirPrivate* d = d_ptr.constData(); + d->initFileLists(); + return d->files.count(); } /*! @@ -1231,10 +1217,9 @@ uint QDir::count() const */ QString QDir::operator[](int pos) const { - Q_D(const QDir); - - d->updateFileLists(); - return d->data->files[pos]; + const QDirPrivate* d = d_ptr.constData(); + d->initFileLists(); + return d->files[pos]; } /*! @@ -1258,9 +1243,8 @@ QString QDir::operator[](int pos) const */ QStringList QDir::entryList(Filters filters, SortFlags sort) const { - Q_D(const QDir); - - return entryList(d->data->nameFilters, filters, sort); + const QDirPrivate* d = d_ptr.constData(); + return entryList(d->nameFilters, filters, sort); } @@ -1282,9 +1266,8 @@ QStringList QDir::entryList(Filters filters, SortFlags sort) const */ QFileInfoList QDir::entryInfoList(Filters filters, SortFlags sort) const { - Q_D(const QDir); - - return entryInfoList(d->data->nameFilters, filters, sort); + const QDirPrivate* d = d_ptr.constData(); + return entryInfoList(d->nameFilters, filters, sort); } /*! @@ -1306,24 +1289,24 @@ QFileInfoList QDir::entryInfoList(Filters filters, SortFlags sort) const QStringList QDir::entryList(const QStringList &nameFilters, Filters filters, SortFlags sort) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (filters == NoFilter) - filters = d->data->filters; + filters = d->filters; #ifdef QT3_SUPPORT if (d->matchAllDirs) filters |= AllDirs; #endif if (sort == NoSort) - sort = d->data->sort; + sort = d->sort; - if (filters == d->data->filters && sort == d->data->sort && nameFilters == d->data->nameFilters) { - d->updateFileLists(); - return d->data->files; + if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) { + d->initFileLists(); + return d->files; } QFileInfoList l; - QDirIterator it(d->data->path, nameFilters, filters); + QDirIterator it(d->path, nameFilters, filters); while (it.hasNext()) { it.next(); l.append(it.fileInfo()); @@ -1352,24 +1335,24 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters, QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filters, SortFlags sort) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (filters == NoFilter) - filters = d->data->filters; + filters = d->filters; #ifdef QT3_SUPPORT if (d->matchAllDirs) filters |= AllDirs; #endif if (sort == NoSort) - sort = d->data->sort; + sort = d->sort; - if (filters == d->data->filters && sort == d->data->sort && nameFilters == d->data->nameFilters) { - d->updateFileLists(); - return d->data->fileInfos; + if (filters == d->filters && sort == d->sort && nameFilters == d->nameFilters) { + d->initFileLists(); + return d->fileInfos; } QFileInfoList l; - QDirIterator it(d->data->path, nameFilters, filters); + QDirIterator it(d->path, nameFilters, filters); while (it.hasNext()) { it.next(); l.append(it.fileInfo()); @@ -1388,17 +1371,15 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter */ bool QDir::mkdir(const QString &dirName) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (dirName.isEmpty()) { qWarning("QDir::mkdir: Empty or null file name(s)"); return false; } - if (!d->data->fileEngine) - return false; QString fn = filePath(dirName); - return d->data->fileEngine->mkdir(fn, false); + return d->fileEngine->mkdir(fn, false); } /*! @@ -1412,17 +1393,15 @@ bool QDir::mkdir(const QString &dirName) const */ bool QDir::rmdir(const QString &dirName) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (dirName.isEmpty()) { qWarning("QDir::rmdir: Empty or null file name(s)"); return false; } - if (!d->data->fileEngine) - return false; QString fn = filePath(dirName); - return d->data->fileEngine->rmdir(fn, false); + return d->fileEngine->rmdir(fn, false); } /*! @@ -1437,17 +1416,15 @@ bool QDir::rmdir(const QString &dirName) const */ bool QDir::mkpath(const QString &dirPath) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (dirPath.isEmpty()) { qWarning("QDir::mkpath: Empty or null file name(s)"); return false; } - if (!d->data->fileEngine) - return false; QString fn = filePath(dirPath); - return d->data->fileEngine->mkdir(fn, true); + return d->fileEngine->mkdir(fn, true); } /*! @@ -1463,17 +1440,15 @@ bool QDir::mkpath(const QString &dirPath) const */ bool QDir::rmpath(const QString &dirPath) const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); if (dirPath.isEmpty()) { qWarning("QDir::rmpath: Empty or null file name(s)"); return false; } - if (!d->data->fileEngine) - return false; QString fn = filePath(dirPath); - return d->data->fileEngine->rmdir(fn, true); + return d->fileEngine->rmdir(fn, true); } /*! @@ -1487,12 +1462,10 @@ bool QDir::rmpath(const QString &dirPath) const */ bool QDir::isReadable() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); - if (!d->data->fileEngine) - return false; const QAbstractFileEngine::FileFlags info = - d->data->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType + d->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType | QAbstractFileEngine::PermsMask); if (!(info & QAbstractFileEngine::DirectoryType)) return false; @@ -1512,17 +1485,7 @@ bool QDir::isReadable() const */ bool QDir::exists() const { - Q_D(const QDir); - - if (!d->data->fileEngine) - return false; - const QAbstractFileEngine::FileFlags info = - d->data->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType - | QAbstractFileEngine::ExistsFlag - | QAbstractFileEngine::Refresh); - if (!(info & QAbstractFileEngine::DirectoryType)) - return false; - return info & QAbstractFileEngine::ExistsFlag; + return d_ptr->exists(); } /*! @@ -1539,11 +1502,7 @@ bool QDir::exists() const */ bool QDir::isRoot() const { - Q_D(const QDir); - - if (!d->data->fileEngine) - return true; - return d->data->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag; + return d_ptr->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag; } /*! @@ -1573,11 +1532,7 @@ bool QDir::isRoot() const */ bool QDir::isRelative() const { - Q_D(const QDir); - - if (!d->data->fileEngine) - return false; - return d->data->fileEngine->isRelativePath(); + return d_ptr->fileEngine->isRelativePath(); } @@ -1590,18 +1545,17 @@ bool QDir::isRelative() const */ bool QDir::makeAbsolute() // ### What do the return values signify? { - Q_D(QDir); - - if (!d->data->fileEngine) - return false; - QString absolutePath = d->data->fileEngine->fileName(QAbstractFileEngine::AbsoluteName); + QString absolutePath = d_ptr.constData()->fileEngine->fileName(QAbstractFileEngine::AbsoluteName); if (QDir::isRelativePath(absolutePath)) return false; - d->detach(); - d->data->path = absolutePath; - d->data->fileEngine->setFileName(absolutePath); - if (!(d->data->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) + + QScopedPointer<QDirPrivate> dir(new QDirPrivate(*d_ptr.constData())); + dir->setPath(absolutePath); + + if (!(dir->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType)) return false; + + d_ptr = dir.take(); return true; } @@ -1616,19 +1570,18 @@ bool QDir::makeAbsolute() // ### What do the return values signify? */ bool QDir::operator==(const QDir &dir) const { - const QDirPrivate *d = d_func(); - const QDirPrivate *other = dir.d_func(); + const QDirPrivate *d = d_ptr.constData(); + const QDirPrivate *other = dir.d_ptr.constData(); - if (d->data == other->data) + if (d == other) return true; - Q_ASSERT(d->data->fileEngine && other->data->fileEngine); - if (d->data->fileEngine->caseSensitive() != other->data->fileEngine->caseSensitive()) + if (d->fileEngine->caseSensitive() != other->fileEngine->caseSensitive()) return false; - if (d->data->filters == other->data->filters - && d->data->sort == other->data->sort - && d->data->nameFilters == other->data->nameFilters) { + if (d->filters == other->filters + && d->sort == other->sort + && d->nameFilters == other->nameFilters) { QString dir1 = absolutePath(), dir2 = dir.absolutePath(); - if (!other->data->fileEngine->caseSensitive()) + if (!other->fileEngine->caseSensitive()) return (dir1.toLower() == dir2.toLower()); return (dir1 == dir2); @@ -1643,11 +1596,7 @@ bool QDir::operator==(const QDir &dir) const */ QDir &QDir::operator=(const QDir &dir) { - if (this == &dir) - return *this; - - Q_D(QDir); - qAtomicAssign(d->data, dir.d_func()->data); + d_ptr = dir.d_ptr; return *this; } @@ -1661,9 +1610,7 @@ QDir &QDir::operator=(const QDir &dir) */ QDir &QDir::operator=(const QString &path) { - Q_D(QDir); - - d->setPath(path); + d_ptr->setPath(path); return *this; } @@ -1707,14 +1654,10 @@ bool QDir::remove(const QString &fileName) */ bool QDir::rename(const QString &oldName, const QString &newName) { - Q_D(QDir); - if (oldName.isEmpty() || newName.isEmpty()) { qWarning("QDir::rename: Empty or null file name(s)"); return false; } - if (!d->data->fileEngine) - return false; QFile file(filePath(oldName)); if (!file.exists()) @@ -2153,9 +2096,9 @@ bool QDir::isRelativePath(const QString &path) */ void QDir::refresh() const { - Q_D(const QDir); - - const_cast<QDirPrivate *>(d)->reset(); + QDirPrivate *d = const_cast<QDir*>(this)->d_ptr.data(); + d->initFileEngine(); + d->clearFileLists(); } /*! @@ -2231,7 +2174,7 @@ QStringList QDir::nameFiltersFromString(const QString &nameFilter) */ bool QDir::matchAllDirs() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); return d->matchAllDirs; } @@ -2243,9 +2186,10 @@ bool QDir::matchAllDirs() const */ void QDir::setMatchAllDirs(bool on) { - Q_D(QDir); + QDirPrivate* d = d_ptr.data(); + d->initFileEngine(); + d->clearFileLists(); - d->reset(); d->matchAllDirs = on; } @@ -2254,8 +2198,7 @@ void QDir::setMatchAllDirs(bool on) */ QString QDir::nameFilter() const { - Q_D(const QDir); - + const QDirPrivate* d = d_ptr.constData(); return nameFilters().join(QString(d->filterSepChar)); } @@ -2281,10 +2224,12 @@ QString QDir::nameFilter() const */ void QDir::setNameFilter(const QString &nameFilter) { - Q_D(QDir); + QDirPrivate* d = d_ptr.data(); + d->initFileEngine(); + d->clearFileLists(); d->filterSepChar = QDirPrivate::getFilterSepChar(nameFilter); - setNameFilters(QDirPrivate::splitFilters(nameFilter, d->filterSepChar)); + d->nameFilters = QDirPrivate::splitFilters(nameFilter, d->filterSepChar); } /*! diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h index 0a56304..9eab24f 100644 --- a/src/corelib/io/qdir.h +++ b/src/corelib/io/qdir.h @@ -45,7 +45,7 @@ #include <QtCore/qstring.h> #include <QtCore/qfileinfo.h> #include <QtCore/qstringlist.h> -#include <QtCore/qscopedpointer.h> +#include <QtCore/qshareddata.h> QT_BEGIN_HEADER @@ -58,9 +58,8 @@ class QDirPrivate; class Q_CORE_EXPORT QDir { protected: - QScopedPointer<QDirPrivate> d_ptr; -private: - Q_DECLARE_PRIVATE(QDir) + QSharedDataPointer<QDirPrivate> d_ptr; + public: enum Filter { Dirs = 0x001, Files = 0x002, diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 61f7180..7eca212 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -47,59 +47,27 @@ QT_BEGIN_NAMESPACE -QFileInfoPrivate::QFileInfoPrivate(const QFileInfo *copy) -{ - if (copy) { - copy->d_func()->data->ref.ref(); - data = copy->d_func()->data; - } else { - data = new QFileInfoPrivate::Data; - } -} - -QFileInfoPrivate::~QFileInfoPrivate() -{ - if (!data->ref.deref()) - delete data; - data = 0; -} - -void QFileInfoPrivate::initFileEngine(const QString &file) -{ - detach(); - delete data->fileEngine; - data->fileEngine = 0; - data->clear(); - data->fileEngine = QAbstractFileEngine::create(file); - data->fileName = file; -} - -void QFileInfoPrivate::detach() -{ - qAtomicDetach(data); -} - QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const { - if (data->cache_enabled && !data->fileNames[(int)name].isNull()) - return data->fileNames[(int)name]; - QString ret = data->fileEngine->fileName(name); + if (cache_enabled && !fileNames[(int)name].isNull()) + return fileNames[(int)name]; + QString ret = fileEngine->fileName(name); if (ret.isNull()) ret = QLatin1String(""); - if (data->cache_enabled) - data->fileNames[(int)name] = ret; + if (cache_enabled) + fileNames[(int)name] = ret; return ret; } QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const { - if (data->cache_enabled && !data->fileOwners[(int)own].isNull()) - return data->fileOwners[(int)own]; - QString ret = data->fileEngine->owner(own); + if (cache_enabled && !fileOwners[(int)own].isNull()) + return fileOwners[(int)own]; + QString ret = fileEngine->owner(own); if (ret.isNull()) ret = QLatin1String(""); - if (data->cache_enabled) - data->fileOwners[(int)own] = ret; + if (cache_enabled) + fileOwners[(int)own] = ret; return ret; } @@ -118,7 +86,7 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons uint cachedFlags = 0; if (request & (QAbstractFileEngine::FlagsMask | QAbstractFileEngine::TypesMask)) { - if (!data->getCachedFlag(CachedFileFlags)) { + if (!getCachedFlag(CachedFileFlags)) { req |= QAbstractFileEngine::FlagsMask; req |= QAbstractFileEngine::TypesMask; req &= (~QAbstractFileEngine::LinkType); @@ -128,14 +96,14 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons } if (request & QAbstractFileEngine::LinkType) { - if (!data->getCachedFlag(CachedLinkTypeFlag)) { + if (!getCachedFlag(CachedLinkTypeFlag)) { req |= QAbstractFileEngine::LinkType; cachedFlags |= CachedLinkTypeFlag; } } if (request & QAbstractFileEngine::BundleType) { - if (!data->getCachedFlag(CachedBundleTypeFlag)) { + if (!getCachedFlag(CachedBundleTypeFlag)) { req |= QAbstractFileEngine::BundleType; cachedFlags |= CachedBundleTypeFlag; } @@ -143,30 +111,30 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons } if (request & QAbstractFileEngine::PermsMask) { - if (!data->getCachedFlag(CachedPerms)) { + if (!getCachedFlag(CachedPerms)) { req |= QAbstractFileEngine::PermsMask; cachedFlags |= CachedPerms; } } if (req) { - if (data->cache_enabled) + if (cache_enabled) req &= (~QAbstractFileEngine::Refresh); else req |= QAbstractFileEngine::Refresh; - QAbstractFileEngine::FileFlags flags = data->fileEngine->fileFlags(req); - data->fileFlags |= uint(flags); - data->setCachedFlag(cachedFlags); + QAbstractFileEngine::FileFlags flags = fileEngine->fileFlags(req); + fileFlags |= uint(flags); + setCachedFlag(cachedFlags); } - return data->fileFlags & request; + return fileFlags & request; } QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) const { - if (!data->cache_enabled) - data->clearFlags(); + if (!cache_enabled) + clearFlags(); uint cf; if (request == QAbstractFileEngine::CreationTime) cf = CachedCTime; @@ -174,11 +142,11 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) cf = CachedMTime; else cf = CachedATime; - if (!data->getCachedFlag(cf)) { - data->fileTimes[request] = data->fileEngine->fileTime(request); - data->setCachedFlag(cf); + if (!getCachedFlag(cf)) { + fileTimes[request] = fileEngine->fileTime(request); + setCachedFlag(cf); } - return data->fileTimes[request]; + return fileTimes[request]; } //************* QFileInfo @@ -285,9 +253,8 @@ QFileInfo::QFileInfo() : d_ptr(new QFileInfoPrivate()) \sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath() */ -QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate()) +QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate(file)) { - d_ptr->initFileEngine(file); } /*! @@ -299,9 +266,8 @@ QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate()) \sa isRelative() */ -QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate()) +QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate(file.fileName())) { - d_ptr->initFileEngine(file.fileName()); } /*! @@ -316,15 +282,16 @@ QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate()) \sa isRelative() */ -QFileInfo::QFileInfo(const QDir &dir, const QString &file) : d_ptr(new QFileInfoPrivate()) +QFileInfo::QFileInfo(const QDir &dir, const QString &file) + : d_ptr(new QFileInfoPrivate(dir.filePath(file))) { - d_ptr->initFileEngine(dir.filePath(file)); } /*! Constructs a new QFileInfo that is a copy of the given \a fileinfo. */ -QFileInfo::QFileInfo(const QFileInfo &fileinfo) : d_ptr(new QFileInfoPrivate(&fileinfo)) +QFileInfo::QFileInfo(const QFileInfo &fileinfo) + : d_ptr(fileinfo.d_ptr) { } @@ -359,17 +326,17 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) const Q_D(const QFileInfo); // ### Qt 5: understand long and short file names on Windows // ### (GetFullPathName()). - if (fileinfo.d_func()->data == d->data) + if (fileinfo.d_ptr == d_ptr) return true; - if (!d->data->fileEngine || !fileinfo.d_func()->data->fileEngine) + if (d->isDefaultConstructed || fileinfo.d_ptr->isDefaultConstructed) return false; - if (d->data->fileEngine->caseSensitive() != fileinfo.d_func()->data->fileEngine->caseSensitive()) + if (d->fileEngine->caseSensitive() != fileinfo.d_ptr->fileEngine->caseSensitive()) return false; if (fileinfo.size() == size()) { //if the size isn't the same... QString file1 = canonicalFilePath(), file2 = fileinfo.canonicalFilePath(); if (file1.length() == file2.length()) { - if (!fileinfo.d_func()->data->fileEngine->caseSensitive()) { + if (!fileinfo.d_ptr->fileEngine->caseSensitive()) { for (int i = 0; i < file1.length(); i++) { if (file1.at(i).toLower() != file2.at(i).toLower()) return false; @@ -407,8 +374,7 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) */ QFileInfo &QFileInfo::operator=(const QFileInfo &fileinfo) { - Q_D(QFileInfo); - qAtomicAssign(d->data, fileinfo.d_func()->data); + d_ptr = fileinfo.d_ptr; return *this; } @@ -429,7 +395,9 @@ QFileInfo &QFileInfo::operator=(const QFileInfo &fileinfo) */ void QFileInfo::setFile(const QString &file) { + bool caching = d_ptr.constData()->cache_enabled; *this = QFileInfo(file); + d_ptr->cache_enabled = caching; } /*! @@ -445,7 +413,7 @@ void QFileInfo::setFile(const QString &file) */ void QFileInfo::setFile(const QFile &file) { - *this = QFileInfo(file.fileName()); + setFile(file.fileName()); } /*! @@ -461,7 +429,7 @@ void QFileInfo::setFile(const QFile &file) */ void QFileInfo::setFile(const QDir &dir, const QString &file) { - *this = QFileInfo(dir.filePath(file)); + setFile(dir.filePath(file)); } /*! @@ -488,7 +456,7 @@ void QFileInfo::setFile(const QDir &dir, const QString &file) QString QFileInfo::absoluteFilePath() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::AbsoluteName); } @@ -505,7 +473,7 @@ QString QFileInfo::absoluteFilePath() const QString QFileInfo::canonicalFilePath() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::CanonicalName); } @@ -532,9 +500,9 @@ QString QFileInfo::absolutePath() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) { + if (d->isDefaultConstructed) { return QLatin1String(""); - } else if (d->data->fileName.isEmpty()) { + } else if (d->fileName.isEmpty()) { qWarning("QFileInfo::absolutePath: Constructed with empty filename"); return QLatin1String(""); } @@ -552,7 +520,7 @@ QString QFileInfo::absolutePath() const QString QFileInfo::canonicalPath() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::CanonicalPathName); } @@ -569,7 +537,7 @@ QString QFileInfo::canonicalPath() const QString QFileInfo::path() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::PathName); } @@ -593,9 +561,9 @@ QString QFileInfo::path() const bool QFileInfo::isRelative() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return true; - return d->data->fileEngine->isRelativePath(); + return d->fileEngine->isRelativePath(); } /*! @@ -607,11 +575,13 @@ bool QFileInfo::isRelative() const */ bool QFileInfo::makeAbsolute() { - Q_D(QFileInfo); - if (!d->data->fileEngine || !d->data->fileEngine->isRelativePath()) + if (d_ptr.constData()->isDefaultConstructed + || !d_ptr.constData()->fileEngine->isRelativePath()) return false; - QString absFileName = d->getFileName(QAbstractFileEngine::AbsoluteName); - d->initFileEngine(absFileName); + QString absFileName = d_ptr.constData()->getFileName(QAbstractFileEngine::AbsoluteName); + // QSharedDataPointer::operator->() will detach. + + setFile(absFileName); return true; } @@ -624,7 +594,7 @@ bool QFileInfo::makeAbsolute() bool QFileInfo::exists() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::ExistsFlag); } @@ -639,7 +609,7 @@ bool QFileInfo::exists() const void QFileInfo::refresh() { Q_D(QFileInfo); - d->reset(); + d->clear(); } /*! @@ -651,7 +621,7 @@ void QFileInfo::refresh() QString QFileInfo::filePath() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::DefaultName); } @@ -670,7 +640,7 @@ QString QFileInfo::filePath() const QString QFileInfo::fileName() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::BaseName); } @@ -690,7 +660,7 @@ QString QFileInfo::fileName() const QString QFileInfo::bundleName() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::BundleName); } @@ -714,7 +684,7 @@ QString QFileInfo::bundleName() const QString QFileInfo::baseName() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::BaseName).section(QLatin1Char('.'), 0, 0); } @@ -733,7 +703,7 @@ QString QFileInfo::baseName() const QString QFileInfo::completeBaseName() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); QString name = d->getFileName(QAbstractFileEngine::BaseName); int index = name.lastIndexOf(QLatin1Char('.')); @@ -754,7 +724,7 @@ QString QFileInfo::completeBaseName() const QString QFileInfo::completeSuffix() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); QString fileName = d->getFileName(QAbstractFileEngine::BaseName); int firstDot = fileName.indexOf(QLatin1Char('.')); @@ -781,7 +751,7 @@ QString QFileInfo::completeSuffix() const QString QFileInfo::suffix() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); QString fileName = d->getFileName(QAbstractFileEngine::BaseName); int lastDot = fileName.lastIndexOf(QLatin1Char('.')); @@ -846,7 +816,7 @@ QDir QFileInfo::dir(bool absPath) const bool QFileInfo::isReadable() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::ReadUserPerm); } @@ -859,7 +829,7 @@ bool QFileInfo::isReadable() const bool QFileInfo::isWritable() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::WriteUserPerm); } @@ -872,7 +842,7 @@ bool QFileInfo::isWritable() const bool QFileInfo::isExecutable() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::ExeUserPerm); } @@ -886,7 +856,7 @@ bool QFileInfo::isExecutable() const bool QFileInfo::isHidden() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::HiddenFlag); } @@ -901,7 +871,7 @@ bool QFileInfo::isHidden() const bool QFileInfo::isFile() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::FileType); } @@ -915,7 +885,7 @@ bool QFileInfo::isFile() const bool QFileInfo::isDir() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::DirectoryType); } @@ -931,7 +901,7 @@ bool QFileInfo::isDir() const bool QFileInfo::isBundle() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::BundleType); } @@ -956,7 +926,7 @@ bool QFileInfo::isBundle() const bool QFileInfo::isSymLink() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::LinkType); } @@ -969,7 +939,7 @@ bool QFileInfo::isSymLink() const bool QFileInfo::isRoot() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return true; return d->getFileFlags(QAbstractFileEngine::RootFlag); } @@ -997,7 +967,7 @@ bool QFileInfo::isRoot() const QString QFileInfo::readLink() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileName(QAbstractFileEngine::LinkName); } @@ -1015,7 +985,7 @@ QString QFileInfo::readLink() const QString QFileInfo::owner() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileOwner(QAbstractFileEngine::OwnerUser); } @@ -1031,9 +1001,9 @@ QString QFileInfo::owner() const uint QFileInfo::ownerId() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return 0; - return d->data->fileEngine->ownerId(QAbstractFileEngine::OwnerUser); + return d->fileEngine->ownerId(QAbstractFileEngine::OwnerUser); } /*! @@ -1049,7 +1019,7 @@ uint QFileInfo::ownerId() const QString QFileInfo::group() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QLatin1String(""); return d->getFileOwner(QAbstractFileEngine::OwnerGroup); } @@ -1065,9 +1035,9 @@ QString QFileInfo::group() const uint QFileInfo::groupId() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return 0; - return d->data->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup); + return d->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup); } /*! @@ -1086,7 +1056,7 @@ uint QFileInfo::groupId() const bool QFileInfo::permission(QFile::Permissions permissions) const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return false; return d->getFileFlags(QAbstractFileEngine::FileFlags((int)permissions)) == (uint)permissions; } @@ -1098,7 +1068,7 @@ bool QFileInfo::permission(QFile::Permissions permissions) const QFile::Permissions QFileInfo::permissions() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return 0; return QFile::Permissions(d->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask); } @@ -1113,13 +1083,13 @@ QFile::Permissions QFileInfo::permissions() const qint64 QFileInfo::size() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return 0; - if (!d->data->getCachedFlag(QFileInfoPrivate::CachedSize)) { - d->data->setCachedFlag(QFileInfoPrivate::CachedSize); - d->data->fileSize = d->data->fileEngine->size(); + if (!d->getCachedFlag(QFileInfoPrivate::CachedSize)) { + d->setCachedFlag(QFileInfoPrivate::CachedSize); + d->fileSize = d->fileEngine->size(); } - return d->data->fileSize; + return d->fileSize; } /*! @@ -1138,7 +1108,7 @@ qint64 QFileInfo::size() const QDateTime QFileInfo::created() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QDateTime(); return d->getFileTime(QAbstractFileEngine::CreationTime); } @@ -1151,7 +1121,7 @@ QDateTime QFileInfo::created() const QDateTime QFileInfo::lastModified() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QDateTime(); return d->getFileTime(QAbstractFileEngine::ModificationTime); } @@ -1167,7 +1137,7 @@ QDateTime QFileInfo::lastModified() const QDateTime QFileInfo::lastRead() const { Q_D(const QFileInfo); - if (!d->data->fileEngine) + if (d->isDefaultConstructed) return QDateTime(); return d->getFileTime(QAbstractFileEngine::AccessTime); } @@ -1177,8 +1147,7 @@ QDateTime QFileInfo::lastRead() const */ void QFileInfo::detach() { - Q_D(QFileInfo); - d->detach(); + d_ptr.detach(); } /*! @@ -1189,7 +1158,7 @@ void QFileInfo::detach() bool QFileInfo::caching() const { Q_D(const QFileInfo); - return d->data->cache_enabled; + return d->cache_enabled; } /*! @@ -1207,8 +1176,7 @@ bool QFileInfo::caching() const void QFileInfo::setCaching(bool enable) { Q_D(QFileInfo); - detach(); - d->data->cache_enabled = enable; + d->cache_enabled = enable; } /*! diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index f0c6d60..aec7543 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -44,7 +44,7 @@ #include <QtCore/qfile.h> #include <QtCore/qlist.h> -#include <QtCore/qscopedpointer.h> +#include <QtCore/qshareddata.h> QT_BEGIN_HEADER @@ -170,10 +170,20 @@ public: #endif protected: - QScopedPointer<QFileInfoPrivate> d_ptr; + QSharedDataPointer<QFileInfoPrivate> d_ptr; private: - Q_DECLARE_PRIVATE(QFileInfo) + inline QFileInfoPrivate* d_func() + { + detach(); + return const_cast<QFileInfoPrivate *>(d_ptr.constData()); + } + + inline const QFileInfoPrivate* d_func() const + { + return d_ptr.constData(); + } }; + Q_DECLARE_TYPEINFO(QFileInfo, Q_MOVABLE_TYPE); #ifdef QT3_SUPPORT diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h index 306ffe1..b9b1092 100644 --- a/src/corelib/io/qfileinfo_p.h +++ b/src/corelib/io/qfileinfo_p.h @@ -57,71 +57,83 @@ #include "qabstractfileengine.h" #include "qdatetime.h" #include "qatomic.h" +#include "qshareddata.h" QT_BEGIN_NAMESPACE -class QFileInfoPrivate +class QFileInfoPrivate : public QSharedData { public: - QFileInfoPrivate(const QFileInfo *copy=0); - ~QFileInfoPrivate(); - void initFileEngine(const QString &); + enum { CachedFileFlags=0x01, CachedLinkTypeFlag=0x02, CachedBundleTypeFlag=0x04, + CachedMTime=0x10, CachedCTime=0x20, CachedATime=0x40, + CachedSize =0x08, CachedPerms=0x80 }; + + inline QFileInfoPrivate() + : QSharedData(), fileEngine(0), + cachedFlags(0), + isDefaultConstructed(true), + cache_enabled(true), fileFlags(0), fileSize(0) + {} + inline QFileInfoPrivate(const QFileInfoPrivate ©) + : QSharedData(copy), fileEngine(QAbstractFileEngine::create(copy.fileName)), + fileName(copy.fileName), + cachedFlags(0), +#ifndef QT_NO_FSFILEENGINE + isDefaultConstructed(false), +#else + isDefaultConstructed(!fileEngine), +#endif + cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) + {} + inline QFileInfoPrivate(const QString &file) + : QSharedData(), fileEngine(QAbstractFileEngine::create(file)), + fileName(file), + cachedFlags(0), +#ifndef QT_NO_FSFILEENGINE + isDefaultConstructed(false), +#else + isDefaultConstructed(!fileEngine), +#endif + cache_enabled(true), fileFlags(0), fileSize(0) + { + } + + inline void clearFlags() const { + fileFlags = 0; + cachedFlags = 0; + if (fileEngine) + (void)fileEngine->fileFlags(QAbstractFileEngine::Refresh); + } + inline void clear() { + clearFlags(); + for (int i = QAbstractFileEngine::NFileNames - 1 ; i >= 0 ; --i) + fileNames[i].clear(); + fileOwners[1].clear(); + fileOwners[0].clear(); + } uint getFileFlags(QAbstractFileEngine::FileFlags) const; QDateTime &getFileTime(QAbstractFileEngine::FileTime) const; QString getFileName(QAbstractFileEngine::FileName) const; QString getFileOwner(QAbstractFileEngine::FileOwner own) const; - enum { CachedFileFlags=0x01, CachedLinkTypeFlag=0x02, CachedBundleTypeFlag=0x04, - CachedMTime=0x10, CachedCTime=0x20, CachedATime=0x40, - CachedSize =0x08, CachedPerms=0x80 }; - struct Data { - inline Data() - : ref(1), fileEngine(0), - cachedFlags(0), cache_enabled(1), fileFlags(0), fileSize(0) - {} - inline Data(const Data ©) - : ref(1), fileEngine(QAbstractFileEngine::create(copy.fileName)), - fileName(copy.fileName), - cachedFlags(0), cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0) - {} - inline ~Data() { delete fileEngine; } - inline void clearFlags() { - fileFlags = 0; - cachedFlags = 0; - if (fileEngine) - (void)fileEngine->fileFlags(QAbstractFileEngine::Refresh); - } - inline void clear() { - clearFlags(); - for (int i = QAbstractFileEngine::NFileNames - 1 ; i >= 0 ; --i) - fileNames[i].clear(); - fileOwners[1].clear(); - fileOwners[0].clear(); - } - mutable QAtomicInt ref; + QScopedPointer<QAbstractFileEngine> const fileEngine; - QAbstractFileEngine *fileEngine; - mutable QString fileName; - mutable QString fileNames[QAbstractFileEngine::NFileNames]; - mutable QString fileOwners[2]; + mutable QString fileName; + mutable QString fileNames[QAbstractFileEngine::NFileNames]; + mutable QString fileOwners[2]; - mutable uint cachedFlags : 31; - mutable uint cache_enabled : 1; - mutable uint fileFlags; - mutable qint64 fileSize; - mutable QDateTime fileTimes[3]; - inline bool getCachedFlag(uint c) const - { return cache_enabled ? (cachedFlags & c) : 0; } - inline void setCachedFlag(uint c) - { if (cache_enabled) cachedFlags |= c; } - } *data; - inline void reset() { - detach(); - data->clear(); - } - void detach(); + mutable uint cachedFlags : 30; + bool const isDefaultConstructed : 1; // QFileInfo is a default constructed instance + bool cache_enabled : 1; + mutable uint fileFlags; + mutable qint64 fileSize; + mutable QDateTime fileTimes[3]; + inline bool getCachedFlag(uint c) const + { return cache_enabled ? (cachedFlags & c) : 0; } + inline void setCachedFlag(uint c) const + { if (cache_enabled) cachedFlags |= c; } }; QT_END_NAMESPACE diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 84120b4..c27a424 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -43,6 +43,7 @@ #include "qplatformdefs.h" #include "qabstractfileengine.h" #include "private/qfsfileengine_p.h" +#include <private/qsystemlibrary_p.h> #include <qdebug.h> #include "qfile.h" @@ -179,7 +180,7 @@ void QFSFileEnginePrivate::resolveLibs() triedResolve = true; #if !defined(Q_OS_WINCE) - HINSTANCE advapiHnd = LoadLibrary(L"advapi32"); + HINSTANCE advapiHnd = QSystemLibrary::load(L"advapi32"); if (advapiHnd) { ptrGetNamedSecurityInfoW = (PtrGetNamedSecurityInfoW)GetProcAddress(advapiHnd, "GetNamedSecurityInfoW"); ptrLookupAccountSidW = (PtrLookupAccountSidW)GetProcAddress(advapiHnd, "LookupAccountSidW"); @@ -211,7 +212,7 @@ void QFSFileEnginePrivate::resolveLibs() ptrFreeSid(pWorld); } } - HINSTANCE userenvHnd = LoadLibrary(L"userenv"); + HINSTANCE userenvHnd = QSystemLibrary::load(L"userenv"); if (userenvHnd) ptrGetUserProfileDirectoryW = (PtrGetUserProfileDirectoryW)GetProcAddress(userenvHnd, "GetUserProfileDirectoryW"); HINSTANCE kernel32 = LoadLibrary(L"kernel32"); @@ -245,7 +246,7 @@ bool QFSFileEnginePrivate::resolveUNCLibs() #endif triedResolve = true; #if !defined(Q_OS_WINCE) - HINSTANCE hLib = LoadLibrary(L"netapi32"); + HINSTANCE hLib = QSystemLibrary::load(L"Netapi32"); if (hLib) { ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum"); if (ptrNetShareEnum) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 384804a..f25c272 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -69,7 +69,7 @@ #ifdef Q_OS_WIN // for homedirpath reading from registry #include "qt_windows.h" -#include "qlibrary.h" +#include <private/qsystemlibrary_p.h> #endif // Q_OS_WIN #endif // QT_NO_QOBJECT @@ -1044,9 +1044,9 @@ static QString windowsConfigPath(int type) // We can't use QLibrary if there is QT_NO_QOBJECT is defined // This only happens when bootstrapping qmake. #ifndef Q_OS_WINCE - QLibrary library(QLatin1String("shell32")); + QSystemLibrary library(QLatin1String("shell32")); #else - QLibrary library(QLatin1String("coredll")); + QSystemLibrary library(QLatin1String("coredll")); #endif // Q_OS_WINCE typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL); GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW"); diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 20ec995..b320624 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3446,16 +3446,20 @@ QString QUrlPrivate::canonicalHost() const if (host.contains(QLatin1Char(':'))) { // This is an IP Literal, use _IPLiteral to validate QByteArray ba = host.toLatin1(); + bool needsBraces = false; if (!ba.startsWith('[')) { // surround the IP Literal with [ ] if it's not already done so ba.reserve(ba.length() + 2); ba.prepend('['); ba.append(']'); + needsBraces = true; } const char *ptr = ba.constData(); if (!_IPLiteral(&ptr)) that->host.clear(); + else if (needsBraces) + that->host = QString::fromLatin1(ba.toLower()); else that->host = host.toLower(); } else { @@ -5005,6 +5009,10 @@ void QUrl::setEncodedQuery(const QByteArray &query) pairDelimiter(), and the key and value are delimited by valueDelimiter(). + \note This method does not encode spaces (ASCII 0x20) as plus (+) signs, + like HTML forms do. If you need that kind of encoding, you must encode + the value yourself and use QUrl::setEncodedQueryItems. + \sa setQueryDelimiters(), queryItems(), setEncodedQueryItems() */ void QUrl::setQueryItems(const QList<QPair<QString, QString> > &query) @@ -5075,6 +5083,10 @@ void QUrl::setEncodedQueryItems(const QList<QPair<QByteArray, QByteArray> > &que character returned by valueDelimiter(). Each key/value pair is delimited by the character returned by pairDelimiter(). + \note This method does not encode spaces (ASCII 0x20) as plus (+) signs, + like HTML forms do. If you need that kind of encoding, you must encode + the value yourself and use QUrl::addEncodedQueryItem. + \sa addEncodedQueryItem() */ void QUrl::addQueryItem(const QString &key, const QString &value) @@ -5131,6 +5143,10 @@ void QUrl::addEncodedQueryItem(const QByteArray &key, const QByteArray &value) /*! Returns the query string of the URL, as a map of keys and values. + \note This method does not decode spaces plus (+) signs as spaces (ASCII + 0x20), like HTML forms do. If you need that kind of decoding, you must + use QUrl::encodedQueryItems and decode the data yourself. + \sa setQueryItems(), setEncodedQuery() */ QList<QPair<QString, QString> > QUrl::queryItems() const @@ -5235,6 +5251,10 @@ bool QUrl::hasEncodedQueryItem(const QByteArray &key) const Returns the first query string value whose key is equal to \a key from the URL. + \note This method does not decode spaces plus (+) signs as spaces (ASCII + 0x20), like HTML forms do. If you need that kind of decoding, you must + use QUrl::encodedQueryItemValue and decode the data yourself. + \sa allQueryItemValues() */ QString QUrl::queryItemValue(const QString &key) const @@ -5279,6 +5299,10 @@ QByteArray QUrl::encodedQueryItemValue(const QByteArray &key) const Returns the a list of query string values whose key is equal to \a key from the URL. + \note This method does not decode spaces plus (+) signs as spaces (ASCII + 0x20), like HTML forms do. If you need that kind of decoding, you must + use QUrl::allEncodedQueryItemValues and decode the data yourself. + \sa queryItemValue() */ QStringList QUrl::allQueryItemValues(const QString &key) const @@ -5657,7 +5681,7 @@ QString QUrl::toString(FormattingOptions options) const if ((options & QUrl::RemoveAuthority) != QUrl::RemoveAuthority) { bool doFileScheme = d->scheme == QLatin1String("file") && ourPath.startsWith(QLatin1Char('/')); QString tmp = d->authority(options); - if (!tmp.isEmpty() || doFileScheme) { + if (!tmp.isNull() || doFileScheme) { if (doFileScheme && !ourPath.startsWith(QLatin1Char('/'))) url += QLatin1Char('/'); url += QLatin1String("//"); diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index 3a6395b..4fc9792 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -2603,9 +2603,13 @@ bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sour return false; } - d->changes.push(QAbstractItemModelPrivate::Change(sourceParent, sourceFirst, sourceLast)); + QAbstractItemModelPrivate::Change sourceChange(sourceParent, sourceFirst, sourceLast); + sourceChange.needsAdjust = sourceParent.isValid() && sourceParent.row() >= destinationChild && sourceParent.parent() == destinationParent; + d->changes.push(sourceChange); int destinationLast = destinationChild + (sourceLast - sourceFirst); - d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast)); + QAbstractItemModelPrivate::Change destinationChange(destinationParent, destinationChild, destinationLast); + destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent; + d->changes.push(destinationChange); emit rowsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild); emit layoutAboutToBeChanged(); @@ -2635,7 +2639,17 @@ void QAbstractItemModel::endMoveRows() d->itemsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first, Qt::Vertical); - emit rowsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first); + QModelIndex adjustedSource = removeChange.parent; + QModelIndex adjustedDestination = insertChange.parent; + + const int numMoved = removeChange.last - removeChange.first + 1; + if (insertChange.needsAdjust) + adjustedDestination = createIndex(adjustedDestination.row() - numMoved, adjustedDestination.column(), adjustedDestination.internalPointer()); + + if (removeChange.needsAdjust) + adjustedSource = createIndex(adjustedSource.row() + numMoved, adjustedSource.column(), adjustedSource.internalPointer()); + + emit rowsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first); emit layoutChanged(); } @@ -2812,9 +2826,13 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s return false; } - d->changes.push(QAbstractItemModelPrivate::Change(sourceParent, sourceFirst, sourceLast)); + QAbstractItemModelPrivate::Change sourceChange(sourceParent, sourceFirst, sourceLast); + sourceChange.needsAdjust = sourceParent.isValid() && sourceParent.row() >= destinationChild && sourceParent.parent() == destinationParent; + d->changes.push(sourceChange); int destinationLast = destinationChild + (sourceLast - sourceFirst); - d->changes.push(QAbstractItemModelPrivate::Change(destinationParent, destinationChild, destinationLast)); + QAbstractItemModelPrivate::Change destinationChange(destinationParent, destinationChild, destinationLast); + destinationChange.needsAdjust = destinationParent.isValid() && destinationParent.row() >= sourceLast && destinationParent.parent() == sourceParent; + d->changes.push(destinationChange); d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal); @@ -2845,7 +2863,17 @@ void QAbstractItemModel::endMoveColumns() d->itemsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first, Qt::Horizontal); - emit columnsMoved(removeChange.parent, removeChange.first, removeChange.last, insertChange.parent, insertChange.first); + QModelIndex adjustedSource = removeChange.parent; + QModelIndex adjustedDestination = insertChange.parent; + + const int numMoved = removeChange.last - removeChange.first + 1; + if (insertChange.needsAdjust) + adjustedDestination = createIndex(adjustedDestination.row(), adjustedDestination.column() - numMoved, adjustedDestination.internalPointer()); + + if (removeChange.needsAdjust) + adjustedSource = createIndex(adjustedSource.row(), adjustedSource.column() + numMoved, adjustedSource.internalPointer()); + + emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first); emit layoutChanged(); } diff --git a/src/corelib/kernel/qabstractitemmodel_p.h b/src/corelib/kernel/qabstractitemmodel_p.h index 7844a10..3113dff 100644 --- a/src/corelib/kernel/qabstractitemmodel_p.h +++ b/src/corelib/kernel/qabstractitemmodel_p.h @@ -133,11 +133,26 @@ public: struct Change { Change() : first(-1), last(-1) {} - Change(const Change &c) : parent(c.parent), first(c.first), last(c.last) {} - Change(const QModelIndex &p, int f, int l) : parent(p), first(f), last(l) {} + Change(const Change &c) : parent(c.parent), first(c.first), last(c.last), needsAdjust(c.needsAdjust) {} + Change(const QModelIndex &p, int f, int l) : parent(p), first(f), last(l), needsAdjust(false) {} QModelIndex parent; int first, last; + + // In cases such as this: + // - A + // - B + // - C + // - - D + // - - E + // - - F + // + // If B is moved to above E, C is the source parent in the signal and its row is 2. When the move is + // completed however, C is at row 1 and there is no row 2 at the same level in the model at all. + // The QModelIndex is adjusted to correct that in those cases before reporting it though the + // rowsMoved signal. + bool needsAdjust; + bool isValid() { return first >= 0 && last >= 0; } }; QStack<Change> changes; diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp index 073ed6b..df1c1ef 100644 --- a/src/corelib/kernel/qcore_symbian_p.cpp +++ b/src/corelib/kernel/qcore_symbian_p.cpp @@ -133,7 +133,6 @@ public: private: void init() { -#ifdef Q_OS_SYMBIAN _LIT(KLibName_3_1, "qts60plugin_3_1" QT_LIBINFIX_UNICODE L".dll"); _LIT(KLibName_3_2, "qts60plugin_3_2" QT_LIBINFIX_UNICODE L".dll"); _LIT(KLibName_5_0, "qts60plugin_5_0" QT_LIBINFIX_UNICODE L".dll"); @@ -159,7 +158,12 @@ private: TUidType libUid(KDynamicLibraryUid, KSharedLibraryUid, TUid::Uid(uidValue)); lib.Load(libName, libUid); -#endif + + // Duplicate lib handle to enable process wide access to it. Since Duplicate overwrites + // existing handle without closing it, store original for subsequent closing. + RLibrary origHandleCloser = lib; + lib.Duplicate(RThread(), EOwnerProcess); + origHandleCloser.Close(); } RLibrary lib; diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 5ab867f..02736dd 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -232,8 +232,12 @@ void QTimerActiveObject::DoCancel() void QTimerActiveObject::RunL() { - int error; - QT_TRYCATCH_ERROR(error, Run()); + int error = KErrNone; + if (iStatus == KErrNone) { + QT_TRYCATCH_ERROR(error, Run()); + } else { + error = iStatus.Int(); + } // All Symbian error codes are negative. if (error < 0) { CActiveScheduler::Current()->Error(error); // stop and report here, as this timer will be deleted on scope exit diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index e3f537f..153ccdf 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -43,7 +43,7 @@ #include "qcoreapplication.h" #include "qhash.h" -#include "qlibrary.h" +#include <private/qsystemlibrary_p.h> #include "qpair.h" #include "qset.h" #include "qsocketnotifier.h" @@ -65,7 +65,11 @@ extern uint qGlobalPostedEventsCount(); #endif #ifndef QS_RAWINPUT +# ifdef Q_OS_WINCE +# define QS_RAWINPUT 0x0000 +# else # define QS_RAWINPUT 0x0400 +# endif #endif #ifndef WM_TOUCH @@ -80,8 +84,7 @@ extern uint qGlobalPostedEventsCount(); enum { WM_QT_SOCKETNOTIFIER = WM_USER, - WM_QT_SENDPOSTEDEVENTS = WM_USER + 1, - SendPostedEventsTimerId = ~1u + WM_QT_SENDPOSTEDEVENTS = WM_USER + 1 }; #if defined(Q_OS_WINCE) @@ -323,11 +326,11 @@ static void resolveTimerAPI() #endif triedResolve = true; #if !defined(Q_OS_WINCE) - qtimeSetEvent = (ptimeSetEvent)QLibrary::resolve(QLatin1String("winmm"), "timeSetEvent"); - qtimeKillEvent = (ptimeKillEvent)QLibrary::resolve(QLatin1String("winmm"), "timeKillEvent"); + qtimeSetEvent = (ptimeSetEvent)QSystemLibrary::resolve(QLatin1String("winmm"), "timeSetEvent"); + qtimeKillEvent = (ptimeKillEvent)QSystemLibrary::resolve(QLatin1String("winmm"), "timeKillEvent"); #else - qtimeSetEvent = (ptimeSetEvent)QLibrary::resolve(QLatin1String("Mmtimer"), "timeSetEvent"); - qtimeKillEvent = (ptimeKillEvent)QLibrary::resolve(QLatin1String("Mmtimer"), "timeKillEvent"); + qtimeSetEvent = (ptimeSetEvent)QSystemLibrary::resolve(QLatin1String("Mmtimer"), "timeSetEvent"); + qtimeKillEvent = (ptimeKillEvent)QSystemLibrary::resolve(QLatin1String("Mmtimer"), "timeKillEvent"); #endif } } @@ -516,12 +519,10 @@ LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) if (q) { QEventDispatcherWin32Private *d = q->d_func(); int localSerialNumber = d->serialNumber; -#ifdef Q_OS_WINCE - MSG dummyMsg; - if (HIWORD(GetQueueStatus(QS_INPUT)) == 0 - && PeekMessage(&dummyMsg, 0, WM_TIMER, WM_TIMER, PM_NOREMOVE) == 0 -#else - if (HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER)) == 0 + MSG unused; + if ((HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT)) == 0 + && PeekMessage(&unused, 0, WM_TIMER, WM_TIMER, PM_NOREMOVE) == 0) +#ifndef Q_OS_WINCE || GetMessageTime() - d->lastMessageTime >= 10 #endif ) { @@ -824,7 +825,7 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) pHandles[i] = d->winEventNotifierList.at(i)->handle(); emit aboutToBlock(); - waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE); + waitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE); emit awake(); if (waitRet >= WAIT_OBJECT_0 && waitRet < WAIT_OBJECT_0 + nCount) { d->activateEventNotifier(d->winEventNotifierList.at(waitRet - WAIT_OBJECT_0)); diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri index 2e7db5d..50b005d 100644 --- a/src/corelib/plugin/plugin.pri +++ b/src/corelib/plugin/plugin.pri @@ -8,6 +8,7 @@ HEADERS += \ plugin/qplugin.h \ plugin/quuid.h \ plugin/qfactoryloader_p.h \ + plugin/qsystemlibrary_p.h \ plugin/qelfparser_p.h SOURCES += \ @@ -18,7 +19,9 @@ SOURCES += \ plugin/qelfparser_p.cpp win32 { - SOURCES += plugin/qlibrary_win.cpp + SOURCES += \ + plugin/qlibrary_win.cpp \ + plugin/qsystemlibrary.cpp } unix { diff --git a/src/corelib/plugin/qsystemlibrary.cpp b/src/corelib/plugin/qsystemlibrary.cpp new file mode 100644 index 0000000..a11ed50 --- /dev/null +++ b/src/corelib/plugin/qsystemlibrary.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsystemlibrary_p.h" +#include <QtCore/qvarlengtharray.h> +#include <QtCore/qstringlist.h> +#include <QtCore/qfileinfo.h> + +/*! + + \internal + \class QSystemLibrary + + The purpose of this class is to load only libraries that are located in + well-known and trusted locations on the filesystem. It does not suffer from + the security problem that QLibrary has, therefore it will never search in + the current directory. + + The search order is the same as the order in DLL Safe search mode Windows, + except that we don't search: + * The current directory + * The 16-bit system directory. (normally c:\windows\system) + * The Windows directory. (normally c:\windows) + + This means that the effective search order is: + 1. Application path. + 2. System libraries path. + 3. Trying all paths inside the PATH environment variable. + + Note, when onlySystemDirectory is true it will skip 1) and 3). + + DLL Safe search mode is documented in the "Dynamic-Link Library Search + Order" document on MSDN. + + Since library loading code is sometimes shared between Windows and WinCE, + this class can also be used on WinCE. However, its implementation just + calls the LoadLibrary() function. This is ok since it is documented as not + loading from the current directory on WinCE. This behaviour is documented + in the documentation for LoadLibrary for Windows CE at MSDN. + (http://msdn.microsoft.com/en-us/library/ms886736.aspx) +*/ +#if defined(Q_OS_WINCE) +HINSTANCE QSystemLibrary::load(const wchar_t *libraryName, bool onlySystemDirectory/*= true*/) +{ + return ::LoadLibrary(libraryName); +} +#else + +#if !defined(QT_BOOTSTRAPPED) +extern QString qAppFileName(); +#endif + +static QString qSystemDirectory() +{ + QVarLengthArray<wchar_t, MAX_PATH> fullPath; + + UINT retLen = ::GetSystemDirectory(fullPath.data(), MAX_PATH); + if (retLen > MAX_PATH) { + fullPath.resize(retLen); + retLen = ::GetSystemDirectory(fullPath.data(), retLen); + } + // in some rare cases retLen might be 0 + return QString::fromWCharArray(fullPath.constData(), int(retLen)); +} + +HINSTANCE QSystemLibrary::load(const wchar_t *libraryName, bool onlySystemDirectory/*= true*/) +{ + QStringList searchOrder; + +#if !defined(QT_BOOTSTRAPPED) + if (!onlySystemDirectory) + searchOrder << QFileInfo(qAppFileName()).path(); +#endif + searchOrder << qSystemDirectory(); + + if (!onlySystemDirectory) { + const QString PATH(QLatin1String(qgetenv("PATH").constData())); + searchOrder << PATH.split(QLatin1Char(';'), QString::SkipEmptyParts); + } + QString fileName = QString::fromWCharArray(libraryName); + fileName.append(QLatin1String(".dll")); + + // Start looking in the order specified + for (int i = 0; i < searchOrder.count(); ++i) { + QString fullPathAttempt = searchOrder.at(i); + if (!fullPathAttempt.endsWith(QLatin1Char('\\'))) { + fullPathAttempt.append(QLatin1Char('\\')); + } + fullPathAttempt.append(fileName); + HINSTANCE inst = ::LoadLibrary((const wchar_t *)fullPathAttempt.utf16()); + if (inst != 0) + return inst; + } + return 0; + +} + +#endif //Q_OS_WINCE diff --git a/src/corelib/plugin/qsystemlibrary_p.h b/src/corelib/plugin/qsystemlibrary_p.h new file mode 100644 index 0000000..3251a3c --- /dev/null +++ b/src/corelib/plugin/qsystemlibrary_p.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSYSTEMLIBRARY_P_H +#define QSYSTEMLIBRARY_P_H + +#include <QtCore/qglobal.h> +#ifdef Q_OS_WIN +#include <qt_windows.h> +#include <QtCore/qstring.h> + +class QSystemLibrary +{ +public: + explicit QSystemLibrary(const QString &libraryName) + { + m_libraryName = libraryName; + m_handle = 0; + m_didLoad = false; + } + + explicit QSystemLibrary(const wchar_t *libraryName) + { + m_libraryName = QString::fromWCharArray(libraryName); + m_handle = 0; + m_didLoad = false; + } + + bool load(bool onlySystemDirectory = true) + { + m_handle = load((const wchar_t *)m_libraryName.utf16(), onlySystemDirectory); + m_didLoad = true; + return (m_handle != 0); + } + + bool isLoaded() + { + return (m_handle != 0); + } + + void *resolve(const char *symbol) + { + if (!m_didLoad) + load(); + if (!m_handle) + return 0; +#ifdef Q_OS_WINCE + return (void*)GetProcAddress(m_handle, (const wchar_t*)QString::fromLatin1(symbol).utf16()); +#else + return (void*)GetProcAddress(m_handle, symbol); +#endif + } + + static void *resolve(const QString &libraryName, const char *symbol) + { + return QSystemLibrary(libraryName).resolve(symbol); + } + + static Q_CORE_EXPORT HINSTANCE load(const wchar_t *lpFileName, bool onlySystemDirectory = true); +private: + HINSTANCE m_handle; + QString m_libraryName; + bool m_didLoad; +}; + +#endif //Q_OS_WIN + +#endif //QSYSTEMLIBRARY_P_H diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 3062c4a..0a4aad2 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -854,7 +854,7 @@ QByteArray::Data QByteArray::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1), This operation takes \l{constant time}, because QByteArray is \l{implicitly shared}. This makes returning a QByteArray from a function very fast. If a shared instance is modified, it will be - copied (copy-on-write), and that takes \l{linear time}. + copied (copy-on-write), taking \l{linear time}. \sa operator=() */ @@ -1190,10 +1190,18 @@ void QByteArray::chop(int n) Example: \snippet doc/src/snippets/code/src_corelib_tools_qbytearray.cpp 12 - This operation is typically very fast (\l{constant time}), - because QByteArray preallocates extra space at the end of the - character data so it can grow without reallocating the entire - data each time. + Note: QByteArray is an \l{implicitly shared} class. Consequently, + if \e this is an empty QByteArray, then \e this will just share + the data held in \a ba. In this case, no copying of data is done, + taking \l{constant time}. If a shared instance is modified, it will + be copied (copy-on-write), taking \l{linear time}. + + If \e this is not an empty QByteArray, a deep copy of the data is + performed, taking \l{linear time}. + + This operation typically does not suffer from allocation overhead, + because QByteArray preallocates extra space at the end of the data + so that it may grow without reallocating for each append operation. \sa append(), prepend() */ @@ -1478,7 +1486,12 @@ QByteArray QByteArray::nulTerminated() const Note: QByteArray is an \l{implicitly shared} class. Consequently, if \e this is an empty QByteArray, then \e this will just share - the data held in \a ba. In this case, no copying of data is done. + the data held in \a ba. In this case, no copying of data is done, + taking \l{constant time}. If a shared instance is modified, it will + be copied (copy-on-write), taking \l{linear time}. + + If \e this is not an empty QByteArray, a deep copy of the data is + performed, taking \l{linear time}. \sa append(), insert() */ @@ -1551,14 +1564,18 @@ QByteArray &QByteArray::prepend(char ch) This is the same as insert(size(), \a ba). - This operation is typically very fast (\l{constant time}), - because QByteArray preallocates extra space at the end of the - character data so it can grow without reallocating the entire - data each time. - Note: QByteArray is an \l{implicitly shared} class. Consequently, if \e this is an empty QByteArray, then \e this will just share - the data held in \a ba. In this case, no copying of data is done. + the data held in \a ba. In this case, no copying of data is done, + taking \l{constant time}. If a shared instance is modified, it will + be copied (copy-on-write), taking \l{linear time}. + + If \e this is not an empty QByteArray, a deep copy of the data is + performed, taking \l{linear time}. + + This operation typically does not suffer from allocation overhead, + because QByteArray preallocates extra space at the end of the data + so that it may grow without reallocating for each append operation. \sa operator+=(), prepend(), insert() */ diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index ee791e0..7fe9170 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -332,7 +332,7 @@ public: enum Type { In, Out, InOut, OutIn }; QEasingCurveFunction(QEasingCurveFunction::Type type = In, qreal period = 0.3, qreal amplitude = 1.0, - qreal overshoot = 1.70158f) + qreal overshoot = 1.70158) : _t(type), _p(period), _a(amplitude), _o(overshoot) { } virtual ~QEasingCurveFunction() {} @@ -359,9 +359,9 @@ QEasingCurveFunction *QEasingCurveFunction::copy() const bool QEasingCurveFunction::operator==(const QEasingCurveFunction& other) { return _t == other._t && - _p == other._p && - _a == other._a && - _o == other._o; + qFuzzyCompare(_p, other._p) && + qFuzzyCompare(_a, other._a) && + qFuzzyCompare(_o, other._o); } QT_BEGIN_INCLUDE_NAMESPACE @@ -400,8 +400,8 @@ struct ElasticEase : public QEasingCurveFunction qreal value(qreal t) { - qreal p = (_p < 0) ? 0.3f : _p; - qreal a = (_a < 0) ? 1.0f : _a; + qreal p = (_p < 0) ? qreal(0.3) : _p; + qreal a = (_a < 0) ? qreal(1.0) : _a; switch(_t) { case In: return easeInElastic(t, a, p); @@ -420,7 +420,7 @@ struct ElasticEase : public QEasingCurveFunction struct BounceEase : public QEasingCurveFunction { BounceEase(Type type) - : QEasingCurveFunction(type, 0.3f, 1.0f) + : QEasingCurveFunction(type, qreal(0.3), qreal(1.0)) { } QEasingCurveFunction *copy() const @@ -432,7 +432,7 @@ struct BounceEase : public QEasingCurveFunction qreal value(qreal t) { - qreal a = (_a < 0) ? 1.0f : _a; + qreal a = (_a < 0) ? qreal(1.0) : _a; switch(_t) { case In: return easeInBounce(t, a); @@ -451,7 +451,7 @@ struct BounceEase : public QEasingCurveFunction struct BackEase : public QEasingCurveFunction { BackEase(Type type) - : QEasingCurveFunction(type, 0.3f, 1.0f, 1.70158f) + : QEasingCurveFunction(type, qreal(0.3), qreal(1.0), qreal(1.70158)) { } QEasingCurveFunction *copy() const @@ -463,7 +463,7 @@ struct BackEase : public QEasingCurveFunction qreal value(qreal t) { - qreal o = (_o < 0) ? 1.70158f : _o; + qreal o = (_o < 0) ? qreal(1.70158) : _o; switch(_t) { case In: return easeInBack(t, o); @@ -595,7 +595,7 @@ static QEasingCurveFunction *curveToFunctionObject(QEasingCurve::Type type) curveFunc = new BackEase(BackEase::OutIn); break; default: - curveFunc = new QEasingCurveFunction(QEasingCurveFunction::In, 0.3f, 1.0f, 1.70158f); // ### + curveFunc = new QEasingCurveFunction(QEasingCurveFunction::In, qreal(0.3), qreal(1.0), qreal(1.70158)); } return curveFunc; @@ -657,9 +657,17 @@ bool QEasingCurve::operator==(const QEasingCurve &other) const { bool res = d_ptr->func == other.d_ptr->func && d_ptr->type == other.d_ptr->type; - if (res && d_ptr->config && other.d_ptr->config) { + if (res) { + if (d_ptr->config && other.d_ptr->config) { // catch the config content - res = d_ptr->config->operator==(*(other.d_ptr->config)); + res = d_ptr->config->operator==(*(other.d_ptr->config)); + + } else if (d_ptr->config || other.d_ptr->config) { + // one one has a config object, which could contain default values + res = qFuzzyCompare(amplitude(), other.amplitude()) && + qFuzzyCompare(period(), other.period()) && + qFuzzyCompare(overshoot(), other.overshoot()); + } } return res; } @@ -681,7 +689,7 @@ bool QEasingCurve::operator==(const QEasingCurve &other) const */ qreal QEasingCurve::amplitude() const { - return d_ptr->config ? d_ptr->config->_a : 1.0; + return d_ptr->config ? d_ptr->config->_a : qreal(1.0); } /*! @@ -705,7 +713,7 @@ void QEasingCurve::setAmplitude(qreal amplitude) */ qreal QEasingCurve::period() const { - return d_ptr->config ? d_ptr->config->_p : 0.3; + return d_ptr->config ? d_ptr->config->_p : qreal(0.3); } /*! @@ -729,7 +737,7 @@ void QEasingCurve::setPeriod(qreal period) */ qreal QEasingCurve::overshoot() const { - return d_ptr->config ? d_ptr->config->_o : 1.70158f; + return d_ptr->config ? d_ptr->config->_o : qreal(1.70158) ; } /*! diff --git a/src/corelib/tools/qelapsedtimer_unix.cpp b/src/corelib/tools/qelapsedtimer_unix.cpp index 2c4ea58..633fa00 100644 --- a/src/corelib/tools/qelapsedtimer_unix.cpp +++ b/src/corelib/tools/qelapsedtimer_unix.cpp @@ -40,22 +40,58 @@ ****************************************************************************/ #include "qelapsedtimer.h" -#include "qpair.h" #include <sys/time.h> #include <time.h> #include <unistd.h> -#if !defined(QT_NO_CLOCK_MONOTONIC) -# if defined(QT_BOOTSTRAPPED) -# define QT_NO_CLOCK_MONOTONIC +#if defined(QT_NO_CLOCK_MONOTONIC) || defined(QT_BOOTSTRAPPED) +// turn off the monotonic clock +# ifdef _POSIX_MONOTONIC_CLOCK +# undef _POSIX_MONOTONIC_CLOCK # endif +# define _POSIX_MONOTONIC_CLOCK -1 #endif QT_BEGIN_NAMESPACE -static qint64 fractionAdjustment() +#if (_POSIX_MONOTONIC_CLOCK-0 != 0) +static const bool monotonicClockChecked = true; +static const bool monotonicClockAvailable = _POSIX_MONOTONIC_CLOCK > 0; +#else +static int monotonicClockChecked = false; +static int monotonicClockAvailable = false; +#endif + +#ifdef Q_CC_GNU +# define is_likely(x) __builtin_expect((x), 1) +#else +# define is_likely(x) (x) +#endif +#define load_acquire(x) ((volatile const int&)(x)) +#define store_release(x,v) ((volatile int&)(x) = (v)) + +static void unixCheckClockType() +{ +#if (_POSIX_MONOTONIC_CLOCK-0 == 0) + if (is_likely(load_acquire(monotonicClockChecked))) + return; + +# if defined(_SC_MONOTONIC_CLOCK) + // detect if the system support monotonic timers + long x = sysconf(_SC_MONOTONIC_CLOCK); + store_release(monotonicClockAvailable, x >= 200112L); +# endif + + store_release(monotonicClockChecked, true); +#endif +} + +static inline qint64 fractionAdjustment() { - if (QElapsedTimer::isMonotonic()) { + // disabled, but otherwise indicates bad usage of QElapsedTimer + //Q_ASSERT(monotonicClockChecked); + + if (monotonicClockAvailable) { // the monotonic timer is measured in nanoseconds // 1 ms = 1000000 ns return 1000*1000ull; @@ -68,90 +104,73 @@ static qint64 fractionAdjustment() bool QElapsedTimer::isMonotonic() { -#if (_POSIX_MONOTONIC_CLOCK-0 > 0) - return true; -#else - static int returnValue = 0; - - if (returnValue == 0) { -# if (_POSIX_MONOTONIC_CLOCK-0 < 0) || !defined(_SC_MONOTONIC_CLOCK) - returnValue = -1; -# elif (_POSIX_MONOTONIC_CLOCK == 0) - // detect if the system support monotonic timers - long x = sysconf(_SC_MONOTONIC_CLOCK); - returnValue = (x >= 200112L) ? 1 : -1; -# endif - } - - return returnValue != -1; -#endif + unixCheckClockType(); + return monotonicClockAvailable; } QElapsedTimer::ClockType QElapsedTimer::clockType() { - return isMonotonic() ? MonotonicClock : SystemTime; + unixCheckClockType(); + return monotonicClockAvailable ? MonotonicClock : SystemTime; } -static inline QPair<long, long> do_gettime() +static inline void do_gettime(qint64 *sec, qint64 *frac) { -#if (_POSIX_MONOTONIC_CLOCK-0 > 0) - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return qMakePair<long,long>(ts.tv_sec, ts.tv_nsec); -#else -# if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED) - if (QElapsedTimer::isMonotonic()) { +#if (_POSIX_MONOTONIC_CLOCK-0 >= 0) + unixCheckClockType(); + if (is_likely(monotonicClockAvailable)) { timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); - return qMakePair<long,long>(ts.tv_sec, ts.tv_nsec); + *sec = ts.tv_sec; + *frac = ts.tv_nsec; + return; } -# endif +#endif // use gettimeofday timeval tv; ::gettimeofday(&tv, 0); - return qMakePair<long,long>(tv.tv_sec, tv.tv_usec); -#endif + *sec = tv.tv_sec; + *frac = tv.tv_usec; } // used in qcore_unix.cpp and qeventdispatcher_unix.cpp timeval qt_gettime() { - QPair<long, long> r = do_gettime(); + qint64 sec, frac; + do_gettime(&sec, &frac); timeval tv; - tv.tv_sec = r.first; - tv.tv_usec = r.second; - if (QElapsedTimer::isMonotonic()) + tv.tv_sec = sec; + tv.tv_usec = frac; + if (monotonicClockAvailable) tv.tv_usec /= 1000; return tv; } +static qint64 elapsedAndRestart(qint64 sec, qint64 frac, + qint64 *nowsec, qint64 *nowfrac) +{ + do_gettime(nowsec, nowfrac); + sec = *nowsec - sec; + frac = *nowfrac - frac; + return sec * Q_INT64_C(1000) + frac / fractionAdjustment(); +} + void QElapsedTimer::start() { - QPair<long, long> r = do_gettime(); - t1 = r.first; - t2 = r.second; + do_gettime(&t1, &t2); } qint64 QElapsedTimer::restart() { - QPair<long, long> r = do_gettime(); - qint64 oldt1 = t1; - qint64 oldt2 = t2; - t1 = r.first; - t2 = r.second; - - r.first -= oldt1; - r.second -= oldt2; - return r.first * Q_INT64_C(1000) + r.second / fractionAdjustment(); + return elapsedAndRestart(t1, t2, &t1, &t2); } qint64 QElapsedTimer::elapsed() const { - QElapsedTimer now; - now.start(); - return msecsTo(now); + qint64 sec, frac; + return elapsedAndRestart(t1, t2, &sec, &frac); } qint64 QElapsedTimer::msecsSinceReference() const diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 68ab033..7babf3a 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -54,8 +54,20 @@ #if defined(Q_OS_LINUX) && defined(__arm__) #include "private/qcore_unix_p.h" -#include <asm/hwcap.h> -#include <linux/auxvec.h> +// the kernel header definitions for HWCAP_* +// (the ones we need/may need anyway) + +// copied from <asm/hwcap.h> (ARM) +#define HWCAP_IWMMXT 512 +#define HWCAP_CRUNCH 1024 +#define HWCAP_THUMBEE 2048 +#define HWCAP_NEON 4096 +#define HWCAP_VFPv3 8192 +#define HWCAP_VFPv3D16 16384 + +// copied from <linux/auxvec.h> +#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ + #endif QT_BEGIN_NAMESPACE @@ -140,56 +152,41 @@ static inline uint detectProcessorFeatures() uint result = 0; /* see p. 118 of amd64 instruction set manual Vol3 */ #if defined(Q_CC_GNU) - asm ("push %%ebx\n" - "pushf\n" - "pop %%eax\n" - "mov %%eax, %%ebx\n" - "xor $0x00200000, %%eax\n" - "push %%eax\n" - "popf\n" - "pushf\n" - "pop %%eax\n" - "xor %%edx, %%edx\n" - "xor %%ebx, %%eax\n" - "jz 1f\n" - - "mov $0x00000001, %%eax\n" - "cpuid\n" - "1:\n" - "pop %%ebx\n" - "mov %%edx, %0\n" - "mov %%ecx, %1\n" - : "=r" (result), "=r" (feature_result) - : - : "%eax", "%ecx", "%edx" - ); - - asm ("push %%ebx\n" - "pushf\n" - "pop %%eax\n" - "mov %%eax, %%ebx\n" - "xor $0x00200000, %%eax\n" - "push %%eax\n" + long cpuid_supported, tmp1; + asm ("pushf\n" + "pop %0\n" + "mov %0, %1\n" + "xor $0x00200000, %0\n" + "push %0\n" "popf\n" "pushf\n" - "pop %%eax\n" - "xor %%edx, %%edx\n" - "xor %%ebx, %%eax\n" - "jz 2f\n" - - "mov $0x80000000, %%eax\n" - "cpuid\n" - "cmp $0x80000000, %%eax\n" - "jbe 2f\n" - "mov $0x80000001, %%eax\n" - "cpuid\n" - "2:\n" - "pop %%ebx\n" - "mov %%edx, %0\n" - : "=r" (extended_result) - : - : "%eax", "%ecx", "%edx" - ); + "pop %0\n" + "xor %1, %0\n" // %eax is now 0 if CPUID is not supported + : "=a" (cpuid_supported), "=r" (tmp1) + ); + if (cpuid_supported) { + asm ("xchg %%ebx, %2\n" + "cpuid\n" + "xchg %%ebx, %2\n" + : "=c" (feature_result), "=d" (result), "=&r" (tmp1) + : "a" (1)); + + asm ("xchg %%ebx, %1\n" + "cpuid\n" + "cmp $0x80000000, %%eax\n" + "jnbe 1f\n" + "xor %0, %0\n" + "jmp 2f\n" + "1:\n" + "mov $0x80000001, %%eax\n" + "cpuid\n" + "2:\n" + "xchg %%ebx, %1\n" + : "=d" (extended_result), "=&r" (tmp1) + : "a" (0x80000000) + : "%ecx" + ); + } #elif defined (Q_OS_WIN) _asm { @@ -289,27 +286,13 @@ static inline uint detectProcessorFeatures() uint feature_result = 0; #if defined(Q_CC_GNU) - asm ("push %%rbx\n" - "pushf\n" - "pop %%rax\n" - "mov %%eax, %%ebx\n" - "xor $0x00200000, %%eax\n" - "push %%rax\n" - "popf\n" - "pushf\n" - "pop %%rax\n" - "xor %%edx, %%edx\n" - "xor %%ebx, %%eax\n" - "jz 1f\n" - - "mov $0x00000001, %%eax\n" + long tmp; + asm ("xchg %%rbx, %1\n" "cpuid\n" - "1:\n" - "pop %%rbx\n" - "mov %%ecx, %0\n" - : "=r" (feature_result) - : - : "%eax", "%ecx", "%edx" + "xchg %%rbx, %1\n" + : "=c" (feature_result), "=&r" (tmp) + : "a" (1) + : "%edx" ); #elif defined (Q_OS_WIN64) { diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index 2626657..664543b 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -51,8 +51,13 @@ QT_BEGIN_HEADER #if defined(QT_NO_MAC_XARCH) || (defined(Q_OS_DARWIN) && (defined(__ppc__) || defined(__ppc64__))) // Disable MMX and SSE on Mac/PPC builds, or if the compiler // does not support -Xarch argument passing -#undef QT_HAVE_SSE2 #undef QT_HAVE_SSE +#undef QT_HAVE_SSE2 +#undef QT_HAVE_SSE3 +#undef QT_HAVE_SSSE3 +#undef QT_HAVE_SSE4_1 +#undef QT_HAVE_SSE4_2 +#undef QT_HAVE_AVX #undef QT_HAVE_3DNOW #undef QT_HAVE_MMX #endif diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index bb7105b..cc90b3a 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -189,19 +189,6 @@ static int ucstricmp(const ushort *a, const ushort *ae, const uchar *b) return 1; } -// Unicode case-sensitive comparison -static int ucstrcmp(const QChar *a, int alen, const QChar *b, int blen) -{ - if (a == b && alen == blen) - return 0; - int l = qMin(alen, blen); - while (l-- && *a == *b) - a++,b++; - if (l == -1) - return (alen-blen); - return a->unicode() - b->unicode(); -} - // Unicode case-sensitive compare two same-sized strings static int ucstrncmp(const QChar *a, const QChar *b, int l) { @@ -212,6 +199,16 @@ static int ucstrncmp(const QChar *a, const QChar *b, int l) return a->unicode() - b->unicode(); } +// Unicode case-sensitive comparison +static int ucstrcmp(const QChar *a, int alen, const QChar *b, int blen) +{ + if (a == b && alen == blen) + return 0; + int l = qMin(alen, blen); + int cmp = ucstrncmp(a, b, l); + return cmp ? cmp : (alen-blen); +} + // Unicode case-insensitive compare two same-sized strings static int ucstrnicmp(const ushort *a, const ushort *b, int l) { diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 535f43d..7eee33d 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -303,9 +303,9 @@ public: #ifndef QT_NO_STL static inline QVector<T> fromStdVector(const std::vector<T> &vector) - { QVector<T> tmp; qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; } + { QVector<T> tmp; tmp.reserve(vector.size()); qCopy(vector.begin(), vector.end(), std::back_inserter(tmp)); return tmp; } inline std::vector<T> toStdVector() const - { std::vector<T> tmp; qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; } + { std::vector<T> tmp; tmp.reserve(size()); qCopy(constBegin(), constEnd(), std::back_inserter(tmp)); return tmp; } #endif private: friend class QRegion; // Optimization for QRegion::rects() |