diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-09-10 19:50:08 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-09-10 19:50:08 (GMT) |
commit | 31cc0b1820c0c8fdfdbc3d5b804f2dba2051c96f (patch) | |
tree | 957b84d8f1792f9e5a43c879274469c4f07168ea /src/corelib | |
parent | e0ef11578048620b3f107b7a357fed3aade0d21e (diff) | |
parent | b3981fd1f7b82742857c613af6dfbe41b5493577 (diff) | |
download | Qt-31cc0b1820c0c8fdfdbc3d5b804f2dba2051c96f.zip Qt-31cc0b1820c0c8fdfdbc3d5b804f2dba2051c96f.tar.gz Qt-31cc0b1820c0c8fdfdbc3d5b804f2dba2051c96f.tar.bz2 |
Merge branch 'qt-master-from-4.7' of scm.dev.nokia.troll.no:qt/qt-integration into master-integration
* 'qt-master-from-4.7' of scm.dev.nokia.troll.no:qt/qt-integration: (284 commits)
Fixed crash in input methods when using symbols menu and numbers only
Fixed crash in input methods when using symbols menu and numbers only
Read the data when the stream passed in is of type CArchiveStream
Autotest for QTBUG-13454.
Changing the Image 'source' should not go through the 'Loading' state if the image is cached.
Make sure we blit to the correct FBO in the GL window surface.
Some optimizations to the GL pixmap data.
QList::toVector()/QVector::toStdVector()/QVector::fromStdVector(): use reserve()
When a move is completed, report the source and destination correctly.
Fixed the scrolling of text in QLineEdit with right alignment
Editable QComboBox popup immediately closes itself after a click
Change RLibrary handle in QS60PluginResolver to be process wide
Cursor is misplaced in the editors text area
Update running animations if a SmoothedAnimation is changed
Removing Q_ENUMS declaration in QTransform
QSslSocketPrivate::systemCaCertificates() hangs sometimes on Symbian
Fix SmoothedAnimation test and docs
Fix qdeclarativeimageprovider autotest compilation on Symbian
Fix reversingModes of QDeclarativeSmoothedAnimation
Re-add quit button to declarative Twitter demo
...
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() |