#include #include #include #ifdef _WIN32 #include #include #endif #include "filesystem.hpp" #ifdef _WIN32 #define S_ISDIR( a ) a & _S_IFDIR using stat_t = struct _stat; #else using stat_t = struct stat; #endif // _WIN32 #ifndef GUI // these functions aren't needed in GUI bool FSLib::exists( const string &path ) { stat_t path_stat; #ifdef _WIN32 return _wstat( path.c_str(), &path_stat ) == 0; #else return stat( path.c_str(), &path_stat ) == 0; #endif } string FSLib::canonical( const string &path ) { #ifdef _WIN32 auto PATH_MAX = MAX_PATH; #endif char_t *canonical_path = new char_t[PATH_MAX]; #ifdef _WIN32 auto failed = !PathCanonicalizeW( canonical_path, path.c_str() ); #else auto failed = realpath( path.c_str(), canonical_path ) == nullptr; #endif if ( failed ) { delete[] canonical_path; return string(); } string canonical_string{ canonical_path }; delete[] canonical_path; return canonical_string; } #endif // ndef GUI bool FSLib::isDirectory( const string &path ) { stat_t path_stat; #ifdef _WIN32 _wstat( path.c_str(), &path_stat ); #else stat( path.c_str(), &path_stat ); #endif return S_ISDIR( path_stat.st_mode ); } bool FSLib::rename( const string &file_a, const string &file_b ) { #ifdef _WIN32 return MoveFileExW( file_a.c_str(), file_b.c_str(), MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING ); #else return ::rename( file_a.c_str(), file_b.c_str() ) == 0; #endif } FSLib::Directory::iterator FSLib::Directory::begin() { return Iterator( *this ); } FSLib::Directory::const_iterator FSLib::Directory::begin() const { return Iterator( *this ); } FSLib::Directory::const_iterator FSLib::Directory::cbegin() const { return begin(); } FSLib::Directory::iterator FSLib::Directory::end() { #ifdef _WIN32 return Iterator( true ); #else return Iterator( *this, nullptr ); #endif } FSLib::Directory::const_iterator FSLib::Directory::end() const { #ifdef _WIN32 return Iterator( true ); #else return Iterator( *this, nullptr ); #endif } FSLib::Directory::const_iterator FSLib::Directory::cend() const { return end(); } const char_t *FSLib::Directory::path() const { return dir_path.c_str(); } char_t const *FSLib::Directory::Iterator::operator*() const { #ifdef _WIN32 return data.cFileName; #else return current_entry->d_name; #endif } #ifdef _WIN32 FSLib::Directory::Iterator &FSLib::Directory::Iterator::operator++() { if ( ended == true ) return *this; // skip . and .. if ( FindNextFileW( hFind, &data ) == 0 ) { ended = true; } else if ( !wcscmp( data.cFileName, L"." ) || !wcscmp( data.cFileName, L".." ) ) { return operator++(); } return *this; } #else FSLib::Directory::Iterator &FSLib::Directory::Iterator::operator++() { if ( current_entry == nullptr ) return *this; current_entry = readdir( d ); // skip . and .. if ( current_entry != nullptr && ( !strcmp( current_entry->d_name, "." ) || !strcmp( current_entry->d_name, ".." ) ) ) return operator++(); return *this; } #endif FSLib::Directory::Iterator FSLib::Directory::Iterator::operator++( int ) { Iterator ret( *this ); operator++(); return ret; } bool FSLib::Directory::Iterator::operator==( const Iterator &i_other ) const { #ifdef _WIN32 return i_other.ended == ended; #else return i_other.current_entry == current_entry; #endif } bool FSLib::Directory::Iterator::operator!=( const Iterator &i_other ) const { return !( i_other == *this ); }