gdirectory_unix_glob.cpp
Go to the documentation of this file.
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 // gdirectory_unix_glob.cpp
19 //
20 
21 #include "gdef.h"
22 #include "gdirectory.h"
23 #include "gfile.h"
24 #include "gdebug.h"
25 #include "glog.h"
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <dirent.h>
29 #include <glob.h>
30 #include <fcntl.h>
31 
32 namespace G
33 {
34  class DirectoryIteratorImp ;
35 }
36 
37 // ===
38 
43 {
44 private:
45  glob_t m_glob ;
46  Directory m_dir ;
47  bool m_first ;
48  size_t m_index ; // 'int' on some systems
49  bool m_error ;
50 
51 public:
52  DirectoryIteratorImp( const Directory &dir , const std::string & wildcard ) ;
54  bool isDir() const ;
55  bool more() ;
56  bool error() const ;
57  std::string modificationTimeString() const ;
58  std::string sizeString() const ;
59  Path filePath() const ;
60  Path fileName() const ;
61 
62 private:
63  void operator=( const DirectoryIteratorImp & ) ;
65 } ;
66 
67 // ===
68 
70  m_imp( new DirectoryIteratorImp(dir,std::string()) )
71 {
72 }
73 
74 G::DirectoryIterator::DirectoryIterator( const Directory & dir , const std::string & wc ) :
75  m_imp( new DirectoryIteratorImp(dir,wc) )
76 {
77  // note that this overload is rarely used -- if glob() is
78  // unavailable and this overload is never called then the
79  // DirectoryIteratorImp class can be rewritten with
80  // just a default constructor that uses readdir()
81 }
82 
84 {
85  return m_imp->error() ;
86 }
87 
89 {
90  return m_imp->more() ;
91 }
92 
94 {
95  return m_imp->filePath() ;
96 }
97 
99 {
100  return m_imp->fileName() ;
101 }
102 
104 {
105  return m_imp->isDir() ;
106 }
107 
109 {
110  return m_imp->modificationTimeString() ;
111 }
112 
114 {
115  return m_imp->sizeString() ;
116 }
117 
119 {
120  delete m_imp ;
121 }
122 
123 // ===
124 
125 extern "C"
126 {
127  int gdirectory_unix_on_error_( const char * , int ) ;
128  int gdirectory_unix_on_error_( const char * , int )
129  {
130  const int abort = 1 ;
131  return abort ;
132  }
133 }
134 
135 G::DirectoryIteratorImp::DirectoryIteratorImp( const Directory & dir , const std::string & wildcard ) :
136  m_dir(dir) ,
137  m_first(true) ,
138  m_index(0) ,
139  m_error(false)
140 {
141  m_glob.gl_pathc = 0 ;
142  m_glob.gl_pathv = NULL ;
143 
144  Path wild_path( dir.path() , wildcard.empty() ? std::string("*") : wildcard ) ;
145 
146  int flags = 0 | GLOB_ERR ;
147  int error = ::glob( wild_path.str().c_str() , flags , gdirectory_unix_on_error_ , &m_glob ) ;
148  if( error || m_glob.gl_pathv == NULL )
149  m_error = true ;
150 }
151 
153 {
154  return m_error ;
155 }
156 
158 {
159  if( m_error )
160  return false ;
161 
162  if( ! m_first )
163  m_index++ ;
164  m_first = false ;
165 
166  if( m_index >= static_cast<size_t>(m_glob.gl_pathc) )
167  return false ;
168 
169  return true ;
170 }
171 
173 {
174  const bool sane =
175  m_index < static_cast<size_t>(m_glob.gl_pathc) &&
176  m_glob.gl_pathv != NULL &&
177  m_glob.gl_pathv[m_index] != NULL ;
178  const char * file_path = sane ? m_glob.gl_pathv[m_index] : "" ;
179  return Path( file_path ) ;
180 }
181 
183 {
184  return Path( filePath().basename() ) ;
185 }
186 
188 {
189  Directory dir( filePath().str() ) ;
190  return dir.valid() ;
191 }
192 
194 {
195  if( ! m_error )
196  ::globfree( &m_glob ) ;
197 }
198 
200 {
201  return std::string() ; // for now
202 }
203 
205 {
206  std::string s = G::File::sizeString( filePath() ) ;
207  return s.empty() ? std::string("0") : s ;
208 }
209 
std::string sizeString() const
Returns the file size as a decimal string.
std::string modificationTimeString() const
std::string sizeString() const
Path filePath() const
Returns the path of the current item.
DirectoryIterator(const Directory &dir, const std::string &wc)
Constructor taking a directory reference and a wildcard specification.
Path path() const
Returns the directory's path.
Definition: gdirectory.cpp:69
bool valid(bool for_creating_files=false) const
Returns true if the object represents a valid directory.
An encapsulation of a file system directory which allows for iterating through the set of contained f...
Definition: gdirectory.h:46
Path fileName() const
Returns the name of the current item.
Low-level classes.
int gdirectory_unix_on_error_(const char *, int)
DirectoryIteratorImp(const Directory &dir, const std::string &wildcard)
bool more()
Returns true if more and advances by one.
bool isDir() const
Returns true if the current item is a directory.
std::string modificationTimeString() const
Returns the last-modified time for the file in an undefined format – used for comparison.
static std::string sizeString(const Path &file)
Returns the file's size in string format.
Definition: gfile_unix.cpp:67
A pimple-pattern implementation class for DirectoryIterator.
bool error() const
Returns true on error. The caller should stop the iteration.
A Path object represents a file system path.
Definition: gpath.h:44