From ae309ca63219db15bb3e4a11feb844cfe9ce3d83 Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 27 Aug 2024 21:49:23 -0400 Subject: [PATCH] use std::filesystem for C++17 --- libi2pd/FS.cpp | 96 ++++++++++++++++++++-------------- libi2pd/FS.h | 6 ++- libi2pd_client/AddressBook.cpp | 17 ++++-- 3 files changed, 73 insertions(+), 46 deletions(-) diff --git a/libi2pd/FS.cpp b/libi2pd/FS.cpp index 47a3e52c..9bb7aee2 100644 --- a/libi2pd/FS.cpp +++ b/libi2pd/FS.cpp @@ -7,7 +7,6 @@ */ #include -#include #if defined(MAC_OSX) #include @@ -25,6 +24,14 @@ #include "Log.h" #include "Garlic.h" +#if STD_FILESYSTEM +#include +namespace fs_lib = std::filesystem; +#else +#include +namespace fs_lib = boost::filesystem; +#endif + namespace i2p { namespace fs { std::string appName = "i2pd"; @@ -55,13 +62,13 @@ namespace fs { const std::string GetUTF8DataDir () { #ifdef _WIN32 #if (BOOST_VERSION >= 108500) - boost::filesystem::path path (dataDir); + fs_lib::path path (dataDir); #else - boost::filesystem::wpath path (dataDir); + fs_lib::wpath path (dataDir); #endif - auto loc = boost::filesystem::path::imbue(std::locale( std::locale(), new std::codecvt_utf8_utf16() ) ); // convert path to UTF-8 + auto loc = fs_lib::path::imbue(std::locale( std::locale(), new std::codecvt_utf8_utf16() ) ); // convert path to UTF-8 auto dataDirUTF8 = path.string(); - boost::filesystem::path::imbue(loc); // Return locale settings back + fs_lib::path::imbue(loc); // Return locale settings back return dataDirUTF8; #else return dataDir; // linux, osx, android uses UTF-8 by default @@ -92,9 +99,9 @@ namespace fs { else { #if (BOOST_VERSION >= 108500) - dataDir = boost::filesystem::path(commonAppData).string() + "\\" + appName; + dataDir = fs_lib::path(commonAppData).string() + "\\" + appName; #else - dataDir = boost::filesystem::wpath(commonAppData).string() + "\\" + appName; + dataDir = fs_lib::wpath(commonAppData).string() + "\\" + appName; #endif } #else @@ -121,13 +128,13 @@ namespace fs { else { #if (BOOST_VERSION >= 108500) - auto execPath = boost::filesystem::path(localAppData).parent_path(); + auto execPath = fs_lib::path(localAppData).parent_path(); #else - auto execPath = boost::filesystem::wpath(localAppData).parent_path(); + auto execPath = fs_lib::wpath(localAppData).parent_path(); #endif // if config file exists in .exe's folder use it - if(boost::filesystem::exists(execPath/"i2pd.conf")) // TODO: magic string + if(fs_lib::exists(execPath/"i2pd.conf")) // TODO: magic string { dataDir = execPath.string (); } else // otherwise %appdata% @@ -144,9 +151,9 @@ namespace fs { else { #if (BOOST_VERSION >= 108500) - dataDir = boost::filesystem::path(localAppData).string() + "\\" + appName; + dataDir = fs_lib::path(localAppData).string() + "\\" + appName; #else - dataDir = boost::filesystem::wpath(localAppData).string() + "\\" + appName; + dataDir = fs_lib::wpath(localAppData).string() + "\\" + appName; #endif } } @@ -169,7 +176,7 @@ namespace fs { #if defined(ANDROID) const char * ext = getenv("EXTERNAL_STORAGE"); if (!ext) ext = "/sdcard"; - if (boost::filesystem::exists(ext)) + if (fs_lib::exists(ext)) { dataDir = std::string (ext) + "/" + appName; return; @@ -202,16 +209,16 @@ namespace fs { } bool Init() { - if (!boost::filesystem::exists(dataDir)) - boost::filesystem::create_directory(dataDir); + if (!fs_lib::exists(dataDir)) + fs_lib::create_directory(dataDir); std::string destinations = DataDirPath("destinations"); - if (!boost::filesystem::exists(destinations)) - boost::filesystem::create_directory(destinations); + if (!fs_lib::exists(destinations)) + fs_lib::create_directory(destinations); std::string tags = DataDirPath("tags"); - if (!boost::filesystem::exists(tags)) - boost::filesystem::create_directory(tags); + if (!fs_lib::exists(tags)) + fs_lib::create_directory(tags); else i2p::garlic::CleanUpTagsFiles (); @@ -219,13 +226,13 @@ namespace fs { } bool ReadDir(const std::string & path, std::vector & files) { - if (!boost::filesystem::exists(path)) + if (!fs_lib::exists(path)) return false; - boost::filesystem::directory_iterator it(path); - boost::filesystem::directory_iterator end; + fs_lib::directory_iterator it(path); + fs_lib::directory_iterator end; for ( ; it != end; it++) { - if (!boost::filesystem::is_regular_file(it->status())) + if (!fs_lib::is_regular_file(it->status())) continue; files.push_back(it->path().string()); } @@ -234,29 +241,38 @@ namespace fs { } bool Exists(const std::string & path) { - return boost::filesystem::exists(path); + return fs_lib::exists(path); } uint32_t GetLastUpdateTime (const std::string & path) { - if (!boost::filesystem::exists(path)) + if (!fs_lib::exists(path)) return 0; +#if STD_FILESYSTEM + std::error_code ec; + auto t = std::filesystem::last_write_time (path, ec); + if (ec) return 0; + auto sctp = std::chrono::time_point_cast( + t - decltype(t)::clock::now() + std::chrono::system_clock::now()); + return std::chrono::system_clock::to_time_t(sctp); +#else boost::system::error_code ec; auto t = boost::filesystem::last_write_time (path, ec); return ec ? 0 : t; +#endif } bool Remove(const std::string & path) { - if (!boost::filesystem::exists(path)) + if (!fs_lib::exists(path)) return false; - return boost::filesystem::remove(path); + return fs_lib::remove(path); } bool CreateDirectory (const std::string& path) { - if (boost::filesystem::exists(path) && boost::filesystem::is_directory (boost::filesystem::status (path))) + if (fs_lib::exists(path) && fs_lib::is_directory (fs_lib::status (path))) return true; - return boost::filesystem::create_directory(path); + return fs_lib::create_directory(path); } void HashedStorage::SetPlace(const std::string &path) { @@ -264,18 +280,18 @@ namespace fs { } bool HashedStorage::Init(const char * chars, size_t count) { - if (!boost::filesystem::exists(root)) { - boost::filesystem::create_directories(root); + if (!fs_lib::exists(root)) { + fs_lib::create_directories(root); } for (size_t i = 0; i < count; i++) { auto p = root + i2p::fs::dirSep + prefix1 + chars[i]; - if (boost::filesystem::exists(p)) + if (fs_lib::exists(p)) continue; #if TARGET_OS_SIMULATOR // ios simulator fs says it is case sensitive, but it is not boost::system::error_code ec; - if (boost::filesystem::create_directory(p, ec)) + if (fs_lib::create_directory(p, ec)) continue; switch (ec.value()) { case boost::system::errc::file_exists: @@ -285,7 +301,7 @@ namespace fs { throw boost::system::system_error( ec, __func__ ); } #else - if (boost::filesystem::create_directory(p)) + if (fs_lib::create_directory(p)) continue; /* ^ throws exception on failure */ #endif return false; @@ -308,9 +324,9 @@ namespace fs { void HashedStorage::Remove(const std::string & ident) { std::string path = Path(ident); - if (!boost::filesystem::exists(path)) + if (!fs_lib::exists(path)) return; - boost::filesystem::remove(path); + fs_lib::remove(path); } void HashedStorage::Traverse(std::vector & files) { @@ -321,12 +337,12 @@ namespace fs { void HashedStorage::Iterate(FilenameVisitor v) { - boost::filesystem::path p(root); - boost::filesystem::recursive_directory_iterator it(p); - boost::filesystem::recursive_directory_iterator end; + fs_lib::path p(root); + fs_lib::recursive_directory_iterator it(p); + fs_lib::recursive_directory_iterator end; for ( ; it != end; it++) { - if (!boost::filesystem::is_regular_file( it->status() )) + if (!fs_lib::is_regular_file( it->status() )) continue; const std::string & t = it->path().string(); v(t); diff --git a/libi2pd/FS.h b/libi2pd/FS.h index 7911c6a0..de5db9d3 100644 --- a/libi2pd/FS.h +++ b/libi2pd/FS.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2020, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -15,6 +15,10 @@ #include #include +#if (!defined(_WIN32) && !TARGET_OS_SIMULATOR && (__cplusplus >= 201703L)) // C++ 17 or higher +# define STD_FILESYSTEM 1 +#endif + namespace i2p { namespace fs { extern std::string dirSep; diff --git a/libi2pd_client/AddressBook.cpp b/libi2pd_client/AddressBook.cpp index 8f2117a7..928aaa05 100644 --- a/libi2pd_client/AddressBook.cpp +++ b/libi2pd_client/AddressBook.cpp @@ -1,5 +1,5 @@ /* -* Copyright (c) 2013-2023, The PurpleI2P Project +* Copyright (c) 2013-2024, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * @@ -15,7 +15,6 @@ #include #include #include -#include #include "Base.h" #include "util.h" #include "Identity.h" @@ -27,6 +26,14 @@ #include "AddressBook.h" #include "Config.h" +#if STD_FILESYSTEM +#include +namespace fs_lib = std::filesystem; +#else +#include +namespace fs_lib = boost::filesystem; +#endif + namespace i2p { namespace client @@ -266,11 +273,11 @@ namespace client void AddressBookFilesystemStorage::ResetEtags () { LogPrint (eLogError, "Addressbook: Resetting eTags"); - for (boost::filesystem::directory_iterator it (etagsPath); it != boost::filesystem::directory_iterator (); ++it) + for (fs_lib::directory_iterator it (etagsPath); it != fs_lib::directory_iterator (); ++it) { - if (!boost::filesystem::is_regular_file (it->status ())) + if (!fs_lib::is_regular_file (it->status ())) continue; - boost::filesystem::remove (it->path ()); + fs_lib::remove (it->path ()); } }