summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Abecasis <joao@trolltech.com>2010-02-02 19:34:23 (GMT)
committerJoão Abecasis <joao@trolltech.com>2010-02-03 14:16:21 (GMT)
commit14054a47230d41063a10ce8fbf7dc65c916163d7 (patch)
tree50cd404468e90d072bfbad3c6e6a88259318ed6f
parent63f66fb0008f93638de782b03f53e9777a941ab7 (diff)
downloadQt-14054a47230d41063a10ce8fbf7dc65c916163d7.zip
Qt-14054a47230d41063a10ce8fbf7dc65c916163d7.tar.gz
Qt-14054a47230d41063a10ce8fbf7dc65c916163d7.tar.bz2
QDir fix issues with (shared) cached lists
With 2964718224c0ed356511335742368d4fc421c6bd, QDir started really using the cached file lists. However, these were not being properly updated on setNameFilters, setFilter and setSorting. QDir::refresh, on the other hand, would invalidate the lists without first detaching, thus breaking the copy-on-write promise. Summarizing, shared data must be detached and cached lists invalidated, so they get regenerated. Reviewed-by: Olivier Goffart Reviewed-by: Ritt Konstantin
-rw-r--r--src/corelib/io/qdir.cpp10
-rw-r--r--tests/auto/qdir/tst_qdir.cpp92
-rw-r--r--tests/shared/filesystem.h97
3 files changed, 195 insertions, 4 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 250e5e5..f5d803e 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -960,7 +960,7 @@ void QDir::setNameFilters(const QStringList &nameFilters)
{
Q_D(QDir);
- d->detach();
+ d->reset();
d->data->nameFilters = nameFilters;
}
@@ -1146,7 +1146,7 @@ void QDir::setFilter(Filters filters)
{
Q_D(QDir);
- d->detach();
+ d->reset();
d->data->filters = filters;
}
@@ -1204,7 +1204,7 @@ void QDir::setSorting(SortFlags sort)
{
Q_D(QDir);
- d->detach();
+ d->reset();
d->data->sort = sort;
}
@@ -2155,7 +2155,7 @@ void QDir::refresh() const
{
Q_D(const QDir);
- d->data->clear();
+ const_cast<QDirPrivate *>(d)->reset();
}
/*!
@@ -2244,6 +2244,8 @@ bool QDir::matchAllDirs() const
void QDir::setMatchAllDirs(bool on)
{
Q_D(QDir);
+
+ d->reset();
d->matchAllDirs = on;
}
diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp
index 1d909c9..ba18bbb 100644
--- a/tests/auto/qdir/tst_qdir.cpp
+++ b/tests/auto/qdir/tst_qdir.cpp
@@ -49,6 +49,7 @@
#include <qregexp.h>
#include <qstringlist.h>
#include "../network-settings.h"
+#include "../../shared/filesystem.h"
#if defined(Q_OS_SYMBIAN)
# define STRINGIFY(x) #x
@@ -164,6 +165,8 @@ private slots:
void longFileName_data();
void longFileName();
+
+ void updateFileLists();
};
// Testing get/set functions
@@ -1442,6 +1445,95 @@ void tst_QDir::longFileName()
QFile::remove(fileName);
}
+void tst_QDir::updateFileLists()
+{
+ // Test setup
+
+ FileSystem fs;
+
+ QVERIFY( fs.createDirectory("update-file-lists") );
+ QVERIFY( fs.createFile("update-file-lists/file1.txt") );
+ QVERIFY( fs.createFile("update-file-lists/file2.doc") );
+
+ QVERIFY( fs.createDirectory("update-file-lists/sub-dir1") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir1/file3.txt") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir1/file4.doc") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir1/file5.txt") );
+
+ QVERIFY( fs.createDirectory("update-file-lists/sub-dir2") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir2/file6.txt") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir2/file7.txt") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir2/file8.doc") );
+ QVERIFY( fs.createFile("update-file-lists/sub-dir2/file9.doc") );
+
+ // Actual test
+
+ QDir dir("update-file-lists");
+
+ QCOMPARE(dir.count(), uint(6));
+ QCOMPARE(dir.entryList().size(), 6);
+ QCOMPARE(dir.entryInfoList().size(), 6);
+
+ dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
+
+ QCOMPARE(dir.entryList().size(), 4);
+ QCOMPARE(dir.count(), uint(4));
+ QCOMPARE(dir.entryInfoList().size(), 4);
+
+ dir.setPath("update-file-lists/sub-dir1");
+
+ QCOMPARE(dir.entryInfoList().size(), 3);
+ QCOMPARE(dir.count(), uint(3));
+ QCOMPARE(dir.entryList().size(), 3);
+
+ dir.setNameFilters(QStringList("*.txt"));
+
+ QCOMPARE(dir.entryInfoList().size(), 2);
+ QCOMPARE(dir.entryList().size(), 2);
+ QCOMPARE(dir.count(), uint(2));
+
+ dir.setPath("update-file-lists");
+ dir = QDir(dir.path(),
+ "*.txt",
+ QDir::Name | QDir::DirsLast,
+ QDir::AllEntries | QDir::AllDirs | QDir::NoDotAndDotDot);
+
+ QCOMPARE(dir.count(), uint(3));
+ QCOMPARE(dir.entryList().size(), 3);
+ QCOMPARE(dir.entryInfoList().size(), 3);
+ QCOMPARE(dir.entryList(), QStringList() << "file1.txt" << "sub-dir1" << "sub-dir2");
+
+ dir.setSorting(QDir::Name | QDir::DirsFirst);
+
+ QCOMPARE(dir.count(), uint(3));
+ QCOMPARE(dir.entryList().size(), 3);
+ QCOMPARE(dir.entryInfoList().size(), 3);
+ QCOMPARE(dir.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt");
+
+ {
+ QVERIFY( fs.createFile("update-file-lists/extra-file.txt") );
+
+ QDir dir2(dir);
+
+ QCOMPARE(dir2.count(), uint(3));
+ QCOMPARE(dir2.entryList().size(), 3);
+ QCOMPARE(dir2.entryInfoList().size(), 3);
+ QCOMPARE(dir2.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt");
+
+ dir2.refresh();
+
+ QCOMPARE(dir2.count(), uint(4));
+ QCOMPARE(dir2.entryList().size(), 4);
+ QCOMPARE(dir2.entryInfoList().size(), 4);
+ QCOMPARE(dir2.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "extra-file.txt" << "file1.txt");
+ }
+
+ QCOMPARE(dir.count(), uint(3));
+ QCOMPARE(dir.entryList().size(), 3);
+ QCOMPARE(dir.entryInfoList().size(), 3);
+ QCOMPARE(dir.entryList(), QStringList() << "sub-dir1" << "sub-dir2" << "file1.txt");
+}
+
QTEST_MAIN(tst_QDir)
#include "tst_qdir.moc"
diff --git a/tests/shared/filesystem.h b/tests/shared/filesystem.h
new file mode 100644
index 0000000..2d46c0d
--- /dev/null
+++ b/tests/shared/filesystem.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+// Helper functions for creating file-system hierarchies and cleaning up.
+
+#ifndef QT_TESTS_SHARED_FILESYSTEM_H_INCLUDED
+#define QT_TESTS_SHARED_FILESYSTEM_H_INCLUDED
+
+#include <QString>
+#include <QStringList>
+#include <QDir>
+#include <QFile>
+
+struct FileSystem
+{
+ ~FileSystem()
+ {
+ Q_FOREACH(QString fileName, createdFiles)
+ QFile::remove(fileName);
+
+ Q_FOREACH(QString dirName, createdDirectories)
+ currentDir.rmdir(dirName);
+ }
+
+ bool createDirectory(const QString &dirName)
+ {
+ if (currentDir.mkdir(dirName)) {
+ createdDirectories.prepend(dirName);
+ return true;
+ }
+ return false;
+ }
+
+ bool createFile(const QString &fileName)
+ {
+ QFile file(fileName);
+ if (file.open(QIODevice::WriteOnly)) {
+ createdFiles << fileName;
+ return true;
+ }
+ return false;
+ }
+
+ bool createLink(const QString &destination, const QString &linkName)
+ {
+ if (QFile::link(destination, linkName)) {
+ createdFiles << linkName;
+ return true;
+ }
+ return false;
+ }
+
+private:
+ QDir currentDir;
+
+ QStringList createdDirectories;
+ QStringList createdFiles;
+};
+
+#endif // include guard