updated build system
This commit is contained in:
parent
f4a3c52428
commit
098d172f40
@ -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)
|
||||||
|
@ -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}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
@ -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(
|
|
||||||
-DCPPHTTPLIB_OPENSSL_SUPPORT
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DPROJECT_ENABLE_CPP_HTTPLIB
|
-DCPPHTTPLIB_OPENSSL_SUPPORT
|
||||||
-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()
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
@ -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; \
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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>;
|
||||||
|
@ -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,
|
||||||
return utils::collection_includes(item.second, consumer);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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 {
|
||||||
|
@ -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_
|
||||||
|
@ -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_
|
||||||
|
@ -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 ¬_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_
|
|
@ -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_
|
|
@ -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
|
||||||
|
@ -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_
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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") {
|
||||||
|
@ -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,8 +989,8 @@ 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
|
||||||
) {
|
) {
|
||||||
return api_error::not_supported;
|
return api_error::not_supported;
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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) \
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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 {
|
||||||
|
@ -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()) {
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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]);
|
||||||
|
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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"},
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
|
||||||
|
@ -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 ¬_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
|
|
@ -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
|
|
@ -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) {
|
||||||
|
@ -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__)
|
||||||
|
@ -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
|
||||||
|
@ -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"
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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();
|
||||||
|
@ -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 {
|
||||||
|
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
|
@ -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) {
|
||||||
|
@ -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());
|
||||||
|
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
36
support/3rd_party/include/utils/all.hpp
vendored
Normal 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_
|
@ -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 =
|
||||||
? 0U & i++
|
input.at(i) == '='
|
||||||
: kDecodingTable[static_cast<int>(input[i++])];
|
? 0U & i++
|
||||||
std::uint32_t b = input[i] == '='
|
: kDecodingTable[static_cast<unsigned char>(input.at(i++))];
|
||||||
? 0U & i++
|
std::uint32_t b =
|
||||||
: kDecodingTable[static_cast<int>(input[i++])];
|
input.at(i) == '='
|
||||||
std::uint32_t c = input[i] == '='
|
? 0U & i++
|
||||||
? 0U & i++
|
: kDecodingTable[static_cast<unsigned char>(input.at(i++))];
|
||||||
: kDecodingTable[static_cast<int>(input[i++])];
|
std::uint32_t c =
|
||||||
std::uint32_t d = input[i] == '='
|
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.at(i) == '='
|
||||||
|
? 0U & 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);
|
133
support/3rd_party/include/utils/collection.hpp
vendored
Normal file
133
support/3rd_party/include/utils/collection.hpp
vendored
Normal 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_
|
@ -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_
|
111
support/3rd_party/include/utils/common.hpp
vendored
Normal file
111
support/3rd_party/include/utils/common.hpp
vendored
Normal 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_
|
313
support/3rd_party/include/utils/config.hpp
vendored
Normal file
313
support/3rd_party/include/utils/config.hpp
vendored
Normal 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_
|
160
support/3rd_party/include/utils/encryption.hpp
vendored
Normal file
160
support/3rd_party/include/utils/encryption.hpp
vendored
Normal 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_
|
52
support/3rd_party/include/utils/error.hpp
vendored
Normal file
52
support/3rd_party/include/utils/error.hpp
vendored
Normal 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
147
support/3rd_party/include/utils/file.hpp
vendored
Normal 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
403
support/3rd_party/include/utils/path.hpp
vendored
Normal 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_
|
496
support/3rd_party/include/utils/string.hpp
vendored
Normal file
496
support/3rd_party/include/utils/string.hpp
vendored
Normal 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_
|
64
support/3rd_party/include/utils/time.hpp
vendored
Normal file
64
support/3rd_party/include/utils/time.hpp
vendored
Normal 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_
|
64
support/3rd_party/include/utils/unix.hpp
vendored
Normal file
64
support/3rd_party/include/utils/unix.hpp
vendored
Normal 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_
|
43
support/3rd_party/include/utils/windows.hpp
vendored
Normal file
43
support/3rd_party/include/utils/windows.hpp
vendored
Normal 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_
|
5
support/3rd_party/src/backward.cpp
vendored
5
support/3rd_party/src/backward.cpp
vendored
@ -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
169
support/3rd_party/src/utils/common.cpp
vendored
Normal 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
|
103
support/3rd_party/src/utils/encryption.cpp
vendored
Normal file
103
support/3rd_party/src/utils/encryption.cpp
vendored
Normal 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
71
support/3rd_party/src/utils/error.cpp
vendored
Normal 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
366
support/3rd_party/src/utils/file.cpp
vendored
Normal 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
225
support/3rd_party/src/utils/path.cpp
vendored
Normal 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
Loading…
x
Reference in New Issue
Block a user