diff options
author | Prasanth Ullattil <prasanth.ullattil@nokia.com> | 2010-09-15 17:10:21 +0200 |
---|---|---|
committer | Prasanth Ullattil <prasanth.ullattil@nokia.com> | 2010-09-15 18:56:43 +0200 |
commit | 6bc165d0fbbc4704d87e59cc0795dc2769228dc3 (patch) | |
tree | 39e63f6e92eb3c11afc8fd3ac1a8408b5121abab /src/corelib/io/qfilesystemiterator_win.cpp | |
parent | fd4463c07f577d9df212388062028f9119e19add (diff) |
Implement QFileSystemIterator for windows.
The search is implemented using FindFirstFileEx(). Following
optimizations are done
* Using large Fetch buffer on Windows 7
* Querying only the long file name
* Querying for directories only, depending on QDir::Filters
Reviewed-by: Joao
Diffstat (limited to 'src/corelib/io/qfilesystemiterator_win.cpp')
-rw-r--r-- | src/corelib/io/qfilesystemiterator_win.cpp | 84 |
1 files changed, 80 insertions, 4 deletions
diff --git a/src/corelib/io/qfilesystemiterator_win.cpp b/src/corelib/io/qfilesystemiterator_win.cpp index 3c734967dd..373a50a653 100644 --- a/src/corelib/io/qfilesystemiterator_win.cpp +++ b/src/corelib/io/qfilesystemiterator_win.cpp @@ -40,26 +40,102 @@ ****************************************************************************/ #include "qfilesystemiterator_p.h" +#include "qfilesystemengine_p.h" +#include "qplatformdefs.h" QT_BEGIN_NAMESPACE +bool done = true; + QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Filters filters, const QStringList &nameFilters, QDirIterator::IteratorFlags flags) + : nativePath(entry.nativeFilePath()) + , dirPath(entry.filePath()) + , findFileHandle(INVALID_HANDLE_VALUE) + , uncFallback(false) + , uncShareIndex(0) + , onlyDirs(false) { - Q_UNUSED(entry) - Q_UNUSED(filters) Q_UNUSED(nameFilters) Q_UNUSED(flags) + if (nativePath.endsWith(QLatin1String(".lnk"))) { + QFileSystemMetaData metaData; + QFileSystemEntry link = QFileSystemEngine::getLinkTarget(entry, metaData); + nativePath = link.nativeFilePath(); + } + if (!nativePath.endsWith(QLatin1Char('\\'))) + nativePath.append(QLatin1Char('\\')); + nativePath.append(QLatin1Char('*')); + if (!dirPath.endsWith(QLatin1Char('//'))) + dirPath.append(QLatin1Char('//')); + if ((filters & (QDir::Dirs|QDir::Drives)) && (!(filters & (QDir::Files)))) + onlyDirs = true; } QFileSystemIterator::~QFileSystemIterator() { + if (findFileHandle != INVALID_HANDLE_VALUE) + FindClose(findFileHandle); } bool QFileSystemIterator::advance(QFileSystemEntry &fileEntry, QFileSystemMetaData &metaData) { - Q_UNUSED(fileEntry) - Q_UNUSED(metaData) + bool haveData = false; + WIN32_FIND_DATA findData; + + if (findFileHandle == INVALID_HANDLE_VALUE && !uncFallback) { + haveData = true; + DWORD dwAdditionalFlags = 0; + if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7) + dwAdditionalFlags = 2; // FIND_FIRST_EX_LARGE_FETCH + int searchOps = 0; // FindExSearchNameMatch + if (onlyDirs) + searchOps = 1 ; // FindExSearchLimitToDirectories +#if !defined(Q_OS_WINCE) + int infoLevel = 1 ; // FindExInfoBasic; +#else + int infoLevel = 0; // FindExInfoStandard; +#endif + findFileHandle = FindFirstFileEx((const wchar_t *)nativePath.utf16(), FINDEX_INFO_LEVELS(infoLevel), &findData, + FINDEX_SEARCH_OPS(searchOps), 0, dwAdditionalFlags); + if (findFileHandle == INVALID_HANDLE_VALUE) { + if (nativePath.startsWith(QLatin1String("\\\\?\\UNC\\"))) { + QStringList parts = nativePath.split(QLatin1Char('\\'), QString::SkipEmptyParts); + if (parts.count() == 4 && QFileSystemEngine::uncListSharesOnServer( + QLatin1String("\\\\") + parts.at(2), &uncShares)) { + if (uncShares.isEmpty()) + return false; // No shares found in the server + else + uncFallback = true; + } + } + } + } + if (findFileHandle == INVALID_HANDLE_VALUE && !uncFallback) + return false; + // Retrieve the new file information. + if (!haveData) { + if (uncFallback) { + if (++uncShareIndex >= uncShares.count()) + return false; + } else { + if (!FindNextFile(findFileHandle, &findData)) + return false; + } + } + // Create the new file system entry & meta data. + if (uncFallback) { + fileEntry = QFileSystemEntry(dirPath + uncShares.at(uncShareIndex)); + metaData.fillFromFileAttribute(FILE_ATTRIBUTE_DIRECTORY); + return true; + } else { + QString fileName = QString::fromWCharArray(findData.cFileName); + fileEntry = QFileSystemEntry(dirPath + fileName); + if (!fileName.endsWith(QLatin1String(".lnk"))) { + metaData.fillFromFindData(findData, true); + } + return true; + } return false; } |