/*! \internal */ void QDirIteratorPrivate::advance() { // Store the current entry if (!fileEngineIterators.isEmpty()) currentFilePath = fileEngineIterators.top()->currentFilePath(); // Advance to the next entry if (followNextDir) { // Start by navigating into the current directory. followNextDir = false; QAbstractFileEngineIterator *it = fileEngineIterators.top(); QString subDir = it->currentFilePath(); #ifdef Q_OS_WIN if (currentFileInfo.isSymLink()) subDir = currentFileInfo.canonicalFilePath(); #endif pushSubDirectory(subDir, it->nameFilters(), it->filters()); } while (!fileEngineIterators.isEmpty()) { QAbstractFileEngineIterator *it = fileEngineIterators.top(); // Find the next valid iterator that matches the filters. bool foundDirectory = false; while (it->hasNext()) { it->next(); if (matchesFilters(it)) { currentFileInfo = nextFileInfo; nextFileInfo = it->currentFileInfo(); // Signal that we want to follow this entry. followNextDir = shouldFollowDirectory(nextFileInfo); //We found a matching entry. return; } else if (iteratorFlags & QDirIterator::Subdirectories) { QFileInfo fileInfo = it->currentFileInfo(); if (!shouldFollowDirectory(fileInfo)) continue; QString subDir = it->currentFilePath(); #ifdef Q_OS_WIN if (fileInfo.isSymLink()) subDir = fileInfo.canonicalFilePath(); #endif pushSubDirectory(subDir, it->nameFilters(), it->filters()); foundDirectory = true; break; } } if (!foundDirectory) delete fileEngineIterators.pop(); } currentFileInfo = nextFileInfo; done = true; }
/*! \internal */ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters, QDirIterator::IteratorFlags flags) : engine(0), path(path), iteratorFlags(flags), followNextDir(false), first(true), done(false) { if (filters == QDir::NoFilter) filters = QDir::AllEntries; this->filters = filters; this->nameFilters = nameFilters; nextFileInfo.setFile(path); pushSubDirectory(nextFileInfo.isSymLink() ? nextFileInfo.canonicalFilePath() : path, nameFilters, filters); }
/*! \internal */ QFileSystemIteratorPrivate::QFileSystemIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters, QFileSystemIterator::IteratorFlags flags) : iteratorFlags(flags) { if (filters == QDir::NoFilter) filters = QDir::AllEntries; this->filters = filters; this->nameFilters = nameFilters; fileInfo.setFile(path); QString dir = fileInfo.isSymLink() ? fileInfo.canonicalFilePath() : path; pushSubDirectory(dir.toLocal8Bit()); // skip to acceptable entry while (true) { if (atEnd()) return; if (isAcceptable()) return; if (advanceHelper()) return; } }
bool QFileSystemIteratorPrivate::advanceHelper() { if (m_dirStructs.isEmpty()) return true; //printf("ADV %d %d\n", int(m_currentDirShown), int(m_nextDirShown)); if ((filters & QDir::Dirs)) { m_currentDirShown = m_nextDirShown; if (m_nextDirShown == ShowDir) { //printf("RESTING ON DIR %s %x\n", m_dirPaths.top().constData(), int(filters)); m_nextDirShown = (filters & QDir::NoDotAndDotDot) ? DontShowDir : ShowDotDir; // skip start directory itself if (m_dirStructs.size() == 1 && m_currentDirShown == ShowDir) return advanceHelper(); return true; } if (m_nextDirShown == ShowDotDir) { //printf("RESTING ON DOT %s %x\n", m_dirPaths.top().constData(), int(filters)); m_nextDirShown = ShowDotDotDir; return true; } if (m_nextDirShown == ShowDotDotDir) { //printf("RESTING ON DOTDOT %s %x\n", m_dirPaths.top().constData(), int(filters)); m_nextDirShown = DontShowDir; return true; } m_currentDirShown = DontShowDir; } #ifdef Q_OS_WIN m_entry = &m_fileSearchResult; if (m_bFirstSearchResult) { m_bFirstSearchResult = false; } else { if (!FindNextFile(m_dirStructs.top(), m_entry)) m_entry = 0; } while (m_entry && isDotOrDotDot(m_entry->cFileName)) if (!FindNextFile(m_dirStructs.top(), m_entry)) m_entry = 0; if (!m_entry) { m_dirPaths.pop(); FindClose(m_dirStructs.pop()); return false; } if (m_entry->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { QByteArray ba = m_dirPaths.top(); ba += '\\'; ba += QString::fromWCharArray(m_entry->cFileName); pushSubDirectory(ba); } #else m_entry = ::readdir(m_dirStructs.top()); while (m_entry && isDotOrDotDot(m_entry->d_name)) m_entry = ::readdir(m_dirStructs.top()); //return false; // further iteration possibly needed //printf("READ %p %s\n", m_entry, m_entry ? m_entry->d_name : ""); if (!m_entry) { m_dirPaths.pop(); DIR *dir = m_dirStructs.pop(); ::closedir(dir); return false; // further iteration possibly needed } const char *name = m_entry->d_name; QByteArray ba = m_dirPaths.top(); ba += '/'; ba += name; struct stat st; lstat(ba.constData(), &st); if (S_ISDIR(st.st_mode)) { pushSubDirectory(ba); return false; // further iteration possibly needed } #endif return false; // further iteration possiblye needed }
/*! \internal */ void QDirIteratorPrivate::advance() { // Store the current entry if (!fileEngineIterators.isEmpty()) currentFilePath = fileEngineIterators.top()->currentFilePath(); // Advance to the next entry if (followNextDir) { // Start by navigating into the current directory. followNextDir = false; QAbstractFileEngineIterator *it = fileEngineIterators.top(); QString subDir = it->currentFilePath(); #ifdef Q_OS_WIN if (fileInfo.isSymLink()) subDir = fileInfo.canonicalFilePath(); #endif pushSubDirectory(subDir, it->nameFilters(), it->filters()); } if (fileEngineIterators.isEmpty()) done = true; bool foundValidEntry = false; while (!fileEngineIterators.isEmpty()) { QAbstractFileEngineIterator *it = fileEngineIterators.top(); // Find the next valid iterator that matches the filters. foundValidEntry = false; while (it->hasNext()) { it->next(); if (matchesFilters(it)) { foundValidEntry = true; break; } } if (!foundValidEntry) { // If this iterator is done, pop and delete it, and continue // iteration on the parent. Otherwise break, we're done. if (!fileEngineIterators.isEmpty()) { delete it; it = fileEngineIterators.pop(); continue; } break; } fileInfo = it->currentFileInfo(); // If we're doing flat iteration, we're done. if (!(iteratorFlags & QDirIterator::Subdirectories)) break; // Subdirectory iteration. QString filePath = fileInfo.filePath(); // Never follow . and .. if (fileInfo.fileName() == QLatin1String(".") || fileInfo.fileName() == QLatin1String("..")) break; // Never follow non-directory entries if (!fileInfo.isDir()) break; // Check symlinks if (fileInfo.isSymLink() && !(iteratorFlags & QDirIterator::FollowSymlinks)) { // Follow symlinks only if FollowSymlinks was passed break; } // Stop link loops if (visitedLinks.contains(fileInfo.canonicalFilePath())) break; // Signal that we want to follow this entry. followNextDir = true; break; } if (!foundValidEntry) done = true; }