updated build system

This commit is contained in:
Scott E. Graves 2024-08-02 10:53:11 -05:00
parent f4a3c52428
commit 098d172f40
104 changed files with 3725 additions and 1635 deletions

View File

@ -13,6 +13,16 @@ include(CheckIncludeFileCXX)
include(CheckIncludeFiles) include(CheckIncludeFiles)
include(ExternalProject) include(ExternalProject)
check_include_files(sys/xattr.h HAS_SETXATTR)
if(HAS_SETXATTR)
add_definitions(-DHAS_SETXATTR)
endif()
check_include_files("wordexp.h" HAS_WORDEXP_H)
if(HAS_WORDEXP_H)
add_definitions(-DHAS_WORDEXP_H)
endif()
include(cmake/versions.cmake) include(cmake/versions.cmake)
include(cmake/arch.cmake) include(cmake/arch.cmake)
include(cmake/os.cmake) include(cmake/os.cmake)

View File

@ -1,4 +1,7 @@
list(APPEND PROJECT_COMMON_FLAG_LIST list(APPEND PROJECT_COMMON_FLAG_LIST
-D_GNU_SOURCE
-D_LARGEFILE_SOURCE
-D_LARGEFILE64_SOURCE
-D_FILE_OFFSET_BITS=64 -D_FILE_OFFSET_BITS=64
-D_TIME_BITS=64 -D_TIME_BITS=64
-march=${PROJECT_MARCH} -march=${PROJECT_MARCH}

View File

@ -26,21 +26,7 @@ function(set_common_target_options name)
endif() endif()
endfunction(set_common_target_options) endfunction(set_common_target_options)
function(add_project_executable name dependencies libraries) function(add_project_executable2 name dependencies libraries headers sources)
file(GLOB_RECURSE headers
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/*.h
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/*.hh
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/*.hpp
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/*.hxx
)
file(GLOB_RECURSE sources
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.c
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cc
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cxx
)
if (PROJECT_WINDOWS_VERSION_RC) if (PROJECT_WINDOWS_VERSION_RC)
list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC}) list(APPEND sources ${PROJECT_WINDOWS_VERSION_RC})
endif() endif()
@ -62,6 +48,28 @@ function(add_project_executable name dependencies libraries)
endif() endif()
target_link_libraries(${name} PRIVATE ${libraries}) target_link_libraries(${name} PRIVATE ${libraries})
if(PROJECT_ENABLE_SDL AND PROJECT_IS_MINGW)
target_link_libraries(${name} PRIVATE SDL2::SDL2main)
endif ()
endfunction(add_project_executable2)
function(add_project_executable name dependencies libraries)
file(GLOB_RECURSE headers
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/*.h
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/*.hh
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/*.hpp
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/*.hxx
)
file(GLOB_RECURSE sources
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.c
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cc
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cxx
)
add_project_executable2(${name} "${dependencies}" "${libraries}" "${headers}" "${sources}")
endfunction(add_project_executable) endfunction(add_project_executable)
function(add_project_library name dependencies libraries additional_sources) function(add_project_library name dependencies libraries additional_sources)
@ -96,7 +104,24 @@ function(add_project_test_executable name dependencies libraries)
find_package(GTest ${GTEST_VERSION} REQUIRED) find_package(GTest ${GTEST_VERSION} REQUIRED)
enable_testing() enable_testing()
add_project_executable(${name} "${dependencies}" "${libraries}") file(GLOB_RECURSE headers
${PROJECT_3RD_PARTY_DIR}/test/include/*.hpp
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/*.h
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/*.hh
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/${name}/include/*.hpp
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/include/${name}/include/${name}/include/*.hxx
)
file(GLOB_RECURSE sources
${PROJECT_3RD_PARTY_DIR}/test/src/*.cpp
${additional_sources}
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.c
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cc
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}/${name}/src/*.cxx
)
add_project_executable2(${name} "${dependencies}" "${libraries}" "${headers}" "${sources}")
target_compile_definitions(${name} PRIVATE -DPROJECT_TESTING) target_compile_definitions(${name} PRIVATE -DPROJECT_TESTING)
@ -104,6 +129,10 @@ function(add_project_test_executable name dependencies libraries)
${GTEST_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS}
) )
target_include_directories(${name} AFTER PRIVATE
${PROJECT_3RD_PARTY_DIR}/test/include
)
target_link_libraries(${name} PRIVATE target_link_libraries(${name} PRIVATE
GTest::gtest GTest::gtest
GTest::gmock GTest::gmock

View File

@ -1,8 +1,8 @@
if(PROJECT_ENABLE_BACKWARD_CPP AND PROJECT_BUILD) if(PROJECT_ENABLE_BACKWARD_CPP AND PROJECT_BUILD)
add_definitions(-DPROJECT_ENABLE_BACKWARD_CPP)
if(PROJECT_IS_MINGW) if(PROJECT_IS_MINGW)
link_libraries(msvcr90) link_libraries(msvcr90)
add_definitions(-DPROJECT_ENABLE_BACKWARD_CPP)
else() else()
link_libraries(bfd) link_libraries(bfd)
add_definitions(-DBACKWARD_HAS_BFD) add_definitions(-DBACKWARD_HAS_BFD)

View File

@ -1,8 +1,6 @@
set(Boost_USE_STATIC_LIBS ${PROJECT_STATIC_LINK}) set(Boost_USE_STATIC_LIBS ${PROJECT_STATIC_LINK})
if(PROJECT_ENABLE_BOOST) if(PROJECT_ENABLE_BOOST)
add_definitions(-DPROJECT_ENABLE_BOOST)
if(PROJECT_ENABLE_LIBBITCOIN_SYSTEM) if(PROJECT_ENABLE_LIBBITCOIN_SYSTEM)
set(BOOST_MAJOR_VERSION ${BOOST2_MAJOR_VERSION}) set(BOOST_MAJOR_VERSION ${BOOST2_MAJOR_VERSION})
set(BOOST_MINOR_VERSION ${BOOST2_MINOR_VERSION}) set(BOOST_MINOR_VERSION ${BOOST2_MINOR_VERSION})
@ -40,6 +38,8 @@ if(PROJECT_ENABLE_BOOST)
wserialization wserialization
) )
add_definitions(-DPROJECT_ENABLE_BOOST)
include_directories(BEFORE SYSTEM include_directories(BEFORE SYSTEM
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
) )
@ -107,5 +107,7 @@ if(PROJECT_ENABLE_BOOST)
) )
list(APPEND PROJECT_DEPENDENCIES boost_project) list(APPEND PROJECT_DEPENDENCIES boost_project)
add_dependencies(boost_project openssl_project)
endif() endif()
endif() endif()

View File

@ -1,15 +1,10 @@
if(PROJECT_ENABLE_CPP_HTTPLIB) if(PROJECT_ENABLE_CPP_HTTPLIB)
if(PROJECT_BUILD) if(PROJECT_BUILD)
if(PROJECT_ENABLE_OPENSSL)
add_definitions( add_definitions(
-DCPPHTTPLIB_OPENSSL_SUPPORT -DCPPHTTPLIB_OPENSSL_SUPPORT
)
endif()
add_definitions(
-DPROJECT_ENABLE_CPP_HTTPLIB
-DCPPHTTPLIB_TCP_NODELAY=true -DCPPHTTPLIB_TCP_NODELAY=true
-DCPPHTTPLIB_ZLIB_SUPPORT -DCPPHTTPLIB_ZLIB_SUPPORT
-DPROJECT_ENABLE_CPP_HTTPLIB
) )
elseif(NOT PROJECT_IS_MINGW OR CMAKE_HOST_WIN32) elseif(NOT PROJECT_IS_MINGW OR CMAKE_HOST_WIN32)
ExternalProject_Add(cpphttplib_project ExternalProject_Add(cpphttplib_project
@ -29,10 +24,9 @@ if(PROJECT_ENABLE_CPP_HTTPLIB)
list(APPEND PROJECT_DEPENDENCIES cpphttplib_project) list(APPEND PROJECT_DEPENDENCIES cpphttplib_project)
add_dependencies(cpphttplib_project curl_project) add_dependencies(cpphttplib_project
curl_project
if(PROJECT_ENABLE_OPENSSL) openssl_project
add_dependencies(cpphttplib_project openssl_project) )
endif()
endif() endif()
endif() endif()

View File

@ -48,8 +48,6 @@ if(PROJECT_ENABLE_CURL)
list(APPEND PROJECT_DEPENDENCIES curl_project) list(APPEND PROJECT_DEPENDENCIES curl_project)
if(PROJECT_ENABLE_OPENSSL)
add_dependencies(curl_project openssl_project) add_dependencies(curl_project openssl_project)
endif() endif()
endif()
endif() endif()

View File

@ -1,6 +1,7 @@
if(PROJECT_ENABLE_FUSE AND NOT PROJECT_IS_MINGW) if(PROJECT_ENABLE_FUSE AND NOT PROJECT_IS_MINGW)
if(PROJECT_BUILD) if(PROJECT_BUILD)
add_definitions(-DPROJECT_ENABLE_FUSE) add_definitions(-DPROJECT_ENABLE_FUSE)
include_directories(BEFORE SYSTEM ${PROJECT_FUSE_INCLUDE_DIRS}) include_directories(BEFORE SYSTEM ${PROJECT_FUSE_INCLUDE_DIRS})
if(PROJECT_FUSE STREQUAL "fuse3") if(PROJECT_FUSE STREQUAL "fuse3")
@ -18,11 +19,6 @@ if(PROJECT_ENABLE_FUSE AND NOT PROJECT_IS_MINGW)
link_libraries(fuse) link_libraries(fuse)
endif() endif()
endif() endif()
check_include_files(sys/xattr.h HAS_SETXATTR)
if(HAS_SETXATTR)
add_definitions(-DHAS_SETXATTR)
endif()
else() else()
pkg_check_modules(LIBFUSE3 fuse3>=3.0.0) pkg_check_modules(LIBFUSE3 fuse3>=3.0.0)
if(LIBFUSE3_FOUND) if(LIBFUSE3_FOUND)

View File

@ -48,113 +48,7 @@
#if defined(__cplusplus) #if defined(__cplusplus)
REPERTORY_IGNORE_WARNINGS_ENABLE() REPERTORY_IGNORE_WARNINGS_ENABLE()
#include "utils/config.hpp"
#if defined(_WIN32)
#define WINVER 0x0602
#define _WIN32_WINNT WINVER
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <shellapi.h>
#include <shlwapi.h>
#include <shlobj.h>
#include <ciso646>
#include <direct.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>
#else
#include <climits>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
#include <libgen.h>
#include <pwd.h>
#include <sys/file.h>
#include <sys/stat.h>
#if defined(__linux__)
#include <sys/statfs.h>
#endif
#include <unistd.h>
#if defined(HAS_SETXATTR)
#include <sys/types.h>
#include <sys/xattr.h>
#endif
#if defined(__APPLE__)
#include <libproc.h>
#include <sys/attr.h>
#include <sys/vnode.h>
#endif
#if defined(__APPLE__)
#include <sys/mount.h>
#include <sys/statvfs.h>
#endif
#endif
#include <algorithm>
#include <atomic>
#include <chrono>
#include <codecvt>
#include <condition_variable>
#include <deque>
#include <filesystem>
#include <fstream>
#include <future>
#include <iomanip>
#include <iostream>
#include <limits>
#include <mutex>
#include <optional>
#include <random>
#include <sstream>
#include <string>
#include <string_view>
#include <thread>
#include <type_traits>
#include <unordered_map>
#include <vector>
#include "sodium.h"
template <typename data_type>
[[nodiscard]] inline auto repertory_rand() -> data_type {
data_type ret{};
randombytes_buf(&ret, sizeof(ret));
return ret;
}
#include "boost/archive/text_iarchive.hpp"
#include "boost/archive/text_oarchive.hpp"
#include "boost/asio.hpp"
#include "boost/asio/io_context.hpp"
#include "boost/bind/bind.hpp"
#include "boost/dynamic_bitset.hpp"
#include "boost/dynamic_bitset/serialization.hpp"
#include "boost/endian/conversion.hpp"
#include "boost/serialization/vector.hpp"
#include "curl/curl.h"
#include "curl/multi.h"
#include "json.hpp"
#include "sqlite3.h"
#include "uuid.h"
#if defined(_WIN32)
#include <sddl.h>
#include "winfsp/winfsp.hpp"
#else
#if FUSE_USE_VERSION >= 30
#include <fuse.h>
#include <fuse_lowlevel.h>
#else
#include <fuse/fuse.h>
#endif
#endif
#include "pugixml.hpp"
#include "httplib.h"
REPERTORY_IGNORE_WARNINGS_DISABLE() REPERTORY_IGNORE_WARNINGS_DISABLE()
using namespace std::chrono_literals; using namespace std::chrono_literals;
@ -279,26 +173,6 @@ inline constexpr const auto NANOS_PER_SECOND = 1000000000L;
#endif #endif
#endif #endif
#ifndef fstat64
#define fstat64 fstat
#endif
#ifndef pread64
#define pread64 pread
#endif
#ifndef pwrite64
#define pwrite64 pwrite
#endif
#ifndef stat64
#define stat64 stat
#endif
#ifndef statfs64
#define statfs64 statfs
#endif
#define WINFSP_ALLOCATION_UNIT UINT64(4096U) #define WINFSP_ALLOCATION_UNIT UINT64(4096U)
#if defined(_WIN32) #if defined(_WIN32)
@ -409,13 +283,6 @@ using FileInfo = FSP_FSCTL_FILE_INFO;
using namespace Fsp; using namespace Fsp;
namespace {
template <class... Ts> struct overloaded : Ts... {
using Ts::operator()...;
};
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
} // namespace
#define INTERFACE_SETUP(name) \ #define INTERFACE_SETUP(name) \
public: \ public: \
name(const name &) noexcept = delete; \ name(const name &) noexcept = delete; \

View File

@ -24,7 +24,7 @@
#if !defined(_WIN32) #if !defined(_WIN32)
#include "events/event_system.hpp" #include "events/event_system.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
class app_config; class app_config;

View File

@ -32,7 +32,7 @@
#include "types/remote.hpp" #include "types/remote.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/base64.hpp" #include "utils/base64.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#define REPERTORY_DIRECTORY_PAGE_SIZE std::size_t(100U) #define REPERTORY_DIRECTORY_PAGE_SIZE std::size_t(100U)

View File

@ -24,7 +24,7 @@
#include "events/event.hpp" #include "events/event.hpp"
#include "events/t_event_system.hpp" #include "events/t_event_system.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
namespace repertory { namespace repertory {
using event_system = t_event_system<event>; using event_system = t_event_system<event>;

View File

@ -23,6 +23,7 @@
#define INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_ #define INCLUDE_EVENTS_T_EVENT_SYSTEM_HPP_
#include "events/event.hpp" #include "events/event.hpp"
#include "utils/collection.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {
@ -151,14 +152,14 @@ public:
void release(event_consumer *consumer) { void release(event_consumer *consumer) {
recur_mutex_lock lock(consumer_mutex_); recur_mutex_lock lock(consumer_mutex_);
auto iter = auto iter = std::find_if(event_consumers_.begin(), event_consumers_.end(),
std::find_if(event_consumers_.begin(), event_consumers_.end(),
[&](const auto &item) -> bool { [&](const auto &item) -> bool {
return utils::collection_includes(item.second, consumer); return utils::collection::includes(item.second,
consumer);
}); });
if (iter != event_consumers_.end()) { if (iter != event_consumers_.end()) {
utils::remove_element_from((*iter).second, consumer); utils::collection::remove_element((*iter).second, consumer);
} }
} }

View File

@ -102,6 +102,12 @@ enum class api_error {
api_error_to_string(const api_error &error) -> const std::string &; api_error_to_string(const api_error &error) -> const std::string &;
enum class download_type { direct, fallback, ring_buffer }; enum class download_type { direct, fallback, ring_buffer };
[[nodiscard]] auto
download_type_from_string(std::string type,
const download_type &default_type) -> download_type;
[[nodiscard]] auto
download_type_to_string(const download_type &type) -> std::string;
enum class exit_code : std::int32_t { enum class exit_code : std::int32_t {
success, success,

View File

@ -23,7 +23,7 @@
#define INCLUDE_TYPES_S3_HPP_ #define INCLUDE_TYPES_S3_HPP_
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {

View File

@ -23,6 +23,7 @@
#define INCLUDE_UTILS_ENCRYPT_HPP_ #define INCLUDE_UTILS_ENCRYPT_HPP_
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/encryption.hpp"
#include "utils/encrypting_reader.hpp" #include "utils/encrypting_reader.hpp"
namespace repertory::utils::encryption { namespace repertory::utils::encryption {
@ -40,122 +41,6 @@ using reader_func = std::function<api_error(data_buffer &cypher_text,
const key_type &key, reader_func reader, const key_type &key, reader_func reader,
std::uint64_t total_size, std::uint64_t total_size,
data_buffer &data) -> api_error; data_buffer &data) -> api_error;
[[nodiscard]] auto generate_key(std::string_view encryption_token) -> key_type;
// Implementations
template <typename result>
[[nodiscard]] inline auto
decrypt_data(const key_type &key, const unsigned char *buffer,
std::size_t buffer_size, result &res) -> bool {
const auto header_size =
static_cast<std::uint32_t>(encrypting_reader::get_header_size());
if (buffer_size > header_size) {
const std::uint32_t size =
boost::endian::native_to_big(static_cast<std::uint32_t>(buffer_size));
res.resize(buffer_size - header_size);
return crypto_aead_xchacha20poly1305_ietf_decrypt_detached(
reinterpret_cast<unsigned char *>(res.data()), nullptr,
&buffer[header_size], res.size(),
&buffer[crypto_aead_xchacha20poly1305_IETF_NPUBBYTES],
reinterpret_cast<const unsigned char *>(&size), sizeof(size),
buffer, key.data()) == 0;
}
return false;
}
template <typename buffer, typename result>
[[nodiscard]] inline auto decrypt_data(const key_type &key, const buffer &buf,
result &res) -> bool {
return decrypt_data<result>(
key, reinterpret_cast<const unsigned char *>(buf.data()), buf.size(),
res);
}
template <typename buffer, typename result>
[[nodiscard]] inline auto decrypt_data(std::string_view encryption_token,
const buffer &buf, result &res) -> bool {
return decrypt_data<buffer, result>(generate_key(encryption_token), buf, res);
}
template <typename result>
[[nodiscard]] inline auto
decrypt_data(std::string_view encryption_token, const unsigned char *buffer,
std::size_t buffer_size, result &res) -> bool {
return decrypt_data<result>(generate_key(encryption_token), buffer,
buffer_size, res);
}
template <typename result>
inline void
encrypt_data(const std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv,
const key_type &key, const unsigned char *buffer,
std::size_t buffer_size, result &res) {
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_ABYTES> mac{};
const auto header_size =
static_cast<std::uint32_t>(encrypting_reader::get_header_size());
const std::uint32_t size = boost::endian::native_to_big(
static_cast<std::uint32_t>(buffer_size + header_size));
res.resize(buffer_size + header_size);
unsigned long long mac_length{};
if (crypto_aead_xchacha20poly1305_ietf_encrypt_detached(
reinterpret_cast<unsigned char *>(&res[header_size]), mac.data(),
&mac_length, buffer, buffer_size,
reinterpret_cast<const unsigned char *>(&size), sizeof(size), nullptr,
iv.data(), key.data()) != 0) {
throw std::runtime_error("encryption failed");
}
std::memcpy(res.data(), iv.data(), iv.size());
std::memcpy(&res[iv.size()], mac.data(), mac.size());
}
template <typename result>
inline void encrypt_data(const key_type &key, const unsigned char *buffer,
std::size_t buffer_size, result &res) {
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> iv{};
randombytes_buf(iv.data(), iv.size());
encrypt_data<result>(iv, key, buffer, buffer_size, res);
}
template <typename result>
inline void encrypt_data(std::string_view encryption_token,
const unsigned char *buffer, std::size_t buffer_size,
result &res) {
encrypt_data<result>(generate_key(encryption_token), buffer, buffer_size,
res);
}
template <typename buffer, typename result>
inline void encrypt_data(std::string_view encryption_token, const buffer &buf,
result &res) {
encrypt_data<result>(generate_key(encryption_token),
reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res);
}
template <typename buffer, typename result>
inline void encrypt_data(const key_type &key, const buffer &buf, result &res) {
encrypt_data<result>(key, reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res);
}
template <typename buffer, typename result>
inline void
encrypt_data(const std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv,
const key_type &key, const buffer &buf, result &res) {
encrypt_data<result>(iv, key,
reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res);
}
} // namespace repertory::utils::encryption } // namespace repertory::utils::encryption
#endif // INCLUDE_UTILS_ENCRYPT_HPP_ #endif // INCLUDE_UTILS_ENCRYPT_HPP_

View File

@ -23,6 +23,7 @@
#define INCLUDE_UTILS_FILE_UTILS_HPP_ #define INCLUDE_UTILS_FILE_UTILS_HPP_
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/file.hpp"
#include "utils/native_file.hpp" #include "utils/native_file.hpp"
namespace repertory::utils::file { namespace repertory::utils::file {
@ -62,16 +63,9 @@ get_free_drive_space(const std::string &path) -> std::uint64_t;
[[nodiscard]] auto [[nodiscard]] auto
get_total_drive_space(const std::string &path) -> std::uint64_t; get_total_drive_space(const std::string &path) -> std::uint64_t;
[[nodiscard]] auto get_file_size(std::string_view path,
std::uint64_t &file_size) -> bool;
[[nodiscard]] auto get_modified_time(const std::string &path, [[nodiscard]] auto get_modified_time(const std::string &path,
std::uint64_t &modified) -> bool; std::uint64_t &modified) -> bool;
[[nodiscard]] auto is_directory(const std::string &path) -> bool;
[[nodiscard]] auto is_file(const std::string &path) -> bool;
[[nodiscard]] auto [[nodiscard]] auto
is_modified_date_older_than(const std::string &path, is_modified_date_older_than(const std::string &path,
const std::chrono::hours &hours) -> bool; const std::chrono::hours &hours) -> bool;
@ -81,16 +75,11 @@ is_modified_date_older_than(const std::string &path,
[[nodiscard]] auto [[nodiscard]] auto
read_file_lines(const std::string &path) -> std::vector<std::string>; read_file_lines(const std::string &path) -> std::vector<std::string>;
[[nodiscard]] auto read_json_file(const std::string &path, json &data) -> bool;
[[nodiscard]] auto reset_modified_time(const std::string &path) -> bool; [[nodiscard]] auto reset_modified_time(const std::string &path) -> bool;
[[nodiscard]] auto retry_delete_directory(const std::string &dir) -> bool; [[nodiscard]] auto retry_delete_directory(const std::string &dir) -> bool;
[[nodiscard]] auto retry_delete_file(const std::string &file) -> bool; [[nodiscard]] auto retry_delete_file(const std::string &file) -> bool;
[[nodiscard]] auto write_json_file(const std::string &path,
const json &j) -> bool;
} // namespace repertory::utils::file } // namespace repertory::utils::file
#endif // INCLUDE_UTILS_FILE_UTILS_HPP_ #endif // INCLUDE_UTILS_FILE_UTILS_HPP_

View File

@ -1,66 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_UTILS_PATH_UTILS_HPP_
#define INCLUDE_UTILS_PATH_UTILS_HPP_
namespace repertory::utils::path {
#if defined(_WIN32)
static const std::string directory_seperator = "\\";
static const std::string not_directory_seperator = "/";
#else
static const std::string directory_seperator = "/";
static const std::string not_directory_seperator = "\\";
#endif
// Prototypes
[[nodiscard]] auto absolute(std::string path) -> std::string;
[[nodiscard]] auto
combine(std::string path, const std::vector<std::string> &paths) -> std::string;
[[nodiscard]] auto create_api_path(std::string path) -> std::string;
[[nodiscard]] auto finalize(std::string path) -> std::string;
auto format_path(std::string &path, const std::string &sep,
const std::string &not_sep) -> std::string &;
[[nodiscard]] auto get_parent_api_path(const std::string &path) -> std::string;
#if !defined(_WIN32)
[[nodiscard]] auto get_parent_directory(std::string path) -> std::string;
#endif
[[nodiscard]] auto is_ads_file_path(const std::string &path) -> bool;
[[nodiscard]] auto is_trash_directory(std::string path) -> bool;
[[nodiscard]] auto remove_file_name(std::string path) -> std::string;
#if !defined(_WIN32)
[[nodiscard]] auto resolve(std::string path) -> std::string;
#endif
[[nodiscard]] auto strip_to_file_name(std::string path) -> std::string;
} // namespace repertory::utils::path
#endif // INCLUDE_UTILS_PATH_UTILS_HPP_

View File

@ -1,114 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef INCLUDE_UTILS_STRING_UTILS_HPP_
#define INCLUDE_UTILS_STRING_UTILS_HPP_
namespace repertory::utils::string {
// Prototypes
constexpr auto begins_with(std::string_view str, std::string_view val) -> bool {
return (str.find(val) == 0U);
}
constexpr auto contains(std::string_view str, std::string_view search) -> bool {
return (str.find(search) != std::string_view::npos);
}
[[nodiscard]] /* constexpr c++20 */ auto
ends_with(std::string_view str, std::string_view val) -> bool;
[[nodiscard]] auto from_bool(bool val) -> std::string;
[[nodiscard]] auto
from_dynamic_bitset(const boost::dynamic_bitset<> &bitset) -> std::string;
[[nodiscard]] auto from_utf8(std::string_view str) -> std::wstring;
[[nodiscard]] /* constexpr c++20 */ auto
is_numeric(std::string_view str) -> bool;
[[nodiscard]] auto join(const std::vector<std::string> &arr,
const char &delim) -> std::string;
auto left_trim(std::string &str) -> std::string &;
auto left_trim(std::string &str, const char &trim_ch) -> std::string &;
auto replace(std::string &src, const char &character,
const char &with) -> std::string &;
auto replace(std::string &src, const std::string &find, const std::string &with,
size_t start_pos = 0) -> std::string &;
[[nodiscard]] auto replace_copy(std::string src, const char &character,
const char &with) -> std::string;
[[nodiscard]] auto replace_copy(std::string src, const std::string &find,
const std::string &with,
size_t start_pos = 0) -> std::string;
auto right_trim(std::string &str) -> std::string &;
auto right_trim(std::string &str, const char &trim_ch) -> std::string &;
[[nodiscard]] auto split(const std::string &str, const char &delim,
bool should_trim = true) -> std::vector<std::string>;
[[nodiscard]] auto to_bool(std::string val) -> bool;
[[nodiscard]] auto to_double(const std::string &str) -> double;
[[nodiscard]] auto
to_dynamic_bitset(const std::string &val) -> boost::dynamic_bitset<>;
[[nodiscard]] auto to_lower(std::string str) -> std::string;
[[nodiscard]] auto to_int32(const std::string &val) -> std::int32_t;
[[nodiscard]] auto to_int64(const std::string &val) -> std::int64_t;
[[nodiscard]] auto to_size_t(const std::string &val) -> std::size_t;
[[nodiscard]] auto to_uint8(const std::string &val) -> std::uint8_t;
[[nodiscard]] auto to_uint16(const std::string &val) -> std::uint16_t;
[[nodiscard]] auto to_uint32(const std::string &val) -> std::uint32_t;
[[nodiscard]] auto to_uint64(const std::string &val) -> std::uint64_t;
[[nodiscard]] auto to_upper(std::string str) -> std::string;
[[nodiscard]] auto to_utf8(std::string_view str) -> std::string;
[[nodiscard]] auto to_utf8(std::wstring_view str) -> std::string;
auto trim(std::string &str) -> std::string &;
auto trim(std::string &str, const char &trim_ch) -> std::string &;
[[nodiscard]] auto trim_copy(std::string str) -> std::string;
[[nodiscard]] auto trim_copy(std::string str,
const char &trim_ch) -> std::string;
} // namespace repertory::utils::string
#endif // INCLUDE_UTILS_STRING_UTILS_HPP_

View File

@ -25,6 +25,7 @@
#include "types/remote.hpp" #include "types/remote.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/unix.hpp"
namespace repertory::utils { namespace repertory::utils {
#if defined(__linux__) #if defined(__linux__)
@ -35,25 +36,8 @@ inline const std::array<std::string, 4U> attribute_namespaces = {
"user", "user",
}; };
#endif #endif
#if defined(__APPLE__)
template <typename t>
[[nodiscard]] auto convert_to_uint64(const t *ptr) -> std::uint64_t;
#else
[[nodiscard]] auto convert_to_uint64(const pthread_t &thread) -> std::uint64_t;
#endif
[[nodiscard]] auto from_api_error(const api_error &err) -> int; [[nodiscard]] auto from_api_error(const api_error &err) -> int;
[[nodiscard]] auto get_last_error_code() -> int;
[[nodiscard]] auto get_thread_id() -> std::uint64_t;
[[nodiscard]] auto is_uid_member_of_group(const uid_t &uid,
const gid_t &gid) -> bool;
void set_last_error_code(int error_code);
[[nodiscard]] auto to_api_error(int err) -> api_error; [[nodiscard]] auto to_api_error(int err) -> api_error;
[[nodiscard]] auto unix_error_to_windows(int err) -> std::int32_t; [[nodiscard]] auto unix_error_to_windows(int err) -> std::int32_t;
@ -61,22 +45,12 @@ void set_last_error_code(int error_code);
[[nodiscard]] auto [[nodiscard]] auto
unix_time_to_windows_time(const remote::file_time &file_time) -> UINT64; unix_time_to_windows_time(const remote::file_time &file_time) -> UINT64;
void use_getpwuid(uid_t uid, std::function<void(struct passwd *pass)> callback);
void windows_create_to_unix(const UINT32 &create_options, void windows_create_to_unix(const UINT32 &create_options,
const UINT32 &granted_access, std::uint32_t &flags, const UINT32 &granted_access, std::uint32_t &flags,
remote::file_mode &mode); remote::file_mode &mode);
[[nodiscard]] auto [[nodiscard]] auto
windows_time_to_unix_time(std::uint64_t win_time) -> remote::file_time; windows_time_to_unix_time(std::uint64_t win_time) -> remote::file_time;
// template implementations
#if defined(__APPLE__)
template <typename t>
[[nodiscard]] auto convert_to_uint64(const t *v) -> std::uint64_t {
return static_cast<std::uint64_t>(reinterpret_cast<std::uintptr_t>(v));
}
#endif
} // namespace repertory::utils } // namespace repertory::utils
#endif // !_WIN32 #endif // !_WIN32

View File

@ -32,73 +32,19 @@ void calculate_allocation_size(bool directory, std::uint64_t file_size,
UINT64 allocation_size, UINT64 allocation_size,
std::string &allocation_meta_size); std::string &allocation_meta_size);
[[nodiscard]] auto calculate_read_size(const uint64_t &total_size,
std::size_t read_size,
const uint64_t &offset) -> std::size_t;
template <typename t>
[[nodiscard]] auto collection_excludes(t collection,
const typename t::value_type &val)
-> bool;
template <typename t>
[[nodiscard]] auto collection_includes(t collection,
const typename t::value_type &val)
-> bool;
[[nodiscard]] auto compare_version_strings(std::string version1,
std::string version2) -> int;
[[nodiscard]] auto convert_api_date(const std::string &date) -> std::uint64_t; [[nodiscard]] auto convert_api_date(const std::string &date) -> std::uint64_t;
[[nodiscard]] auto create_curl() -> CURL *; [[nodiscard]] auto create_curl() -> CURL *;
[[nodiscard]] auto create_uuid_string() -> std::string; [[nodiscard]] auto
create_volume_label(const provider_type &prov) -> std::string;
[[nodiscard]] auto create_volume_label(const provider_type &prov)
-> std::string;
template <typename t>
[[nodiscard]] auto divide_with_ceiling(const t &n, const t &d) -> t;
[[nodiscard]] auto download_type_from_string(std::string type,
const download_type &default_type)
-> download_type;
[[nodiscard]] auto download_type_to_string(const download_type &type)
-> std::string;
template <typename t>
[[nodiscard]] auto from_hex_string(const std::string &str, t &val) -> bool;
[[nodiscard]] auto generate_random_string(std::uint16_t length) -> std::string;
[[nodiscard]] auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD; [[nodiscard]] auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD;
[[nodiscard]] auto get_environment_variable(const std::string &variable)
-> std::string;
[[nodiscard]] auto get_file_time_now() -> std::uint64_t;
void get_local_time_now(struct tm &local_time);
[[nodiscard]] auto get_next_available_port(std::uint16_t first_port,
std::uint16_t &available_port)
-> bool;
[[nodiscard]] auto get_time_now() -> std::uint64_t;
template <typename data_type>
[[nodiscard]] auto random_between(const data_type &begin, const data_type &end)
-> data_type;
template <typename t>
void remove_element_from(t &collection, const typename t::value_type &val);
[[nodiscard]] auto reset_curl(CURL *curl_handle) -> CURL *; [[nodiscard]] auto reset_curl(CURL *curl_handle) -> CURL *;
[[nodiscard]] auto retryable_action(const std::function<bool()> &action) [[nodiscard]] auto
-> bool; retryable_action(const std::function<bool()> &action) -> bool;
void spin_wait_for_mutex(std::function<bool()> complete, void spin_wait_for_mutex(std::function<bool()> complete,
std::condition_variable &cond, std::mutex &mtx, std::condition_variable &cond, std::mutex &mtx,
@ -107,75 +53,6 @@ void spin_wait_for_mutex(std::function<bool()> complete,
void spin_wait_for_mutex(bool &complete, std::condition_variable &cond, void spin_wait_for_mutex(bool &complete, std::condition_variable &cond,
std::mutex &mtx, const std::string &text = ""); std::mutex &mtx, const std::string &text = "");
template <typename collection_t>
[[nodiscard]] auto to_hex_string(const collection_t &collection) -> std::string;
// template implementations
template <typename t>
[[nodiscard]] auto collection_excludes(t collection,
const typename t::value_type &val)
-> bool {
return std::find(collection.begin(), collection.end(), val) ==
collection.end();
}
template <typename t>
[[nodiscard]] auto collection_includes(t collection,
const typename t::value_type &val)
-> bool {
return std::find(collection.begin(), collection.end(), val) !=
collection.end();
}
template <typename t>
[[nodiscard]] auto divide_with_ceiling(const t &n, const t &d) -> t {
return n ? (n / d) + (n % d != 0) : 0;
}
template <typename t>
[[nodiscard]] auto from_hex_string(const std::string &str, t &val) -> bool {
static constexpr const auto base16 = 16;
val.clear();
if (not(str.length() % 2U)) {
for (std::size_t i = 0U; i < str.length(); i += 2U) {
val.emplace_back(static_cast<typename t::value_type>(
strtol(str.substr(i, 2U).c_str(), nullptr, base16)));
}
return true;
}
return false;
}
template <typename data_type>
[[nodiscard]] auto random_between(const data_type &begin, const data_type &end)
-> data_type {
return begin + repertory_rand<data_type>() % ((end + data_type{1}) - begin);
}
template <typename collection_t>
void remove_element_from(collection_t &collection,
const typename collection_t::value_type &value) {
collection.erase(std::remove(collection.begin(), collection.end(), value),
collection.end());
}
template <typename collection_t>
[[nodiscard]] auto to_hex_string(const collection_t &collection)
-> std::string {
static_assert(sizeof(typename collection_t::value_type) == 1U,
"value_type must be 1 byte in size");
static constexpr const auto mask = 0xFF;
std::stringstream stream;
for (const auto &val : collection) {
stream << std::setfill('0') << std::setw(2) << std::hex
<< (static_cast<std::uint32_t>(val) & mask);
}
return stream.str();
}
} // namespace repertory::utils } // namespace repertory::utils
#endif // INCLUDE_UTILS_UTILS_HPP_ #endif // INCLUDE_UTILS_UTILS_HPP_

View File

@ -25,15 +25,9 @@
#include "types/remote.hpp" #include "types/remote.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/windows.hpp"
namespace repertory::utils { namespace repertory::utils {
[[nodiscard]] auto
filetime_to_unix_time(const FILETIME &ft) -> remote::file_time;
[[nodiscard]] auto get_last_error_code() -> DWORD;
[[nodiscard]] auto get_local_app_data_directory() -> const std::string &;
[[nodiscard]] auto [[nodiscard]] auto
get_accessed_time_from_meta(const api_meta_map &meta) -> std::uint64_t; get_accessed_time_from_meta(const api_meta_map &meta) -> std::uint64_t;
@ -46,29 +40,14 @@ get_creation_time_from_meta(const api_meta_map &meta) -> std::uint64_t;
[[nodiscard]] auto [[nodiscard]] auto
get_written_time_from_meta(const api_meta_map &meta) -> std::uint64_t; get_written_time_from_meta(const api_meta_map &meta) -> std::uint64_t;
[[nodiscard]] auto get_thread_id() -> std::uint64_t;
[[nodiscard]] auto is_process_elevated() -> bool;
[[nodiscard]] auto run_process_elevated(std::vector<const char *> args) -> int;
void set_last_error_code(DWORD errorCode);
[[nodiscard]] auto from_api_error(const api_error &e) -> NTSTATUS; [[nodiscard]] auto from_api_error(const api_error &e) -> NTSTATUS;
auto strptime(const char *s, const char *f, struct tm *tm) -> const char *;
[[nodiscard]] auto unix_access_mask_to_windows(std::int32_t mask) -> int; [[nodiscard]] auto unix_access_mask_to_windows(std::int32_t mask) -> int;
[[nodiscard]] auto [[nodiscard]] auto
unix_open_flags_to_flags_and_perms(const remote::file_mode &mode, unix_open_flags_to_flags_and_perms(const remote::file_mode &mode,
const remote::open_flags &flags, const remote::open_flags &flags,
std::int32_t &perms) -> int; std::int32_t &perms) -> int;
void unix_time_to_filetime(const remote::file_time &ts, FILETIME &ft);
[[nodiscard]] auto
time64_to_unix_time(const __time64_t &t) -> remote::file_time;
} // namespace repertory::utils } // namespace repertory::utils
#endif // _WIN32 #endif // _WIN32

View File

@ -24,7 +24,7 @@
#include "types/startup_exception.hpp" #include "types/startup_exception.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/unix/unix_utils.hpp" #include "utils/unix/unix_utils.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"

View File

@ -22,8 +22,8 @@
#include "comm/curl/curl_comm.hpp" #include "comm/curl/curl_comm.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
namespace repertory { namespace repertory {
const curl_comm::write_callback curl_comm::write_data = const curl_comm::write_callback curl_comm::write_data =
@ -92,8 +92,8 @@ auto curl_comm::construct_url(CURL *curl, const std::string &relative_path,
relative_path, url); relative_path, url);
} }
auto curl_comm::create_host_config(const s3_config &cfg, bool use_s3_path_style) auto curl_comm::create_host_config(const s3_config &cfg,
-> host_config { bool use_s3_path_style) -> host_config {
host_config host_cfg{}; host_config host_cfg{};
host_cfg.api_password = cfg.secret_key; host_cfg.api_password = cfg.secret_key;
host_cfg.api_user = cfg.access_key; host_cfg.api_user = cfg.access_key;

View File

@ -21,7 +21,7 @@
*/ */
#include "comm/curl/requests/http_put_file.hpp" #include "comm/curl/requests/http_put_file.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
namespace repertory::curl::requests { namespace repertory::curl::requests {
auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const auto http_put_file::set_method(CURL *curl, stop_type &stop_requested) const

View File

@ -23,6 +23,7 @@
#include "events/events.hpp" #include "events/events.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/collection.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/timeout.hpp" #include "utils/timeout.hpp"
#include "version.hpp" #include "version.hpp"
@ -102,7 +103,7 @@ auto packet_client::get_client() -> std::shared_ptr<packet_client::client> {
connect(*ret); connect(*ret);
} else { } else {
ret = clients_[0U]; ret = clients_[0U];
utils::remove_element_from(clients_, ret); utils::collection::remove_element(clients_, ret);
clients_lock.unlock(); clients_lock.unlock();
} }
} }

View File

@ -26,7 +26,7 @@
#include "events/events.hpp" #include "events/events.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {

View File

@ -23,6 +23,7 @@
#include "drives/directory_iterator.hpp" #include "drives/directory_iterator.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/collection.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {
@ -72,7 +73,7 @@ void directory_cache::remove_directory(std::uint64_t handle) {
handle) != kv.second.handles.end(); handle) != kv.second.handles.end();
}); });
if (it != directory_lookup_.end()) { if (it != directory_lookup_.end()) {
utils::remove_element_from(it->second.handles, handle); utils::collection::remove_element(it->second.handles, handle);
if (it->second.handles.empty()) { if (it->second.handles.empty()) {
directory_lookup_.erase(it); directory_lookup_.erase(it);
} }

View File

@ -22,7 +22,7 @@
#include "drives/directory_iterator.hpp" #include "drives/directory_iterator.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
#if !defined(_WIN32) #if !defined(_WIN32)

View File

@ -29,9 +29,10 @@
#include "events/events.hpp" #include "events/events.hpp"
#include "initialize.hpp" #include "initialize.hpp"
#include "providers/i_provider.hpp" #include "providers/i_provider.hpp"
#include "utils/collection.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {
@ -615,7 +616,7 @@ auto fuse_base::parse_args(std::vector<std::string> &args) -> int {
force_no_console = true; force_no_console = true;
} }
} }
utils::remove_element_from(args, "-nc"); utils::collection::remove_element(args, "-nc");
for (std::size_t i = 1u; i < args.size(); i++) { for (std::size_t i = 1u; i < args.size(); i++) {
if (args[i] == "-f") { if (args[i] == "-f") {

View File

@ -39,6 +39,7 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "types/startup_exception.hpp" #include "types/startup_exception.hpp"
#include "utils/base64.hpp" #include "utils/base64.hpp"
#include "utils/collection.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
@ -905,7 +906,7 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
api_meta_map meta; api_meta_map meta;
if ((res = provider_.get_item_meta(api_path, meta)) == api_error::success) { if ((res = provider_.get_item_meta(api_path, meta)) == api_error::success) {
for (const auto &meta_item : meta) { for (const auto &meta_item : meta) {
if (utils::collection_excludes(META_USED_NAMES, meta_item.first)) { if (utils::collection::excludes(META_USED_NAMES, meta_item.first)) {
auto attribute_name = meta_item.first; auto attribute_name = meta_item.first;
#if defined(__APPLE__) #if defined(__APPLE__)
if (attribute_name != G_KAUTH_FILESEC_XATTR) { if (attribute_name != G_KAUTH_FILESEC_XATTR) {
@ -948,7 +949,7 @@ auto fuse_drive::removexattr_impl(std::string api_path,
return check_and_perform( return check_and_perform(
api_path, X_OK, [&](api_meta_map &meta) -> api_error { api_path, X_OK, [&](api_meta_map &meta) -> api_error {
if ((meta.find(name) != meta.end()) && if ((meta.find(name) != meta.end()) &&
(utils::collection_excludes(META_USED_NAMES, name))) { (utils::collection::excludes(META_USED_NAMES, name))) {
return provider_.remove_item_meta(api_path, attribute_name); return provider_.remove_item_meta(api_path, attribute_name);
} }
@ -988,7 +989,7 @@ auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
if (utils::string::contains(attribute_name, " .") || if (utils::string::contains(attribute_name, " .") ||
utils::string::contains(attribute_name, ". ") utils::string::contains(attribute_name, ". ")
#if !defined(__APPLE__) #if !defined(__APPLE__)
|| utils::collection_excludes(utils::attribute_namespaces, || utils::collection::excludes(utils::attribute_namespaces,
attribute_namespace) attribute_namespace)
#endif #endif
) { ) {

View File

@ -23,7 +23,7 @@
#include "app_config.hpp" #include "app_config.hpp"
#include "comm/packet/packet.hpp" #include "comm/packet/packet.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory::remote_fuse { namespace repertory::remote_fuse {
remote_client::remote_client(const app_config &config) remote_client::remote_client(const app_config &config)

View File

@ -34,7 +34,7 @@
#include "types/remote.hpp" #include "types/remote.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory::remote_fuse { namespace repertory::remote_fuse {

View File

@ -38,7 +38,7 @@
#include "utils/base64.hpp" #include "utils/base64.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory::remote_fuse { namespace repertory::remote_fuse {
#define RAISE_REMOTE_FUSE_SERVER_EVENT(func, file, ret) \ #define RAISE_REMOTE_FUSE_SERVER_EVENT(func, file, ret) \

View File

@ -23,6 +23,7 @@
#include "events/event_system.hpp" #include "events/event_system.hpp"
#include "events/events.hpp" #include "events/events.hpp"
#include "utils/collection.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {
@ -30,7 +31,7 @@ void remote_open_file_table::add_directory(const std::string &client_id,
std::uint64_t handle) { std::uint64_t handle) {
recur_mutex_lock directory_lock(directory_mutex_); recur_mutex_lock directory_lock(directory_mutex_);
auto &list = directory_lookup_[client_id]; auto &list = directory_lookup_[client_id];
if (utils::collection_excludes(list, handle)) { if (utils::collection::excludes(list, handle)) {
directory_lookup_[client_id].emplace_back(handle); directory_lookup_[client_id].emplace_back(handle);
} }
} }
@ -144,7 +145,7 @@ auto remote_open_file_table::has_open_directory(const std::string &client_id,
std::uint64_t handle) -> bool { std::uint64_t handle) -> bool {
recur_mutex_lock directory_lock(directory_mutex_); recur_mutex_lock directory_lock(directory_mutex_);
auto &list = directory_lookup_[client_id]; auto &list = directory_lookup_[client_id];
return (utils::collection_includes(list, handle)); return (utils::collection::includes(list, handle));
} }
auto remote_open_file_table::has_compat_open_info( auto remote_open_file_table::has_compat_open_info(
@ -207,8 +208,8 @@ auto remote_open_file_table::remove_directory(const std::string &client_id,
std::uint64_t handle) -> bool { std::uint64_t handle) -> bool {
recur_mutex_lock directory_lock(directory_mutex_); recur_mutex_lock directory_lock(directory_mutex_);
auto &list = directory_lookup_[client_id]; auto &list = directory_lookup_[client_id];
if (utils::collection_includes(list, handle)) { if (utils::collection::includes(list, handle)) {
utils::remove_element_from(list, handle); utils::collection::remove_element(list, handle);
if (directory_lookup_[client_id].empty()) { if (directory_lookup_[client_id].empty()) {
directory_lookup_.erase(client_id); directory_lookup_.erase(client_id);
} }

View File

@ -26,7 +26,7 @@
#include "events/event_system.hpp" #include "events/event_system.hpp"
#include "events/events.hpp" #include "events/events.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "version.hpp" #include "version.hpp"
namespace repertory::remote_winfsp { namespace repertory::remote_winfsp {

View File

@ -37,7 +37,7 @@
#include "types/remote.hpp" #include "types/remote.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#if !defined(_SH_DENYNO) #if !defined(_SH_DENYNO)
#define _SH_DENYRW 0x10 // deny read/write mode #define _SH_DENYRW 0x10 // deny read/write mode

View File

@ -29,9 +29,10 @@
#include "events/events.hpp" #include "events/events.hpp"
#include "platform/platform.hpp" #include "platform/platform.hpp"
#include "rpc/server/server.hpp" #include "rpc/server/server.hpp"
#include "utils/collection.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory::remote_winfsp { namespace repertory::remote_winfsp {
@ -232,7 +233,7 @@ auto remote_winfsp_drive::mount(const std::vector<std::string> &drive_args)
-> int { -> int {
std::vector<std::string> parsed_drive_args; std::vector<std::string> parsed_drive_args;
const auto force_no_console = utils::collection_includes(drive_args, "-nc"); const auto force_no_console = utils::collection::includes(drive_args, "-nc");
auto enable_console = false; auto enable_console = false;
for (const auto &arg : drive_args) { for (const auto &arg : drive_args) {

View File

@ -32,10 +32,11 @@
#include "providers/i_provider.hpp" #include "providers/i_provider.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "types/startup_exception.hpp" #include "types/startup_exception.hpp"
#include "utils/collection.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {
@ -560,7 +561,7 @@ auto winfsp_drive::Init(PVOID host) -> NTSTATUS {
auto winfsp_drive::mount(const std::vector<std::string> &drive_args) -> int { auto winfsp_drive::mount(const std::vector<std::string> &drive_args) -> int {
std::vector<std::string> parsed_drive_args; std::vector<std::string> parsed_drive_args;
const auto force_no_console = utils::collection_includes(drive_args, "-nc"); const auto force_no_console = utils::collection::includes(drive_args, "-nc");
auto enable_console = false; auto enable_console = false;
for (const auto &arg : drive_args) { for (const auto &arg : drive_args) {

View File

@ -25,7 +25,7 @@
#include "spdlog/async.h" #include "spdlog/async.h"
#include "spdlog/sinks/rotating_file_sink.h" #include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
logging_consumer::logging_consumer(event_level level, logging_consumer::logging_consumer(event_level level,

View File

@ -21,7 +21,7 @@
*/ */
#include "events/event.hpp" #include "events/event.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
namespace repertory { namespace repertory {
auto event_level_from_string(std::string level) -> event_level { auto event_level_from_string(std::string level) -> event_level {

View File

@ -32,13 +32,13 @@
#include "utils/encrypting_reader.hpp" #include "utils/encrypting_reader.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace { namespace {
[[nodiscard]] auto create_resume_entry(const repertory::i_open_file &file) [[nodiscard]] auto
-> json { create_resume_entry(const repertory::i_open_file &file) -> json {
return { return {
{"chunk_size", file.get_chunk_size()}, {"chunk_size", file.get_chunk_size()},
{"path", file.get_api_path()}, {"path", file.get_api_path()},
@ -439,11 +439,10 @@ auto file_manager::open(const std::string &api_path, bool directory,
return open(api_path, directory, ofd, handle, file, nullptr); return open(api_path, directory, ofd, handle, file, nullptr);
} }
auto file_manager::open(const std::string &api_path, bool directory, auto file_manager::open(
const open_file_data &ofd, std::uint64_t &handle, const std::string &api_path, bool directory, const open_file_data &ofd,
std::shared_ptr<i_open_file> &file, std::uint64_t &handle, std::shared_ptr<i_open_file> &file,
std::shared_ptr<i_closeable_open_file> closeable_file) std::shared_ptr<i_closeable_open_file> closeable_file) -> api_error {
-> api_error {
const auto create_and_add_handle = const auto create_and_add_handle =
[&](std::shared_ptr<i_closeable_open_file> cur_file) { [&](std::shared_ptr<i_closeable_open_file> cur_file) {
handle = get_next_handle(); handle = get_next_handle();
@ -696,8 +695,8 @@ auto file_manager::rename_directory(const std::string &from_api_path,
} }
auto file_manager::rename_file(const std::string &from_api_path, auto file_manager::rename_file(const std::string &from_api_path,
const std::string &to_api_path, bool overwrite) const std::string &to_api_path,
-> api_error { bool overwrite) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__); constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (not provider_.is_rename_supported()) { if (not provider_.is_rename_supported()) {

View File

@ -27,7 +27,7 @@
#include "types/startup_exception.hpp" #include "types/startup_exception.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/unix/unix_utils.hpp" #include "utils/unix/unix_utils.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"

View File

@ -21,7 +21,7 @@
*/ */
#include "file_manager/file_manager.hpp" #include "file_manager/file_manager.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
file_manager::open_file_base::open_file_base(std::uint64_t chunk_size, file_manager::open_file_base::open_file_base(std::uint64_t chunk_size,

View File

@ -27,7 +27,7 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/encrypting_reader.hpp" #include "utils/encrypting_reader.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/unix/unix_utils.hpp" #include "utils/unix/unix_utils.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"

View File

@ -28,7 +28,7 @@
#include "types/startup_exception.hpp" #include "types/startup_exception.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/unix/unix_utils.hpp" #include "utils/unix/unix_utils.hpp"
namespace repertory { namespace repertory {

View File

@ -29,7 +29,7 @@
#include "events/events.hpp" #include "events/events.hpp"
#include "file_manager/i_file_manager.hpp" #include "file_manager/i_file_manager.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
namespace repertory { namespace repertory {

View File

@ -29,7 +29,7 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/encrypting_reader.hpp" #include "utils/encrypting_reader.hpp"
#include "utils/encrypt.hpp" #include "utils/encrypt.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
namespace { namespace {

View File

@ -26,8 +26,8 @@
#include "database/db_insert.hpp" #include "database/db_insert.hpp"
#include "database/db_select.hpp" #include "database/db_select.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
namespace repertory { namespace repertory {
meta_db::meta_db(const app_config &cfg) { meta_db::meta_db(const app_config &cfg) {
@ -101,8 +101,8 @@ auto meta_db::get_api_path_list() -> std::vector<std::string> {
return ret; return ret;
} }
auto meta_db::get_item_meta(const std::string &api_path, api_meta_map &meta) auto meta_db::get_item_meta(const std::string &api_path,
-> api_error { api_meta_map &meta) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__); constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto result = db::db_select{*db_, table_name} auto result = db::db_select{*db_, table_name}
@ -283,8 +283,8 @@ auto meta_db::set_item_meta(const std::string &api_path,
return update_item_meta(api_path, existing_meta); return update_item_meta(api_path, existing_meta);
} }
auto meta_db::update_item_meta(const std::string &api_path, api_meta_map meta) auto meta_db::update_item_meta(const std::string &api_path,
-> api_error { api_meta_map meta) -> api_error {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__); constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
auto directory = utils::string::to_bool(meta[META_DIRECTORY]); auto directory = utils::string::to_bool(meta[META_DIRECTORY]);

View File

@ -32,9 +32,9 @@
#include "utils/encrypting_reader.hpp" #include "utils/encrypting_reader.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
namespace repertory { namespace repertory {
s3_provider::s3_provider(app_config &config, i_http_comm &comm) s3_provider::s3_provider(app_config &config, i_http_comm &comm)

View File

@ -29,9 +29,9 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {

View File

@ -28,7 +28,7 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "types/rpc.hpp" #include "types/rpc.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
full_server::full_server(app_config &config, i_provider &provider, full_server::full_server(app_config &config, i_provider &provider,

View File

@ -22,8 +22,40 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "types/startup_exception.hpp" #include "types/startup_exception.hpp"
#include "utils/string.hpp"
namespace repertory { namespace repertory {
auto download_type_from_string(
std::string type, const download_type &default_type) -> download_type {
type = utils::string::to_lower(utils::string::trim(type));
if (type == "direct") {
return download_type::direct;
}
if (type == "fallback") {
return download_type::fallback;
}
if (type == "ring_buffer") {
return download_type::ring_buffer;
}
return default_type;
}
auto download_type_to_string(const download_type &type) -> std::string {
switch (type) {
case download_type::direct:
return "direct";
case download_type::fallback:
return "fallback";
case download_type::ring_buffer:
return "ring_buffer";
default:
return "fallback";
}
}
static const std::unordered_map<api_error, std::string> LOOKUP = { static const std::unordered_map<api_error, std::string> LOOKUP = {
{api_error::success, "success"}, {api_error::success, "success"},
{api_error::access_denied, "access_denied"}, {api_error::access_denied, "access_denied"},

View File

@ -22,9 +22,10 @@
#include "utils/cli_utils.hpp" #include "utils/cli_utils.hpp"
#include "app_config.hpp" #include "app_config.hpp"
#include "utils/collection.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory::utils::cli { namespace repertory::utils::cli {
@ -187,14 +188,16 @@ auto parse_drive_options(
if (new_drive_args[i].find("-o") == 0) { if (new_drive_args[i].find("-o") == 0) {
if (new_drive_args[i].size() == 2) { if (new_drive_args[i].size() == 2) {
if ((i + 1) < drive_args.size()) { if ((i + 1) < drive_args.size()) {
utils::remove_element_from(new_drive_args, new_drive_args[i]); utils::collection::remove_element(new_drive_args,
utils::remove_element_from(new_drive_args, new_drive_args[i]); new_drive_args[i]);
utils::collection::remove_element(new_drive_args,
new_drive_args[i]);
i--; i--;
} }
continue; continue;
} }
utils::remove_element_from(new_drive_args, new_drive_args[i]); utils::collection::remove_element(new_drive_args, new_drive_args[i]);
i--; i--;
continue; continue;
} }

View File

@ -65,30 +65,6 @@ auto decrypt_file_name(std::string_view encryption_token,
return api_error::success; return api_error::success;
} }
auto generate_key(std::string_view encryption_token) -> key_type {
crypto_hash_sha256_state state{};
auto res = crypto_hash_sha256_init(&state);
if (res != 0) {
throw std::runtime_error("failed to initialize sha256|" +
std::to_string(res));
}
res = crypto_hash_sha256_update(
&state, reinterpret_cast<const unsigned char *>(encryption_token.data()),
encryption_token.size());
if (res != 0) {
throw std::runtime_error("failed to update sha256|" + std::to_string(res));
}
key_type ret{};
res = crypto_hash_sha256_final(&state, ret.data());
if (res != 0) {
throw std::runtime_error("failed to finalize sha256|" +
std::to_string(res));
}
return ret;
}
auto read_encrypted_range(const http_range &range, const key_type &key, auto read_encrypted_range(const http_range &range, const key_type &key,
reader_func reader, std::uint64_t total_size, reader_func reader, std::uint64_t total_size,
data_buffer &data) -> api_error { data_buffer &data) -> api_error {

View File

@ -23,8 +23,8 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory::utils::file { namespace repertory::utils::file {
@ -483,51 +483,6 @@ auto get_modified_time(const std::string &path,
return ret; return ret;
} }
auto get_file_size(std::string_view path, std::uint64_t &file_size) -> bool {
file_size = 0U;
auto abs_path = utils::path::absolute(std::string{path});
#if defined(_WIN32)
struct _stat64 st {};
if (_stat64(abs_path.c_str(), &st) != 0) {
#else
#if defined(__APPLE__)
struct stat st {};
if (stat(abs_path.c_str(), &st) != 0) {
#else
struct stat64 st {};
if (stat64(abs_path.c_str(), &st) != 0) {
#endif
#endif
return false;
}
if (st.st_size >= 0) {
file_size = static_cast<std::uint64_t>(st.st_size);
}
return (st.st_size >= 0);
}
auto is_directory(const std::string &path) -> bool {
#if defined(_WIN32)
return ::PathIsDirectory(path.c_str()) != 0;
#else
struct stat st {};
return (not stat(path.c_str(), &st) && S_ISDIR(st.st_mode));
#endif
}
auto is_file(const std::string &path) -> bool {
#if defined(_WIN32)
return (::PathFileExists(path.c_str()) &&
not ::PathIsDirectory(path.c_str()));
#else
struct stat st {};
return (not stat(path.c_str(), &st) && not S_ISDIR(st.st_mode));
#endif
}
auto is_modified_date_older_than(const std::string &path, auto is_modified_date_older_than(const std::string &path,
const std::chrono::hours &hours) -> bool { const std::chrono::hours &hours) -> bool {
auto ret = false; auto ret = false;
@ -580,40 +535,6 @@ auto read_file_lines(const std::string &path) -> std::vector<std::string> {
return ret; return ret;
} }
auto read_json_file(const std::string &path, json &data) -> bool {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
if (not utils::file::is_file(path)) {
return true;
}
try {
std::ifstream file_stream(path.c_str());
if (file_stream.is_open()) {
try {
std::stringstream ss;
ss << file_stream.rdbuf();
std::string json_text = ss.str();
if (not json_text.empty()) {
data = json::parse(json_text.c_str());
}
file_stream.close();
return true;
} catch (const std::exception &e) {
file_stream.close();
throw e;
}
}
} catch (const std::exception &e) {
utils::error::raise_error(function_name, e, path,
"failed to read json file");
}
return false;
}
auto reset_modified_time(const std::string &path) -> bool { auto reset_modified_time(const std::string &path) -> bool {
auto ret = false; auto ret = false;
#if defined(_WIN32) #if defined(_WIN32)
@ -660,24 +581,4 @@ auto retry_delete_file(const std::string &file) -> bool {
return deleted; return deleted;
} }
auto write_json_file(const std::string &path, const json &j) -> bool {
std::string data;
{
std::stringstream ss;
ss << std::setw(2) << j;
data = ss.str();
}
native_file_ptr nf;
auto ret = (native_file::create_or_open(path, nf) == api_error::success);
if (ret) {
std::size_t bytes_written{0U};
ret = nf->truncate(0) &&
nf->write_bytes(reinterpret_cast<const unsigned char *>(data.data()),
data.size(), 0U, bytes_written);
nf->close();
}
return ret;
}
} // namespace repertory::utils::file } // namespace repertory::utils::file

View File

@ -22,7 +22,7 @@
#include "utils/native_file.hpp" #include "utils/native_file.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/unix/unix_utils.hpp" #include "utils/unix/unix_utils.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"

View File

@ -1,204 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/path_utils.hpp"
#include "types/repertory.hpp"
#include "utils/error_utils.hpp"
#include "utils/string_utils.hpp"
#include "utils/utils.hpp"
namespace repertory::utils::path {
auto absolute(std::string path) -> std::string {
path = finalize(path);
#if defined(_WIN32)
if (not path.empty() && ::PathIsRelative(path.c_str())) {
std::string temp;
temp.resize(MAX_PATH + 1);
path = _fullpath(temp.data(), path.c_str(), MAX_PATH);
}
#else
if (not path.empty() && (path[0U] != '/')) {
auto found = false;
auto tmp = path;
do {
auto *res = realpath(&tmp[0U], nullptr);
if (res) {
path = combine(res, {path.substr(tmp.size())});
free(res);
found = true;
} else if (tmp == ".") {
found = true;
} else {
tmp = dirname(&tmp[0U]);
}
} while (not found);
}
#endif
return path;
}
auto combine(std::string path,
const std::vector<std::string> &paths) -> std::string {
return absolute(
std::accumulate(paths.begin(), paths.end(), path,
[](std::string next_path, const auto &path_part) {
if (next_path.empty()) {
return path_part;
}
return next_path + (directory_seperator + path_part);
}));
}
auto create_api_path(std::string path) -> std::string {
if (path.empty() || (path == ".") || (path == "/")) {
return "/";
}
format_path(path, "/", "\\");
if (path.find("./") == 0) {
path = path.substr(1);
}
if (path[0U] != '/') {
path = "/" + path;
}
if ((path != "/") && utils::string::ends_with(path, "/")) {
utils::string::right_trim(path, '/');
}
return path;
}
auto finalize(std::string path) -> std::string {
format_path(path, not_directory_seperator, directory_seperator);
format_path(path, directory_seperator, not_directory_seperator);
if ((path.size() > 1U) &&
(path[path.size() - 1U] == directory_seperator[0U])) {
path = path.substr(0U, path.size() - 1U);
}
#if defined(_WIN32)
if ((path.size() >= 2u) && (path[1U] == ':')) {
path[0U] = utils::string::to_lower(std::string(1U, path[0U]))[0U];
}
#endif
return path;
}
auto format_path(std::string &path, const std::string &sep,
const std::string &not_sep) -> std::string & {
std::replace(path.begin(), path.end(), not_sep[0U], sep[0U]);
while (utils::string::contains(path, sep + sep)) {
utils::string::replace(path, sep + sep, sep);
}
return path;
}
auto get_parent_api_path(const std::string &path) -> std::string {
std::string ret;
if (path != "/") {
ret = path.substr(0, path.rfind('/') + 1);
if (ret != "/") {
ret = utils::string::right_trim(ret, '/');
}
}
return ret;
}
#if !defined(_WIN32)
auto get_parent_directory(std::string path) -> std::string {
auto ret = std::string(dirname(&path[0U]));
if (ret == ".") {
ret = "/";
}
return ret;
}
#endif
auto is_ads_file_path([[maybe_unused]] const std::string &path) -> bool {
#if defined(_WIN32)
return utils::string::contains(path, ":");
#else
return false;
#endif
}
auto is_trash_directory(std::string path) -> bool {
path = create_api_path(utils::string::to_lower(path));
if (utils::string::begins_with(path, "/.trash-") ||
utils::string::begins_with(path, "/.trashes") ||
utils::string::begins_with(path, "/$recycle.bin")) {
return true;
}
return false;
}
auto remove_file_name(std::string path) -> std::string {
path = absolute(path);
#if defined(_WIN32)
::PathRemoveFileSpec(&path[0U]);
path = path.c_str();
#else
if (path != "/") {
auto i = path.size() - 1;
while ((i != 0) && (path[i] != '/')) {
i--;
}
path = (i > 0) ? absolute(path.substr(0, i)) : "/";
}
#endif
return path;
}
#if !defined(_WIN32)
auto resolve(std::string path) -> std::string {
std::string home{};
use_getpwuid(getuid(), [&home](struct passwd *pw) {
home = (pw->pw_dir ? pw->pw_dir : "");
if (home.empty() || ((home == "/") && (getuid() != 0))) {
home = combine("/home", {pw->pw_name});
}
});
return absolute(utils::string::replace(path, "~", home));
}
#endif
auto strip_to_file_name(std::string path) -> std::string {
#if defined(_WIN32)
return ::PathFindFileName(path.c_str());
#else
return utils::string::contains(path, "/") ? basename(&path[0U]) : path;
#endif
}
} // namespace repertory::utils::path

View File

@ -1,230 +0,0 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/string_utils.hpp"
namespace repertory::utils::string {
/* constexpr c++20 */ auto ends_with(std::string_view str,
std::string_view val) -> bool {
if (val.size() > str.size()) {
return false;
}
return std::equal(val.rbegin(), val.rend(), str.rbegin());
}
auto from_bool(bool val) -> std::string {
return std::to_string(static_cast<int>(val));
}
auto from_dynamic_bitset(const boost::dynamic_bitset<> &bitset) -> std::string {
std::stringstream stream;
boost::archive::text_oarchive archive(stream);
archive << bitset;
return stream.str();
}
auto from_utf8(std::string_view str) -> std::wstring {
return str.empty()
? L""
: std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>()
.from_bytes(std::string{str});
}
/* constexpr c++20 */ auto is_numeric(std::string_view str) -> bool {
if ((str.length() > 1U) && (str[0U] == '+' || str[0U] == '-')) {
str = str.substr(1U);
}
if (str.empty()) {
return false;
}
auto has_decimal = false;
return std::find_if(str.begin(), str.end(),
[&has_decimal](
const std::string_view::value_type &cur_ch) -> bool {
if (has_decimal && cur_ch == '.') {
return true;
}
has_decimal = has_decimal || cur_ch == '.';
if (has_decimal) {
return false;
}
return std::isdigit(cur_ch) == 0;
}) == str.end();
}
auto join(const std::vector<std::string> &arr,
const char &delim) -> std::string {
if (arr.empty()) {
return "";
}
return std::accumulate(
std::next(arr.begin()), arr.end(), arr[0U],
[&delim](auto str, const auto &cur) { return str + delim + cur; });
}
auto left_trim(std::string &str) -> std::string & {
return left_trim(str, ' ');
}
auto left_trim(std::string &str, const char &trim_ch) -> std::string & {
str.erase(0, str.find_first_not_of(trim_ch));
return str;
}
auto replace(std::string &src, const char &character,
const char &with) -> std::string & {
std::replace(src.begin(), src.end(), character, with);
return src;
}
auto replace(std::string &src, const std::string &find, const std::string &with,
size_t start_pos) -> std::string & {
if (!src.empty() && (start_pos < src.size())) {
while ((start_pos = src.find(find, start_pos)) != std::string::npos) {
src.replace(start_pos, find.size(), with);
start_pos += with.size();
}
}
return src;
}
auto replace_copy(std::string src, const char &character,
const char &with) -> std::string {
std::replace(src.begin(), src.end(), character, with);
return src;
}
auto replace_copy(std::string src, const std::string &find,
const std::string &with, size_t start_pos) -> std::string {
return replace(src, find, with, start_pos);
}
auto right_trim(std::string &str) -> std::string & {
return right_trim(str, ' ');
}
auto right_trim(std::string &str, const char &trim_ch) -> std::string & {
str.erase(str.find_last_not_of(trim_ch) + 1);
return str;
}
auto split(const std::string &str, const char &delim,
bool should_trim) -> std::vector<std::string> {
std::vector<std::string> ret;
std::stringstream stream(str);
std::string item;
while (std::getline(stream, item, delim)) {
ret.push_back(should_trim ? trim(item) : item);
}
return ret;
}
auto to_bool(std::string val) -> bool {
auto ret = false;
trim(val);
if (is_numeric(val)) {
if (contains(val, ".")) {
ret = (to_double(val) != 0.0);
} else {
std::istringstream(val) >> ret;
}
} else {
std::istringstream(to_lower(val)) >> std::boolalpha >> ret;
}
return ret;
}
auto to_double(const std::string &str) -> double { return std::stod(str); }
auto to_dynamic_bitset(const std::string &val) -> boost::dynamic_bitset<> {
std::stringstream stream(val);
boost::dynamic_bitset<> bitset;
boost::archive::text_iarchive archive(stream);
archive >> bitset;
return bitset;
}
auto to_int32(const std::string &val) -> std::int32_t { return std::stoi(val); }
auto to_int64(const std::string &val) -> std::int64_t {
return std::stoll(val);
}
auto to_lower(std::string str) -> std::string {
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return str;
}
auto to_size_t(const std::string &val) -> std::size_t {
return static_cast<std::size_t>(std::stoull(val));
}
auto to_uint8(const std::string &val) -> std::uint8_t {
return static_cast<std::uint8_t>(std::stoul(val));
}
auto to_uint16(const std::string &val) -> std::uint16_t {
return static_cast<std::uint16_t>(std::stoul(val));
}
auto to_uint32(const std::string &val) -> std::uint32_t {
return static_cast<std::uint32_t>(std::stoul(val));
}
auto to_uint64(const std::string &val) -> std::uint64_t {
return std::stoull(val);
}
auto to_upper(std::string str) -> std::string {
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
return str;
}
auto to_utf8(std::string_view str) -> std::string { return std::string{str}; }
auto to_utf8(std::wstring_view str) -> std::string {
return str.empty()
? ""
: std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>()
.to_bytes(std::wstring{str});
}
auto trim(std::string &str) -> std::string & {
return right_trim(left_trim(str));
}
auto trim(std::string &str, const char &trim_ch) -> std::string & {
return right_trim(left_trim(str, trim_ch), trim_ch);
}
auto trim_copy(std::string str) -> std::string {
return right_trim(left_trim(str));
}
auto trim_copy(std::string str, const char &trim_ch) -> std::string {
return right_trim(left_trim(str, trim_ch), trim_ch);
}
} // namespace repertory::utils::string

View File

@ -24,15 +24,8 @@
#include "utils/unix/unix_utils.hpp" #include "utils/unix/unix_utils.hpp"
#include "utils/error_utils.hpp" #include "utils/error_utils.hpp"
#include "utils/utils.hpp"
namespace repertory::utils { namespace repertory::utils {
#if !defined(__APPLE__)
auto convert_to_uint64(const pthread_t &thread) -> std::uint64_t {
return static_cast<std::uint64_t>(thread);
}
#endif
auto from_api_error(const api_error &err) -> int { auto from_api_error(const api_error &err) -> int {
switch (err) { switch (err) {
case api_error::access_denied: case api_error::access_denied:
@ -100,30 +93,6 @@ auto from_api_error(const api_error &err) -> int {
} }
} }
auto get_last_error_code() -> int { return errno; }
auto get_thread_id() -> std::uint64_t {
return convert_to_uint64(pthread_self());
}
auto is_uid_member_of_group(const uid_t &uid, const gid_t &gid) -> bool {
std::vector<gid_t> groups{};
use_getpwuid(uid, [&groups](struct passwd *pass) {
int group_count{};
if (getgrouplist(pass->pw_name, pass->pw_gid, nullptr, &group_count) < 0) {
groups.resize(static_cast<std::size_t>(group_count));
#if defined(__APPLE__)
getgrouplist(pass->pw_name, pass->pw_gid,
reinterpret_cast<int *>(groups.data()), &group_count);
#else
getgrouplist(pass->pw_name, pass->pw_gid, groups.data(), &group_count);
#endif
}
});
return collection_includes(groups, gid);
}
auto to_api_error(int err) -> api_error { auto to_api_error(int err) -> api_error {
switch (abs(err)) { switch (abs(err)) {
case 0: case 0:
@ -192,8 +161,6 @@ auto to_api_error(int err) -> api_error {
} }
} }
void set_last_error_code(int error_code) { errno = error_code; }
auto unix_error_to_windows(int err) -> std::int32_t { auto unix_error_to_windows(int err) -> std::int32_t {
switch (err) { switch (err) {
case 0: case 0:
@ -238,21 +205,6 @@ auto unix_time_to_windows_time(const remote::file_time &file_time) -> UINT64 {
return (file_time / 100ULL) + 116444736000000000ULL; return (file_time / 100ULL) + 116444736000000000ULL;
} }
void use_getpwuid(uid_t uid,
std::function<void(struct passwd *pass)> callback) {
constexpr const auto *function_name = static_cast<const char *>(__FUNCTION__);
static std::mutex mtx{};
mutex_lock lock{mtx};
auto *temp_pw = getpwuid(uid);
if (temp_pw == nullptr) {
utils::error::raise_error(function_name, "'getpwuid' returned nullptr");
return;
}
callback(temp_pw);
}
void windows_create_to_unix(const UINT32 &create_options, void windows_create_to_unix(const UINT32 &create_options,
const UINT32 &granted_access, std::uint32_t &flags, const UINT32 &granted_access, std::uint32_t &flags,
remote::file_mode &mode) { remote::file_mode &mode) {

View File

@ -27,9 +27,10 @@
#include "providers/i_provider.hpp" #include "providers/i_provider.hpp"
#include "types/startup_exception.hpp" #include "types/startup_exception.hpp"
#include "utils/com_init_wrapper.hpp" #include "utils/com_init_wrapper.hpp"
#include "utils/common.hpp"
#include "utils/native_file.hpp" #include "utils/native_file.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
namespace repertory::utils { namespace repertory::utils {
void calculate_allocation_size(bool directory, std::uint64_t file_size, void calculate_allocation_size(bool directory, std::uint64_t file_size,
@ -51,47 +52,6 @@ void calculate_allocation_size(bool directory, std::uint64_t file_size,
allocation_meta_size = std::to_string(allocation_size); allocation_meta_size = std::to_string(allocation_size);
} }
auto calculate_read_size(const uint64_t &total_size, std::size_t read_size,
const uint64_t &offset) -> std::size_t {
return static_cast<std::size_t>(
((offset + read_size) > total_size)
? ((offset < total_size) ? total_size - offset : 0U)
: read_size);
}
auto compare_version_strings(std::string version1,
std::string version2) -> int {
if (utils::string::contains(version1, "-")) {
version1 = utils::string::split(version1, '-')[0U];
}
if (utils::string::contains(version2, "-")) {
version2 = utils::string::split(version2, '-')[0U];
}
auto nums1 = utils::string::split(version1, '.');
auto nums2 = utils::string::split(version2, '.');
while (nums1.size() > nums2.size()) {
nums2.emplace_back("0");
}
while (nums2.size() > nums1.size()) {
nums1.emplace_back("0");
}
for (std::size_t i = 0U; i < nums1.size(); i++) {
const auto int1 = utils::string::to_uint32(nums1[i]);
const auto int2 = utils::string::to_uint32(nums2[i]);
const auto res = std::memcmp(&int1, &int2, sizeof(int1));
if (res != 0) {
return res;
}
}
return 0;
}
auto convert_api_date(const std::string &date) -> std::uint64_t { auto convert_api_date(const std::string &date) -> std::uint64_t {
// 2009-10-12T17:50:30.000Z // 2009-10-12T17:50:30.000Z
const auto date_parts = utils::string::split(date, '.'); const auto date_parts = utils::string::split(date, '.');
@ -118,165 +78,14 @@ auto create_curl() -> CURL * {
return reset_curl(curl_easy_init()); return reset_curl(curl_easy_init());
} }
auto create_uuid_string() -> std::string {
std::random_device random_device;
auto seed_data = std::array<int, std::mt19937::state_size>{};
std::generate(std::begin(seed_data), std::end(seed_data),
std::ref(random_device));
std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
std::mt19937 generator(seq);
uuids::uuid_random_generator gen{generator};
return uuids::to_string(gen());
}
auto create_volume_label(const provider_type &prov) -> std::string { auto create_volume_label(const provider_type &prov) -> std::string {
return "repertory_" + app_config::get_provider_name(prov); return "repertory_" + app_config::get_provider_name(prov);
} }
auto download_type_from_string(
std::string type, const download_type &default_type) -> download_type {
type = utils::string::to_lower(utils::string::trim(type));
if (type == "direct") {
return download_type::direct;
}
if (type == "fallback") {
return download_type::fallback;
}
if (type == "ring_buffer") {
return download_type::ring_buffer;
}
return default_type;
}
auto download_type_to_string(const download_type &type) -> std::string {
switch (type) {
case download_type::direct:
return "direct";
case download_type::fallback:
return "fallback";
case download_type::ring_buffer:
return "ring_buffer";
default:
return "fallback";
}
}
#if defined(_WIN32)
// https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/
auto filetime_to_unix_time(const FILETIME &ft) -> remote::file_time {
LARGE_INTEGER date{};
date.HighPart = static_cast<LONG>(ft.dwHighDateTime);
date.LowPart = ft.dwLowDateTime;
date.QuadPart -= 116444736000000000LL;
return static_cast<remote::file_time>(date.QuadPart) * 100ULL;
}
void unix_time_to_filetime(const remote::file_time &ts, FILETIME &ft) {
const auto win_time = (ts / 100ULL) + 116444736000000000ULL;
ft.dwHighDateTime = static_cast<DWORD>(win_time >> 32U);
ft.dwLowDateTime = win_time & 0xFFFFFFFF;
}
#endif
auto generate_random_string(std::uint16_t length) -> std::string {
std::string ret;
ret.resize(length);
for (std::uint16_t i = 0U; i < length; i++) {
do {
ret[i] = static_cast<char>(repertory_rand<std::uint8_t>() % 74 + 48);
} while (((ret[i] >= 91) && (ret[i] <= 96)) ||
((ret[i] >= 58) && (ret[i] <= 64)));
}
return ret;
}
auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD { auto get_attributes_from_meta(const api_meta_map &meta) -> DWORD {
return static_cast<DWORD>(utils::string::to_uint32(meta.at(META_ATTRIBUTES))); return static_cast<DWORD>(utils::string::to_uint32(meta.at(META_ATTRIBUTES)));
} }
auto get_environment_variable(const std::string &variable) -> std::string {
static std::mutex mtx{};
mutex_lock lock{mtx};
const auto *val = std::getenv(variable.c_str());
auto ret = std::string(val == nullptr ? "" : val);
return ret;
}
auto get_file_time_now() -> std::uint64_t {
#if defined(_WIN32)
SYSTEMTIME st{};
::GetSystemTime(&st);
FILETIME ft{};
::SystemTimeToFileTime(&st, &ft);
return static_cast<std::uint64_t>(
(reinterpret_cast<LARGE_INTEGER *>(&ft))->QuadPart);
#else
return get_time_now();
#endif
}
void get_local_time_now(struct tm &local_time) {
memset(&local_time, 0, sizeof(local_time));
const auto now =
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
#if defined(_WIN32)
localtime_s(&local_time, &now);
#else
localtime_r(&now, &local_time);
#endif
}
auto get_next_available_port(std::uint16_t first_port,
std::uint16_t &available_port) -> bool {
using namespace boost::asio;
using ip::tcp;
boost::system::error_code error_code{};
while (first_port != 0U) {
io_service svc{};
tcp::acceptor acceptor(svc);
acceptor.open(tcp::v4(), error_code) ||
acceptor.bind({tcp::v4(), first_port}, error_code);
if (not error_code) {
break;
}
++first_port;
}
if (not error_code) {
available_port = first_port;
}
return not error_code;
}
auto get_time_now() -> std::uint64_t {
#if defined(_WIN32)
return static_cast<std::uint64_t>(
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
#else
#if defined(__APPLE__)
return std::chrono::nanoseconds(
std::chrono::system_clock::now().time_since_epoch())
.count();
#else
return static_cast<std::uint64_t>(
std::chrono::nanoseconds(
std::chrono::high_resolution_clock::now().time_since_epoch())
.count());
#endif
#endif
}
auto reset_curl(CURL *curl_handle) -> CURL * { auto reset_curl(CURL *curl_handle) -> CURL * {
curl_easy_reset(curl_handle); curl_easy_reset(curl_handle);
#if defined(__APPLE__) #if defined(__APPLE__)

View File

@ -25,7 +25,7 @@
#include "types/startup_exception.hpp" #include "types/startup_exception.hpp"
#include "utils/com_init_wrapper.hpp" #include "utils/com_init_wrapper.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#if !defined(STATUS_DEVICE_INSUFFICIENT_RESOURCES) #if !defined(STATUS_DEVICE_INSUFFICIENT_RESOURCES)
#define STATUS_DEVICE_INSUFFICIENT_RESOURCES static_cast<NTSTATUS>(0xC0000468L) #define STATUS_DEVICE_INSUFFICIENT_RESOURCES static_cast<NTSTATUS>(0xC0000468L)
@ -232,10 +232,6 @@ auto unix_open_flags_to_flags_and_perms(const remote::file_mode & /*mode*/,
return ret; return ret;
} }
auto time64_to_unix_time(const __time64_t &t) -> remote::file_time {
return static_cast<remote::file_time>(t * NANOS_PER_SECOND);
}
} // namespace repertory::utils } // namespace repertory::utils
#endif // _WIN32 #endif // _WIN32

View File

@ -30,7 +30,7 @@
#include "utils/cli_utils.hpp" #include "utils/cli_utils.hpp"
#include "utils/com_init_wrapper.hpp" #include "utils/com_init_wrapper.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#if defined(_WIN32) #if defined(_WIN32)
#include "drives/winfsp/remotewinfsp/remote_client.hpp" #include "drives/winfsp/remotewinfsp/remote_client.hpp"

View File

@ -29,7 +29,7 @@
#include "types/remote.hpp" #include "types/remote.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {

View File

@ -27,7 +27,7 @@
#include "drives/winfsp/i_winfsp_drive.hpp" #include "drives/winfsp/i_winfsp_drive.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {

View File

@ -24,6 +24,7 @@
#include "test_common.hpp" #include "test_common.hpp"
#include "utils/collection.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {
@ -59,7 +60,7 @@ private:
public: public:
void process_event(const event &event) { void process_event(const event &event) {
unique_mutex_lock l(mutex_); unique_mutex_lock l(mutex_);
utils::remove_element_from(event_names_, event.get_name()); utils::collection::remove_element(event_names_, event.get_name());
fired_event_names_.emplace_back(event.get_name()); fired_event_names_.emplace_back(event.get_name());
notify_.notify_all(); notify_.notify_all();
l.unlock(); l.unlock();

View File

@ -23,8 +23,8 @@
#include "app_config.hpp" #include "app_config.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
namespace repertory { namespace repertory {
class config_test : public ::testing::Test { class config_test : public ::testing::Test {

View File

@ -24,7 +24,7 @@
#include "database/db_common.hpp" #include "database/db_common.hpp"
#include "database/db_insert.hpp" #include "database/db_insert.hpp"
#include "database/db_select.hpp" #include "database/db_select.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
TEST(database, db_insert) { TEST(database, db_insert) {

View File

@ -24,7 +24,7 @@
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/encrypting_reader.hpp" #include "utils/encrypting_reader.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
static auto get_source_file_name() -> std::string { static auto get_source_file_name() -> std::string {

View File

@ -26,7 +26,7 @@
#include "mocks/mock_upload_manager.hpp" #include "mocks/mock_upload_manager.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/event_capture.hpp" #include "utils/event_capture.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
static constexpr const std::size_t test_chunk_size = 1024u; static constexpr const std::size_t test_chunk_size = 1024u;

View File

@ -25,7 +25,7 @@
#include "mocks/mock_provider.hpp" #include "mocks/mock_provider.hpp"
#include "mocks/mock_upload_manager.hpp" #include "mocks/mock_upload_manager.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/unix/unix_utils.hpp" #include "utils/unix/unix_utils.hpp"
namespace repertory { namespace repertory {

View File

@ -33,9 +33,9 @@
#include "utils/event_capture.hpp" #include "utils/event_capture.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/native_file.hpp" #include "utils/native_file.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/polling.hpp" #include "utils/polling.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {

View File

@ -25,7 +25,7 @@
#include "mocks/mock_provider.hpp" #include "mocks/mock_provider.hpp"
#include "mocks/mock_upload_manager.hpp" #include "mocks/mock_upload_manager.hpp"
#include "utils/event_capture.hpp" #include "utils/event_capture.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
static constexpr const std::size_t test_chunk_size = 1024u; static constexpr const std::size_t test_chunk_size = 1024u;

View File

@ -21,7 +21,7 @@
*/ */
#include "test_common.hpp" #include "test_common.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
namespace repertory { namespace repertory {
TEST(path_utils, combine) { TEST(path_utils, combine) {

View File

@ -29,9 +29,10 @@
#include "providers/i_provider.hpp" #include "providers/i_provider.hpp"
#include "providers/s3/s3_provider.hpp" #include "providers/s3/s3_provider.hpp"
#include "providers/sia/sia_provider.hpp" #include "providers/sia/sia_provider.hpp"
#include "utils/collection.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
#include "gtest/gtest.h" #include "gtest/gtest.h"
@ -562,8 +563,8 @@ static void get_file_list(const app_config &cfg, i_provider &provider) {
for (auto &file : list) { for (auto &file : list) {
decrypt_parts(cfg, file.api_parent); decrypt_parts(cfg, file.api_parent);
decrypt_parts(cfg, file.api_path); decrypt_parts(cfg, file.api_path);
utils::remove_element_from(expected_parents, file.api_parent); utils::collection::remove_element(expected_parents, file.api_parent);
utils::remove_element_from(expected_paths, file.api_path); utils::collection::remove_element(expected_paths, file.api_path);
} }
EXPECT_TRUE(expected_parents.empty()); EXPECT_TRUE(expected_parents.empty());
EXPECT_TRUE(expected_paths.empty()); EXPECT_TRUE(expected_paths.empty());

View File

@ -21,7 +21,7 @@
*/ */
#include "test_common.hpp" #include "test_common.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
namespace repertory { namespace repertory {
TEST(string_utils, is_numeric) { TEST(string_utils, is_numeric) {

View File

@ -22,7 +22,7 @@
#include "test_common.hpp" #include "test_common.hpp"
#include "types/repertory.hpp" #include "types/repertory.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {

View File

@ -22,8 +22,8 @@
#include "test_common.hpp" #include "test_common.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/path_utils.hpp" #include "utils/path.hpp"
#include "utils/string_utils.hpp" #include "utils/string.hpp"
#include "utils/utils.hpp" #include "utils/utils.hpp"
namespace repertory { namespace repertory {

View File

@ -23,6 +23,10 @@ if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_STATIC_LINK}" == "OFF" ]; th
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libboost*.dll) PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libboost*.dll)
fi fi
if [ "${PROJECT_ENABLE_BACKWARD_CPP}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/msvcr90.dll)
fi
if [ "${PROJECT_ENABLE_CLI11}" == "ON" ]; then if [ "${PROJECT_ENABLE_CLI11}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libcli11*.dll) PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libcli11*.dll)
fi fi
@ -31,11 +35,14 @@ if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_STATIC_LINK}" == "OFF" ]; th
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libFLAC*.dll) PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libFLAC*.dll)
fi fi
if [ "${PROJECT_ENABLE_FMT}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libfmt*.dll)
fi
if [ "${PROJECT_ENABLE_FONTCONFIG}" == "ON" ]; then if [ "${PROJECT_ENABLE_FONTCONFIG}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=( PROJECT_MINGW64_COPY_DEPENDENCIES+=(
/mingw64/bin/libexpat*.dll /mingw64/bin/libexpat*.dll
/mingw64/bin/libfontconfig*.dll /mingw64/bin/libfontconfig*.dll
/mingw64/bin/libpng*.dll
) )
fi fi
@ -47,6 +54,11 @@ if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_STATIC_LINK}" == "OFF" ]; th
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libcurl*.dll) PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libcurl*.dll)
fi fi
if [ "${PROJECT_ENABLE_LIBJPEG_TURBO}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libjpeg*.dll)
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libturbo*.dll)
fi
if [ "${PROJECT_ENABLE_LIBSODIUM}" == "ON" ]; then if [ "${PROJECT_ENABLE_LIBSODIUM}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libsodium*.dll) PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libsodium*.dll)
fi fi
@ -70,6 +82,14 @@ if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_STATIC_LINK}" == "OFF" ]; th
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libopenal*.dll) PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libopenal*.dll)
fi fi
if [ "${PROJECT_ENABLE_LIBPNG}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libpng*.dll)
fi
if [ "${PROJECT_ENABLE_NANA}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libnana*.dll)
fi
if [ "${PROJECT_ENABLE_PUGIXML}" == "ON" ]; then if [ "${PROJECT_ENABLE_PUGIXML}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libpugi*.dll) PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libpugi*.dll)
fi fi
@ -82,11 +102,15 @@ if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_STATIC_LINK}" == "OFF" ]; th
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libsecp256k1*.dll) PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libsecp256k1*.dll)
fi fi
if [ "${PROJECT_ENABLE_SDL}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/SDL*.dll)
fi
if [ "${PROJECT_ENABLE_SFML}" == "ON" ]; then if [ "${PROJECT_ENABLE_SFML}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libsfml*.dll) PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libsfml*.dll)
fi fi
if [ "${PROJECT_ENABLE_SFML}" == "ON" ]; then if [ "${PROJECT_ENABLE_SPDLOG}" == "ON" ]; then
PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libspdlog*.dll) PROJECT_MINGW64_COPY_DEPENDENCIES+=(/mingw64/bin/libspdlog*.dll)
fi fi

View File

@ -41,11 +41,24 @@ done
PROJECT_APP_LIST=() PROJECT_APP_LIST=()
PROJECT_CMAKE_OPTS="" PROJECT_CMAKE_OPTS=""
PROJECT_IS_ALPINE=0 PROJECT_IS_ALPINE=0
PROJECT_IS_ARM64=0
PROJECT_MINGW64_COPY_DEPENDENCIES=() PROJECT_MINGW64_COPY_DEPENDENCIES=()
PROJECT_MSYS2_PACKAGE_LIST=() PROJECT_MSYS2_PACKAGE_LIST=()
PROJECT_REQUIRE_ALPINE=OFF PROJECT_REQUIRE_ALPINE=OFF
PROJECT_STATIC_LINK=OFF PROJECT_STATIC_LINK=OFF
if [ "${PROJECT_BUILD_ARCH}" == "" ]; then
PROJECT_BUILD_ARCH=x86_64
elif [ "${PROJECT_BUILD_ARCH}" == "aarch64" ]; then
PROJECT_IS_ARM64=1
fi
if [ "${PROJECT_BUILD_ARCH}" == "x86_64" ]; then
PROJECT_BUILD_ARCH2="x86-64"
else
PROJECT_BUILD_ARCH2="${PROJECT_BUILD_ARCH}"
fi
if [ -f /etc/alpine-release ]; then if [ -f /etc/alpine-release ]; then
PROJECT_IS_ALPINE=1 PROJECT_IS_ALPINE=1
fi fi
@ -110,22 +123,13 @@ if [ "${PROJECT_ENABLE_BOOST}" == "ON" ]; then
PROJECT_ENABLE_OPENSSL=ON PROJECT_ENABLE_OPENSSL=ON
fi fi
if [ "${PROJECT_ENABLE_WXWIDGETS}" == "ON" ] || [ "${PROJECT_ENABLE_NANA}" == "ON" ]; then if [ "${PROJECT_ENABLE_FONTCONFIG}" == "ON" ] || [ "${PROJECT_ENABLE_NANA}" == "ON" ] || [ "${PROJECT_ENABLE_WXWIDGETS}" == "ON" ]; then
PROJECT_ENABLE_LIBJPEG_TURBO=ON PROJECT_ENABLE_LIBJPEG_TURBO=ON
PROJECT_ENABLE_LIBPNG=ON PROJECT_ENABLE_LIBPNG=ON
fi fi
PROJECT_IS_ARM64=0 if [ "${PROJECT_IS_MINGW}" == "1" ]; then
if [ "${PROJECT_BUILD_ARCH}" == "" ]; then PROJECT_ENABLE_BACKWARD_CPP=OFF
PROJECT_BUILD_ARCH=x86_64
elif [ "${PROJECT_BUILD_ARCH}" == "aarch64" ]; then
PROJECT_IS_ARM64=1
fi
if [ "${PROJECT_BUILD_ARCH}" == "x86_64" ]; then
PROJECT_BUILD_ARCH2="x86-64"
else
PROJECT_BUILD_ARCH2="${PROJECT_BUILD_ARCH}"
fi fi
if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_IS_MINGW_UNIX}" != "1" ]; then if [ "${PROJECT_IS_MINGW}" == "1" ] && [ "${PROJECT_IS_MINGW_UNIX}" != "1" ]; then

36
support/3rd_party/include/utils/all.hpp vendored Normal file
View File

@ -0,0 +1,36 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_ALL_HPP_
#define REPERTORY_INCLUDE_UTILS_ALL_HPP_
#include "utils/config.hpp"
#include "utils/collection.hpp"
#include "utils/com_init_wrapper.hpp"
#include "utils/common.hpp"
#include "utils/path.hpp"
#include "utils/string.hpp"
#include "utils/time.hpp"
#include "utils/unix.hpp"
#include "utils/windows.hpp"
#endif // REPERTORY_INCLUDE_UTILS_ALL_HPP_

View File

@ -128,18 +128,22 @@ Decode(std::string_view input) {
out.resize(out_len); out.resize(out_len);
for (std::size_t i = 0U, j = 0U; i < in_len;) { for (std::size_t i = 0U, j = 0U; i < in_len;) {
std::uint32_t a = input[i] == '=' std::uint32_t a =
input.at(i) == '='
? 0U & i++ ? 0U & i++
: kDecodingTable[static_cast<int>(input[i++])]; : kDecodingTable[static_cast<unsigned char>(input.at(i++))];
std::uint32_t b = input[i] == '=' std::uint32_t b =
input.at(i) == '='
? 0U & i++ ? 0U & i++
: kDecodingTable[static_cast<int>(input[i++])]; : kDecodingTable[static_cast<unsigned char>(input.at(i++))];
std::uint32_t c = input[i] == '=' std::uint32_t c =
input.at(i) == '='
? 0U & i++ ? 0U & i++
: kDecodingTable[static_cast<int>(input[i++])]; : kDecodingTable[static_cast<unsigned char>(input.at(i++))];
std::uint32_t d = input[i] == '=' std::uint32_t d =
input.at(i) == '='
? 0U & i++ ? 0U & i++
: kDecodingTable[static_cast<int>(input[i++])]; : kDecodingTable[static_cast<unsigned char>(input.at(i++))];
std::uint32_t triple = std::uint32_t triple =
(a << 3U * 6U) + (b << 2U * 6U) + (c << 1U * 6U) + (d << 0U * 6U); (a << 3U * 6U) + (b << 2U * 6U) + (c << 1U * 6U) + (d << 0U * 6U);

View File

@ -0,0 +1,133 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_COLLECTION_HPP_
#define REPERTORY_INCLUDE_UTILS_COLLECTION_HPP_
#include "utils/config.hpp"
namespace repertory::utils::collection {
template <typename col_t>
[[nodiscard]] inline auto
excludes(const col_t &collection,
const typename col_t::value_type &val) -> bool;
template <typename col_t>
[[nodiscard]] inline auto
includes(const col_t &collection,
const typename col_t::value_type &val) -> bool;
template <typename val_t>
[[nodiscard]] inline auto from_hex_string(std::string_view str,
val_t &val) -> bool;
template <typename val_t>
[[nodiscard]] inline auto from_hex_string(std::wstring_view str,
val_t &val) -> bool;
template <typename col_t>
inline auto remove_element(col_t &collection,
const typename col_t::value_type &value) -> col_t &;
template <typename col_t>
[[nodiscard]] inline auto to_hex_string(const col_t &collection) -> std::string;
template <typename col_t>
[[nodiscard]] inline auto
to_hex_wstring(const col_t &collection) -> std::wstring;
template <typename col_t>
inline auto excludes(const col_t &collection,
const typename col_t::value_type &val) -> bool {
return std::find(collection.begin(), collection.end(), val) ==
collection.end();
}
template <typename col_t>
inline auto includes(const col_t &collection,
const typename col_t::value_type &val) -> bool {
return std::find(collection.begin(), collection.end(), val) !=
collection.end();
}
template <typename val_t, typename string_t>
[[nodiscard]] inline auto
from_hex_string_t(std::basic_string_view<typename string_t::value_type> str,
val_t &val) -> bool {
static constexpr const auto base16{16};
val.clear();
if (not(str.length() % 2U)) {
for (std::size_t i = 0U; i < str.length(); i += 2U) {
val.emplace_back(static_cast<typename val_t::value_type>(
std::strtol(string_t{str.substr(i, 2U)}.c_str(), nullptr, base16)));
}
return true;
}
return false;
}
template <typename col_t>
inline auto remove_element(col_t &collection,
const typename col_t::value_type &value) -> col_t & {
collection.erase(std::remove(collection.begin(), collection.end(), value),
collection.end());
return collection;
}
template <typename col_t, typename string_t>
[[nodiscard]] inline auto to_hex_string_t(const col_t &collection) -> string_t {
static_assert(sizeof(typename col_t::value_type) == 1U,
"value_type must be 1 byte in size");
static constexpr const auto mask = 0xFF;
std::basic_stringstream<typename string_t::value_type> stream{};
for (auto &&val : collection) {
stream << std::setfill('0') << std::setw(2) << std::hex
<< (static_cast<std::uint32_t>(val) & mask);
}
return stream.str();
}
template <typename val_t>
inline auto from_hex_string(std::string_view str, val_t &val) -> bool {
return from_hex_string_t<val_t, std::string>(str, val);
}
template <typename val_t>
inline auto from_hex_string(std::wstring_view str, val_t &val) -> bool {
return from_hex_string_t<val_t, std::wstring>(str, val);
}
template <typename col_t>
inline auto to_hex_string(const col_t &collection) -> std::string {
return to_hex_string_t<col_t, std::string>(collection);
}
template <typename col_t>
inline auto to_hex_wstring(const col_t &collection) -> std::wstring {
return to_hex_string_t<col_t, std::wstring>(collection);
}
} // namespace repertory::utils::collection
#endif // REPERTORY_INCLUDE_UTILS_COLLECTION_HPP_

View File

@ -19,11 +19,13 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
*/ */
#ifndef INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_ #ifndef REPERTORY_INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_
#define INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_ #define REPERTORY_INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_
#if defined(_WIN32) #if defined(_WIN32)
namespace repertory { #include "utils/config.hpp"
namespace repertory::utils {
class com_init_wrapper { class com_init_wrapper {
public: public:
com_init_wrapper() com_init_wrapper()
@ -37,9 +39,9 @@ public:
} }
private: private:
const BOOL uninit_; BOOL uninit_;
}; };
} // namespace repertory } // namespace repertory::utils
#endif // _WIN32 #endif // defined(_WIN32)
#endif // INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_ #endif // REPERTORY_INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_

View File

@ -0,0 +1,111 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_COMMON_HPP_
#define REPERTORY_INCLUDE_UTILS_COMMON_HPP_
#include "utils/config.hpp"
namespace repertory::utils {
struct result final {
std::string_view function_name;
bool ok{false};
std::string reason{};
[[nodiscard]] operator bool() const { return ok; }
};
[[nodiscard]] inline auto
calculate_read_size(std::uint64_t total_size, std::size_t read_size,
std::uint64_t offset) -> std::size_t {
return static_cast<std::size_t>(
((offset + read_size) > total_size)
? ((offset < total_size) ? total_size - offset : 0U)
: read_size);
}
[[nodiscard]] auto
compare_version_strings(std::string version1,
std::string version2) -> std::int32_t;
[[nodiscard]] auto
compare_version_strings(std::wstring_view version1,
std::wstring_view version2) -> std::int32_t;
#if defined(PROJECT_ENABLE_STDUUID)
[[nodiscard]] auto create_uuid_string() -> std::string;
[[nodiscard]] auto create_uuid_wstring() -> std::wstring;
#endif // defined(PROJECT_ENABLE_STDUUID)
#if defined(PROJECT_ENABLE_LIBSODIUM)
template <typename data_type>
[[nodiscard]] inline auto generate_random() -> data_type;
template <typename data_type>
[[nodiscard]] inline auto
generate_random_between(const data_type &begin,
const data_type &end) -> data_type;
[[nodiscard]] auto generate_random_string(std::uint16_t length) -> std::string;
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
[[nodiscard]] auto
get_environment_variable(std::string_view variable) -> std::string;
[[nodiscard]] auto
get_environment_variable(std::wstring_view variable) -> std::wstring;
#if defined(PROJECT_ENABLE_BOOST)
[[nodiscard]] auto
get_next_available_port(std::uint16_t first_port,
std::uint16_t &available_port) -> bool;
#endif // defined(PROJECT_ENABLE_BOOST)
[[nodiscard]] auto resolve_variables(std::string str) -> std::string;
[[nodiscard]] auto resolve_variables(std::wstring_view str) -> std::wstring;
// template implementations
template <typename val_t>
[[nodiscard]] inline auto divide_with_ceiling(const val_t &n,
const val_t &d) -> val_t {
return n ? (n / d) + (n % d != 0) : 0;
}
#if defined(PROJECT_ENABLE_LIBSODIUM)
template <typename data_type>
[[nodiscard]] inline auto generate_random() -> data_type {
data_type ret{};
randombytes_buf(&ret, sizeof(ret));
return ret;
}
template <typename data_type>
[[nodiscard]] inline auto
generate_random_between(const data_type &begin,
const data_type &end) -> data_type {
return begin + generate_random<data_type>() % ((end + data_type{1}) - begin);
}
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
} // namespace repertory::utils
#endif // REPERTORY_INCLUDE_UTILS_COMMON_HPP_

View File

@ -0,0 +1,313 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_CONFIG_HPP_
#define REPERTORY_INCLUDE_UTILS_CONFIG_HPP_
#if defined(_WIN32)
#define WINVER 0x0602
#define _WIN32_WINNT WINVER
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#if defined(PROJECT_ENABLE_WINFSP)
#include <sddl.h>
#endif // defined(PROJECT_ENABLE_WINFSP)
#include <direct.h>
#include <errno.h>
#include <fcntl.h>
#include <io.h>
#include <iphlpapi.h>
#include <objbase.h>
#include <psapi.h>
#include <rpc.h>
#include <share.h>
#include <shellapi.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#else // !defined(_WIN32)
#include <arpa/inet.h>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
#include <libgen.h>
#include <netinet/in.h>
#include <pwd.h>
#include <sys/file.h>
#include <sys/socket.h>
#if defined(__LFS64__)
#include <sys/stat64.h>
#else
#include <sys/stat.h>
#endif
#if defined(__linux__)
#include <sys/statfs.h>
#endif // defined(HAS_SETXATTR)
#if defined(HAS_SETXATTR)
#include <sys/types.h>
#include <sys/xattr.h>
#endif // defined(HAS_SETXATTR)
#if defined(__APPLE__)
#include <libproc.h>
#include <sys/attr.h>
#include <sys/mount.h>
#include <sys/statvfs.h>
#include <sys/vnode.h>
#endif // defined(__APPLE__)
#include <unistd.h>
#endif // defined(_WIN32)
#if defined(HAS_WORDEXP_H)
#include <wordexp.h>
#endif // defined(HAS_WORDEXP_H)
#if defined(__cplusplus)
#include <algorithm>
#include <array>
#include <atomic>
#include <bit>
#include <chrono>
#include <ciso646>
#include <climits>
#include <codecvt>
#include <condition_variable>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <filesystem>
#include <fstream>
#include <functional>
#include <future>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <locale>
#include <map>
#include <memory>
#include <mutex>
#include <numeric>
#include <optional>
#include <ostream>
#include <queue>
#include <random>
#include <ranges>
#include <regex>
#include <span>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <thread>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <variant>
#include <vector>
#endif // defined(__cplusplus)
#if defined(PROJECT_ENABLE_CURL)
#include "curl/curl.h"
#include "curl/multi.h"
#endif // defined(PROJECT_ENABLE_CURL)
#if defined(PROJECT_ENABLE_FUSE)
#if FUSE_USE_VERSION >= 30
#include <fuse.h>
#include <fuse_lowlevel.h>
#else
#include <fuse/fuse.h>
#endif
#endif // defined(PROJECT_ENABLE_FUSE)
#if defined(PROJECT_ENABLE_FZF)
#if defined(__cplusplus)
extern "C" {
#endif // defined(__cplusplus)
#include "fzf.h"
#if defined(__cplusplus)
}
#endif // defined(__cplusplus)
#endif // defined(PROJECT_ENABLE_FZF)
#if defined(PROJECT_ENABLE_LIBEVENT)
#include "event2/buffer.h"
#include "event2/bufferevent.h"
#include "event2/listener.h"
#include "event2/thread.h"
#include "event2/util.h"
#endif // defined(PROJECT_ENABLE_LIBEVENT)
#if defined(PROJECT_ENABLE_SDL)
#include "SDL.h"
#include "SDL_gamecontroller.h"
#include "SDL_joystick.h"
#endif // defined(PROJECT_ENABLE_SDL)
#if defined(PROJECT_ENABLE_LIBSODIUM)
#include "sodium.h"
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
#if defined(PROJECT_ENABLE_SQLITE)
#include "sqlite3.h"
#endif // defined(PROJECT_ENABLE_SQLITE)
#if defined(__cplusplus)
#if defined(PROJECT_ENABLE_BOOST)
#include "boost/archive/text_iarchive.hpp"
#include "boost/archive/text_oarchive.hpp"
#include "boost/asio.hpp"
#include "boost/asio/io_context.hpp"
#include "boost/bind/bind.hpp"
#include "boost/dynamic_bitset.hpp"
#include "boost/dynamic_bitset/serialization.hpp"
#include "boost/endian/conversion.hpp"
#include "boost/integer.hpp"
#include "boost/interprocess/sync/named_mutex.hpp"
#include "boost/interprocess/sync/scoped_lock.hpp"
#include "boost/multiprecision/cpp_dec_float.hpp"
#include "boost/multiprecision/cpp_int.hpp"
#include "boost/serialization/vector.hpp"
#endif // defined(PROJECT_ENABLE_BOOST)
#if defined(PROJECT_ENABLE_CPP_HTTPLIB)
#include "httplib.h"
#endif // defined(PROJECT_ENABLE_JSON)
#if defined(PROJECT_ENABLE_DTL)
#include "dtl/dtl.hpp"
#endif // defined(PROJECT_ENABLE_DTL)
#if defined(PROJECT_ENABLE_JSON)
#include "json.hpp"
#endif // defined(PROJECT_ENABLE_JSON)
#if defined(PROJECT_ENABLE_NANA)
#include "nana/gui.hpp"
#include "nana/gui/timer.hpp"
#include "nana/gui/widgets/button.hpp"
#include "nana/gui/widgets/combox.hpp"
#include "nana/gui/widgets/group.hpp"
#include "nana/gui/widgets/label.hpp"
#include "nana/gui/widgets/panel.hpp"
#include "nana/gui/widgets/picture.hpp"
#include "nana/gui/widgets/tabbar.hpp"
#endif // defined(PROJECT_ENABLE_NANA)
#if defined(PROJECT_ENABLE_PUGIXML)
#include "pugixml.hpp"
#endif // defined(PROJECT_ENABLE_PUGIXML)
#if defined(PROJECT_ENABLE_ROCKSDB)
#include "rocksdb/db.h"
#include "rocksdb/utilities/transaction_db.h"
#endif // defined(PROJECT_ENABLE_ROCKSDB)
#if defined(PROJECT_ENABLE_SFML)
#include "RoundedRectangleShape.hpp"
#include "SFML/Graphics.hpp"
#include "Text2.hpp"
#endif // defined(PROJECT_ENABLE_SFML)
#if defined(PROJECT_ENABLE_SAGO_PLATFORM_FOLDERS)
#include "platform_folders.hpp"
#endif // defined(PROJECT_ENABLE_SAGO_PLATFORM_FOLDERS)
#if defined(PROJECT_ENABLE_SPDLOG)
#include "spdlog/async.h"
#include "spdlog/fmt/bundled/core.h"
#include "spdlog/fmt/bundled/format.h"
#include "spdlog/fmt/chrono.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"
#endif // defined(PROJECT_ENABLE_SPDLOG)
#if defined(PROJECT_ENABLE_STDUUID)
#include "uuid.h"
#endif // defined(PROJECT_ENABLE_STDUUID)
#if defined(PROJECT_ENABLE_TPL)
#include "process.hpp"
#endif // defined(PROJECT_ENABLE_TPL)
#if defined(PROJECT_ENABLE_WINFSP)
#include "winfsp/winfsp.hpp"
#endif // defined(PROJECT_ENABLE_WINFSP)
#if !defined(fstat64)
#define fstat64 fstat
#endif // !defined(fstat64)
#if !defined(pread64)
#define pread64 pread
#endif // !defined(pread64)
#if !defined(pwrite64)
#define pwrite64 pwrite
#endif // !defined(pwrite64)
#if !defined(stat64)
#define stat64 stat
#endif // !defined(stat64)
#if !defined(statfs64)
#define statfs64 statfs
#endif // !defined(statfs64)
namespace repertory {
using data_buffer = std::vector<unsigned char>;
using mutex_lock = std::lock_guard<std::mutex>;
using recur_mutex_lock = std::lock_guard<std::recursive_mutex>;
using unique_mutex_lock = std::unique_lock<std::mutex>;
using unique_recur_mutex_lock = std::unique_lock<std::recursive_mutex>;
template <class... Ts> struct overloaded : Ts... {
using Ts::operator()...;
};
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
struct file_deleter final {
void operator()(FILE *file) {
if (file != nullptr) {
fclose(file);
}
}
};
using file_t = std::unique_ptr<FILE, file_deleter>;
} // namespace repertory
#endif // defined(__cplusplus)
#endif // REPERTORY_INCLUDE_UTILS_CONFIG_HPP_

View File

@ -0,0 +1,160 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_ENCRYPTION_HPP_
#define REPERTORY_INCLUDE_UTILS_ENCRYPTION_HPP_
#if defined(PROJECT_ENABLE_LIBSODIUM)
#include "utils/config.hpp"
namespace repertory::utils::encryption {
using hash_256_t = std::array<unsigned char, 32U>;
using hash_256_func_t = std::function<hash_256_t(std::string_view)>;
using key_type = std::array<unsigned char, 32U>;
inline constexpr const std::uint32_t encryption_header_size{
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES +
crypto_aead_xchacha20poly1305_IETF_ABYTES,
};
[[nodiscard]] auto decrypt_data(
std::string_view data, std::string_view password,
std::optional<hash_256_func_t> hasher = std::nullopt) -> data_buffer;
[[nodiscard]] auto encrypt_data(
std::string_view data, std::string_view password,
std::optional<hash_256_func_t> hasher = std::nullopt) -> data_buffer;
[[nodiscard]] auto generate_key(std::string_view encryption_token) -> key_type;
#if defined(PROJECT_ENABLE_BOOST)
template <typename result>
[[nodiscard]] inline auto
decrypt_data(const key_type &key, const unsigned char *buffer,
std::size_t buffer_size, result &res) -> bool {
if (buffer_size > encryption_header_size) {
const std::uint32_t size =
boost::endian::native_to_big(static_cast<std::uint32_t>(buffer_size));
res.resize(buffer_size - encryption_header_size);
return crypto_aead_xchacha20poly1305_ietf_decrypt_detached(
reinterpret_cast<unsigned char *>(res.data()), nullptr,
&buffer[header_size], res.size(),
&buffer[crypto_aead_xchacha20poly1305_IETF_NPUBBYTES],
reinterpret_cast<const unsigned char *>(&size), sizeof(size),
buffer, key.data()) == 0;
}
return false;
}
template <typename buffer, typename result>
[[nodiscard]] inline auto decrypt_data(const key_type &key, const buffer &buf,
result &res) -> bool {
return decrypt_data<result>(
key, reinterpret_cast<const unsigned char *>(buf.data()), buf.size(),
res);
}
template <typename buffer, typename result>
[[nodiscard]] inline auto decrypt_data(std::string_view encryption_token,
const buffer &buf, result &res) -> bool {
return decrypt_data<buffer, result>(generate_key(encryption_token), buf, res);
}
template <typename result>
[[nodiscard]] inline auto
decrypt_data(std::string_view encryption_token, const unsigned char *buffer,
std::size_t buffer_size, result &res) -> bool {
return decrypt_data<result>(generate_key(encryption_token), buffer,
buffer_size, res);
}
template <typename result>
inline void
encrypt_data(const std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv,
const key_type &key, const unsigned char *buffer,
std::size_t buffer_size, result &res) {
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_ABYTES> mac{};
const std::uint32_t size = boost::endian::native_to_big(
static_cast<std::uint32_t>(buffer_size + encryption_header_size));
res.resize(buffer_size + header_size);
unsigned long long mac_length{};
if (crypto_aead_xchacha20poly1305_ietf_encrypt_detached(
reinterpret_cast<unsigned char *>(&res[encryption_header_size]),
mac.data(), &mac_length, buffer, buffer_size,
reinterpret_cast<const unsigned char *>(&size), sizeof(size), nullptr,
iv.data(), key.data()) != 0) {
throw std::runtime_error("encryption failed");
}
std::memcpy(res.data(), iv.data(), iv.size());
std::memcpy(&res[iv.size()], mac.data(), mac.size());
}
template <typename result>
inline void encrypt_data(const key_type &key, const unsigned char *buffer,
std::size_t buffer_size, result &res) {
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> iv{};
randombytes_buf(iv.data(), iv.size());
encrypt_data<result>(iv, key, buffer, buffer_size, res);
}
template <typename result>
inline void encrypt_data(std::string_view encryption_token,
const unsigned char *buffer, std::size_t buffer_size,
result &res) {
encrypt_data<result>(generate_key(encryption_token), buffer, buffer_size,
res);
}
template <typename buffer, typename result>
inline void encrypt_data(std::string_view encryption_token, const buffer &buf,
result &res) {
encrypt_data<result>(generate_key(encryption_token),
reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res);
}
template <typename buffer, typename result>
inline void encrypt_data(const key_type &key, const buffer &buf, result &res) {
encrypt_data<result>(key, reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res);
}
template <typename buffer, typename result>
inline void
encrypt_data(const std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv,
const key_type &key, const buffer &buf, result &res) {
encrypt_data<result>(iv, key,
reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res);
}
#endif // defined(PROJECT_ENABLE_BOOST)
} // namespace repertory::utils::encryption
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
#endif // REPERTORY_INCLUDE_UTILS_ENCRYPTION_HPP_

View File

@ -0,0 +1,52 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_ERROR_HPP_
#define REPERTORY_INCLUDE_UTILS_ERROR_HPP_
#include "utils/config.hpp"
namespace repertory::utils::error {
struct i_exception_handler {
virtual ~i_exception_handler() {}
i_exception_handler(const i_exception_handler &) noexcept = delete;
i_exception_handler(i_exception_handler &&) noexcept = delete;
auto operator=(const i_exception_handler &) noexcept = delete;
auto operator=(i_exception_handler &&) noexcept = delete;
virtual void handle_exception(std::string_view function_name) const = 0;
virtual void handle_exception(std::string_view function_name,
const std::exception &ex) const = 0;
protected:
i_exception_handler() = default;
};
void handle_exception(std::string_view function_name);
void handle_exception(std::string_view function_name, const std::exception &ex);
void set_exception_handler(i_exception_handler *handler);
} // namespace repertory::utils::error
#endif // REPERTORY_INCLUDE_UTILS_ERROR_HPP_

147
support/3rd_party/include/utils/file.hpp vendored Normal file
View File

@ -0,0 +1,147 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_FILE_HPP_
#define REPERTORY_INCLUDE_UTILS_FILE_HPP_
#include "utils/config.hpp"
namespace repertory::utils::file {
class file final {
public:
[[nodiscard]] static auto open_file(std::filesystem::path path) -> file;
[[nodiscard]] static auto
open_or_create_file(std::filesystem::path path) -> file;
protected:
file(std::fstream stream, std::filesystem::path path)
: path_(std::move(path)), stream_(std::move(stream)) {}
file() = default;
public:
file(const file &) = delete;
file(file &&file_) noexcept = default;
~file() { close(); }
auto operator=(const file &) noexcept -> file & = delete;
auto operator=(file &&file_) noexcept -> file & = default;
private:
std::error_code error_{};
std::filesystem::path path_;
std::fstream stream_;
public:
void close();
[[nodiscard]] auto get_error_code() const -> std::error_code {
return error_;
}
[[nodiscard]] auto get_path() const -> std::filesystem::path { return path_; }
[[nodiscard]] auto move_to(std::filesystem::path new_path) -> bool;
[[nodiscard]] auto read(data_buffer &data, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool {
return read(data.data(), data.size(), offset, total_read);
}
[[nodiscard]] auto remove() -> bool;
[[nodiscard]] auto truncate() -> bool { return truncate(0U); }
[[nodiscard]] auto truncate(std::size_t size) -> bool;
#if defined(PROJECT_ENABLE_JSON)
[[nodiscard]] auto write(const nlohmann::json &data, std::uint64_t offset,
std::size_t *total_written = nullptr) -> bool {
return write(data.dump().c_str(), offset, total_written);
}
#endif // defined(PROJECT_ENABLE_JSON)
[[nodiscard]] auto write(const data_buffer &data, std::uint64_t offset,
std::size_t *total_written = nullptr) -> bool {
return write(data.data(), data.size(), offset, total_written);
}
[[nodiscard]] operator bool() const { return stream_.is_open(); }
private:
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
std::uint64_t offset,
std::size_t *total_read) -> bool;
[[nodiscard]] auto write(const typename data_buffer::value_type *data,
std::size_t to_write, std::size_t offset,
std::size_t *total_written) -> bool;
};
[[nodiscard]] auto get_file_size(std::string_view path,
std::uint64_t &file_size) -> bool;
[[nodiscard]] auto get_file_size(std::wstring_view path,
std::uint64_t &file_size) -> bool;
[[nodiscard]] auto is_directory(std::string_view path) -> bool;
[[nodiscard]] auto is_directory(std::wstring_view path) -> bool;
[[nodiscard]] auto is_file(std::string_view path) -> bool;
[[nodiscard]] auto is_file(std::wstring_view path) -> bool;
#if defined(PROJECT_ENABLE_JSON)
#if defined(PROJECT_ENABLE_LIBSODIUM)
[[nodiscard]] auto
read_json_file(std::string_view path, nlohmann::json &data,
std::optional<std::string_view> password = std::nullopt) -> bool;
[[nodiscard]] auto read_json_file(
std::wstring_view path, nlohmann::json &data,
std::optional<std::wstring_view> password = std::nullopt) -> bool;
[[nodiscard]] auto write_json_file(
std::string_view path, const nlohmann::json &data,
std::optional<std::string_view> password = std::nullopt) -> bool;
[[nodiscard]] auto write_json_file(
std::wstring_view path, const nlohmann::json &data,
std::optional<std::wstring_view> password = std::nullopt) -> bool;
#else // !defined(PROJECT_ENABLE_LIBSODIUM)
[[nodiscard]] auto read_json_file(std::string_view path,
nlohmann::json &data) -> bool;
[[nodiscard]] auto read_json_file(std::wstring_view path,
nlohmann::json &data) -> bool;
[[nodiscard]] auto write_json_file(std::string_view path,
const nlohmann::json &data) -> bool;
[[nodiscard]] auto write_json_file(std::wstring_view path,
const nlohmann::json &data) -> bool;
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
#endif // defined(PROJECT_ENABLE_JSON)
} // namespace repertory::utils::file
#endif // REPERTORY_INCLUDE_UTILS_FILE_HPP_

403
support/3rd_party/include/utils/path.hpp vendored Normal file
View File

@ -0,0 +1,403 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_PATH_HPP_
#define REPERTORY_INCLUDE_UTILS_PATH_HPP_
#include "utils/config.hpp"
#include "utils/string.hpp"
namespace repertory::utils::path {
inline constexpr const std::string_view backslash{"\\"};
inline constexpr const std::wstring_view backslash_w{L"\\"};
inline constexpr const std::string_view dot{"."};
inline constexpr const std::wstring_view dot_w{L"."};
inline constexpr const std::string_view dot_slash{"./"};
inline constexpr const std::wstring_view dot_slash_w{L"./"};
inline constexpr const std::string_view slash{"/"};
inline constexpr const std::wstring_view slash_w{L"/"};
#if defined(_WIN32)
inline constexpr const std::string_view directory_seperator{backslash};
inline constexpr const std::wstring_view directory_seperator_w{backslash_w};
inline constexpr const std::string_view not_directory_seperator{slash};
inline constexpr const std::wstring_view not_directory_seperator_w{slash_w};
#else // !defined(_WIN32)
inline constexpr const std::string_view directory_seperator{slash};
inline constexpr const std::wstring_view directory_seperator_w{slash_w};
inline constexpr const std::string_view not_directory_seperator{backslash};
inline constexpr const std::wstring_view not_directory_seperator_w{backslash_w};
#endif // defined(_WIN32)
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_backslash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_backslash<char>() -> std::basic_string_view<char> {
return backslash;
}
template <>
[[nodiscard]] inline constexpr auto
get_backslash<wchar_t>() -> std::basic_string_view<wchar_t> {
return backslash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto get_dot() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot<char>() -> std::basic_string_view<char> {
return dot;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot<wchar_t>() -> std::basic_string_view<wchar_t> {
return dot_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_dot_slash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot_slash<char>() -> std::basic_string_view<char> {
return dot_slash;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot_slash<wchar_t>() -> std::basic_string_view<wchar_t> {
return dot_slash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_slash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_slash<char>() -> std::basic_string_view<char> {
return slash;
}
template <>
[[nodiscard]] inline constexpr auto
get_slash<wchar_t>() -> std::basic_string_view<wchar_t> {
return slash_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_directory_seperator() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_directory_seperator<char>() -> std::basic_string_view<char> {
return directory_seperator;
}
template <>
[[nodiscard]] inline constexpr auto
get_directory_seperator<wchar_t>() -> std::basic_string_view<wchar_t> {
return directory_seperator_w;
}
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_not_directory_seperator() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_not_directory_seperator<char>() -> std::basic_string_view<char> {
return not_directory_seperator;
}
template <>
[[nodiscard]] inline constexpr auto
get_not_directory_seperator<wchar_t>() -> std::basic_string_view<wchar_t> {
return not_directory_seperator_w;
}
[[nodiscard]] inline auto absolute(std::string_view path) -> std::string;
[[nodiscard]] inline auto absolute(std::wstring_view path) -> std::wstring;
[[nodiscard]] inline auto
combine(std::string path,
const std::vector<std::string_view> &paths) -> std::string;
[[nodiscard]] inline auto
combine(std::wstring path,
const std::vector<std::wstring_view> &paths) -> std::wstring;
[[nodiscard]] auto inline create_api_path(std::string_view path) -> std::string;
[[nodiscard]] auto inline create_api_path(std::wstring_view path)
-> std::wstring;
[[nodiscard]] inline auto
directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool;
[[nodiscard]] inline auto
directory_exists_in_path(std::wstring_view path,
std::wstring_view sub_directory) -> bool;
[[nodiscard]] inline auto
file_exists_in_path(std::string_view path, std::string_view file_name) -> bool;
[[nodiscard]] inline auto
file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool;
[[nodiscard]] inline auto finalize(std::string_view path) -> std::string;
[[nodiscard]] inline auto finalize(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto
find_program_in_path(const std::string &name_without_extension) -> std::string;
[[nodiscard]] auto
find_program_in_path(std::wstring_view name_without_extension) -> std::wstring;
template <typename string_t>
inline auto
format_path(string_t &path,
std::basic_string_view<typename string_t::value_type> sep,
std::basic_string_view<typename string_t::value_type> not_sep)
-> string_t &;
[[nodiscard]] inline auto
get_parent_api_path(std::string_view path) -> std::string;
[[nodiscard]] inline auto
get_parent_api_path(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto get_parent_directory(std::string_view path) -> std::string;
[[nodiscard]] auto get_parent_directory(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto is_trash_directory(std::string_view path) -> bool;
[[nodiscard]] auto is_trash_directory(std::wstring_view path) -> bool;
[[nodiscard]] auto make_file_uri(std::string_view path) -> std::string;
[[nodiscard]] auto make_file_uri(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto remove_file_name(std::string_view path) -> std::string;
[[nodiscard]] auto remove_file_name(std::wstring_view path) -> std::wstring;
#if !defined(_WIN32)
[[nodiscard]] auto resolve(std::string path) -> std::string;
[[nodiscard]] auto resolve(std::wstring_view path) -> std::wstring;
#endif // !defined(_WIN32)
[[nodiscard]] auto strip_to_file_name(std::string_view path) -> std::string;
[[nodiscard]] auto unmake_file_uri(std::string_view uri) -> std::string;
[[nodiscard]] auto unmake_file_uri(std::wstring_view uri) -> std::wstring;
inline auto absolute(std::string_view path) -> std::string {
return finalize(std::filesystem::absolute(path).lexically_normal().string());
}
inline auto absolute(std::wstring_view path) -> std::wstring {
return finalize(std::filesystem::absolute(path).lexically_normal().wstring());
}
template <typename string_t>
[[nodiscard]] inline auto combine_t(
string_t path,
const std::vector<std::basic_string_view<typename string_t::value_type>>
&paths) -> string_t {
return absolute(std::accumulate(
paths.begin(), paths.end(), path, [](auto next_path, auto &&path_part) {
if (next_path.empty()) {
return string_t{path_part};
}
return next_path +
string_t{
get_directory_seperator<typename string_t::value_type>()} +
string_t{path_part};
}));
}
inline auto combine(std::string path,
const std::vector<std::string_view> &paths) -> std::string {
return combine_t<std::string>(path, paths);
}
inline auto
combine(std::wstring path,
const std::vector<std::wstring_view> &paths) -> std::wstring {
return combine_t<std::wstring>(path, paths);
}
template <typename string_t>
[[nodiscard]] inline auto create_api_path_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
static auto backslash_t = get_backslash<typename string_t::value_type>();
static auto dot_slash_t = get_dot_slash<typename string_t::value_type>();
static auto dot_t = get_dot<typename string_t::value_type>();
static auto slash_t = get_slash<typename string_t::value_type>();
if (path.empty() || (path == dot_t) || (path == slash_t)) {
return string_t{slash_t};
}
string_t api_path{path};
format_path(api_path, slash_t, backslash_t);
if (api_path.find(dot_slash_t) == 0) {
api_path = api_path.substr(1U);
}
if (api_path.at(0U) != '/') {
api_path = string_t{slash_t} + api_path;
}
if ((api_path != slash_t) && utils::string::ends_with(api_path, slash_t)) {
utils::string::right_trim(api_path, '/');
}
return api_path;
}
inline auto create_api_path(std::string_view path) -> std::string {
return create_api_path_t<std::string>(path);
}
inline auto create_api_path(std::wstring_view path) -> std::wstring {
return create_api_path_t<std::wstring>(path);
}
template <typename string_t>
[[nodiscard]] inline auto directory_exists_in_path_t(
std::basic_string_view<typename string_t::value_type> path,
std::basic_string_view<typename string_t::value_type> sub_directory)
-> bool {
return std::filesystem::is_directory(
std::filesystem::path(path).append(sub_directory));
}
inline auto directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool {
return directory_exists_in_path_t<std::string>(path, sub_directory);
}
inline auto directory_exists_in_path(std::wstring_view path,
std::wstring_view sub_directory) -> bool {
return directory_exists_in_path_t<std::wstring>(path, sub_directory);
}
template <typename string_t>
[[nodiscard]] inline auto file_exists_in_path_t(
std::basic_string_view<typename string_t::value_type> path,
std::basic_string_view<typename string_t::value_type> file_name) -> bool {
return std::filesystem::is_regular_file(
std::filesystem::path(path).append(file_name));
}
inline auto file_exists_in_path(std::string_view path,
std::string_view file_name) -> bool {
return file_exists_in_path_t<std::string>(path, file_name);
}
inline auto file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool {
return file_exists_in_path_t<std::wstring>(path, file_name);
}
template <typename string_t>
[[nodiscard]] inline auto finalize_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
string_t fmt_path{path};
#if defined(_WIN32)
if ((fmt_path.size() >= 2U) && (fmt_path.at(1U) == ':')) {
fmt_path[0U] =
utils::string::to_lower(string_t{1U, fmt_path.at(0U)}).at(0U);
}
#endif // defined(_WIN32)
return fmt_path;
}
inline auto finalize(std::string_view path) -> std::string {
return finalize_t<std::string>(path);
}
inline auto finalize(std::wstring_view path) -> std::wstring {
return finalize_t<std::wstring>(path);
}
template <typename string_t>
inline auto
format_path(string_t &path,
std::basic_string_view<typename string_t::value_type> sep,
std::basic_string_view<typename string_t::value_type> not_sep)
-> string_t & {
utils::string::replace(path, not_sep, sep);
string_t double_sep{2, sep.at(0U)};
while (utils::string::contains(path, double_sep)) {
utils::string::replace(path, double_sep, sep);
}
return path;
}
template <typename string_t>
[[nodiscard]] inline auto get_parent_api_path_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
static auto slash_t = get_slash<typename string_t::value_type>();
string_t ret;
if (path == slash_t) {
return ret;
}
ret = path.substr(0, path.rfind('/') + 1);
if (ret == slash_t) {
return ret;
}
return utils::string::right_trim(ret, '/');
}
inline auto get_parent_api_path(std::string_view path) -> std::string {
return get_parent_api_path_t<std::string>(path);
}
inline auto get_parent_api_path(std::wstring_view path) -> std::wstring {
return get_parent_api_path_t<std::wstring>(path);
}
} // namespace repertory::utils::path
#endif // REPERTORY_INCLUDE_UTILS_PATH_HPP_

View File

@ -0,0 +1,496 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_STRING_HPP_
#define REPERTORY_INCLUDE_UTILS_STRING_HPP_
#include "utils/config.hpp"
namespace repertory::utils::string {
template <typename string_t> struct chain_replace_with_hex;
template <typename string_t>
[[nodiscard]] inline auto
char_to_hex(typename string_t::value_type character) -> string_t;
[[nodiscard]] inline auto begins_with(std::string_view str,
std::string_view val) -> bool;
[[nodiscard]] inline auto begins_with(std::wstring_view str,
std::wstring_view val) -> bool;
template <typename string_t>
[[nodiscard]] inline auto case_insensitive_find_string(string_t in_str,
string_t for_str) ->
typename string_t::const_iterator;
[[nodiscard]] inline auto contains(std::string_view str,
std::string_view search) -> bool;
[[nodiscard]] inline auto contains(std::wstring_view str,
std::wstring_view search) -> bool;
[[nodiscard]] inline auto ends_with(std::string_view str,
std::string_view val) -> bool;
[[nodiscard]] inline auto ends_with(std::wstring_view str,
std::wstring_view val) -> bool;
[[nodiscard]] auto from_bool(bool val) -> std::string;
#if defined(PROJECT_ENABLE_BOOST)
[[nodiscard]] auto
from_dynamic_bitset(const boost::dynamic_bitset<> &bitset) -> std::string;
#endif // defined(PROJECT_ENABLE_BOOST)
[[nodiscard]] auto from_utf8(std::string_view str) -> std::wstring;
[[nodiscard]] inline auto is_numeric(std::string_view str) -> bool;
[[nodiscard]] inline auto is_numeric(std::wstring_view str) -> bool;
template <typename string_t>
[[nodiscard]] inline auto join(const std::vector<string_t> &arr,
typename string_t::value_type delim) -> string_t;
template <typename string_t>
auto left_trim(string_t &str,
typename string_t::value_type trim_ch = ' ') -> string_t &;
template <typename string_t>
inline auto replace(string_t &src, typename string_t::value_type character,
typename string_t::value_type with,
std::size_t start_pos = 0U) -> string_t &;
template <typename string_t>
inline auto replace(string_t &src,
std::basic_string_view<typename string_t::value_type> find,
std::basic_string_view<typename string_t::value_type> with,
std::size_t start_pos = 0U) -> string_t &;
template <typename t>
[[nodiscard]] auto from_hex_string(const std::string &str, t &val) -> bool;
template <typename collection_t>
[[nodiscard]] auto to_hex_string(const collection_t &collection) -> std::string;
template <typename string_t>
[[nodiscard]] inline auto replace_copy(string_t src,
typename string_t::value_type character,
typename string_t::value_type with,
std::size_t start_pos = 0U) -> string_t;
template <typename string_t>
[[nodiscard]] inline auto
replace_copy(string_t src,
std::basic_string_view<typename string_t::value_type> find,
std::basic_string_view<typename string_t::value_type> with,
std::size_t start_pos = 0U) -> string_t;
template <typename string_t>
[[nodiscard]] inline auto
replace_with_hex(string_t &str, typename string_t::value_type character)
-> chain_replace_with_hex<string_t>;
template <typename string_t>
inline auto
right_trim(string_t &str,
typename string_t::value_type trim_ch = ' ') -> string_t &;
[[nodiscard]] inline auto split(std::string_view str, char delim,
bool should_trim) -> std::vector<std::string>;
[[nodiscard]] inline auto split(std::wstring_view str, wchar_t delim,
bool should_trim) -> std::vector<std::wstring>;
[[nodiscard]] inline auto split(std::string_view str, std::string_view delim,
bool should_trim) -> std::vector<std::string>;
[[nodiscard]] inline auto split(std::wstring_view str, std::wstring_view delim,
bool should_trim) -> std::vector<std::wstring>;
#if defined(PROJECT_ENABLE_SFML)
auto replace_sf(sf::String &src, const sf::String &find, const sf::String &with,
std::size_t start_pos = 0U) -> sf::String &;
[[nodiscard]] auto split_sf(sf::String str, wchar_t delim,
bool should_trim) -> std::vector<sf::String>;
#endif // defined(PROJECT_ENABLE_SFML)
[[nodiscard]] auto to_bool(std::string val) -> bool;
[[nodiscard]] auto to_double(const std::string &str) -> double;
#if defined(PROJECT_ENABLE_BOOST)
[[nodiscard]] auto
to_dynamic_bitset(const std::string &val) -> boost::dynamic_bitset<>;
#endif // defined(PROJECT_ENABLE_BOOST)
template <typename string_t>
[[nodiscard]] inline auto to_lower(string_t str) -> string_t;
[[nodiscard]] auto to_int32(const std::string &val) -> std::int32_t;
[[nodiscard]] auto to_int64(const std::string &val) -> std::int64_t;
[[nodiscard]] auto to_size_t(const std::string &val) -> std::size_t;
[[nodiscard]] auto to_uint8(const std::string &val) -> std::uint8_t;
[[nodiscard]] auto to_uint16(const std::string &val) -> std::uint16_t;
[[nodiscard]] auto to_uint32(const std::string &val) -> std::uint32_t;
[[nodiscard]] auto to_uint64(const std::string &val) -> std::uint64_t;
template <typename string_t>
[[nodiscard]] inline auto to_upper(string_t str) -> string_t;
[[nodiscard]] auto to_utf8(std::string_view str) -> std::string;
[[nodiscard]] auto to_utf8(std::wstring_view str) -> std::string;
template <typename string_t> struct chain_replace_with_hex final {
explicit chain_replace_with_hex(string_t &value) : str(value) {}
chain_replace_with_hex(const chain_replace_with_hex &) = delete;
chain_replace_with_hex(chain_replace_with_hex &&) = delete;
~chain_replace_with_hex() = default;
auto operator=(const chain_replace_with_hex &) -> chain_replace_with_hex & =
delete;
auto
operator=(chain_replace_with_hex &&) -> chain_replace_with_hex & = delete;
auto operator()(typename string_t::value_type character)
-> chain_replace_with_hex {
return replace_with_hex<string_t>(str, character);
}
string_t &str;
};
template <typename string_t>
inline auto trim(string_t &str,
typename string_t::value_type trim_ch = ' ') -> string_t &;
template <typename string_t>
[[nodiscard]] inline auto
trim_copy(string_t str,
typename string_t::value_type trim_ch = ' ') -> string_t;
template <typename char_t>
[[nodiscard]] inline auto
begins_with_t(std::basic_string_view<char_t> str,
std::basic_string_view<char_t> val) -> bool {
return (str.find(val) == 0U);
}
inline auto begins_with(std::string_view str, std::string_view val) -> bool {
return begins_with_t<std::string_view::value_type>(str, val);
}
inline auto begins_with(std::wstring_view str, std::wstring_view val) -> bool {
return begins_with_t<std::wstring_view::value_type>(str, val);
}
template <typename string_t>
inline auto case_insensitive_find_string(string_t in_str, string_t for_str) ->
typename string_t::const_iterator {
static const auto compare_chars =
[](typename string_t::value_type char_a,
typename string_t::value_type char_b) -> bool {
return (std::tolower(char_a) == std::tolower(char_b));
};
return (std::search(in_str.begin(), in_str.end(), for_str.begin(),
for_str.end(), compare_chars));
}
template <typename string_t>
inline auto char_to_hex(typename string_t::value_type character) -> string_t {
std::basic_stringstream<typename string_t::value_type> stream;
stream << '%' << std::setfill<typename string_t::value_type>('0')
<< std::setw(sizeof(character)) << std::hex
<< static_cast<std::uint32_t>(character);
return stream.str();
}
template <typename char_t>
[[nodiscard]] inline auto
contains_t(std::basic_string_view<char_t> str,
std::basic_string_view<char_t> search) -> bool {
return (str.find(search) != std::basic_string_view<char_t>::npos);
}
inline auto contains(std::string_view str, std::string_view search) -> bool {
return contains_t<std::string_view::value_type>(str, search);
}
inline auto contains(std::wstring_view str, std::wstring_view search) -> bool {
return contains_t<std::wstring_view::value_type>(str, search);
}
template <typename char_t>
[[nodiscard]] inline auto
ends_with_t(std::basic_string_view<char_t> str,
std::basic_string_view<char_t> val) -> bool {
if (val.size() > str.size()) {
return false;
}
return std::equal(val.rbegin(), val.rend(), str.rbegin());
}
inline auto ends_with(std::string_view str, std::string_view val) -> bool {
return ends_with_t<std::string_view::value_type>(str, val);
}
inline auto ends_with(std::wstring_view str, std::wstring_view val) -> bool {
return ends_with_t<std::wstring_view::value_type>(str, val);
}
template <typename char_t>
[[nodiscard]] inline auto
is_numeric_t(std::basic_string_view<char_t> str) -> bool {
if ((str.length() > 1U) && (str.at(0U) == '+' || str.at(0U) == '-')) {
str = str.substr(1U);
}
if (str.empty()) {
return false;
}
auto has_decimal{false};
return std::find_if(str.begin(), str.end(),
[&has_decimal](auto &&cur_ch) -> bool {
if (has_decimal && cur_ch == '.') {
return true;
}
has_decimal = has_decimal || cur_ch == '.';
if (has_decimal) {
return false;
}
return std::isdigit(cur_ch) == 0;
}) == str.end();
}
inline auto is_numeric(std::string_view str) -> bool {
return is_numeric_t<std::string_view::value_type>(str);
}
inline auto is_numeric(std::wstring_view str) -> bool {
return is_numeric_t<std::wstring_view::value_type>(str);
}
template <typename string_t>
inline auto join(const std::vector<string_t> &arr,
typename string_t::value_type delim) -> string_t {
if (arr.empty()) {
return {};
}
return std::accumulate(
std::next(arr.begin()), arr.end(), arr[0U],
[&delim](auto str, const auto &cur) { return str + delim + cur; });
}
template <typename string_t>
auto left_trim(string_t &str,
typename string_t::value_type trim_ch) -> string_t & {
str.erase(0, str.find_first_not_of(trim_ch));
return str;
}
template <typename string_t>
inline auto replace(string_t &src, typename string_t::value_type character,
typename string_t::value_type with,
std::size_t start_pos) -> string_t & {
if (not src.empty() && (start_pos < src.size())) {
std::replace(std::next(src.begin(), start_pos), src.end(), character, with);
}
return src;
}
template <typename string_t>
inline auto replace(string_t &src,
std::basic_string_view<typename string_t::value_type> find,
std::basic_string_view<typename string_t::value_type> with,
std::size_t start_pos) -> string_t & {
if (not src.empty() && (start_pos < src.size())) {
while ((start_pos = src.find(find, start_pos)) != string_t::npos) {
src.replace(start_pos, find.size(), with);
start_pos += with.size();
}
}
return src;
}
template <typename string_t>
inline auto replace_copy(string_t src, typename string_t::value_type character,
typename string_t::value_type with,
std::size_t start_pos) -> string_t {
return replace(src, character, with, start_pos);
}
template <typename string_t>
inline auto
replace_copy(string_t src,
std::basic_string_view<typename string_t::value_type> find,
std::basic_string_view<typename string_t::value_type> with,
std::size_t start_pos) -> string_t {
return replace(src, find, with, start_pos);
}
template <typename string_t>
inline auto replace_with_hex(string_t &str,
typename string_t::value_type character)
-> chain_replace_with_hex<string_t> {
return chain_replace_with_hex(
replace(str, string_t{1U, character}, char_to_hex<string_t>(character)));
}
template <typename string_t>
inline auto right_trim(string_t &str,
typename string_t::value_type trim_ch) -> string_t & {
str.erase(str.find_last_not_of(trim_ch) + 1);
return str;
}
template <typename string_t> inline auto to_lower(string_t str) -> string_t {
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
return str;
}
template <typename string_t> inline auto to_upper(string_t str) -> string_t {
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
return str;
}
template <typename string_t>
inline auto trim(string_t &str,
typename string_t::value_type trim_ch) -> string_t & {
return right_trim(left_trim(str, trim_ch), trim_ch);
}
template <typename string_t>
inline auto trim_copy(string_t str,
typename string_t::value_type trim_ch) -> string_t {
return trim(str, trim_ch);
}
template <typename string_t>
[[nodiscard]] inline auto
split_t(std::basic_string_view<typename string_t::value_type> str,
typename string_t::value_type delim,
bool should_trim) -> std::vector<string_t> {
std::vector<string_t> ret;
std::basic_stringstream<typename string_t::value_type> stream{string_t{str}};
string_t val;
while (std::getline(stream, val, delim)) {
if (should_trim) {
trim(val);
}
ret.push_back(std::move(val));
}
return ret;
}
inline auto split(std::string_view str, char delim,
bool should_trim) -> std::vector<std::string> {
return split_t<std::string>(str, delim, should_trim);
}
inline auto split(std::wstring_view str, wchar_t delim,
bool should_trim) -> std::vector<std::wstring> {
return split_t<std::wstring>(str, delim, should_trim);
}
template <typename string_t>
[[nodiscard]] inline auto
split_t(std::basic_string_view<typename string_t::value_type> str,
std::basic_string_view<typename string_t::value_type> delim,
bool should_trim) -> std::vector<string_t> {
auto result = std::views::split(str, delim);
std::vector<string_t> ret{};
for (auto &&word : result) {
auto val = string_t{word.begin(), word.end()};
if (should_trim) {
trim(val);
}
ret.push_back(std::move(val));
}
return ret;
}
inline auto split(std::string_view str, std::string_view delim,
bool should_trim) -> std::vector<std::string> {
return split_t<std::string>(str, delim, should_trim);
}
inline auto split(std::wstring_view str, std::wstring_view delim,
bool should_trim) -> std::vector<std::wstring> {
return split_t<std::wstring>(str, delim, should_trim);
}
template <typename t>
auto from_hex_string(const std::string &str, t &val) -> bool {
static constexpr const auto base16 = 16;
val.clear();
if (not(str.length() % 2U)) {
for (std::size_t i = 0U; i < str.length(); i += 2U) {
val.emplace_back(static_cast<typename t::value_type>(
strtol(str.substr(i, 2U).c_str(), nullptr, base16)));
}
return true;
}
return false;
}
template <typename collection_t>
auto to_hex_string(const collection_t &collection) -> std::string {
static_assert(sizeof(typename collection_t::value_type) == 1U,
"value_type must be 1 byte in size");
static constexpr const auto mask = 0xFF;
std::stringstream stream;
for (auto &&val : collection) {
stream << std::setfill('0') << std::setw(2) << std::hex
<< (static_cast<std::uint32_t>(val) & mask);
}
return stream.str();
}
} // namespace repertory::utils::string
#endif // REPERTORY_INCLUDE_UTILS_STRING_HPP_

View File

@ -0,0 +1,64 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_TIME_HPP_
#define REPERTORY_INCLUDE_UTILS_TIME_HPP_
#include "utils/config.hpp"
namespace repertory::utils::time {
inline constexpr const auto NANOS_PER_SECOND = 1000000000L;
#if defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
[[nodiscard]] inline auto convert_to_utc(time_t time) -> std::time_t {
auto calendar_time = fmt::gmtime(time);
return std::mktime(&calendar_time);
}
#endif // defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
#if defined(_WIN32)
[[nodiscard]] auto
filetime_to_unix_time(const FILETIME &file_time) -> std::uint64_t;
#endif // defined(_WIN32)
#if defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
[[nodiscard]] inline auto get_current_time_utc() -> std::time_t {
auto calendar_time = fmt::gmtime(std::time(nullptr));
return std::mktime(&calendar_time);
}
#endif // defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT)
[[nodiscard]] auto get_file_time_now() -> std::uint64_t;
void get_local_time_now(struct tm &local_time);
[[nodiscard]] auto get_time_now() -> std::uint64_t;
#if defined(_WIN32)
auto strptime(const char *s, const char *f, struct tm *tm) -> const char *;
[[nodiscard]] auto time64_to_unix_time(const __time64_t &time) -> std::uint64_t;
[[nodiscard]] auto unix_time_to_filetime(std::uint64_t unix_time) -> FILETIME;
#endif // defined(_WIN32)
} // namespace repertory::utils::time
#endif // REPERTORY_INCLUDE_UTILS_TIME_HPP_

View File

@ -0,0 +1,64 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_UNIX_HPP_
#define REPERTORY_INCLUDE_UTILS_UNIX_HPP_
#if !defined(_WIN32)
#include "utils/common.hpp"
#include "utils/config.hpp"
namespace repertory::utils {
using passwd_callback_t = std::function<void(struct passwd *pass)>;
#if defined(__APPLE__)
template <typename thread_t>
[[nodiscard]] auto
convert_to_uint64(const thread_t *thread_ptr) -> std::uint64_t;
#else // !defined(__APPLE__)
[[nodiscard]] auto convert_to_uint64(const pthread_t &thread) -> std::uint64_t;
#endif // defined(__APPLE__)
[[nodiscard]] auto get_last_error_code() -> int;
[[nodiscard]] auto get_thread_id() -> std::uint64_t;
[[nodiscard]] auto is_uid_member_of_group(const uid_t &uid,
const gid_t &gid) -> bool;
void set_last_error_code(int error_code);
[[nodiscard]] auto use_getpwuid(uid_t uid,
passwd_callback_t callback) -> utils::result;
// template implementations
#if defined(__APPLE__)
template <typename t>
[[nodiscard]] auto
convert_to_uint64(const thread_t *thread_ptr) -> std::uint64_t {
return static_cast<std::uint64_t>(
reinterpret_cast<std::uintptr_t>(thread_ptr));
}
#endif // defined(__APPLE__)
} // namespace repertory::utils
#endif // !defined(_WIN32)
#endif // REPERTORY_INCLUDE_UTILS_UNIX_HPP_

View File

@ -0,0 +1,43 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_WINDOWS_HPP_
#define REPERTORY_INCLUDE_UTILS_WINDOWS_HPP_
#if defined(_WIN32)
#include "utils/config.hpp"
namespace repertory::utils {
[[nodiscard]] auto get_local_app_data_directory() -> const std::string &;
[[nodiscard]] auto get_last_error_code() -> DWORD;
[[nodiscard]] auto get_thread_id() -> std::uint64_t;
[[nodiscard]] auto is_process_elevated() -> bool;
[[nodiscard]] auto run_process_elevated(std::vector<const char *> args) -> int;
void set_last_error_code(DWORD errorCode);
} // namespace repertory::utils
#endif // defined(_WIN32)
#endif // REPERTORY_INCLUDE_UTILS_WINDOWS_HPP_

View File

@ -1,4 +1,3 @@
#if defined(PROJECT_ENABLE_BACKWARD_CPP)
// Pick your poison. // Pick your poison.
// //
// On GNU/Linux, you have few choices to get the most out of your stack trace. // On GNU/Linux, you have few choices to get the most out of your stack trace.
@ -33,12 +32,14 @@
// - apt-get install libunwind-dev // - apt-get install libunwind-dev
// - g++/clang++ -lunwind // - g++/clang++ -lunwind
// #define BACKWARD_HAS_LIBUNWIND 1 // #define BACKWARD_HAS_LIBUNWIND 1
#include "backward.hpp" #include "backward.hpp"
#if defined(PROJECT_ENABLE_BACKWARD_CPP)
namespace backward { namespace backward {
backward::SignalHandling sh; backward::SignalHandling sh;
} // namespace backward } // namespace backward
#endif // defined(PROJECT_ENABLE_BACKWARD_CPP) #endif // defined(PROJECT_ENABLE_BACKWARD_CPP)

169
support/3rd_party/src/utils/common.cpp vendored Normal file
View File

@ -0,0 +1,169 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/common.hpp"
#include "utils/string.hpp"
namespace repertory::utils {
auto compare_version_strings(std::string version1,
std::string version2) -> std::int32_t {
if (utils::string::contains(version1, "-")) {
version1 = utils::string::split(version1, '-', true)[0U];
}
if (utils::string::contains(version2, "-")) {
version2 = utils::string::split(version2, '-', true)[0U];
}
auto nums1 = utils::string::split(version1, '.', true);
auto nums2 = utils::string::split(version2, '.', true);
while (nums1.size() > nums2.size()) {
nums2.emplace_back("0");
}
while (nums2.size() > nums1.size()) {
nums1.emplace_back("0");
}
for (std::size_t idx = 0U; idx < nums1.size(); idx++) {
auto int1 = utils::string::to_uint32(nums1[idx]);
auto int2 = utils::string::to_uint32(nums2[idx]);
auto res = std::memcmp(&int1, &int2, sizeof(int1));
if (res != 0) {
return res;
}
}
return 0;
}
auto compare_version_strings(std::wstring_view version1,
std::wstring_view version2) -> std::int32_t {
return compare_version_strings(utils::string::to_utf8(version1),
utils::string::to_utf8(version2));
}
#if defined(PROJECT_ENABLE_STDUUID)
auto create_uuid_string() -> std::string {
std::random_device random_device;
auto seed_data = std::array<int, std::mt19937::state_size>{};
std::generate(std::begin(seed_data), std::end(seed_data),
std::ref(random_device));
std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
std::mt19937 generator(seq);
uuids::uuid_random_generator gen{generator};
return uuids::to_string(gen());
}
auto create_uuid_wstring() -> std::wstring {
return utils::string::from_utf8(create_uuid_string());
}
#endif // defined(PROJECT_ENABLE_STDUUID)
#if defined(PROJECT_ENABLE_LIBSODIUM)
auto generate_random_string(std::uint16_t length) -> std::string {
std::string ret;
ret.resize(length);
for (std::uint16_t i = 0U; i < length; i++) {
do {
ret[i] = static_cast<char>(generate_random<std::uint8_t>() % 74 + 48);
} while (((ret[i] >= 91) && (ret[i] <= 96)) ||
((ret[i] >= 58) && (ret[i] <= 64)));
}
return ret;
}
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
auto get_environment_variable(std::string_view variable) -> std::string {
static std::mutex mtx{};
mutex_lock lock{mtx};
const auto *val = std::getenv(std::string{variable}.c_str());
return std::string{val == nullptr ? "" : val};
}
auto get_environment_variable(std::wstring_view variable) -> std::wstring {
return utils::string::from_utf8(
get_environment_variable(utils::string::to_utf8(variable)));
}
#if defined(PROJECT_ENABLE_BOOST)
auto get_next_available_port(std::uint16_t first_port,
std::uint16_t &available_port) -> bool {
using namespace boost::asio;
using ip::tcp;
boost::system::error_code error_code{};
while (first_port != 0U) {
io_service svc{};
tcp::acceptor acceptor(svc);
acceptor.open(tcp::v4(), error_code) ||
acceptor.bind({tcp::v4(), first_port}, error_code);
if (not error_code) {
break;
}
++first_port;
}
if (not error_code) {
available_port = first_port;
}
return not error_code;
}
#endif // defined(PROJECT_ENABLE_BOOST)
auto resolve_variables(std::string str) -> std::string {
#if defined(HAS_WORDEXP_H)
wordexp_t wt{};
int ret{};
if ((ret = wordexp(std::string{str}.c_str(), &wt, 0)) != 0) {
throw std::runtime_error("'wordexp()' failed|" + std::to_string(ret));
}
str = wt.we_wordv[0U];
wordfree(&wt);
#else // !defined(HAS_WORDEXP_H)
std::string dest;
dest.resize(::ExpandEnvironmentStringsA(str.c_str(), nullptr, 0));
::ExpandEnvironmentStringsA(str.c_str(), dest.data(),
static_cast<DWORD>(dest.size()));
str = std::string(dest.c_str(), strlen(dest.c_str()));
dest.resize(::GetFullPathNameA(str.c_str(), 0, nullptr, nullptr));
::GetFullPathNameA(str.c_str(), static_cast<DWORD>(dest.size()), dest.data(),
nullptr);
str = std::string(dest.c_str(), strlen(dest.c_str()));
#endif // defined(HAS_WORDEXP_H)
return str;
}
auto resolve_variables(std::wstring_view str) -> std::wstring {
return utils::string::from_utf8(
resolve_variables(utils::string::to_utf8(str)));
}
} // namespace repertory::utils

View File

@ -0,0 +1,103 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/encryption.hpp"
#if defined(PROJECT_ENABLE_LIBSODIUM)
namespace {
using nonce_t =
std::array<unsigned char, crypto_aead_xchacha20poly1305_ietf_NPUBBYTES>;
static constexpr const auto nonce_size{sizeof(nonce_t)};
[[nodiscard]] static auto create_hash_256(std::string_view data)
-> repertory::utils::encryption::hash_256_t {
repertory::utils::encryption::hash_256_t hash{};
crypto_generichash_blake2b_state state{};
crypto_generichash_blake2b_init(&state, nullptr, 0U, hash.size());
crypto_generichash_blake2b_update(
&state, reinterpret_cast<const unsigned char *>(data.data()),
data.size());
crypto_generichash_blake2b_final(&state, hash.data(), hash.size());
return hash;
}
} // namespace
namespace repertory::utils::encryption {
auto decrypt_data(std::string_view data, std::string_view password,
std::optional<hash_256_func_t> hasher) -> data_buffer {
auto key =
hasher.has_value() ? (*hasher)(password) : create_hash_256(password);
data_buffer buf{};
if (not decrypt_data(key,
reinterpret_cast<const unsigned char *>(data.data()),
data.size(), buf)) {
throw std::runtime_error("decryption failed");
}
return buf;
}
auto encrypt_data(std::string_view data, std::string_view password,
std::optional<hash_256_func_t> hasher) -> data_buffer {
auto key =
hasher.has_value() ? (*hasher)(password) : create_hash_256(password);
data_buffer buf{};
if (not encrypt_data(key,
reinterpret_cast<const unsigned char *>(data.data()),
data.size(), buf)) {
throw std::runtime_error("encryption failed");
}
return buf;
}
auto generate_key(std::string_view encryption_token) -> key_type {
crypto_hash_sha256_state state{};
auto res = crypto_hash_sha256_init(&state);
if (res != 0) {
throw std::runtime_error("failed to initialize sha256|" +
std::to_string(res));
}
res = crypto_hash_sha256_update(
&state, reinterpret_cast<const unsigned char *>(encryption_token.data()),
encryption_token.size());
if (res != 0) {
throw std::runtime_error("failed to update sha256|" + std::to_string(res));
}
key_type ret{};
res = crypto_hash_sha256_final(&state, ret.data());
if (res != 0) {
throw std::runtime_error("failed to finalize sha256|" +
std::to_string(res));
}
return ret;
}
} // namespace repertory::utils::encryption
#endif // defined(PROJECT_ENABLE_LIBSODIUM)

71
support/3rd_party/src/utils/error.cpp vendored Normal file
View File

@ -0,0 +1,71 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/error.hpp"
namespace {
struct default_exception_handler final
: repertory::utils::error::i_exception_handler {
void handle_exception(std::string_view function_name) const override {
std::cerr << function_name << "|exception|unknown" << std::endl;
}
void handle_exception(std::string_view function_name,
const std::exception &ex) const override {
std::cerr << function_name << "|exception|"
<< (ex.what() == nullptr ? "unknown" : ex.what()) << std::endl;
}
};
static default_exception_handler default_handler{};
static std::atomic<repertory::utils::error::i_exception_handler *>
exception_handler{
&default_handler,
};
} // namespace
namespace repertory::utils::error {
void handle_exception(std::string_view function_name) {
i_exception_handler *handler{exception_handler};
if (handler != nullptr) {
handler->handle_exception(function_name);
return;
}
default_handler.handle_exception(function_name);
}
void handle_exception(std::string_view function_name,
const std::exception &ex) {
i_exception_handler *handler{exception_handler};
if (handler != nullptr) {
handler->handle_exception(function_name, ex);
return;
}
default_handler.handle_exception(function_name, ex);
}
void set_exception_handler(i_exception_handler *handler) {
exception_handler = handler;
}
} // namespace repertory::utils::error

366
support/3rd_party/src/utils/file.cpp vendored Normal file
View File

@ -0,0 +1,366 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/file.hpp"
#include "utils/encryption.hpp"
#include "utils/error.hpp"
#include "utils/path.hpp"
#include "utils/string.hpp"
namespace repertory::utils::file {
auto file::open_file(std::filesystem::path path) -> file {
path = utils::path::absolute(path.string());
if (not is_file(path.string())) {
throw std::runtime_error("file not found: " + path.string());
}
auto stream = std::fstream{
path,
std::ios_base::binary | std::ios_base::in | std::ios_base::out,
};
return {
std::move(stream),
path,
};
}
auto file::open_or_create_file(std::filesystem::path path) -> file {
path = utils::path::absolute(path.string());
auto stream = std::fstream{
path.string().c_str(),
std::ios_base::binary | std::ios_base::trunc | std::ios_base::in |
std::ios_base::out,
};
return {
std::move(stream),
path,
};
}
void file::close() {
if (stream_.is_open()) {
stream_.close();
}
}
auto file::move_to(std::filesystem::path new_path) -> bool {
new_path = utils::path::absolute(new_path.string());
auto reopen{false};
if (stream_.is_open()) {
reopen = true;
close();
}
std::filesystem::rename(path_, new_path, error_);
if (not error_) {
path_ = new_path;
if (reopen) {
*this = std::move(open_file(path_));
}
return true;
}
if (reopen) {
*this = std::move(open_file(path_));
}
return false;
}
auto file::read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
std::size_t *total_read) -> bool {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
if (total_read != nullptr) {
(*total_read) = 0U;
}
try {
stream_.seekg(static_cast<std::streamoff>(offset));
auto before = stream_.tellg();
if (before == -1) {
throw std::runtime_error("failed to tellg() before read");
}
stream_.read(reinterpret_cast<char *>(data),
static_cast<std::streamoff>(to_read));
if (total_read != nullptr) {
auto after = stream_.tellg();
if (after == -1) {
throw std::runtime_error("failed to tellg() after read");
}
(*total_read) = static_cast<std::size_t>(after - before);
}
return true;
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
return false;
}
auto file::remove() -> bool {
close();
return std::filesystem::remove(path_, error_);
}
auto file::truncate(std::size_t size) -> bool {
auto reopen{false};
if (stream_.is_open()) {
reopen = true;
close();
}
std::filesystem::resize_file(path_, size, error_);
if (reopen) {
*this = std::move(open_file(path_));
}
return not error_;
}
auto file::write(const typename data_buffer::value_type *data,
std::size_t to_write, std::size_t offset,
std::size_t *total_written) -> bool {
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
if (total_written != nullptr) {
(*total_written) = 0U;
}
try {
stream_.seekp(static_cast<std::streamoff>(offset));
auto before = stream_.tellp();
if (before == -1) {
throw std::runtime_error("failed to tellp() before write");
}
stream_.write(reinterpret_cast<const char *>(data),
static_cast<std::streamoff>(to_write));
auto after = stream_.tellp();
if (after == -1) {
throw std::runtime_error("failed to tellp() after write");
}
if (total_written != nullptr) {
(*total_written) = static_cast<std::size_t>(after - before);
}
return true;
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
return false;
}
auto get_file_size(std::string_view path, std::uint64_t &file_size) -> bool {
auto abs_path = utils::path::absolute(path);
file_size = 0U;
#if defined(_WIN32)
struct _stat64 st {};
if (_stat64(abs_path.c_str(), &st) != 0) {
#else // !defined(_WIN32)
struct stat st {};
if (stat(abs_path.c_str(), &st) != 0) {
#endif // defined(_WIN32)
return false;
}
if (st.st_size >= 0) {
file_size = static_cast<std::uint64_t>(st.st_size);
}
return (st.st_size >= 0);
}
auto get_file_size(std::wstring_view path, std::uint64_t &file_size) -> bool {
return get_file_size(utils::string::to_utf8(path), file_size);
}
auto is_directory(std::string_view path) -> bool {
auto abs_path = utils::path::absolute(path);
#if defined(_WIN32)
return ::PathIsDirectory(abs_path.c_str()) != 0;
#else // !defined(_WIN32)
struct stat st {};
return (stat(abs_path.c_str(), &st) == 0 && S_ISDIR(st.st_mode));
#endif // defined(_WIN32)
}
auto is_directory(std::wstring_view path) -> bool {
return is_directory(utils::string::to_utf8(path));
}
auto is_file(std::string_view path) -> bool {
auto abs_path = utils::path::absolute(path);
#if defined(_WIN32)
return (::PathFileExists(abs_path.c_str()) &&
not ::PathIsDirectory(abs_path.c_str()));
#else // !defined(_WIN32)
struct stat st {};
return (stat(abs_path.c_str(), &st) == 0 && not S_ISDIR(st.st_mode));
#endif // defined(_WIN32)
}
auto is_file(std::wstring_view path) -> bool {
return is_file(utils::string::to_utf8(path));
}
#if defined(PROJECT_ENABLE_JSON)
#if defined(PROJECT_ENABLE_LIBSODIUM)
auto read_json_file(std::string_view path, nlohmann::json &data,
std::optional<std::string_view> password) -> bool {
#else // !defined(PROJECT_ENABLE_LIBSODIUM)
auto read_json_file(std::string_view path, nlohmann::json &data) -> bool {
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
try {
auto abs_path = utils::path::absolute(path);
std::ifstream file_stream{
abs_path.c_str(),
std::ios_base::binary | std::ios::in,
};
if (not file_stream.is_open()) {
throw std::runtime_error("failed to open file: " + abs_path);
}
auto ret{true};
try {
std::stringstream stream;
stream << file_stream.rdbuf();
auto json_text = stream.str();
#if defined(PROJECT_ENABLE_LIBSODIUM)
if (password.has_value()) {
auto data = utils::encryption::decrypt_data(json_text, *password);
json_text = {data.begin(), data.end()};
}
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
if (not json_text.empty()) {
data = nlohmann::json::parse(json_text.c_str());
}
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
ret = false;
} catch (...) {
utils::error::handle_exception(function_name);
ret = false;
}
file_stream.close();
return ret;
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
return false;
}
#if defined(PROJECT_ENABLE_LIBSODIUM)
auto write_json_file(std::string_view path, const nlohmann::json &data,
std::optional<std::string_view> password) -> bool {
#else // !defined(PROJECT_ENABLE_LIBSODIUM)
auto write_json_file(std::string_view path,
const nlohmann::json &data) -> bool {
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
static constexpr const std::string_view function_name{
static_cast<const char *>(__FUNCTION__),
};
try {
auto file = file::open_or_create_file(path);
if (not file.truncate()) {
throw std::runtime_error("failed to truncate file: " +
file.get_error_code().message());
}
#if defined(PROJECT_ENABLE_LIBSODIUM)
if (password.has_value()) {
return file.write(utils::encryption::encrypt_data(data.dump(), *password),
0U);
}
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
return file.write(data, 0U);
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
return false;
}
#if defined(PROJECT_ENABLE_LIBSODIUM)
auto read_json_file(std::wstring_view path, nlohmann::json &data,
std::optional<std::wstring_view> password) -> bool {
if (password.has_value()) {
auto password_a = utils::string::to_utf8(*password);
return read_json_file(utils::string::to_utf8(path), data, password_a);
}
return read_json_file(utils::string::to_utf8(path), data, std::nullopt);
}
auto write_json_file(std::wstring_view path, const nlohmann::json &data,
std::optional<std::wstring_view> password) -> bool {
if (password.has_value()) {
auto password_a = utils::string::to_utf8(*password);
return write_json_file(utils::string::to_utf8(path), data, password_a);
}
return write_json_file(utils::string::to_utf8(path), data, std::nullopt);
}
#else // !defined(PROJECT_ENABLE_LIBSODIUM)
auto read_json_file(std::wstring_view path, nlohmann::json &data) -> bool {
return read_json_file(utils::string::to_utf8(path), data);
}
auto write_json_file(std::wstring_view path,
const nlohmann::json &data) -> bool {
return write_json_file(utils::string::to_utf8(path), data);
}
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
#endif // defined(PROJECT_ENABLE_JSON)
} // namespace repertory::utils::file

225
support/3rd_party/src/utils/path.cpp vendored Normal file
View File

@ -0,0 +1,225 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "utils/path.hpp"
#include "utils/common.hpp"
#include "utils/string.hpp"
#include "utils/unix.hpp"
namespace {
static const std::string directory_seperator_str{
repertory::utils::path::directory_seperator,
};
static const std::wstring directory_seperator_str_w{
repertory::utils::path::directory_seperator_w,
};
} // namespace
namespace repertory::utils::path {
auto find_program_in_path(const std::string &name_without_extension)
-> std::string {
static std::mutex mtx{};
static std::unordered_map<std::string, std::string> found_items{};
mutex_lock lock(mtx);
if (found_items.contains(name_without_extension)) {
return found_items.at(name_without_extension);
}
auto path = utils::get_environment_variable("PATH");
if (path.empty()) {
return path;
}
#if defined(_WIN32)
static constexpr const std::array<std::string_view, 4U> extension_list{
".bat",
".cmd",
".exe",
".ps1",
};
static constexpr const auto split_char = ';';
#else // !defined(_WIN32)
static constexpr const std::array<std::string_view, 2U> extension_list{
"",
".sh",
};
static constexpr const auto split_char = ':';
#endif // defined(_WIN32)
const auto search_path_list = utils::string::split(path, split_char, false);
for (auto &&search_path : search_path_list) {
for (auto &&extension : extension_list) {
auto exec_path = combine(
search_path, {name_without_extension + std::string{extension}});
if (std::filesystem::exists(exec_path)) {
found_items[name_without_extension] = exec_path;
return exec_path;
}
}
}
return "";
}
[[nodiscard]] auto
find_program_in_path(std::wstring_view name_without_extension) -> std::wstring {
return utils::string::from_utf8(
find_program_in_path(utils::string::to_utf8(name_without_extension)));
}
auto get_parent_directory(std::string_view path) -> std::string {
auto ret = std::filesystem::path{path}.parent_path().string();
#if !defined(_WIN32)
if (ret == ".") {
ret = "/";
}
#endif // !defined(_WIN32)
return absolute(ret);
}
auto get_parent_directory(std::wstring_view path) -> std::wstring {
return utils::string::from_utf8(
get_parent_directory(utils::string::to_utf8(path)));
}
auto is_trash_directory(std::string_view path) -> bool {
auto trash_path = utils::string::to_lower(absolute(path));
return utils::string::begins_with(trash_path,
directory_seperator_str + ".trash-") ||
utils::string::begins_with(trash_path,
directory_seperator_str + ".trashes") ||
utils::string::begins_with(trash_path,
directory_seperator_str + "$recycle.bin");
}
auto is_trash_directory(std::wstring_view path) -> bool {
auto trash_path = utils::string::to_lower(absolute(path));
return utils::string::begins_with(trash_path,
directory_seperator_str_w + L".trash-") ||
utils::string::begins_with(trash_path,
directory_seperator_str_w + L".trashes") ||
utils::string::begins_with(trash_path, directory_seperator_str_w +
L"$recycle.bin");
}
auto make_file_uri(std::string_view path) -> std::string {
auto abs_path = absolute(path);
#if defined(_WIN32)
utils::string::replace(abs_path, '\\', '/');
abs_path = '/' + abs_path;
#endif // defined(_WIN32)
return "file://" + abs_path;
}
auto make_file_uri(std::wstring_view path) -> std::wstring {
return utils::string::from_utf8(make_file_uri(utils::string::to_utf8(path)));
}
auto remove_file_name(std::string_view path) -> std::string {
auto abs_path = absolute(path);
#if defined(_WIN32)
::PathRemoveFileSpec(abs_path.data());
abs_path = abs_path.c_str();
#else // !defined(_WIN32)
if (abs_path != "/") {
auto idx{abs_path.size() - 1U};
while ((idx != 0U) && (abs_path.at(idx) != '/')) {
idx--;
}
abs_path = (idx > 0U) ? absolute(abs_path.substr(0U, idx)) : "/";
}
#endif // defined(_WIN32)
return abs_path;
}
#if !defined(_WIN32)
auto resolve(std::string path) -> std::string {
std::string home{};
use_getpwuid(getuid(), [&home](struct passwd *pw) {
home = (pw->pw_dir ? pw->pw_dir : "");
if (home.empty() || ((home == "/") && (getuid() != 0))) {
home = combine("/home", {pw->pw_name});
}
});
return absolute(utils::string::replace(path, "~", home));
}
auto resolve(std::wstring_view path) -> std::wstring {
return utils::string::from_utf8(resolve(utils::string::to_utf8(path)));
}
#endif // !defined(_WIN32)
auto strip_to_file_name(std::string path) -> std::string {
#if defined(_WIN32)
return ::PathFindFileName(path.c_str());
#else
return utils::string::contains(path, "/") ? basename(path.data()) : path;
#endif
}
auto unmake_file_uri(std::string_view uri) -> std::string {
static constexpr const std::array<std::string_view, 23U> escape_characters = {
{
" ", "<", ">", "#", "%", "+", "{", "}", "|", "\\", "^", "~",
"[", "]", "`", ";", "/", "?", ":", "@", "=", "&", "$",
}};
static constexpr const std::array<std::string_view, 23U>
escape_sequences_lower = {{
"%20", "%3c", "%3e", "%23", "%25", "%2b", "%7b", "%7d",
"%7c", "%5c", "%5e", "%7e", "%5b", "%5d", "%60", "%3b",
"%2f", "%3f", "%3a", "%40", "%3d", "%26", "%24",
}};
static constexpr const std::array<std::string_view, 23U>
escape_sequences_upper = {{
"%20", "%3C", "%3E", "%23", "%25", "%2B", "%7B", "%7D",
"%7C", "%5C", "%5E", "%7E", "%5B", "%5D", "%60", "%3B",
"%2F", "%3F", "%3A", "%40", "%3D", "%26", "%24",
}};
std::string ret_uri{uri};
#if defined(_WIN32)
ret_uri = ret_uri.substr(8U);
#else
ret_uri = ret_uri.substr(7U);
#endif
for (std::size_t idx = 0U; idx < escape_characters.size(); idx++) {
utils::string::replace(ret_uri, escape_sequences_lower.at(idx),
escape_characters.at(idx));
utils::string::replace(ret_uri, escape_sequences_upper.at(idx),
escape_characters.at(idx));
}
return absolute(uri);
}
auto unmake_file_uri(std::wstring_view uri) -> std::wstring {
return utils::string::from_utf8(unmake_file_uri(utils::string::to_utf8(uri)));
}
} // namespace repertory::utils::path

Some files were not shown because too many files have changed in this diff Show More