1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
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 gdirectory.h
19 ///
20 
21 #ifndef G_DIRECTORY_H
22 #define G_DIRECTORY_H
23 
24 #include "gdef.h"
25 #include "gpath.h"
26 #include "gexception.h"
27 #include <string>
28 #include <vector>
29 #include <sys/types.h>
30 
31 /// \namespace G
32 namespace G
33 {
34 	class DirectoryIteratorImp ;
35 	class Directory ;
36 	class DirectoryIterator ;
37 	class DirectoryList ;
38 }
39 
40 /// \class G::Directory
41 /// An encapsulation of a file system directory
42 /// which allows for iterating through the set of contained
43 /// files.
44 /// \see G::Path, G::FileSystem, G::File
45 ///
46 class G::Directory
47 {
48 public:
49 	Directory() ;
50 		///< Default constructor for the current directory.
51 
52 	explicit Directory( const char * path ) ;
53 		///< Constructor.
54 
55 	explicit Directory( const Path & path ) ;
56 		///< Constructor.
57 
58 	explicit Directory( const std::string & path ) ;
59 		///< Constructor.
60 
61 	~Directory() ;
62 		///< Destructor.
63 
64 	bool valid( bool for_creating_files = false ) const ;
65 		///< Returns true if the object represents a valid
66 		///< directory.
67 		///<
68 		///< Does additional checks if the 'for-creating-files'
69 		///< parameter is true. But note that the answer is not
70 		///< definitive -- file creation may fail, even if
71 		///< valid() returns true. For a more accurate test
72 		///< use writeable().
73 
74 	bool writeable( std::string probe_filename = tmp() ) const ;
75 		///< Tries to create and then delete an empty test file
76 		///< in the directory. Returns true on success.
77 		///< Precondition: valid()
78 
79 	Path path() const ;
80 		///< Returns the directory's path.
81 
82 	Directory( const Directory & other ) ;
83 		///< Copy constructor.
84 
85 	Directory & operator=( const Directory & ) ;
86 		///< Assignment operator.
87 
88 	static Directory root() ;
89 		///< Returns a root directory object. For DOSy file
90 		///< systems this will not contain a drive part.
91 
92 	static std::string tmp() ;
93 		///< A convenience function for constructing a
94 		///< filename for writeable(). This is factored out
95 		///< so that client code can minimise the time spent
96 		///< with a privileged effective userid.
97 
98 private:
99 	Path m_path ;
100 } ;
101 
102 /// \class G::DirectoryIterator
103 /// A Directory iterator. The iteration model is
104 /// \code
105 /// while(iter.more()) { (void)iter.filePath() ; }
106 /// \endcode
107 ///
108 class G::DirectoryIterator
109 {
110 public:
111 	DirectoryIterator( const Directory & dir , const std::string & wc ) ;
112 		///< Constructor taking a directory reference and
113 		///< a wildcard specification. Iterates over all
114 		///< matching files in the directory.
115 		///<
116 		///< This constructor overload may not be implemented
117 		///< on all platforms, so prefer DirectoryList::readType()
118 		///< where possible.
119 
120 	explicit DirectoryIterator( const Directory & dir ) ;
121 		///< Constructor taking a directory reference.
122 		///< Iterates over all files in the directory.
123 
124 	~DirectoryIterator() ;
125 		///< Destructor.
126 
127 	bool error() const ;
128 		///< Returns true on error. The caller should stop the iteration.
129 
130 	bool more() ;
131 		///< Returns true if more and advances by one.
132 
133 	bool isDir() const ;
134 		///< Returns true if the current item is a directory.
135 
136 	std::string modificationTimeString() const ;
137 		///< Returns the last-modified time for the file in an undefined
138 		///< format -- used for comparison.
139 
140 	std::string sizeString() const ;
141 		///< Returns the file size as a decimal string. The value
142 		///< may be more than 32 bits. See also class G::Number.
143 
144 	Path filePath() const ;
145 		///< Returns the path of the current item.
146 
147 	Path fileName() const ;
148 		///< Returns the name of the current item.
149 
150 private:
151 	DirectoryIterator( const DirectoryIterator & ) ; // not implemented
152 	void operator=( const DirectoryIterator & ) ; // not implemented
153 
154 private:
155 	DirectoryIteratorImp * m_imp ;
156 } ;
157 
158 /// \class G::DirectoryList
159 /// A Directory iterator that does all file i/o in one go.
160 /// This is useful, compared to DirectoryIterator, while temporarily
161 /// adopting additional process privileges to read a directory.
162 /// The implementation uses DirectoryIterator.
163 ///
164 class G::DirectoryList
165 {
166 public:
167 	DirectoryList() ;
168 		///< Default constructor for an empty list. Initialise with a
169 		///< read method.
170 
171 	void readAll( const Path & dir ) ;
172 		///< An initialiser that is to be used after default
173 		///< construction. Reads all files in the directory.
174 		///< All file i/o is done in readAll()/readType().
175 
176 	void readType( const Path & dir , const std::string & suffix , unsigned int limit = 0U ) ;
177 		///< An initialiser that is to be used after default
178 		///< construction. Reads all files that have the given
179 		///< suffix. All file i/o is done in readAll()/readType().
180 
181 	bool more() ;
182 		///< Returns true if more and advances by one.
183 
184 	bool isDir() const ;
185 		///< Returns true if the current item is a directory.
186 
187 	G::Path filePath() const ;
188 		///< Returns the current path.
189 
190 	G::Path fileName() const ;
191 		///< Returns the current filename.
192 
193 private:
194 	DirectoryList( const DirectoryList & ) ;
195 	void operator=( const DirectoryList & ) ;
196 
197 private:
198 	bool m_first ;
199 	unsigned int m_index ;
200 	std::vector<int> m_is_dir ;
201 	std::vector<G::Path> m_path ;
202 	std::vector<G::Path> m_name ;
203 } ;
204 
205 #endif
206