diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-09-09 07:17:15 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-09-09 07:17:15 (GMT) |
commit | 6919e1e9d36d83958750a42e1f8d567f2f74299e (patch) | |
tree | ccbf58400efc7546fd0f5bd58c3855180146934f /src/corelib | |
parent | a9dc52d88fd40f55acfcbb64131291dea18d8ccc (diff) | |
parent | d030e69cbabfcae81054e5b8c893b28b2d9de38b (diff) | |
download | Qt-6919e1e9d36d83958750a42e1f8d567f2f74299e.zip Qt-6919e1e9d36d83958750a42e1f8d567f2f74299e.tar.gz Qt-6919e1e9d36d83958750a42e1f8d567f2f74299e.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1: (27 commits)
Work around a compiler bug on 64-bit.
Fix handling of braces/no-braces in QUrl::host / setHost.
Changes (and minor corrections) to QByteArray documentation.
QtWebKit: Update tag files to match the same content on qtwebkit.git
QtWebKit: Downstream patch 2 fixing a crash on MSVC 64bit.
QtWebKit: Downstream patch 1 fixing a crash on MSVC 64bit.
uic: Fix compile breakage in case QT_NO_QT3_SUPPORT.
uic: Improve messages.
Tools (uic/rcc): Improve warning messages.
QDir: Removed checks for existance of fileEngine
QDir and QFileInfo shouldn't lose properties when detaching
Another bug-o introduced in fixing QDirPrivate refactoring
Reverting QDir::detach introduced earlier
QFileInfo: Prepare for engine-less implementation
Removed QFileInfoPrivate::initFileEngine
Simplify QDir::cd
QDir::makeAbsolute could self-destruct on failure
QDir::operator= simplification
QDirPrivate refactoring
QDirPrivate refactoring
...
Diffstat (limited to 'src/corelib')
-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 | 4 | ||||
-rw-r--r-- | src/corelib/tools/qbytearray.cpp | 41 | ||||
-rw-r--r-- | src/corelib/tools/qsimd.cpp | 9 |
8 files changed, 422 insertions, 464 deletions
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 56a03c9..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 { 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/qsimd.cpp b/src/corelib/tools/qsimd.cpp index a9c33f1..7babf3a 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -286,10 +286,13 @@ static inline uint detectProcessorFeatures() uint feature_result = 0; #if defined(Q_CC_GNU) - asm ("cpuid" - : "=c" (feature_result) + long tmp; + asm ("xchg %%rbx, %1\n" + "cpuid\n" + "xchg %%rbx, %1\n" + : "=c" (feature_result), "=&r" (tmp) : "a" (1) - : "%ebx", "%edx" + : "%edx" ); #elif defined (Q_OS_WIN64) { |