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_noglob.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/types.h>
27 #include <sys/stat.h>
28 #include <dirent.h>
29 #include <unistd.h>
30 #include <dirent.h>
31 #include <fcntl.h>
32 
33 namespace G
34 {
35 	class DirectoryIteratorImp ;
36 }
37 
38 // ===
39 
40 /// \class G::DirectoryIteratorImp
41 /// A pimple-pattern implementation class for DirectoryIterator.
42 ///
43 class G::DirectoryIteratorImp
44 {
45 private:
46 	DIR * m_d ;
47 	struct dirent * m_dp ;
48 	Directory m_dir ;
49 	bool m_error ;
50 
51 public:
52 	explicit DirectoryIteratorImp( const Directory & dir ) ;
53 	~DirectoryIteratorImp() ;
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 & ) ;
64 	DirectoryIteratorImp( const DirectoryIteratorImp & ) ;
65 } ;
66 
67 // ===
68 
DirectoryIterator(const Directory & dir)69 G::DirectoryIterator::DirectoryIterator( const Directory & dir ) :
70 	m_imp( new DirectoryIteratorImp(dir) )
71 {
72 }
73 
error() const74 bool G::DirectoryIterator::error() const
75 {
76 	return m_imp->error() ;
77 }
78 
more()79 bool G::DirectoryIterator::more()
80 {
81 	return m_imp->more() ;
82 }
83 
filePath() const84 G::Path G::DirectoryIterator::filePath() const
85 {
86 	return m_imp->filePath() ;
87 }
88 
fileName() const89 G::Path G::DirectoryIterator::fileName() const
90 {
91 	return m_imp->fileName() ;
92 }
93 
isDir() const94 bool G::DirectoryIterator::isDir() const
95 {
96 	return m_imp->isDir() ;
97 }
98 
modificationTimeString() const99 std::string G::DirectoryIterator::modificationTimeString() const
100 {
101 	return m_imp->modificationTimeString() ;
102 }
103 
sizeString() const104 std::string G::DirectoryIterator::sizeString() const
105 {
106 	return m_imp->sizeString() ;
107 }
108 
~DirectoryIterator()109 G::DirectoryIterator::~DirectoryIterator()
110 {
111 	delete m_imp ;
112 }
113 
114 // ===
115 
DirectoryIteratorImp(const Directory & dir)116 G::DirectoryIteratorImp::DirectoryIteratorImp( const Directory & dir ) :
117 	m_d(NULL) ,
118 	m_dp(NULL) ,
119 	m_dir(dir) ,
120 	m_error(true)
121 {
122 	m_d = ::opendir( dir.path().str().c_str() ) ;
123 	m_error = m_d == NULL ;
124 }
125 
error() const126 bool G::DirectoryIteratorImp::error() const
127 {
128 	return m_error ;
129 }
130 
more()131 bool G::DirectoryIteratorImp::more()
132 {
133 	if( !m_error )
134 	{
135 		m_dp = ::readdir( m_d ) ;
136 		m_error = m_dp == NULL ;
137 	}
138 	return !m_error ;
139 }
140 
filePath() const141 G::Path G::DirectoryIteratorImp::filePath() const
142 {
143 	return m_dir.path() + fileName().str() ;
144 }
145 
fileName() const146 G::Path G::DirectoryIteratorImp::fileName() const
147 {
148 	return Path( m_dp == NULL ? "" : m_dp->d_name ) ;
149 }
150 
isDir() const151 bool G::DirectoryIteratorImp::isDir() const
152 {
153 	struct stat statbuf ;
154 	return ::stat( filePath().str().c_str() , &statbuf ) == 0 && (statbuf.st_mode & S_IFDIR) ;
155 }
156 
~DirectoryIteratorImp()157 G::DirectoryIteratorImp::~DirectoryIteratorImp()
158 {
159 	if( m_d != NULL )
160 		::closedir( m_d ) ;
161 }
162 
modificationTimeString() const163 std::string G::DirectoryIteratorImp::modificationTimeString() const
164 {
165 	return std::string() ; // for now
166 }
167 
sizeString() const168 std::string G::DirectoryIteratorImp::sizeString() const
169 {
170 	std::string s = G::File::sizeString( filePath() ) ;
171 	return s.empty() ? std::string("0") : s ;
172 }
173 
174