diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/global/global.pri | 2 | ||||
-rw-r--r-- | src/corelib/io/qdir.cpp | 479 | ||||
-rw-r--r-- | src/corelib/io/qdir.h | 7 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.cpp | 216 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.h | 16 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo_p.h | 114 | ||||
-rw-r--r-- | src/corelib/io/qurl.cpp | 26 | ||||
-rw-r--r-- | src/corelib/kernel/qeventdispatcher_symbian.cpp | 8 | ||||
-rw-r--r-- | src/corelib/tools/qbytearray.cpp | 41 | ||||
-rw-r--r-- | src/corelib/tools/qelapsedtimer_unix.cpp | 129 | ||||
-rw-r--r-- | src/corelib/tools/qsimd.cpp | 122 | ||||
-rw-r--r-- | src/corelib/tools/qstring.cpp | 23 |
12 files changed, 579 insertions, 604 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/io/qdir.cpp b/src/corelib/io/qdir.cpp index e54d95e..fcd17f7 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('/'))) @@ -867,11 +852,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 { @@ -884,7 +870,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); /* @@ -901,12 +887,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; } @@ -930,9 +917,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; } /*! @@ -952,10 +938,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; } /*! @@ -1058,9 +1045,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; } /*! @@ -1141,10 +1127,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; } /*! @@ -1154,9 +1141,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; } /*! @@ -1199,10 +1185,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; } /*! @@ -1214,10 +1201,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(); } /*! @@ -1229,10 +1215,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]; } /*! @@ -1256,9 +1241,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); } @@ -1280,9 +1264,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); } /*! @@ -1304,24 +1287,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()); @@ -1350,24 +1333,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()); @@ -1386,17 +1369,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); } /*! @@ -1410,17 +1391,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); } /*! @@ -1435,17 +1414,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); } /*! @@ -1461,17 +1438,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); } /*! @@ -1485,12 +1460,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; @@ -1510,17 +1483,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(); } /*! @@ -1537,11 +1500,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; } /*! @@ -1571,11 +1530,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(); } @@ -1588,18 +1543,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; } @@ -1614,19 +1568,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); @@ -1641,11 +1594,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; } @@ -1659,9 +1608,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; } @@ -1705,14 +1652,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()) @@ -2150,9 +2093,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(); } /*! @@ -2228,7 +2171,7 @@ QStringList QDir::nameFiltersFromString(const QString &nameFilter) */ bool QDir::matchAllDirs() const { - Q_D(const QDir); + const QDirPrivate* d = d_ptr.constData(); return d->matchAllDirs; } @@ -2240,9 +2183,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; } @@ -2251,8 +2195,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)); } @@ -2278,10 +2221,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 28da271..7e5fbac 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 7e82aed..f0128b1 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 @@ -166,10 +166,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/qurl.cpp b/src/corelib/io/qurl.cpp index 79a8ce4..74c24b5 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3399,16 +3399,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 { @@ -4958,6 +4962,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) @@ -5028,6 +5036,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) @@ -5084,6 +5096,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 @@ -5188,6 +5204,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 @@ -5232,6 +5252,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 @@ -5610,7 +5634,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/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 1bad8ed..5cc6ae3 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/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 8d38e4c..033da90 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -850,7 +850,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=() */ @@ -1186,10 +1186,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() */ @@ -1474,7 +1482,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() */ @@ -1547,14 +1560,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/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..a9c33f1 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,10 @@ 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" - "cpuid\n" - "1:\n" - "pop %%rbx\n" - "mov %%ecx, %0\n" - : "=r" (feature_result) - : - : "%eax", "%ecx", "%edx" + asm ("cpuid" + : "=c" (feature_result) + : "a" (1) + : "%ebx", "%edx" ); #elif defined (Q_OS_WIN64) { diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index d940bf8..2813b29 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -173,19 +173,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) { @@ -196,6 +183,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) { |