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)69G::DirectoryIterator::DirectoryIterator( const Directory & dir ) : 70 m_imp( new DirectoryIteratorImp(dir) ) 71 { 72 } 73 error() const74bool G::DirectoryIterator::error() const 75 { 76 return m_imp->error() ; 77 } 78 more()79bool G::DirectoryIterator::more() 80 { 81 return m_imp->more() ; 82 } 83 filePath() const84G::Path G::DirectoryIterator::filePath() const 85 { 86 return m_imp->filePath() ; 87 } 88 fileName() const89G::Path G::DirectoryIterator::fileName() const 90 { 91 return m_imp->fileName() ; 92 } 93 isDir() const94bool G::DirectoryIterator::isDir() const 95 { 96 return m_imp->isDir() ; 97 } 98 modificationTimeString() const99std::string G::DirectoryIterator::modificationTimeString() const 100 { 101 return m_imp->modificationTimeString() ; 102 } 103 sizeString() const104std::string G::DirectoryIterator::sizeString() const 105 { 106 return m_imp->sizeString() ; 107 } 108 ~DirectoryIterator()109G::DirectoryIterator::~DirectoryIterator() 110 { 111 delete m_imp ; 112 } 113 114 // === 115 DirectoryIteratorImp(const Directory & dir)116G::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() const126bool G::DirectoryIteratorImp::error() const 127 { 128 return m_error ; 129 } 130 more()131bool 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() const141G::Path G::DirectoryIteratorImp::filePath() const 142 { 143 return m_dir.path() + fileName().str() ; 144 } 145 fileName() const146G::Path G::DirectoryIteratorImp::fileName() const 147 { 148 return Path( m_dp == NULL ? "" : m_dp->d_name ) ; 149 } 150 isDir() const151bool 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()157G::DirectoryIteratorImp::~DirectoryIteratorImp() 158 { 159 if( m_d != NULL ) 160 ::closedir( m_d ) ; 161 } 162 modificationTimeString() const163std::string G::DirectoryIteratorImp::modificationTimeString() const 164 { 165 return std::string() ; // for now 166 } 167 sizeString() const168std::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