123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- #include "fstraverseiterator.h"
- bool QFileInfoLess::operator()(const QFileInfo & first,
- const QFileInfo & second) const
- {
- bool
- rv = first.absoluteFilePath() < second.absoluteFilePath();
- return rv;
- }
- FSGraph::FSGraph(bool filesAllowed)
- : m_filesAllowed(filesAllowed)
- {
- ;
- }
- FSTraverseIterator::FSTraverseIterator(const QString & startingAbsolutePath,
- int flags)
- : m_graph(true)
- , m_flags(flags)
- {
- QFileInfo
- startingPoint(startingAbsolutePath);
- if (startingPoint.exists())
- {
- setupFlagsAndColors();
- m_iterator = Iterator(m_graph,
- startingPoint,
- m_iteratorFlags);
- next(true);
- }
- }
- FSTraverseIterator::FSTraverseIterator(const QStringList & startingAbsolutePaths,
- int flags)
- : m_graph(true)
- , m_flags(flags)
- {
- QFileInfoList
- startingPoints;
- foreach (QString startingAbsolutePath, startingAbsolutePaths)
- {
- QFileInfo
- startingPoint(startingAbsolutePath);
- if (startingPoint.exists())
- {
- startingPoints.push_back(startingPoint);
- }
- }
- if (!startingPoints.empty())
- {
- setupFlagsAndColors();
- m_iterator = Iterator(m_graph,
- startingPoints.begin(),
- startingPoints.end(),
- m_iteratorFlags);
- next(true);
- }
- }
- FSTraverseIterator::FSTraverseIterator()
- : m_graph(false)
- , m_flags(0)
- {
- ;
- }
- QFileInfo * FSTraverseIterator::operator->()
- {
- return &m_currentFileInfo;
- }
- QFileInfo & FSTraverseIterator::operator*()
- {
- return m_currentFileInfo;
- }
- FSTraverseIterator & FSTraverseIterator::operator++()
- {
- next();
- return *this;
- }
- FSTraverseIterator FSTraverseIterator::operator++(int)
- {
- FSTraverseIterator
- tmp(*this);
- next();
- return tmp;
- }
- #define __yield_return(cn) {if(allowed(cn)){m_currentFileInfo=cn.m_node;break;}}
- void FSTraverseIterator::next(bool initializationTime)
- {
- Iterator
- endIt = Iterator();
- while (m_iterator != endIt)
- {
- // On creation, the m_iterator positions on the first
- // unseen item - no need to increment, but from that
- // point on, m_iterator either points to a seen item
- // or the "end".
- if (initializationTime)
- {
- initializationTime = false;
- }
- else
- {
- ++m_iterator;
- }
- if (m_iterator == endIt)
- {
- break;
- }
- ColoredNode<QFileInfo>
- coloredNode(*m_iterator);
- if (allowed(coloredNode))
- {
- __yield_return(coloredNode);
- }
- }
- }
- #undef __yield_return
- void FSTraverseIterator::setupFlagsAndColors()
- {
- // Here we are trying to map FSTraverseIterator::Flag flags
- // to Iterator::Flag flag values.
- //
- // enum Flag // <- FSTraverseIterator::Flag
- // {
- // DirsPreOrder = 1,
- // DirsPostOrder = 2,
- // DirsBoth = DirPreOrder | DirPostOrder,
- // Files = 8,
- // FilesAndDirs = DirsPreOrder | Files
- // };
- // enum Flag // <- Iterator::Flag
- // {
- // PreVisit = 1,
- // PostVisit = 2
- // };
- //
- // The FSTraverseIterator::Flag flags control
- // what kind of content is interesting (files, directories
- // or both) as well as at what point directories should
- // be iterated (before visiting its files, after
- // visiting its files, or both times).
- //
- // Files (that are leaf nodes (nodes without further
- // adjacents) from the point of view of depth first search
- // don't care if they are preorder or postorder visited.
- // Therefore it's up to the directory visiting (pre, post
- // or both) to decide what kind of flags we give to the
- // generic depth-first search.
- m_iteratorFlags = Iterator::PreVisit;
- m_allowedDirColors = NC_GRAY;
- m_allowedFileColor = NC_GRAY;
- if (m_flags & DirsPostOrder)
- {
- if (m_flags & DirsPreOrder)
- {
- // dirs are to be iterated both pre- and postvisit times
- m_iteratorFlags |= Iterator::PostVisit;
- m_allowedDirColors |= NC_BLACK;
- // m_allowedFileColor does not change here - we don't
- // intend to receive duplicate iterations on files
- }
- else
- {
- // dirs are to be visited only at postvisit times
- m_iteratorFlags = Iterator::PostVisit;
- m_allowedDirColors = NC_BLACK;
- // files will get iterated only at post visit times,
- // so we have better enable that
- m_allowedFileColor = NC_BLACK;
- }
- }
- else if (!(m_flags & DirsPreOrder))
- {
- // no directories are to be enumerated, after all (only traversed)
- m_allowedDirColors = 0;
- }
- if ((m_flags & Files) == 0)
- {
- // no files are to be enumerated, after all
- m_allowedFileColor = 0;
- m_graph = FSGraph(false);
- }
- }
- bool FSTraverseIterator::allowed(const ColoredNode<QFileInfo> & coloredNode)
- {
- bool
- rv = false;
- if (coloredNode.m_node.isFile())
- {
- rv = m_allowedFileColor == coloredNode.m_color;
- }
- else // it's a directory
- {
- rv = m_allowedDirColors & coloredNode.m_color;
- }
- return rv;
- }
- bool operator==(const FSTraverseIterator & first,
- const FSTraverseIterator & second)
- {
- typedef FSTraverseIterator::Iterator Iterator;
- return (first.m_iterator == Iterator() && second.m_iterator == Iterator())
- || (first.m_flags == second.m_flags
- && first.m_iterator == second.m_iterator
- && first.m_currentFileInfo == second.m_currentFileInfo
- );
- }
- bool operator!=(const FSTraverseIterator & first,
- const FSTraverseIterator & second)
- {
- return !(first == second);
- }
|