Split filesystem library into 2 files based on operating system

This commit is contained in:
zvon 2019-04-01 20:18:47 +02:00
parent b3db96d485
commit c02a14b1b7
7 changed files with 245 additions and 255 deletions

View File

@ -20,11 +20,11 @@ install_gui: gui
install -d $(PREFIX)/ install -d $(PREFIX)/
install -m 755 tv_rename_gui $(PREFIX)/ install -m 755 tv_rename_gui $(PREFIX)/
tv_rename: functions.o filesystem.o network.o tv_rename.o main.cpp 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.o network.o -lcurl $(CXX) $(CFLAGS) -o tv_rename main.cpp tv_rename.o functions.o filesystem_u.o network.o -lcurl
filesystem.o: filesystem.cpp filesystem_u.o: unix/filesystem.cpp
$(CXX) $(CFLAGS) -c filesystem.cpp $(CXX) $(CFLAGS) -c unix/filesystem.cpp -o filesystem_u.o
functions.o: functions.cpp functions.o: functions.cpp
$(CXX) $(CFLAGS) -c functions.cpp $(CXX) $(CFLAGS) -c functions.cpp
@ -38,11 +38,11 @@ tv_rename.o: tv_rename.cpp
.PHONY: gui .PHONY: gui
gui: tv_rename_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 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_gui.o tv_rename_gui.o `pkg-config gtkmm-3.0 --cflags --libs` -lcurl -DGUI $(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 filesystem_u_gui.o: unix/filesystem.cpp
$(CXX) $(CFLAGS) -c filesystem.cpp -o filesystem_gui.o -DGUI $(CXX) $(CFLAGS) -c unix/filesystem.cpp -o filesystem_u_gui.o -DGUI
functions_gui.o: functions.cpp functions_gui.o: functions.cpp
$(CXX) $(CFLAGS) -c functions.cpp -o functions_gui.o -DGUI $(CXX) $(CFLAGS) -c functions.cpp -o functions_gui.o -DGUI
@ -54,14 +54,14 @@ tv_rename_gui.o: tv_rename.cpp
.PHONY: windows .PHONY: windows
windows: tv_rename.exe windows: tv_rename.exe
tv_rename.exe: tv_rename.cpp filesystem.cpp functions.cpp network.cpp main.cpp tv_rename.exe: tv_rename.cpp functions.cpp windows/filesystem.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 $(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 .PHONY: windows_gui
windows_gui: tv_rename_gui.exe 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 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 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 $(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 tv_rename_gui.res: tv_rename_gui.rc
rc tv_rename_gui.rc rc tv_rename_gui.rc

View File

@ -1,174 +0,0 @@
#include <limits.h>
#include <stdlib.h>
#include <sys/stat.h>
#ifdef _WIN32
#include <Shlwapi.h>
#include <windows.h>
#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 );
}

View File

@ -42,54 +42,20 @@ bool rename( const string &file_a, const string &file_b );
class Directory { class Directory {
public: public:
Directory( const string &path_ ) : dir_path( path_ ) { Directory( const string &path_ );
#ifdef _WIN32
// need to append \\* for windows to search files in directory
dir_path.append( L"\\*" );
#endif
}
Directory() = delete; Directory() = delete;
Directory( const Directory &d ) = default; Directory( const Directory &d ) = default;
Directory( Directory &&d ) = default; Directory( Directory &&d ) = default;
class Iterator { class Iterator {
public: public:
Iterator( const Directory &d_ );
~Iterator();
#ifdef _WIN32 #ifdef _WIN32
Iterator( const Directory &d_ ) { Iterator( bool ended_ );
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 );
}
#else #else
Iterator( const Directory &d_ ) : d( opendir( d_.path() ) ) { Iterator( const Directory &d_, const struct dirent *current_entry_ );
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 );
}
#endif #endif
Iterator() = delete; Iterator() = delete;
@ -102,11 +68,17 @@ public:
Iterator &operator++(); Iterator &operator++();
Iterator operator++( int );
bool operator==( const Iterator &i_other ) const; 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: private:
#ifndef _WIN32 #ifndef _WIN32
@ -122,19 +94,30 @@ public:
using iterator = Iterator; using iterator = Iterator;
using const_iterator = Iterator; using const_iterator = Iterator;
iterator begin();
const_iterator begin() const;
const_iterator cbegin() const;
iterator end(); iterator end();
const_iterator end() const; 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: private:
string dir_path; string dir_path;

View File

@ -11,23 +11,22 @@
#include <iostream> #include <iostream>
#include <shlobj.h> #include <shlobj.h>
#else #else // UNIX
#ifndef GUI #ifndef GUI
#include <curl/curl.h>
#include <iostream> #include <iostream>
#include <stdlib.h> #include <stdlib.h>
#include <vector> #include <vector>
#else #else // UNIX and GUI
#include <pwd.h> #include <pwd.h>
#include <unistd.h> #include <unistd.h>
#endif // GUI #endif // GUI
#endif // _WIN32 #endif // UNIX
#include "filesystem.hpp" #include "filesystem.hpp"
#include "functions.hpp" #include "functions.hpp"
@ -40,7 +39,7 @@
constexpr const char_t *dir_divider = L"\\"; constexpr const char_t *dir_divider = L"\\";
#else #else // UNIX
#define TEXT( a ) a #define TEXT( a ) a
@ -50,7 +49,7 @@ constexpr const char_t *dir_divider = L"\\";
constexpr const char_t *dir_divider = "/"; constexpr const char_t *dir_divider = "/";
#endif // _WIN32 #endif // UNIX
#ifndef GUI #ifndef GUI
@ -389,21 +388,23 @@ bool findLanguage( const char_t *language ) {
return false; return false;
} }
#else #else // GUI
// functions that are needed for GUI but not for CLI // functions that are needed for GUI but not for CLI
// get possible shows for search query in `show` // get possible shows for search query in `show`
std::vector< std::pair< string, string > > std::vector< std::pair< string, string > >
getPossibleShows( string show, const string &language, Curl &c ) { getPossibleShows( string show, const string &language, Curl &c ) {
// encode show name so it can be resolved as url
std::replace( show.begin(), show.end(), ' ', '+' ); std::replace( show.begin(), show.end(), ' ', '+' );
show = encodeUrl( show );
#ifdef _WIN32 #ifdef _WIN32
auto source_code = utf8_to_wstring( auto source_code = utf8_to_wstring(
c.execute( TEXT( "https://www.thetvdb.com/search?q=" ) + c.execute( TEXT( "https://www.thetvdb.com/search?q=" ) +
encodeUrl( show ) + TEXT( "&l=" ) + language ) ); show + TEXT( "&l=" ) + language ) );
#else #else
auto source_code = auto source_code =
c.execute( TEXT( "https://www.thetvdb.com/search?q=" ) + c.execute( TEXT( "https://www.thetvdb.com/search?q=" ) +
encodeUrl( show ) + TEXT( "&l=" ) + language ); show + TEXT( "&l=" ) + language );
#endif #endif
size_t pos{}; size_t pos{};
std::vector< std::pair< string, string > > urls; std::vector< std::pair< string, string > > urls;
@ -443,7 +444,7 @@ string userHome() {
return user_passwd->pw_dir; return user_passwd->pw_dir;
} }
#else #else // UNIX
// get user's %APPDATA% folder location // get user's %APPDATA% folder location
string userHome() { string userHome() {
@ -457,7 +458,7 @@ string userHome() {
return L""; return L"";
} }
#endif #endif // UNIX
#endif // ndef GUI #endif // ndef GUI

View File

@ -19,6 +19,8 @@
using string = std::wstring; using string = std::wstring;
using char_t = wchar_t; using char_t = wchar_t;
std::wstring utf8_to_wstring( const std::string &utf8 );
#else #else
using string = std::string; using string = std::string;
@ -26,12 +28,6 @@ using char_t = char;
#endif #endif
#ifdef _WIN32
std::wstring utf8_to_wstring( const std::string &utf8 );
#endif
#ifndef GUI #ifndef GUI
// CLI functions // CLI functions
@ -58,7 +54,7 @@ std::vector< std::pair< string, string > >
getPossibleShows( string show, const string &language, Curl &c ); getPossibleShows( string show, const string &language, Curl &c );
string userHome(); string userHome();
#endif #endif // GUI
void iterateFS( std::map< int, std::set< string > > &seasons, void iterateFS( std::map< int, std::set< string > > &seasons,
const string &path ); const string &path );

84
unix/filesystem.cpp Normal file
View File

@ -0,0 +1,84 @@
#include <sys/stat.h>
#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;
}

100
windows/filesystem.cpp Normal file
View File

@ -0,0 +1,100 @@
#include <Shlwapi.h>
#include <windows.h>
#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;
}