VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gdirectorytree.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file gdirectorytree.h
19 ///
20 
21 #ifndef G_DIRECTORY_TREE__H
22 #define G_DIRECTORY_TREE__H
23 
24 #include "gdef.h"
25 #include "gdirectory.h"
26 #include "gpath.h"
27 #include <list>
28 #include <vector>
29 
30 namespace G
31 {
32  class DirectoryTree ;
33  class DirectoryTreeCallback ;
34 }
35 
36 /// \class G::DirectoryTree
37 /// A directory tree iterator for sorted, depth-first traversal of files and
38 /// directories.
39 ///
41 {
42 public:
43  DirectoryTree() ;
44  ///< Default contructor for an off-the-end iterator.
45 
46  explicit DirectoryTree( const G::Path & root , bool reverse = false ,
47  DirectoryTreeCallback *ignore = 0 ) ;
48  ///< Contructor for a tree iterator rooted at the given path.
49  ///<
50  ///< If reverse-d the iterator moves through each depth level
51  ///< in reverse; this is not the same a reversal of the whole
52  ///< sequence because the sequence includes non-leaf nodes.
53  ///< It follows that reversal is more useful when directories
54  ///< are filtered out by client code (see G::FileTree).
55  ///<
56  ///< An optional callback function, taking a path and a depth,
57  ///< can be used to filter out files and directories that
58  ///< should be ignored. Directories that are ignored are not
59  ///< traversed at all.
60 
62  ///< Pre-increment operator. Moves to the next file or directory.
63 
64  const DirectoryList::Item & operator*() const ;
65  ///< Dereference operator yielding a G::DirectoryList::Item.
66 
67  bool operator==( const DirectoryTree & ) const ;
68  ///< Comparison operator.
69 
70  bool operator!=( const DirectoryTree & ) const ;
71  ///< Comparison operator.
72 
73  size_t depth() const ;
74  ///< Returns the nesting depth compared to the root.
75 
76  bool down( const std::string & name , bool at_or_after = false ) ;
77  ///< Moves deeper into the directory tree, with a precondition
78  ///< that the iterator currently points to a directory.
79  ///<
80  ///< If 'at_or_after' is false the iterator is moved into the
81  ///< directory to a position that matches the requested name.
82  ///< Returns false if not found, with the iterator position
83  ///< unchanged.
84  ///<
85  ///< If 'at_or_after' is true the iterator is moved into the
86  ///< directory to a position that is at or after the requested
87  ///< name and then returns true. However, if the requested name
88  ///< is lexicographically later than the last name in the
89  ///< directory, then the iterator might advance to another
90  ///< directory altogether or completely off-the-end of the tree,
91  ///< and in this case false is returned.
92  ///<
93  ///< Precondition: operator*().m_is_dir
94 
95  void up() ;
96  ///< Moves up to the parent directory.
97  ///< Precondition: depth() >= 1
98 
99  void swap( DirectoryTree & other ) ;
100  ///< Swaps this and other.
101 
102  DirectoryTree( const DirectoryTree & ) ;
103  ///< Copy constructor.
104 
105  DirectoryTree & operator=( const DirectoryTree & ) ;
106  ///< Assignment operator.
107 
108  void reverse( bool in_reverse = true ) ;
109  ///< Changes the reversal state, returning the previous value.
110 
111  bool reversed() const ;
112  ///< Returns the current reversal state.
113 
114 private:
115  typedef DirectoryList::Item FileItem ;
116  typedef std::vector<FileItem> FileList ;
117  struct Context
118  {
119  FileList m_list ;
120  FileList::iterator m_p ;
121  FileList::iterator m_end ;
122  } ;
123  typedef std::list<Context> Stack ;
124 
125 private:
126  static bool isDir( const Path & ) ;
127  FileList readFileList() const ;
128  void filter( FileList & , size_t ) const ;
129  bool ignore( const FileItem & , size_t ) const ;
130 
131 private:
132  Stack m_stack ;
133  bool m_reverse ;
134  DirectoryTreeCallback * m_callback ;
135 } ;
136 
137 /// \class G::DirectoryTreeCallback
138 /// A callback interface to allow G::DirectoryTree to ignore paths.
139 ///
141 {
142 public:
143  virtual bool directoryTreeIgnore( const G::DirectoryList::Item & , size_t depth ) = 0 ;
144  ///< Returns true if the file should be ignored.
145 
146 protected:
147  virtual ~DirectoryTreeCallback() ;
148 } ;
149 
150 namespace G
151 {
152  inline
153  void swap( DirectoryTree & a , DirectoryTree & b )
154  {
155  a.swap( b ) ;
156  }
157 }
158 
159 #endif
void reverse(bool in_reverse=true)
Changes the reversal state, returning the previous value.
DirectoryTree & operator++()
Pre-increment operator. Moves to the next file or directory.
A directory-entry item for G::DirectoryList.
Definition: gdirectory.h:148
A directory tree iterator for sorted, depth-first traversal of files and directories.
bool operator==(const DirectoryTree &) const
Comparison operator.
bool operator!=(const DirectoryTree &) const
Comparison operator.
DirectoryTree()
Default contructor for an off-the-end iterator.
const DirectoryList::Item & operator*() const
Dereference operator yielding a G::DirectoryList::Item.
virtual bool directoryTreeIgnore(const G::DirectoryList::Item &, size_t depth)=0
Returns true if the file should be ignored.
DirectoryTree & operator=(const DirectoryTree &)
Assignment operator.
void swap(DirectoryTree &other)
Swaps this and other.
bool down(const std::string &name, bool at_or_after=false)
Moves deeper into the directory tree, with a precondition that the iterator currently points to a dir...
bool reversed() const
Returns the current reversal state.
size_t depth() const
Returns the nesting depth compared to the root.
A callback interface to allow G::DirectoryTree to ignore paths.
A Path object represents a file system path.
Definition: gpath.h:72
void up()
Moves up to the parent directory.