From c02a14b1b77e38fe30e215afec0b72c88b97be8e Mon Sep 17 00:00:00 2001 From: zvon Date: Mon, 1 Apr 2019 20:18:47 +0200 Subject: [PATCH] Split filesystem library into 2 files based on operating system --- Makefile | 24 +++--- filesystem.cpp | 174 ----------------------------------------- filesystem.hpp | 85 ++++++++------------ functions.cpp | 23 +++--- functions.hpp | 10 +-- unix/filesystem.cpp | 84 ++++++++++++++++++++ windows/filesystem.cpp | 100 +++++++++++++++++++++++ 7 files changed, 245 insertions(+), 255 deletions(-) delete mode 100644 filesystem.cpp create mode 100644 unix/filesystem.cpp create mode 100644 windows/filesystem.cpp diff --git a/Makefile b/Makefile index 9e484e1..18cabd9 100644 --- a/Makefile +++ b/Makefile @@ -20,11 +20,11 @@ install_gui: gui install -d $(PREFIX)/ install -m 755 tv_rename_gui $(PREFIX)/ -tv_rename: functions.o filesystem.o network.o tv_rename.o main.cpp - $(CXX) $(CFLAGS) -o tv_rename main.cpp tv_rename.o functions.o filesystem.o network.o -lcurl +tv_rename: functions.o filesystem_u.o network.o tv_rename.o main.cpp + $(CXX) $(CFLAGS) -o tv_rename main.cpp tv_rename.o functions.o filesystem_u.o network.o -lcurl -filesystem.o: filesystem.cpp - $(CXX) $(CFLAGS) -c filesystem.cpp +filesystem_u.o: unix/filesystem.cpp + $(CXX) $(CFLAGS) -c unix/filesystem.cpp -o filesystem_u.o functions.o: functions.cpp $(CXX) $(CFLAGS) -c functions.cpp @@ -38,11 +38,11 @@ tv_rename.o: tv_rename.cpp .PHONY: gui gui: tv_rename_gui -tv_rename_gui: gui.cpp mainwindow.cpp seasonwindow.cpp network.o functions_gui.o filesystem_gui.o tv_rename_gui.o - $(CXX) $(CFLAGS) -o tv_rename_gui gui.cpp mainwindow.cpp seasonwindow.cpp network.o functions_gui.o filesystem_gui.o tv_rename_gui.o `pkg-config gtkmm-3.0 --cflags --libs` -lcurl -DGUI +tv_rename_gui: gui.cpp mainwindow.cpp seasonwindow.cpp network.o functions_gui.o filesystem_u_gui.o tv_rename_gui.o + $(CXX) $(CFLAGS) -o tv_rename_gui gui.cpp mainwindow.cpp seasonwindow.cpp network.o functions_gui.o filesystem_u_gui.o tv_rename_gui.o `pkg-config gtkmm-3.0 --cflags --libs` -lcurl -DGUI -filesystem_gui.o: filesystem.cpp - $(CXX) $(CFLAGS) -c filesystem.cpp -o filesystem_gui.o -DGUI +filesystem_u_gui.o: unix/filesystem.cpp + $(CXX) $(CFLAGS) -c unix/filesystem.cpp -o filesystem_u_gui.o -DGUI functions_gui.o: functions.cpp $(CXX) $(CFLAGS) -c functions.cpp -o functions_gui.o -DGUI @@ -54,14 +54,14 @@ tv_rename_gui.o: tv_rename.cpp .PHONY: windows windows: tv_rename.exe -tv_rename.exe: tv_rename.cpp filesystem.cpp functions.cpp network.cpp main.cpp - $(CXX) -MD -EHsc -Fe"tv_rename" tv_rename.cpp filesystem.cpp functions.cpp network.cpp main.cpp -D_WIN32 -DUNICODE -link wininet.lib shlwapi.lib +tv_rename.exe: tv_rename.cpp functions.cpp windows/filesystem.cpp network.cpp main.cpp + $(CXX) -MD -EHsc -Fe"tv_rename" tv_rename.cpp windows/filesystem.cpp functions.cpp network.cpp main.cpp -D_WIN32 -DUNICODE -link wininet.lib shlwapi.lib .PHONY: windows_gui windows_gui: tv_rename_gui.exe -tv_rename_gui.exe: tv_rename_gui.res tv_rename_gui.cpp tv_rename.cpp filesystem.cpp functions.cpp network.cpp - $(CXX) -MD -EHsc -Fe"tv_rename_gui" tv_rename_gui.cpp tv_rename.cpp filesystem.cpp functions.cpp network.cpp -D_WIN32 -DUNICODE -DGUI -link wininet.lib shlwapi.lib ole32.lib shell32.lib gdi32.lib user32.lib tv_rename_gui.res +tv_rename_gui.exe: tv_rename_gui.res tv_rename_gui.cpp tv_rename.cpp windows/filesystem.cpp functions.cpp network.cpp + $(CXX) -MD -EHsc -Fe"tv_rename_gui" tv_rename_gui.cpp tv_rename.cpp windows/filesystem.cpp functions.cpp network.cpp -D_WIN32 -DUNICODE -DGUI -link wininet.lib shlwapi.lib ole32.lib shell32.lib gdi32.lib user32.lib tv_rename_gui.res tv_rename_gui.res: tv_rename_gui.rc rc tv_rename_gui.rc diff --git a/filesystem.cpp b/filesystem.cpp deleted file mode 100644 index d91c724..0000000 --- a/filesystem.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#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 ); -} diff --git a/filesystem.hpp b/filesystem.hpp index 8db819b..4a2cfa6 100644 --- a/filesystem.hpp +++ b/filesystem.hpp @@ -42,54 +42,20 @@ bool rename( const string &file_a, const string &file_b ); class Directory { public: - Directory( const string &path_ ) : dir_path( path_ ) { -#ifdef _WIN32 - // need to append \\* for windows to search files in directory - dir_path.append( L"\\*" ); -#endif - } + Directory( const string &path_ ); Directory() = delete; Directory( const Directory &d ) = default; Directory( Directory &&d ) = default; class Iterator { public: + Iterator( const Directory &d_ ); + ~Iterator(); + #ifdef _WIN32 - Iterator( const Directory &d_ ) { - hFind = FindFirstFileW( d_.path(), &data ); - if ( hFind != INVALID_HANDLE_VALUE ) { - if ( !wcscmp( data.cFileName, L"." ) || - !wcscmp( data.cFileName, L".." ) ) { - ++( *this ); - } - } else { - ended = true; - } - } - // this is definitely not a good way to create the "end" iterator - // but it was the only way I thought of with my limited knowledge of - // windows.h - Iterator( bool ended_ ) : ended( ended_ ) {} - - ~Iterator() { - if ( hFind ) - FindClose( hFind ); - } + Iterator( bool ended_ ); #else - Iterator( const Directory &d_ ) : d( opendir( d_.path() ) ) { - current_entry = readdir( d ); - if ( current_entry != nullptr && - ( !strcmp( current_entry->d_name, "." ) || - !strcmp( current_entry->d_name, ".." ) ) ) - ++( *this ); - } - - Iterator( const Directory &d_, const struct dirent *current_entry_ ) - : d( opendir( d_.path() ) ), current_entry( current_entry_ ) {} - - ~Iterator() { - closedir( d ); - } + Iterator( const Directory &d_, const struct dirent *current_entry_ ); #endif Iterator() = delete; @@ -102,11 +68,17 @@ public: Iterator &operator++(); - Iterator operator++( int ); - bool operator==( const Iterator &i_other ) const; - bool operator!=( const Iterator &i_other ) const; + Iterator operator++( int ) { + Iterator ret( *this ); + operator++(); + return ret; + } + + bool operator!=( const Iterator &i_other ) const { + return !( i_other == *this ); + } private: #ifndef _WIN32 @@ -122,19 +94,30 @@ public: using iterator = Iterator; using const_iterator = Iterator; - iterator begin(); - - const_iterator begin() const; - - const_iterator cbegin() const; - iterator end(); const_iterator end() const; - const_iterator cend() const; + iterator begin() { + return Iterator( *this ); + } + + const_iterator begin() const { + return Iterator( *this ); + } + + const_iterator cbegin() const { + return begin(); + } + + const_iterator cend() const { + return end(); + } + + const char_t *path() const { + return dir_path.c_str(); + } - const char_t *path() const; private: string dir_path; diff --git a/functions.cpp b/functions.cpp index 66a3152..47defb4 100644 --- a/functions.cpp +++ b/functions.cpp @@ -11,23 +11,22 @@ #include #include -#else +#else // UNIX #ifndef GUI -#include #include #include #include -#else +#else // UNIX and GUI #include #include #endif // GUI -#endif // _WIN32 +#endif // UNIX #include "filesystem.hpp" #include "functions.hpp" @@ -40,7 +39,7 @@ constexpr const char_t *dir_divider = L"\\"; -#else +#else // UNIX #define TEXT( a ) a @@ -50,7 +49,7 @@ constexpr const char_t *dir_divider = L"\\"; constexpr const char_t *dir_divider = "/"; -#endif // _WIN32 +#endif // UNIX #ifndef GUI @@ -389,21 +388,23 @@ bool findLanguage( const char_t *language ) { return false; } -#else +#else // GUI // functions that are needed for GUI but not for CLI // get possible shows for search query in `show` std::vector< std::pair< string, string > > getPossibleShows( string show, const string &language, Curl &c ) { + // encode show name so it can be resolved as url std::replace( show.begin(), show.end(), ' ', '+' ); + show = encodeUrl( show ); #ifdef _WIN32 auto source_code = utf8_to_wstring( c.execute( TEXT( "https://www.thetvdb.com/search?q=" ) + - encodeUrl( show ) + TEXT( "&l=" ) + language ) ); + show + TEXT( "&l=" ) + language ) ); #else auto source_code = c.execute( TEXT( "https://www.thetvdb.com/search?q=" ) + - encodeUrl( show ) + TEXT( "&l=" ) + language ); + show + TEXT( "&l=" ) + language ); #endif size_t pos{}; std::vector< std::pair< string, string > > urls; @@ -443,7 +444,7 @@ string userHome() { return user_passwd->pw_dir; } -#else +#else // UNIX // get user's %APPDATA% folder location string userHome() { @@ -457,7 +458,7 @@ string userHome() { return L""; } -#endif +#endif // UNIX #endif // ndef GUI diff --git a/functions.hpp b/functions.hpp index d059aed..9a1d2a6 100644 --- a/functions.hpp +++ b/functions.hpp @@ -19,6 +19,8 @@ using string = std::wstring; using char_t = wchar_t; +std::wstring utf8_to_wstring( const std::string &utf8 ); + #else using string = std::string; @@ -26,12 +28,6 @@ using char_t = char; #endif -#ifdef _WIN32 - -std::wstring utf8_to_wstring( const std::string &utf8 ); - -#endif - #ifndef GUI // CLI functions @@ -58,7 +54,7 @@ std::vector< std::pair< string, string > > getPossibleShows( string show, const string &language, Curl &c ); string userHome(); -#endif +#endif // GUI void iterateFS( std::map< int, std::set< string > > &seasons, const string &path ); diff --git a/unix/filesystem.cpp b/unix/filesystem.cpp new file mode 100644 index 0000000..9918d12 --- /dev/null +++ b/unix/filesystem.cpp @@ -0,0 +1,84 @@ +#include +#include "../filesystem.hpp" + +FSLib::Directory::Directory( const string &path_ ) : dir_path( path_ ) {} + +FSLib::Directory::Iterator::Iterator( const Directory &d_ ) : d( opendir( d_.path() ) ) { + current_entry = readdir( d ); + if ( current_entry != nullptr && + ( !strcmp( current_entry->d_name, "." ) || + !strcmp( current_entry->d_name, ".." ) ) ) + ++( *this ); +} + +FSLib::Directory::Iterator::Iterator( const Directory &d_, const struct dirent *current_entry_ ) + : d( opendir( d_.path() ) ), current_entry( current_entry_ ) {} + +FSLib::Directory::Iterator::~Iterator() { + closedir( d ); +} + +#ifndef GUI // these functions aren't needed in GUI + +bool FSLib::exists( const string &path ) { + struct stat path_stat; + return stat( path.c_str(), &path_stat ) == 0; +} + +string FSLib::canonical( const string &path ) { + + char_t *canonical_path = new char_t[PATH_MAX]; + + auto failed = realpath( path.c_str(), canonical_path ) == nullptr; + + 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 ) { + struct stat path_stat; + + stat( path.c_str(), &path_stat ); + + return S_ISDIR( path_stat.st_mode ); +} + +bool FSLib::rename( const string &file_a, const string &file_b ) { + return ::rename( file_a.c_str(), file_b.c_str() ) == 0; +} + +FSLib::Directory::iterator FSLib::Directory::end() { + return Iterator( *this, nullptr ); +} + +FSLib::Directory::const_iterator FSLib::Directory::end() const { + return Iterator( *this, nullptr ); +} + +char_t const *FSLib::Directory::Iterator::operator*() const { + return current_entry->d_name; +} + +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; +} + +bool FSLib::Directory::Iterator::operator==( const Iterator &i_other ) const { + return i_other.current_entry == current_entry; +} diff --git a/windows/filesystem.cpp b/windows/filesystem.cpp new file mode 100644 index 0000000..1844311 --- /dev/null +++ b/windows/filesystem.cpp @@ -0,0 +1,100 @@ +#include +#include +#include "../filesystem.hpp" + +FSLib::Directory::Directory( const string &path_ ) : dir_path( path_ ) { + // need to append \\* for windows to search files in directory + dir_path.append( L"\\*" ); +} + +FSLib::Directory::Iterator::Iterator( const Directory &d_ ) { + hFind = FindFirstFileW( d_.path(), &data ); + if ( hFind != INVALID_HANDLE_VALUE ) { + if ( !wcscmp( data.cFileName, L"." ) || + !wcscmp( data.cFileName, L".." ) ) { + ++( *this ); + } + } else { + ended = true; + } +} + +FSLib::Directory::Iterator::~Iterator() { + if ( hFind ) + FindClose( hFind ); +} + +// this is definitely not a good way to create the "end" iterator +// but it was the only way I thought of with my limited knowledge of +// windows.h +FSLib::Directory::Iterator::Iterator( bool ended_ ) : ended( ended_ ) {} + +#ifndef GUI // these functions aren't needed in GUI + +bool FSLib::exists( const string &path ) { + struct _stat path_stat; + return _wstat( path.c_str(), &path_stat ) == 0; +} + +string FSLib::canonical( const string &path ) { + char_t *canonical_path = new char_t[MAX_PATH]; + + auto failed = !PathCanonicalizeW( canonical_path, path.c_str() ); + + 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 ) { + struct _stat path_stat; + + _wstat( path.c_str(), &path_stat ); + + return path_stat.st_mode & _S_IFDIR; +} + +bool FSLib::rename( const string &file_a, const string &file_b ) { + return MoveFileExW( file_a.c_str(), file_b.c_str(), + MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING ); +} + +FSLib::Directory::iterator FSLib::Directory::end() { + return Iterator( true ); +} + +FSLib::Directory::const_iterator FSLib::Directory::end() const { + return Iterator( true ); +} + +const char_t *FSLib::Directory::path() const { + return dir_path.c_str(); +} + +char_t const *FSLib::Directory::Iterator::operator*() const { + return data.cFileName; +} + +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; +} + +bool FSLib::Directory::Iterator::operator==( const Iterator &i_other ) const { + return i_other.ended == ended; +}