32#ifndef INVALID_FILE_ATTRIBUTES
33#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
38 class DirectoryIteratorImp ;
43 DWORD attributes = ::GetFileAttributesA( m_path.
cstr() ) ;
44 if( attributes == INVALID_FILE_ATTRIBUTES )
46 DWORD e = ::GetLastError() ;
47 if( e == ERROR_ACCESS_DENIED || e == ERROR_NETWORK_ACCESS_DENIED )
51 return ( attributes & FILE_ATTRIBUTE_DIRECTORY ) ? 0 : ENOTDIR ;
56 Path path( m_path , filename.empty() ? tmp() : filename ) ;
65class G::DirectoryIteratorImp
68 explicit DirectoryIteratorImp(
const Directory &dir ) ;
69 ~DirectoryIteratorImp() ;
73 std::string sizeString()
const ;
74 Path filePath()
const ;
75 std::string fileName()
const ;
78 DirectoryIteratorImp(
const DirectoryIteratorImp & ) = delete ;
79 DirectoryIteratorImp( DirectoryIteratorImp && ) = delete ;
80 DirectoryIteratorImp & operator=(
const DirectoryIteratorImp & ) = delete ;
81 DirectoryIteratorImp & operator=( DirectoryIteratorImp && ) = delete ;
84 WIN32_FIND_DATAA m_context ;
94 m_imp(
std::make_unique<DirectoryIteratorImp>(dir))
100 return m_imp->error() ;
105 return m_imp->more() ;
110 return m_imp->filePath() ;
115 return m_imp->fileName() ;
120 return m_imp->isDir() ;
130 return m_imp->sizeString() ;
138G::DirectoryIteratorImp::DirectoryIteratorImp(
const Directory & dir ) :
143 m_handle = FindFirstFileA( (dir.path()+
"*").cstr() , &m_context ) ;
144 if( m_handle == INVALID_HANDLE_VALUE )
146 DWORD err = ::GetLastError() ;
147 if( err != ERROR_FILE_NOT_FOUND )
152bool G::DirectoryIteratorImp::error()
const
157bool G::DirectoryIteratorImp::more()
159 if( m_handle == INVALID_HANDLE_VALUE )
165 if( std::string(m_context.cFileName) !=
"." && std::string(m_context.cFileName) !=
".." )
171 bool rc = FindNextFileA( m_handle , &m_context ) != 0 ;
174 DWORD err = ::GetLastError() ;
175 if( err != ERROR_NO_MORE_FILES )
178 FindClose( m_handle ) ;
179 m_handle = INVALID_HANDLE_VALUE ;
184 if( std::string(m_context.cFileName) !=
"." && std::string(m_context.cFileName) !=
".." )
191G::Path G::DirectoryIteratorImp::filePath()
const
193 G_ASSERT( m_handle != INVALID_HANDLE_VALUE ) ;
194 return m_dir.path() + m_context.cFileName ;
197std::string G::DirectoryIteratorImp::fileName()
const
199 G_ASSERT( m_handle != INVALID_HANDLE_VALUE ) ;
200 return m_context.cFileName ;
203bool G::DirectoryIteratorImp::isDir()
const
205 return !! ( m_context.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ;
208G::DirectoryIteratorImp::~DirectoryIteratorImp()
210 if( m_handle != INVALID_HANDLE_VALUE )
211 FindClose( m_handle ) ;
214std::string G::DirectoryIteratorImp::sizeString()
const
216 const DWORD & hi = m_context.nFileSizeHigh ;
217 const DWORD & lo = m_context.nFileSizeLow ;
227 int i =
static_cast<int>( n % 10 ) ;
228 char c =
static_cast<char>(
'0' + i ) ;
229 s.insert( 0U , 1U , c ) ;
DirectoryIterator(const Directory &dir)
Constructor taking a directory reference.
std::string fileName() const
Returns the name of the current item.
bool error() const
Returns true on error. The caller should stop the iteration.
std::string sizeString() const
Returns the file size as a decimal string.
bool isLink() const
Returns true if the current item is a symlink.
~DirectoryIterator()
Destructor.
bool isDir() const
Returns true if the current item is a directory.
bool more()
Returns true if more and advances by one.
Path filePath() const
Returns the path of the current item.
int usable(bool for_creating_files=false) const
Returns zero if the object represents a valid directory with permissions that dont disallow reading o...
bool writeable(const std::string &probe_filename=tmp()) const
Tries to create and then delete an empty test file in the directory.
static bool probe(const char *) noexcept
Creates and deletes a temporary probe file.
A Path object represents a file system path.
const char * cstr() const noexcept
Returns the path string.