Пример #1
0
/*!
    \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;
}
Пример #2
0
/*!
    \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);
}
Пример #3
0
/*!
    \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;
    }
}
Пример #4
0
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
}
Пример #5
0
/*!
    \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;
}