From 33634cd85233b75d8c24ef8ed67ff054d709b6e9 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 3 Sep 2010 19:04:12 +0100 Subject: Port over QFileSystemIterator for Symbian OS Also added the QDirIterator::IteratorFlags iteratorFlags as a parameter for QFileSystemIterator, as it impacts what kind of filtering we can do via the OS. i.e. filename filtering isn't compatible with recursive iteration. Reviewed-By: joao --- src/corelib/io/qfilesystemiterator_p.h | 15 ++- src/corelib/io/qfilesystemiterator_symbian.cpp | 134 +++++++++++++++++++++++++ src/corelib/io/qfilesystemiterator_unix.cpp | 3 +- src/corelib/io/qfilesystemiterator_win.cpp | 3 +- 4 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 src/corelib/io/qfilesystemiterator_symbian.cpp diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h index 21ad70a..ed1ef5e 100644 --- a/src/corelib/io/qfilesystemiterator_p.h +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -55,17 +55,25 @@ #include #include +#include #include #include #include +// Platform-specific headers +#if defined(Q_OS_WIN) +#elif defined (Q_OS_SYMBIAN) +#include +#else +#endif + QT_BEGIN_NAMESPACE class QFileSystemIterator { public: - QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters); + QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters, QDirIterator::IteratorFlags flags); ~QFileSystemIterator(); bool advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData); @@ -74,6 +82,11 @@ private: // Platform-specific data #if defined(Q_OS_WIN) +#elif defined (Q_OS_SYMBIAN) + RDir dirHandle; + TEntryArray entries; + TInt lastError; + TInt entryIndex; #else #endif diff --git a/src/corelib/io/qfilesystemiterator_symbian.cpp b/src/corelib/io/qfilesystemiterator_symbian.cpp new file mode 100644 index 0000000..9093599 --- /dev/null +++ b/src/corelib/io/qfilesystemiterator_symbian.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qfilesystemiterator_p.h" +#include "qfilesystemengine_p.h" +#include "qcore_symbian_p.h" + +QT_BEGIN_NAMESPACE + +QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &path, QDir::Filters filters, + const QStringList &nameFilters, QDirIterator::IteratorFlags iteratorFlags) + : lastError(KErrNone), entryIndex(-1) +{ + RFs& fs = qt_s60GetRFs(); + + TFileName symbianPath; + QString abspath = QFileSystemEngine::absoluteName(path).nativeFilePath(); + + if (!abspath.endsWith(QLatin1Char('\\'))) + abspath.append(QLatin1Char('\\')); + + int pathLen = abspath.length(); + if (pathLen > symbianPath.MaxLength()) { + lastError = KErrBadName; + return; + } + symbianPath.Copy(qt_QString2TPtrC(abspath)); + + //set up server side filtering to reduce IPCs + //RDir won't accept all valid name filters e.g. "*. bar" + if (nameFilters.count() == 1 && !(filters & QDir::AllDirs) && iteratorFlags + == QDirIterator::NoIteratorFlags && pathLen + nameFilters[0].length() + <= symbianPath.MaxLength()) { + //server side supports one mask - skip this for recursive mode or if only files should be filtered + symbianPath.Append(qt_QString2TPtrC(nameFilters[0])); + } + + TUint symbianMask = 0; + if ((filters & QDir::Dirs) || (filters & QDir::AllDirs) || (iteratorFlags + & QDirIterator::Subdirectories)) + symbianMask |= KEntryAttDir; //include directories + if (filters & QDir::Hidden) + symbianMask |= KEntryAttHidden; + if (filters & QDir::System) + symbianMask |= KEntryAttSystem; + if (((filters & QDir::Files) == 0) && symbianMask == KEntryAttDir) + symbianMask |= KEntryAttMatchExclusive; //exclude non-directories + else if (symbianMask == 0) { + if ((filters & QDir::PermissionMask) == QDir::Writable) + symbianMask = KEntryAttMatchExclude | KEntryAttReadOnly; + else if ((filters & QDir::PermissionMask) == QDir::Readable) + symbianMask = KEntryAttMatchExclusive | KEntryAttReadOnly; + } + + lastError = dirHandle.Open(fs, symbianPath, symbianMask); +} + +QFileSystemIterator::~QFileSystemIterator() +{ + dirHandle.Close(); +} + +static void createFileSystemMetaDataHelper(const TEntry &entry, QFileSystemMetaData &metaData) +{ + //placeholder + //TODO: adapt from QFileInfoPrivate::fromTEntry(entries[entryIndex], path()); + //or add this functionality to QFileSystemMetaData +} + +bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) +{ + //1st time, lastError is result of dirHandle.Open(), entries.Count() is 0 and entryIndex is -1 so initial read is triggered + //subsequent times, read is triggered each time we reach the end of the entry list + //final time, lastError is KErrEof so we don't need to read anymore. + ++entryIndex; + if (lastError == KErrNone && entryIndex >= entries.Count()) { + lastError = dirHandle.Read(entries); + entryIndex = 0; + } + + //each call to advance() gets the next entry from the entry list. + //from the final (or only) read call, KErrEof is returned together with a full buffer so we still need to go through the list + if ((lastError == KErrNone || lastError == KErrEof) && entryIndex < entries.Count()) { + Q_ASSERT(entryIndex >= 0); + const TEntry &entry(entries[entryIndex]); + fileEntry = QFileSystemEntry(qt_TDesC2QString(entry.iName), QFileSystemEntry::FromNativePath()); + createFileSystemMetaDataHelper(entry, metaData); + return true; + } + + //TODO: error reporting, to allow user to distinguish empty directory from error condition. + + return false; +} + +QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemiterator_unix.cpp b/src/corelib/io/qfilesystemiterator_unix.cpp index 1a6bf87..3c73496 100644 --- a/src/corelib/io/qfilesystemiterator_unix.cpp +++ b/src/corelib/io/qfilesystemiterator_unix.cpp @@ -44,11 +44,12 @@ QT_BEGIN_NAMESPACE QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, - const QStringList &nameFilters) + const QStringList &nameFilters, QDirIterator::IteratorFlags flags) { Q_UNUSED(entry) Q_UNUSED(filters) Q_UNUSED(nameFilters) + Q_UNUSED(flags) } QFileSystemIterator::~QFileSystemIterator() diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 1a6bf87..3c73496 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -44,11 +44,12 @@ QT_BEGIN_NAMESPACE QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, - const QStringList &nameFilters) + const QStringList &nameFilters, QDirIterator::IteratorFlags flags) { Q_UNUSED(entry) Q_UNUSED(filters) Q_UNUSED(nameFilters) + Q_UNUSED(flags) } QFileSystemIterator::~QFileSystemIterator() -- cgit v0.12