v2.0.2-rc (#27)
Some checks reported errors
BlockStorage/repertory/pipeline/head Something is wrong with the build of this commit

## v2.0.2-rc

### BREAKING CHANGES

* Refactored `config.json` - will need to verify configuration settings prior to mounting

### Issues

* \#12 \[Unit Test\] Complete all providers unit tests
* \#14 \[Unit Test\] SQLite mini-ORM unit tests and cleanup
* \#16 Add support for bucket name in Sia provider
* \#17 Update to common c++ build system
  * A single 64-bit Linux Jenkins server is used to build all Linux and Windows versions
  * All dependency sources are now included
  * MSVC is no longer supported
  * MSYS2 is required for building Windows binaries on Windows
  * OS X support is temporarily disabled
* \#19 \[bug\] Rename file is broken for files that are existing
* \#23 \[bug\] Incorrect file size displayed while upload is pending
* \#24 RocksDB implementations should be transactional
* \#25 Writes should block when maximum cache size is reached
* \#26 Complete ring buffer and direct download support

### Changes from v2.0.1-rc

* Ability to choose between RocksDB and SQLite databases
* Added direct reads and implemented download fallback
* Corrected file times on S3 and Sia providers
* Corrected handling of `chown()` and `chmod()`
* Fixed erroneous download of chunks after resize

Reviewed-on: #27
This commit is contained in:
2024-12-28 15:56:40 -06:00
parent 1b8de3b097
commit 8dd46b8ad8
790 changed files with 49979 additions and 417734 deletions

View File

@ -0,0 +1,59 @@
/*
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/base64.hpp"
#include "utils/collection.hpp"
#if defined(_WIN32)
#include "utils/com_init_wrapper.hpp"
#endif // defined(_WIN32)
#include "utils/common.hpp"
#if defined(PROJECT_ENABLE_SQLITE)
#include "utils/db/sqlite/db_common.hpp"
#include "utils/db/sqlite/db_delete.hpp"
#include "utils/db/sqlite/db_insert.hpp"
#include "utils/db/sqlite/db_select.hpp"
#include "utils/db/sqlite/db_update.hpp"
#endif // defined(PROJECT_ENABLE_SQLITE)
#if defined(PROJECT_ENABLE_LIBSODIUM)
#include "utils/encrypting_reader.hpp"
#include "utils/encryption.hpp"
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
#include "utils/error.hpp"
#include "utils/file.hpp"
#if defined(PROJECT_ENABLE_LIBSODIUM)
#include "utils/hash.hpp"
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
#include "utils/path.hpp"
#include "utils/string.hpp"
#include "utils/time.hpp"
#if !defined(_WIN32)
#include "utils/unix.hpp"
#endif // !defined(_WIN32)
#if defined(_WIN32)
#include "utils/windows.hpp"
#endif // defined(_WIN32)
#endif // REPERTORY_INCLUDE_UTILS_ALL_HPP_

View File

@ -0,0 +1,174 @@
// NOLINTBEGIN
#ifndef _MACARON_BASE64_H_
#define _MACARON_BASE64_H_
/**
* The MIT License (MIT)
* Copyright (c) 2016 tomykaira
*
* 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.
*/
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#endif
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wold-style-cast"
#pragma GCC diagnostic ignored "-Wuseless-cast"
#endif
#include <array>
#include <string>
#include <vector>
namespace macaron::Base64 {
static std::string Encode(const unsigned char *data, std::size_t len) {
static constexpr std::array<unsigned char, 64U> sEncodingTable{
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/',
};
auto in_len{len};
std::string ret;
if (in_len > 0) {
std::size_t out_len{4U * ((in_len + 2U) / 3U)};
ret = std::string(out_len, '\0');
std::size_t i;
auto *p = reinterpret_cast<unsigned char *>(ret.data());
for (i = 0U; i < in_len - 2U; i += 3U) {
*p++ = sEncodingTable[(data[i] >> 2U) & 0x3F];
*p++ = sEncodingTable[((data[i] & 0x3) << 4U) |
((int)(data[i + 1U] & 0xF0) >> 4U)];
*p++ = sEncodingTable[((data[i + 1] & 0xF) << 2) |
((int)(data[i + 2U] & 0xC0) >> 6U)];
*p++ = sEncodingTable[data[i + 2U] & 0x3F];
}
if (i < in_len) {
*p++ = sEncodingTable[(data[i] >> 2U) & 0x3F];
if (i == (in_len - 1U)) {
*p++ = sEncodingTable[((data[i] & 0x3) << 4U)];
*p++ = '=';
} else {
*p++ = sEncodingTable[((data[i] & 0x3) << 4U) |
((int)(data[i + 1U] & 0xF0) >> 4U)];
*p++ = sEncodingTable[((data[i + 1U] & 0xF) << 2U)];
}
*p++ = '=';
}
}
return ret;
}
[[maybe_unused]] static std::string Encode(std::string_view data) {
return Encode(reinterpret_cast<const unsigned char *>(data.data()),
data.size());
}
[[maybe_unused]] static std::vector<unsigned char>
Decode(std::string_view input) {
static constexpr std::array<unsigned char, 256> kDecodingTable{
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6,
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64,
};
std::vector<unsigned char> out;
if (not input.empty()) {
auto in_len{input.size()};
if (in_len % 4U != 0U) {
throw std::runtime_error("Input data size is not a multiple of 4");
}
std::size_t out_len{in_len / 4U * 3U};
if (input[in_len - 1U] == '=') {
out_len--;
}
if (input[in_len - 2U] == '=') {
out_len--;
}
out.resize(out_len);
for (std::size_t i = 0U, j = 0U; i < in_len;) {
std::uint32_t a =
input.at(i) == '='
? 0U & i++
: kDecodingTable[static_cast<unsigned char>(input.at(i++))];
std::uint32_t b =
input.at(i) == '='
? 0U & i++
: kDecodingTable[static_cast<unsigned char>(input.at(i++))];
std::uint32_t c =
input.at(i) == '='
? 0U & 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 =
(a << 3U * 6U) + (b << 2U * 6U) + (c << 1U * 6U) + (d << 0U * 6U);
if (j < out_len)
out[j++] = (triple >> 2U * 8U) & 0xFF;
if (j < out_len)
out[j++] = (triple >> 1U * 8U) & 0xFF;
if (j < out_len)
out[j++] = (triple >> 0U * 8U) & 0xFF;
}
}
return out;
}
} // namespace macaron::Base64
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#endif /* _MACARON_BASE64_H_ */
// NOLINTEND

View File

@ -0,0 +1,178 @@
/*
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"
#include "utils/error.hpp"
#include "utils/string.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>
[[nodiscard]] inline auto from_hex_string_t(std::string_view str, val_t &val)
-> bool {
REPERTORY_USES_FUNCTION_NAME();
static constexpr const auto base16{16};
try {
val.clear();
std::string fmt_val{str};
utils::string::trim(fmt_val);
if (fmt_val.empty()) {
return true;
}
fmt_val = utils::string::to_lower(fmt_val);
if (utils::string::begins_with(fmt_val, "0x")) {
fmt_val = fmt_val.substr(2U);
}
if (fmt_val.empty()) {
throw utils::error::create_exception(function_name,
{
"hex string is invalid",
str,
});
}
if (fmt_val.length() % 2U) {
fmt_val = '0' + fmt_val;
}
auto iter = std::find_if_not(
fmt_val.begin(), fmt_val.end(), [](auto cur_char) -> bool {
auto check = static_cast<std::uint32_t>(cur_char);
return ((check >= 48U && check <= 57U) ||
(check >= 97U && check <= 102U));
});
if (iter != fmt_val.end()) {
auto invalid_idx{std::distance(fmt_val.begin(), iter)};
throw std::range_error(utils::error::create_error_message({
function_name,
"invalid character in hex string",
std::to_string(invalid_idx),
std::string(1U, str.at(invalid_idx)),
str,
}));
}
val.resize(fmt_val.length() / 2U);
for (std::size_t idx = 0U; idx < fmt_val.length(); idx += 2U) {
val.at(idx / 2U) = static_cast<typename val_t::value_type>(
std::strtoul(fmt_val.substr(idx, 2U).c_str(), nullptr, base16));
}
return true;
} catch (const std::exception &e) {
utils::error::handle_exception(function_name, e);
} catch (...) {
utils::error::handle_exception(function_name);
}
val.clear();
return false;
}
template <typename val_t>
inline auto from_hex_string(std::string_view str, val_t &val) -> bool {
return from_hex_string_t<val_t>(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>(utils::string::to_utf8(str), val);
}
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>
inline auto to_hex_string(const col_t &collection) -> std::string {
static_assert(sizeof(typename col_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();
}
template <typename col_t>
inline auto to_hex_wstring(const col_t &collection) -> std::wstring {
return utils::string::from_utf8(to_hex_string<col_t>(collection));
}
} // namespace repertory::utils::collection
#endif // REPERTORY_INCLUDE_UTILS_COLLECTION_HPP_

View File

@ -0,0 +1,54 @@
/*
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_COM_INIT_WRAPPER_HPP_
#define REPERTORY_INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_
#if defined(_WIN32)
#include "utils/config.hpp"
namespace repertory::utils {
struct com_init_wrapper final {
com_init_wrapper()
: initialized_(
SUCCEEDED(::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))) {}
com_init_wrapper(const com_init_wrapper &) = delete;
com_init_wrapper(com_init_wrapper &&) = delete;
~com_init_wrapper() {
if (initialized_) {
::CoUninitialize();
}
}
auto operator=(const com_init_wrapper &) -> com_init_wrapper & = delete;
auto operator=(com_init_wrapper &&) -> com_init_wrapper & = delete;
[[nodiscard]] auto is_initialized() const -> bool { return initialized_; }
private:
BOOL initialized_;
};
} // namespace repertory::utils
#endif // defined(_WIN32)
#endif // REPERTORY_INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_

View File

@ -0,0 +1,145 @@
/*
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 function_name;
bool ok{true};
std::string reason{"success"};
[[nodiscard]] operator bool() const { return ok; }
};
using retryable_action_t = std::function<bool()>;
[[nodiscard]] inline constexpr 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)
template <typename result_t, typename data_t>
[[nodiscard]] inline constexpr auto divide_with_ceiling(result_t numerator,
data_t denominator)
-> result_t;
template <typename data_t>
[[nodiscard]] inline auto generate_random_between(data_t begin, data_t end)
-> data_t;
[[nodiscard]] auto generate_random_string(std::size_t length) -> std::string;
[[nodiscard]] auto generate_random_wstring(std::size_t length) -> std::wstring;
#if defined(PROJECT_ENABLE_LIBSODIUM)
template <typename data_t>
[[nodiscard]] inline auto generate_secure_random() -> data_t;
template <typename data_t>
[[nodiscard]] inline auto generate_secure_random(std::size_t size) -> data_t;
#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 retry_action(
retryable_action_t action, std::size_t retry_count = 200U,
std::chrono::milliseconds retry_wait = std::chrono::milliseconds(10))
-> bool;
template <typename result_t, typename data_t>
inline constexpr auto divide_with_ceiling(result_t numerator,
data_t denominator) -> result_t {
static_assert(std::is_integral_v<std::remove_cv_t<data_t>>,
"denominator must be an integral type");
return denominator == 0
? 0
: (numerator / denominator) + (numerator % denominator != 0);
}
template <typename data_t>
inline auto generate_random_between(data_t begin, data_t end) -> data_t {
static_assert(std::is_integral_v<std::remove_cv_t<data_t>>,
"data_t must be an integral type");
if (end <= begin) {
throw std::range_error("end must be greater than begin");
}
thread_local std::mt19937 gen(
static_cast<unsigned long>(std::time(nullptr) ^ std::random_device{}()));
std::uniform_int_distribution<data_t> dis(begin, end);
return dis(gen);
}
#if defined(PROJECT_ENABLE_LIBSODIUM)
template <typename data_t> inline auto generate_secure_random() -> data_t {
static_assert(!is_collection<std::decay_t<data_t>>::value,
"data_t is a vector or collection");
data_t ret{};
randombytes_buf(&ret, sizeof(ret));
return ret;
}
template <typename data_t>
inline auto generate_secure_random(std::size_t size) -> data_t {
static_assert(is_collection<std::decay_t<data_t>>::value,
"data_t is not a vector or collection");
data_t ret;
ret.resize(size);
randombytes_buf(ret.data(), ret.size() * sizeof(typename data_t::value_type));
return ret;
}
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
} // namespace repertory::utils
#endif // REPERTORY_INCLUDE_UTILS_COMMON_HPP_

View File

@ -0,0 +1,483 @@
/*
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_
#define NOMINMAX
#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>
#if !defined(__cplusplus)
#include <errno.h>
#endif // !defined(__cplusplus)
#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>
#if !defined(__cplusplus)
#include <stdio.h>
#endif // !defined(__cplusplus)
#include <sys/stat.h>
#include <sys/types.h>
#if !defined(__cplusplus)
#include <time.h>
#endif // !defined(__cplusplus)
#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 // !defined(__LFS64__)
#include <sys/stat.h>
#endif // defined(__LFS64__)
#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 <cerrno>
#include <chrono>
#include <ciso646>
#include <climits>
#include <codecvt>
#include <condition_variable>
#include <csignal>
#include <cstdint>
#include <cstdio>
#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_OPENSSL)
#include "openssl/ssl.h"
#endif // defined(PROJECT_ENABLE_OPENSSL)
#if defined(PROJECT_ENABLE_LIBDSM)
#if defined(__cplusplus)
extern "C" {
#endif // defined(__cplusplus)
#include "bdsm/bdsm.h"
#if defined(__cplusplus)
}
struct netbios_ns_deleter final {
void operator()(netbios_ns *ns) const {
if (ns != nullptr) {
netbios_ns_destroy(ns);
}
}
};
using netbios_ns_t = std::unique_ptr<netbios_ns, netbios_ns_deleter>;
inline const auto smb_session_deleter = [](smb_session *session) {
if (session != nullptr) {
smb_session_destroy(session);
}
};
using smb_session_t = std::shared_ptr<smb_session>;
struct smb_stat_deleter final {
void operator()(smb_stat st) const {
if (st != nullptr) {
smb_stat_destroy(st);
}
}
};
using smb_stat_t = std::unique_ptr<smb_file, smb_stat_deleter>;
struct smb_stat_list_deleter final {
void operator()(smb_file *list) const {
if (list != nullptr) {
smb_stat_list_destroy(list);
}
}
};
using smb_stat_list_t = std::unique_ptr<smb_file, smb_stat_list_deleter>;
#endif // defined(__cplusplus)
#endif // defined(PROJECT_ENABLE_LIBDSM)
#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_LIBSODIUM)
#include "sodium.h"
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
#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_SQLITE)
#include "sqlite3.h"
#endif // defined(PROJECT_ENABLE_SQLITE)
#if defined(PROJECT_ENABLE_VLC)
#include <vlc/vlc.h>
#if defined(__cplusplus)
[[nodiscard]] inline auto get_libvlc_error_msg() -> std::string {
const auto *msg = libvlc_errmsg();
return msg == nullptr ? "none" : msg;
}
struct vlc_deleter final {
void operator()(libvlc_instance_t *inst) const {
if (inst != nullptr) {
libvlc_release(inst);
}
}
};
using vlc_t = std::unique_ptr<libvlc_instance_t, vlc_deleter>;
struct vlc_media_deleter final {
void operator()(libvlc_media_t *media) const {
if (media != nullptr) {
libvlc_media_release(media);
}
}
};
using vlc_media_t = std::unique_ptr<libvlc_media_t, vlc_media_deleter>;
struct vlc_media_list_deleter final {
void operator()(libvlc_media_list_t *media_list) const {
if (media_list != nullptr) {
libvlc_media_list_release(media_list);
}
}
};
using vlc_media_list_t =
std::unique_ptr<libvlc_media_list_t, vlc_media_list_deleter>;
struct vlc_string_deleter final {
void operator()(char *str) const {
if (str != nullptr) {
libvlc_free(str);
}
}
};
using vlc_string_t = std::unique_ptr<char, vlc_string_deleter>;
#endif // defined(__cplusplus)
#endif // defined(PROJECT_ENABLE_VLC)
#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)
#if !defined(off64_t)
#define off64_t std::size_t
#endif // !defined(off64_t)
#if !defined(__off64_t)
#define __off64_t off64_t
#endif // !defined(__off64_t)
#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_CLI11)
#if defined(PROJECT_IS_MINGW) && !defined(PROJECT_IS_MINGW_UNIX)
#include "CLI/CLI.hpp"
#else // !defined(PROJECT_IS_MINGW) || defined(PROJECT_IS_MINGW_UNIX)
#include "CLI11.hpp"
#endif // defined(PROJECT_IS_MINGW) && !defined(PROJECT_IS_MINGW_UNIX)
#endif // defined(PROJECT_ENABLE_CLI11)
#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/bundled/ranges.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)
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 stop_type = std::atomic_bool;
using unique_mutex_lock = std::unique_lock<std::mutex>;
using unique_recur_mutex_lock = std::unique_lock<std::recursive_mutex>;
#if defined(_WIN32)
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
inline constexpr const auto max_path_length = std::size_t{32767U};
#else // !defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
inline constexpr const auto max_path_length = std::size_t{MAX_PATH};
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
using native_handle = HANDLE;
#else // !defined(_WIN32)
inline constexpr const auto max_path_length = std::size_t{PATH_MAX};
using native_handle = int;
#if !defined(INVALID_HANDLE_VALUE)
#define INVALID_HANDLE_VALUE (-1)
#endif // !defined(INVALID_HANDLE_VALUE)
#endif // defined(_WIN32)
template <class... Ts> struct overloaded : Ts... {
using Ts::operator()...;
};
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
template <typename T> struct is_collection {
static const bool value = false;
};
template <typename T, typename A>
struct is_collection<std::vector<T, A>> : std::true_type {};
template <typename T> struct is_collection<std::deque<T>> : std::true_type {};
template <> struct is_collection<std::string> : std::true_type {};
template <> struct is_collection<std::wstring> : std::true_type {};
struct file_deleter final {
void operator()(FILE *file) {
if (file != nullptr) {
fclose(file);
}
}
};
using file_t = std::unique_ptr<FILE, file_deleter>;
#if defined(PROJECT_ENABLE_CURL)
struct http_range final {
std::uint64_t begin{};
std::uint64_t end{};
};
using http_headers = std::unordered_map<std::string, std::string>;
using http_query_parameters = std::map<std::string, std::string>;
using http_ranges = std::vector<http_range>;
#endif // defined(PROJECT_ENABLE_CURL)
} // namespace repertory
#endif // defined(__cplusplus)
#define REPERTORY_USES_FUNCTION_NAME() \
static constexpr const std::string_view function_name { \
static_cast<const char *>(__FUNCTION__), \
}
#endif // REPERTORY_INCLUDE_UTILS_CONFIG_HPP_

View File

@ -0,0 +1,170 @@
/*
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_DB_SQLITE_DB_COMMON_HPP_
#define REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_COMMON_HPP_
#if defined(PROJECT_ENABLE_SQLITE)
#include "utils/config.hpp"
#include "utils/error.hpp"
namespace repertory::utils::db::sqlite {
using db_types_t = std::variant<std::int64_t, std::string>;
struct sqlite3_deleter final {
void operator()(sqlite3 *db3) const;
};
using db3_t = std::unique_ptr<sqlite3, sqlite3_deleter>;
struct sqlite3_statement_deleter final {
void operator()(sqlite3_stmt *stmt) const {
if (stmt != nullptr) {
sqlite3_finalize(stmt);
}
}
};
using db3_stmt_t = std::unique_ptr<sqlite3_stmt, sqlite3_statement_deleter>;
[[nodiscard]] auto
create_db(std::string db_path,
const std::map<std::string, std::string> &sql_create_tables) -> db3_t;
[[nodiscard]] auto execute_sql(sqlite3 &db3, const std::string &sql,
std::string &err) -> bool;
void set_journal_mode(sqlite3 &db3);
struct db_comp_data_t final {
std::string column_name;
std::string op_type;
};
struct db_context_t {
db_context_t(sqlite3 *db3_, std::string table_name_)
: db3(db3_), table_name(std::move(table_name_)) {}
sqlite3 *db3{};
std::string table_name;
};
struct db_result final {
struct context final {
db3_stmt_t stmt;
};
class db_column final {
public:
db_column(std::int32_t index, std::string name, db_types_t value) noexcept;
db_column() noexcept = default;
db_column(const db_column &) = default;
db_column(db_column &&column) noexcept = default;
~db_column() = default;
auto operator=(const db_column &) -> db_column & = default;
auto operator=(db_column &&) -> db_column & = default;
private:
std::int32_t index_{};
std::string name_;
db_types_t value_;
public:
[[nodiscard]] auto get_index() const -> std::int32_t { return index_; }
[[nodiscard]] auto get_name() const -> std::string { return name_; }
template <typename data_type>
[[nodiscard]] auto get_value() const -> data_type {
REPERTORY_USES_FUNCTION_NAME();
return std::visit(
overloaded{
[](const data_type &value) -> data_type { return value; },
[](auto &&) -> data_type {
throw utils::error::create_exception(
function_name, {
"data type not supported",
});
},
},
value_);
}
#if defined(PROJECT_ENABLE_JSON)
[[nodiscard]] auto get_value_as_json() const -> nlohmann::json;
#endif // defined(PROJECT_ENABLE_JSON)
};
class db_row final {
public:
db_row(std::shared_ptr<context> ctx);
private:
std::map<std::string, db_column> columns_;
public:
[[nodiscard]] auto get_columns() const -> std::vector<db_column>;
[[nodiscard]] auto get_column(std::int32_t index) const -> db_column;
[[nodiscard]] auto get_column(std::string name) const -> db_column;
};
db_result(db3_stmt_t stmt, std::int32_t res);
db_result() = default;
db_result(const db_result &) = default;
db_result(db_result &&) noexcept = default;
auto operator=(const db_result &) -> db_result & = default;
auto operator=(db_result &&) -> db_result & = default;
using row = db_row;
private:
std::shared_ptr<context> ctx_;
mutable std::int32_t res_{};
private:
void set_res(std::int32_t res) const { res_ = res; }
public:
[[nodiscard]] auto get_error() const -> std::int32_t { return res_; }
[[nodiscard]] auto get_error_str() const -> std::string;
[[nodiscard]] auto get_row(std::optional<row> &opt_row) const -> bool;
[[nodiscard]] auto has_row() const -> bool;
void next_row() const;
[[nodiscard]] auto ok() const -> bool;
};
} // namespace repertory::utils::db::sqlite
#endif // defined(PROJECT_ENABLE_SQLITE)
#endif // REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_COMMON_HPP_

View File

@ -0,0 +1,73 @@
/*
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_DB_SQLITE_DB_DELETE_HPP_
#define REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_DELETE_HPP_
#if defined(PROJECT_ENABLE_SQLITE)
#include "utils/db/sqlite/db_common.hpp"
#include "utils/db/sqlite/db_where_t.hpp"
namespace repertory::utils::db::sqlite {
class db_delete final {
public:
struct context final : db_context_t {
struct db_delete_op_t final {
std::shared_ptr<context> ctx;
[[nodiscard]] auto dump() const -> std::string;
[[nodiscard]] auto go() const -> db_result;
};
context(sqlite3 *db3_, std::string table_name_)
: db_context_t(db3_, table_name_) {}
using w_t = db_where_t<context, db_delete_op_t>;
using wd_t = where_data_t<w_t>;
std::unique_ptr<wd_t> where_data;
};
public:
db_delete(sqlite3 &db3, std::string table_name)
: ctx_(std::make_shared<context>(&db3, table_name)) {}
db_delete(std::shared_ptr<context> ctx) : ctx_(std::move(ctx)) {}
private:
std::shared_ptr<context> ctx_;
public:
[[nodiscard]] auto dump() const -> std::string;
[[nodiscard]] auto go() const -> db_result;
[[nodiscard]] auto
group(context::w_t::group_func_t func) -> context::w_t::wn_t;
[[nodiscard]] auto where(std::string column_name) const -> context::w_t::cn_t;
};
} // namespace repertory::utils::db::sqlite
#endif // defined(PROJECT_ENABLE_SQLITE)
#endif // REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_DELETE_HPP_

View File

@ -0,0 +1,64 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_INSERT_HPP_
#define REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_INSERT_HPP_
#if defined(PROJECT_ENABLE_SQLITE)
#include "utils/db/sqlite/db_common.hpp"
namespace repertory::utils::db::sqlite {
class db_insert final {
public:
struct context final : db_context_t {
context(sqlite3 *db3_, std::string table_name_)
: db_context_t(db3_, table_name_) {}
bool or_replace{false};
std::map<std::string, db_types_t> values;
};
public:
db_insert(sqlite3 &db3, std::string table_name)
: ctx_(std::make_shared<context>(&db3, table_name)) {}
db_insert(std::shared_ptr<context> ctx) : ctx_(std::move(ctx)) {}
private:
std::shared_ptr<context> ctx_;
public:
[[nodiscard]] auto or_replace() -> db_insert {
ctx_->or_replace = true;
return *this;
}
[[nodiscard]] auto column_value(std::string column_name, db_types_t value)
-> db_insert;
[[nodiscard]] auto dump() const -> std::string;
[[nodiscard]] auto go() const -> db_result;
};
} // namespace repertory::utils::db::sqlite
#endif // defined(PROJECT_ENABLE_SQLITE)
#endif // REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_INSERT_HPP_

View File

@ -0,0 +1,104 @@
/*
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_DB_SQLITE_DB_SELECT_HPP_
#define REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_SELECT_HPP_
#if defined(PROJECT_ENABLE_SQLITE)
#include "utils/db/sqlite/db_common.hpp"
#include "utils/db/sqlite/db_where_t.hpp"
namespace repertory::utils::db::sqlite {
class db_select final {
public:
struct context final : db_context_t {
struct db_select_op_t final {
std::shared_ptr<context> ctx;
[[nodiscard]] auto dump() const -> std::string;
[[nodiscard]] auto go() const -> db_result;
[[nodiscard]] auto group_by(std::string column_name) -> db_select_op_t;
[[nodiscard]] auto limit(std::int32_t value) -> db_select_op_t;
[[nodiscard]] auto offset(std::int32_t value) -> db_select_op_t;
[[nodiscard]] auto order_by(std::string column_name, bool ascending)
-> db_select_op_t;
};
context(sqlite3 *db3_, std::string table_name_)
: db_context_t(db3_, table_name_) {}
using w_t = db_where_t<context, db_select_op_t>;
using wd_t = where_data_t<w_t>;
std::vector<std::string> columns;
std::map<std::string, std::string> count_columns;
std::vector<std::string> group_by;
std::optional<std::int32_t> limit;
std::optional<std::int32_t> offset;
std::optional<std::pair<std::string, bool>> order_by;
std::unique_ptr<wd_t> where_data;
};
public:
db_select(sqlite3 &db3, std::string table_name)
: ctx_(std::make_shared<context>(&db3, table_name)) {}
db_select(std::shared_ptr<context> ctx) : ctx_(std::move(ctx)) {}
private:
std::shared_ptr<context> ctx_;
public:
[[nodiscard]] auto column(std::string column_name) -> db_select;
[[nodiscard]] auto count(std::string column_name, std::string as_column_name)
-> db_select;
[[nodiscard]] auto dump() const -> std::string;
[[nodiscard]] auto go() const -> db_result;
[[nodiscard]] auto group_by(std::string column_name) -> db_select;
[[nodiscard]] auto group(context::w_t::group_func_t func)
-> context::w_t::wn_t;
[[nodiscard]] auto limit(std::int32_t value) -> db_select;
[[nodiscard]] auto offset(std::int32_t value) -> db_select;
[[nodiscard]] auto order_by(std::string column_name, bool ascending)
-> db_select;
[[nodiscard]] auto where(std::string column_name) const -> context::w_t::cn_t;
};
} // namespace repertory::utils::db::sqlite
#endif // defined(PROJECT_ENABLE_SQLITE)
#endif // REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_SELECT_HPP_

View File

@ -0,0 +1,91 @@
/*
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_DB_SQLITE_DB_UPDATE_HPP_
#define REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_UPDATE_HPP_
#if defined(PROJECT_ENABLE_SQLITE)
#include "utils/db/sqlite/db_common.hpp"
#include "utils/db/sqlite/db_where_t.hpp"
namespace repertory::utils::db::sqlite {
class db_update final {
public:
struct context final : db_context_t {
context(sqlite3 *db3_, std::string table_name_)
: db_context_t(db3_, table_name_) {}
struct db_update_op_t final {
std::shared_ptr<context> ctx;
[[nodiscard]] auto dump() const -> std::string;
[[nodiscard]] auto go() const -> db_result;
[[nodiscard]] auto limit(std::int32_t value) -> db_update_op_t;
[[nodiscard]] auto order_by(std::string column_name, bool ascending)
-> db_update_op_t;
};
using w_t = db_where_t<context, db_update_op_t>;
using wd_t = where_data_t<w_t>;
std::map<std::string, db_types_t> column_values;
std::optional<std::int32_t> limit;
std::optional<std::pair<std::string, bool>> order_by;
std::unique_ptr<wd_t> where_data;
};
public:
db_update(sqlite3 &db3, std::string table_name)
: ctx_(std::make_shared<context>(&db3, table_name)) {}
db_update(std::shared_ptr<context> ctx) : ctx_(std::move(ctx)) {}
private:
std::shared_ptr<context> ctx_;
public:
[[nodiscard]] auto column_value(std::string column_name, db_types_t value)
-> db_update;
[[nodiscard]] auto dump() const -> std::string;
[[nodiscard]] auto go() const -> db_result;
[[nodiscard]] auto group(context::w_t::group_func_t func)
-> context::w_t::wn_t;
[[nodiscard]] auto limit(std::int32_t value) -> db_update;
[[nodiscard]] auto order_by(std::string column_name, bool ascending)
-> db_update;
[[nodiscard]] auto where(std::string column_name) const -> context::w_t::cn_t;
};
} // namespace repertory::utils::db::sqlite
#endif // defined(PROJECT_ENABLE_SQLITE)
#endif // REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_UPDATE_HPP_

View File

@ -0,0 +1,224 @@
/*
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_DB_SQLITE_DB_WHERE_T_HPP_
#define REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_WHERE_T_HPP_
#if defined(PROJECT_ENABLE_SQLITE)
#include "utils/db/sqlite/db_common.hpp"
namespace repertory::utils::db::sqlite {
template <typename w_t> struct where_data_t final {
w_t base;
std::map<std::size_t, std::vector<typename w_t::action_t>> actions;
std::vector<db_types_t> values;
};
template <typename cn_t, typename ctx_t, typename op_t, typename w_t,
typename wn_t>
struct db_next_t final {
std::size_t action_idx{};
std::shared_ptr<ctx_t> ctx;
std::string action;
using group_func_t = std::function<void(w_t &)>;
[[nodiscard]] auto where(std::string column_name) -> cn_t {
return w_t{action_idx, ctx}.where(column_name);
}
[[nodiscard]] auto dump() const -> std::string { return op_t{ctx}.dump(); }
[[nodiscard]] auto dump(std::int32_t &idx) const -> std::string {
return ctx->where_data->base.dump(idx);
}
[[nodiscard]] auto go() const -> auto { return op_t{ctx}.go(); }
[[nodiscard]] auto group(group_func_t func) -> wn_t {
return w_t{action_idx, ctx}.group(std::move(func));
}
[[nodiscard]] auto op() -> op_t {
return op_t{
ctx,
};
}
};
template <typename cn_t, typename ctx_t, typename op_t, typename w_t>
struct db_where_next_t final {
std::size_t action_idx{};
std::shared_ptr<ctx_t> ctx;
using n_t = db_next_t<cn_t, ctx_t, op_t, w_t, db_where_next_t>;
[[nodiscard]] auto and_() -> n_t {
n_t next{
action_idx,
ctx,
"AND",
};
ctx->where_data->actions[action_idx].emplace_back(next);
return next;
}
[[nodiscard]] auto dump() const -> std::string { return op_t{ctx}.dump(); }
[[nodiscard]] auto dump(std::int32_t &idx) const -> std::string {
return ctx->where_data->base.dump(idx);
}
[[nodiscard]] auto go() const -> auto { return op_t{ctx}.go(); }
[[nodiscard]] auto op() -> op_t {
return op_t{
ctx,
};
}
[[nodiscard]] auto or_() -> n_t {
n_t next{
action_idx,
ctx,
"OR",
};
ctx->where_data->actions[action_idx].emplace_back(next);
return next;
}
};
template <typename ctx_t, typename op_t, typename w_t>
struct db_comp_next_t final {
std::size_t action_idx{};
std::shared_ptr<ctx_t> ctx;
std::string column_name;
using wn_t = db_where_next_t<db_comp_next_t, ctx_t, op_t, w_t>;
[[nodiscard]] auto create(std::string operation, db_types_t value) {
ctx->where_data->actions[action_idx].emplace_back(db_comp_data_t{
column_name,
operation,
});
ctx->where_data->values.push_back(value);
return wn_t{
action_idx,
ctx,
};
}
auto equals(db_types_t value) -> wn_t { return create("=", value); };
auto gt(db_types_t value) -> wn_t { return create(">", value); }
auto gte(db_types_t value) -> wn_t { return create(">=", value); }
auto like(db_types_t value) -> wn_t { return create("LIKE", value); }
auto lt(db_types_t value) -> wn_t { return create("<", value); }
auto lte(db_types_t value) -> wn_t { return create("<=", value); }
auto not_equals(db_types_t value) -> wn_t { return create("!=", value); };
};
template <typename ctx_t, typename op_t> struct db_where_t final {
std::size_t action_idx{0U};
std::shared_ptr<ctx_t> ctx;
using cn_t = db_comp_next_t<ctx_t, op_t, db_where_t>;
using wn_t = db_where_next_t<cn_t, ctx_t, op_t, db_where_t>;
using n_t = db_next_t<cn_t, ctx_t, op_t, db_where_t, wn_t>;
using group_func_t = std::function<void(db_where_t &)>;
using action_t = std::variant<db_comp_data_t, n_t, db_where_t>;
[[nodiscard]] static auto dump(std::int32_t &idx,
auto &&actions) -> std::string {
std::stringstream stream;
for (auto &&action : actions) {
std::visit(overloaded{
[&idx, &stream](const db_comp_data_t &comp) {
stream << '"' << comp.column_name << '"' << comp.op_type
<< '?' + std::to_string(++idx);
},
[&idx, &stream](const n_t &next) {
stream << ' ' << next.action << ' ';
},
[&idx, &stream](const db_where_t &where) {
stream << '(' << dump(idx, where.get_actions()) << ')';
},
},
action);
}
return stream.str();
}
[[nodiscard]] auto dump() const -> std::string { return op_t{ctx}.dump(); }
[[nodiscard]] auto dump(std::int32_t &idx) const -> std::string {
return dump(idx, ctx->where_data->actions[action_idx]);
}
[[nodiscard]] auto get_actions() -> auto & {
return ctx->where_data->actions[action_idx];
}
[[nodiscard]] auto get_actions() const -> const auto & {
return ctx->where_data->actions[action_idx];
}
[[nodiscard]] auto group(group_func_t func) -> wn_t {
ctx->where_data->actions[action_idx];
db_where_t where{ctx->where_data->actions.size(), ctx};
func(where);
ctx->where_data->actions[action_idx].emplace_back(where);
return wn_t{
action_idx,
ctx,
};
}
[[nodiscard]] auto where(std::string column_name) -> cn_t {
ctx->where_data->actions[action_idx];
return cn_t{
action_idx,
ctx,
column_name,
};
}
};
} // namespace repertory::utils::db::sqlite
#endif // defined(PROJECT_ENABLE_SQLITE)
#endif // REPERTORY_INCLUDE_UTILS_DB_SQLITE_DB_WHERE_T_HPP_

View File

@ -0,0 +1,145 @@
/*
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_ENCRYPTING_READER_HPP_
#define REPERTORY_INCLUDE_UTILS_ENCRYPTING_READER_HPP_
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
#include "utils/config.hpp"
#include "utils/hash.hpp"
#include "utils/types/file/i_file.hpp"
namespace repertory::utils::encryption {
class encrypting_reader final {
public:
encrypting_reader(std::string_view file_name, std::string_view source_path,
stop_type &stop_requested, std::string_view token,
std::optional<std::string> relative_parent_path,
std::size_t error_return = 0U);
encrypting_reader(std::string_view encrypted_file_path,
std::string_view source_path, stop_type &stop_requested,
std::string_view token, std::size_t error_return = 0U);
encrypting_reader(
std::string_view encrypted_file_path, std::string_view source_path,
stop_type &stop_requested, std::string_view token,
std::vector<std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
iv_list,
std::size_t error_return = 0U);
encrypting_reader(const encrypting_reader &reader);
encrypting_reader(encrypting_reader &&) = delete;
auto operator=(const encrypting_reader &) -> encrypting_reader & = delete;
auto operator=(encrypting_reader &&) -> encrypting_reader & = delete;
~encrypting_reader() noexcept = default;
public:
using iostream = std::basic_iostream<char, std::char_traits<char>>;
using streambuf = std::basic_streambuf<char, std::char_traits<char>>;
private:
utils::encryption::hash_256_t key_;
stop_type &stop_requested_;
size_t error_return_;
std::unique_ptr<utils::file::i_file> source_file_;
private:
std::unordered_map<std::size_t, data_buffer> chunk_buffers_;
std::string encrypted_file_name_;
std::string encrypted_file_path_;
std::vector<
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>>
iv_list_;
std::size_t last_data_chunk_{};
std::size_t last_data_chunk_size_{};
std::uint64_t read_offset_{};
std::uint64_t total_size_{};
private:
static const std::size_t header_size_;
static const std::size_t data_chunk_size_;
static const std::size_t encrypted_chunk_size_;
private:
auto reader_function(char *buffer, size_t size, size_t nitems) -> size_t;
public:
[[nodiscard]] static auto
calculate_decrypted_size(std::uint64_t total_size) -> std::uint64_t;
[[nodiscard]] static auto
calculate_encrypted_size(std::string_view source_path) -> std::uint64_t;
[[nodiscard]] auto create_iostream() const -> std::shared_ptr<iostream>;
[[nodiscard]] static constexpr auto
get_encrypted_chunk_size() -> std::size_t {
return encrypted_chunk_size_;
}
[[nodiscard]] static constexpr auto get_data_chunk_size() -> std::size_t {
return data_chunk_size_;
}
[[nodiscard]] auto get_encrypted_file_name() const -> std::string {
return encrypted_file_name_;
}
[[nodiscard]] auto get_encrypted_file_path() const -> std::string {
return encrypted_file_path_;
}
[[nodiscard]] auto get_error_return() const -> std::size_t {
return error_return_;
}
[[nodiscard]] auto get_iv_list()
-> std::vector<std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES>> {
return iv_list_;
}
[[nodiscard]] auto get_stop_requested() const -> bool {
return stop_requested_;
}
[[nodiscard]] auto get_total_size() const -> std::uint64_t {
return total_size_;
}
[[nodiscard]] static auto reader_function(char *buffer, size_t size,
size_t nitems,
void *instream) -> size_t {
return reinterpret_cast<encrypting_reader *>(instream)->reader_function(
buffer, size, nitems);
}
void set_read_position(std::uint64_t position) { read_offset_ = position; }
};
} // namespace repertory::utils::encryption
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
#endif // REPERTORY_INCLUDE_UTILS_ENCRYPTING_READER_HPP_

View File

@ -0,0 +1,221 @@
/*
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"
#include "utils/error.hpp"
#include "utils/hash.hpp"
namespace repertory::utils::encryption {
inline constexpr const std::uint32_t encryption_header_size{
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES +
crypto_aead_xchacha20poly1305_IETF_ABYTES,
};
template <typename hash_t>
inline auto generate_key(
std::string_view password,
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
default_create_hash<hash_t>()) -> hash_t;
template <typename hash_t>
inline auto generate_key(
std::wstring_view password,
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
default_create_hash<hash_t>()) -> hash_t;
#if defined(PROJECT_ENABLE_BOOST)
[[nodiscard]] auto decrypt_file_name(std::string_view encryption_token,
std::string &file_name) -> bool;
[[nodiscard]] auto decrypt_file_path(std::string_view encryption_token,
std::string &file_path) -> bool;
template <typename result_t, typename arr_t, std::size_t arr_size>
[[nodiscard]] inline auto decrypt_data(const std::array<arr_t, arr_size> &key,
const unsigned char *buffer,
std::size_t buffer_size,
result_t &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[encryption_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_t, typename result_t, typename arr_t,
std::size_t arr_size>
[[nodiscard]] inline auto decrypt_data(const std::array<arr_t, arr_size> &key,
const buffer_t &buf,
result_t &res) -> bool {
return decrypt_data<result_t>(
key, reinterpret_cast<const unsigned char *>(buf.data()), buf.size(),
res);
}
template <typename buffer_t, typename result_t, typename hash_t = hash_256_t>
[[nodiscard]] inline auto decrypt_data(
std::string_view password, const buffer_t &buf, result_t &res,
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
default_create_hash<hash_t>()) -> bool {
return decrypt_data<buffer_t, result_t>(generate_key(password, hasher), buf,
res);
}
template <typename result_t, typename hash_t = hash_256_t>
[[nodiscard]] inline auto decrypt_data(
std::string_view password, const unsigned char *buffer,
std::size_t buffer_size, result_t &res,
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
default_create_hash<hash_t>()) -> bool {
return decrypt_data<result_t>(generate_key(password, hasher), buffer,
buffer_size, res);
}
template <typename result_t, typename arr_t, std::size_t arr_size>
inline void
encrypt_data(const std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv,
const std::array<arr_t, arr_size> &key,
const unsigned char *buffer, std::size_t buffer_size,
result_t &res) {
REPERTORY_USES_FUNCTION_NAME();
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 + encryption_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 repertory::utils::error::create_exception(function_name,
{
"encryption failed",
});
}
std::memcpy(res.data(), iv.data(), iv.size());
std::memcpy(&res[iv.size()], mac.data(), mac.size());
}
template <typename result_t, typename arr_t, std::size_t arr_size>
inline void encrypt_data(const std::array<arr_t, arr_size> &key,
const unsigned char *buffer, std::size_t buffer_size,
result_t &res) {
std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> iv{};
randombytes_buf(iv.data(), iv.size());
encrypt_data<result_t>(iv, key, buffer, buffer_size, res);
}
template <typename result_t, typename hash_t = hash_256_t>
inline void encrypt_data(
std::string_view password, const unsigned char *buffer,
std::size_t buffer_size, result_t &res,
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
default_create_hash<hash_t>()) {
encrypt_data<result_t>(generate_key(password, hasher), buffer, buffer_size,
res);
}
template <typename buffer_t, typename result_t, typename hash_t = hash_256_t>
inline void encrypt_data(
std::string_view password, const buffer_t &buf, result_t &res,
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher =
default_create_hash<hash_t>()) {
encrypt_data<result_t>(generate_key(password, hasher),
reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res);
}
template <typename buffer_t, typename result_t, typename arr_t,
std::size_t arr_size>
inline void encrypt_data(const std::array<arr_t, arr_size> &key,
const buffer_t &buf, result_t &res) {
encrypt_data<result_t>(key,
reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res);
}
template <typename buffer_t, typename result_t, typename arr_t,
std::size_t arr_size>
inline void
encrypt_data(const std::array<unsigned char,
crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv,
const std::array<arr_t, arr_size> &key, const buffer_t &buf,
result_t &res) {
encrypt_data<result_t>(iv, key,
reinterpret_cast<const unsigned char *>(buf.data()),
buf.size(), res);
}
#if defined(PROJECT_ENABLE_CURL)
using reader_func_t =
std::function<bool(data_buffer &cypher_text, std::uint64_t start_offset,
std::uint64_t end_offset)>;
[[nodiscard]] auto
read_encrypted_range(const http_range &range,
const utils::encryption::hash_256_t &key,
reader_func_t reader_func, std::uint64_t total_size,
data_buffer &data) -> bool;
#endif // defined(PROJECT_ENABLE_CURL)
#endif // defined(PROJECT_ENABLE_BOOST)
template <typename hash_t>
inline auto generate_key(
std::string_view password,
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher)
-> hash_t {
return hasher(reinterpret_cast<const unsigned char *>(password.data()),
password.size());
}
template <typename hash_t>
inline auto generate_key(
std::wstring_view password,
std::function<hash_t(const unsigned char *data, std::size_t size)> hasher)
-> hash_t {
return hasher(reinterpret_cast<const unsigned char *>(password.data()),
password.size() * sizeof(wchar_t));
}
} // namespace repertory::utils::encryption
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
#endif // REPERTORY_INCLUDE_UTILS_ENCRYPTION_HPP_

View File

@ -0,0 +1,104 @@
/*
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 {
[[nodiscard]] auto
create_error_message(std::vector<std::string_view> items) -> std::string;
[[nodiscard]] auto
create_exception(std::string_view function_name,
std::vector<std::string_view> items) -> std::runtime_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_error(std::string_view function_name,
std::string_view msg) const = 0;
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;
};
struct iostream_exception_handler final : i_exception_handler {
void handle_error(std::string_view function_name,
std::string_view msg) const override {
std::cerr << create_error_message({
function_name,
msg,
})
<< std::endl;
}
void handle_exception(std::string_view function_name) const override {
std::cerr << create_error_message({
function_name,
"exception",
"unknown",
})
<< std::endl;
}
void handle_exception(std::string_view function_name,
const std::exception &ex) const override {
std::cerr << create_error_message({
function_name,
"exception",
(ex.what() == nullptr ? "unknown" : ex.what()),
})
<< std::endl;
}
};
inline const iostream_exception_handler default_exception_handler{};
extern std::atomic<const i_exception_handler *> exception_handler;
#if defined(PROJECT_ENABLE_TESTING)
[[nodiscard]] inline auto
get_exception_handler() -> const i_exception_handler * {
return exception_handler;
}
#endif // defined(PROJECT_ENABLE_TESTING)
void handle_error(std::string_view function_name, std::string_view msg);
void handle_exception(std::string_view function_name);
void handle_exception(std::string_view function_name, const std::exception &ex);
void set_exception_handler(const i_exception_handler *handler);
} // namespace repertory::utils::error
#endif // REPERTORY_INCLUDE_UTILS_ERROR_HPP_

View File

@ -0,0 +1,182 @@
/*
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"
#include "utils/path.hpp"
#include "utils/string.hpp"
#include "utils/types/file/i_directory.hpp"
#include "utils/types/file/i_file.hpp"
#include "utils/types/file/i_fs_item.hpp"
namespace repertory::utils::file {
[[nodiscard]] auto change_to_process_directory() -> bool;
// INFO: has test
[[nodiscard]] auto create_temp_name(std::string_view file_part) -> std::string;
// INFO: has test
[[nodiscard]] auto
create_temp_name(std::wstring_view file_part) -> std::wstring;
// INFO: has test
[[nodiscard]] inline auto
directory_exists_in_path(std::string_view path,
std::string_view sub_directory) -> bool;
// INFO: has test
[[nodiscard]] inline auto
directory_exists_in_path(std::wstring_view path,
std::wstring_view sub_directory) -> bool;
// INFO: has test
[[nodiscard]] inline auto
file_exists_in_path(std::string_view path, std::string_view file_name) -> bool;
// INFO: has test
[[nodiscard]] inline auto
file_exists_in_path(std::wstring_view path,
std::wstring_view file_name) -> bool;
// INFO: has test
[[nodiscard]] auto
get_free_drive_space(std::string_view path) -> std::optional<std::uint64_t>;
// INFO: has test
[[nodiscard]] auto
get_free_drive_space(std::wstring_view path) -> std::optional<std::uint64_t>;
// INFO: has test
[[nodiscard]] auto get_time(std::string_view path,
time_type type) -> std::optional<std::uint64_t>;
// INFO: has test
[[nodiscard]] auto get_time(std::wstring_view path,
time_type type) -> std::optional<std::uint64_t>;
// INFO: has test
[[nodiscard]] auto
get_times(std::string_view path) -> std::optional<file_times>;
// INFO: has test
[[nodiscard]] auto
get_times(std::wstring_view path) -> std::optional<file_times>;
// INFO: has test
[[nodiscard]] auto
get_total_drive_space(std::string_view path) -> std::optional<std::uint64_t>;
// INFO: has test
[[nodiscard]] auto
get_total_drive_space(std::wstring_view path) -> std::optional<std::uint64_t>;
#if defined(PROJECT_ENABLE_LIBDSM)
[[nodiscard]] auto
smb_create_and_validate_relative_path(std::string_view smb_path,
std::string_view rel_path) -> std::string;
// INFO: has test
[[nodiscard]] auto
smb_create_relative_path(std::string_view smb_path) -> std::string;
// INFO: has test
[[nodiscard]] auto
smb_create_search_path(std::string_view smb_path) -> std::string;
// INFO: has test
[[nodiscard]] auto
smb_create_smb_path(std::string_view smb_path,
std::string_view rel_path) -> std::string;
[[nodiscard]] auto
smb_get_parent_path(std::string_view smb_path) -> std::string;
[[nodiscard]] auto smb_get_root_path(std::string_view smb_path) -> std::string;
[[nodiscard]] auto smb_get_unc_path(std::string_view smb_path) -> std::string;
[[nodiscard]] auto smb_get_uri_path(std::string_view smb_path) -> std::string;
[[nodiscard]] auto smb_get_uri_path(std::string_view smb_path,
std::string_view user,
std::string_view password) -> std::string;
// INFO: has test
[[nodiscard]] auto smb_parent_is_same(std::string_view smb_path1,
std::string_view smb_path2) -> bool;
#define SMB_MOD_RW2 \
(SMB_MOD_READ | SMB_MOD_WRITE | SMB_MOD_READ_EXT | SMB_MOD_WRITE_EXT | \
SMB_MOD_READ_ATTR | SMB_MOD_WRITE_ATTR | SMB_MOD_READ_CTL)
#endif // defined(PROJECT_ENABLE_LIBDSM)
#if defined(PROJECT_ENABLE_JSON)
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
// INFO: has test
[[nodiscard]] auto
read_json_file(std::string_view path, nlohmann::json &data,
std::optional<std::string_view> password = std::nullopt) -> bool;
// INFO: has test
[[nodiscard]] auto read_json_file(
std::wstring_view path, nlohmann::json &data,
std::optional<std::wstring_view> password = std::nullopt) -> bool;
// INFO: has test
[[nodiscard]] auto write_json_file(
std::string_view path, const nlohmann::json &data,
std::optional<std::string_view> password = std::nullopt) -> bool;
// INFO: has test
[[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) && defined(PROJECT_ENABLE_BOOST)
// INFO: has test
[[nodiscard]] auto read_json_file(std::string_view path,
nlohmann::json &data) -> bool;
// INFO: has test
[[nodiscard]] auto read_json_file(std::wstring_view path,
nlohmann::json &data) -> bool;
// INFO: has test
[[nodiscard]] auto write_json_file(std::string_view path,
const nlohmann::json &data) -> bool;
// INFO: has test
[[nodiscard]] auto write_json_file(std::wstring_view path,
const nlohmann::json &data) -> bool;
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
#endif // defined(PROJECT_ENABLE_JSON)
} // namespace repertory::utils::file
#endif // REPERTORY_INCLUDE_UTILS_FILE_HPP_
#include "utils/file_directory.hpp"
#include "utils/file_enc_file.hpp"
#include "utils/file_file.hpp"
#include "utils/file_smb_directory.hpp"
#include "utils/file_smb_file.hpp"
#include "utils/file_thread_file.hpp"

View File

@ -0,0 +1,124 @@
/*
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_DIRECTORY_HPP_
#define REPERTORY_INCLUDE_UTILS_FILE_DIRECTORY_HPP_
#include "utils/file.hpp"
namespace repertory::utils::file {
class directory final : public i_directory {
public:
using directory_t = std::unique_ptr<directory>;
directory() noexcept = default;
directory(std::string_view path, stop_type *stop_requested = nullptr)
: path_(utils::path::absolute(path)), stop_requested_(stop_requested) {}
directory(std::wstring_view path, stop_type *stop_requested = nullptr)
: path_(utils::path::absolute(utils::string::to_utf8(path))),
stop_requested_(stop_requested) {}
directory(const directory &) noexcept = delete;
directory(directory &&move_dir) noexcept = default;
~directory() override = default;
private:
std::string path_;
stop_type *stop_requested_{nullptr};
public:
[[nodiscard]] auto copy_to(std::string_view new_path,
bool overwrite) const -> bool override;
[[nodiscard]] auto
count(bool recursive = false) const -> std::uint64_t override;
[[nodiscard]] auto
create_directory(std::string_view path = "") const -> fs_directory_t override;
[[nodiscard]] auto create_file(std::string_view file_name,
bool read_only) const -> fs_file_t override;
[[nodiscard]] auto exists() const -> bool override;
[[nodiscard]] auto
get_directory(std::string_view path) const -> fs_directory_t override;
[[nodiscard]] auto
get_directories() const -> std::vector<fs_directory_t> override;
[[nodiscard]] auto
get_file(std::string_view path) const -> fs_file_t override;
[[nodiscard]] auto get_files() const -> std::vector<fs_file_t> override;
[[nodiscard]] auto get_items() const -> std::vector<fs_item_t> override;
[[nodiscard]] auto get_path() const -> std::string override { return path_; }
[[nodiscard]] auto is_stop_requested() const -> bool override;
[[nodiscard]] auto is_symlink() const -> bool override;
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
[[nodiscard]] auto remove() -> bool override;
[[nodiscard]] auto remove_recursively() -> bool override;
[[nodiscard]] auto
size(bool recursive = false) const -> std::uint64_t override;
public:
auto operator=(const directory &) noexcept -> directory & = delete;
auto operator=(directory &&move_dir) noexcept -> directory & = default;
[[nodiscard]] operator bool() const override { return exists(); }
};
// INFO: has test
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 directory(utils::path::combine(path, {sub_directory})).exists();
}
// INFO: has test
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);
}
// INFO: has test
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);
}
} // namespace repertory::utils::file
#endif // REPERTORY_INCLUDE_UTILS_FILE_DIRECTORY_HPP_

View File

@ -0,0 +1,122 @@
/*
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_ENC_FILE_HPP_
#define REPERTORY_INCLUDE_UTILS_FILE_ENC_FILE_HPP_
#if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
#include "utils/file.hpp"
namespace repertory::utils::file {
class enc_file final : public i_file {
public:
[[nodiscard]] static auto attach_file(fs_file_t file) -> fs_file_t;
public:
enc_file() noexcept = default;
protected:
enc_file(fs_file_t file);
public:
enc_file(const enc_file &) = delete;
enc_file(enc_file &&move_file) noexcept : file_(std::move(move_file.file_)) {}
~enc_file() override { close(); }
private:
fs_file_t file_;
public:
void close() override;
[[nodiscard]] auto copy_to(std::string_view new_path,
bool overwrite) const -> bool override;
[[nodiscard]] auto exists() const -> bool override { return file_->exists(); }
void flush() const override;
[[nodiscard]] auto get_handle() const -> native_handle override {
return file_->get_handle();
}
[[nodiscard]] auto get_path() const -> std::string override {
return file_->get_path();
}
[[nodiscard]] auto get_read_buffer_size() const -> std::uint32_t override {
return file_->get_read_buffer_size();
}
[[nodiscard]] auto
get_time(time_type type) const -> std::optional<std::uint64_t> override {
return file_->get_time(type);
}
[[nodiscard]] auto is_read_only() const -> bool override {
return file_->is_read_only();
}
[[nodiscard]] auto is_symlink() const -> bool override {
return file_->is_symlink();
}
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool override;
[[nodiscard]] auto remove() -> bool override;
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
return file_->set_read_buffer_size(size);
}
[[nodiscard]] auto size() const -> std::optional<std::uint64_t> override;
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
[[nodiscard]] auto
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
std::size_t *total_written = nullptr) -> bool override;
public:
[[nodiscard]] operator bool() const override {
return static_cast<bool>(*file_);
}
auto operator=(const enc_file &) noexcept -> enc_file & = delete;
auto operator=(enc_file &&move_file) noexcept -> enc_file & {
if (&move_file != this) {
file_ = std::move(move_file.file_);
}
return *this;
}
};
} // namespace repertory::utils::file
#endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST)
#endif // REPERTORY_INCLUDE_UTILS_FILE_ENC_FILE_HPP_

View File

@ -0,0 +1,176 @@
/*
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_FILE_HPP_
#define REPERTORY_INCLUDE_UTILS_FILE_FILE_HPP_
#include "utils/file.hpp"
namespace repertory::utils::file {
class file final : public i_file {
public:
// [[nodiscard]] static auto
// attach_file(native_handle handle,
// bool read_only = false) -> fs_file_t;
// INFO: has test
[[nodiscard]] static auto open_file(std::string_view path,
bool read_only = false) -> fs_file_t;
[[nodiscard]] static auto open_file(std::wstring_view path,
bool read_only = false) -> fs_file_t {
return open_file(utils::string::to_utf8(path), read_only);
}
// INFO: has test
[[nodiscard]] static auto
open_or_create_file(std::string_view path,
bool read_only = false) -> fs_file_t;
[[nodiscard]] static auto
open_or_create_file(std::wstring_view path,
bool read_only = false) -> fs_file_t {
return open_or_create_file(utils::string::to_utf8(path), read_only);
}
public:
file() noexcept = default;
file(std::string_view path)
: file_(nullptr), path_(utils::path::absolute(path)) {}
file(std::wstring_view path)
: file_(nullptr),
path_(utils::path::absolute(utils::string::to_utf8(path))) {}
private:
file(file_t file_ptr, std::string_view path, bool read_only)
: file_(std::move(file_ptr)), path_(path), read_only_(read_only) {}
public:
file(const file &) = delete;
file(file &&move_file) noexcept
: file_(std::move(move_file.file_)),
path_(std::move(move_file.path_)),
read_only_(move_file.read_only_) {}
~file() override { close(); }
private:
file_t file_;
std::string path_;
bool read_only_{false};
private:
std::atomic_uint32_t read_buffer_size{65536U};
private:
void open();
public:
void close() override;
[[nodiscard]] auto copy_to(std::string_view new_path,
bool overwrite) const -> bool override;
[[nodiscard]] auto exists() const -> bool override;
void flush() const override;
[[nodiscard]] auto get_handle() const -> native_handle override;
[[nodiscard]] auto get_path() const -> std::string override { return path_; }
[[nodiscard]] auto get_read_buffer_size() const -> std::uint32_t override {
return read_buffer_size;
}
[[nodiscard]] auto is_read_only() const -> bool override {
return read_only_;
}
[[nodiscard]] auto is_symlink() const -> bool override;
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool override;
[[nodiscard]] auto remove() -> bool override;
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
read_buffer_size = size;
return read_buffer_size;
}
#if defined(PROJECT_ENABLE_LIBSODIUM)
[[nodiscard]] auto sha256() -> std::optional<std::string>;
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
[[nodiscard]] auto size() const -> std::optional<std::uint64_t> override;
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
[[nodiscard]] auto
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
std::size_t *total_written = nullptr) -> bool override;
public:
auto operator=(const file &) noexcept -> file & = delete;
auto operator=(file &&move_file) noexcept -> file & {
if (&move_file != this) {
file_ = std::move(move_file.file_);
path_ = std::move(move_file.path_);
read_only_ = move_file.read_only_;
}
return *this;
}
[[nodiscard]] operator bool() const override { return file_ != nullptr; }
};
// INFO: has test
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 file(utils::path::combine(path, {file_name})).exists();
}
// INFO: has test
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);
}
// INFO: has test
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);
}
} // namespace repertory::utils::file
#endif // REPERTORY_INCLUDE_UTILS_FILE_FILE_HPP_

View File

@ -0,0 +1,140 @@
/*
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_SMB_DIRECTORY_HPP_
#define REPERTORY_INCLUDE_UTILS_FILE_SMB_DIRECTORY_HPP_
#if defined(PROJECT_ENABLE_LIBDSM)
#include "utils/file.hpp"
namespace repertory::utils::file {
class smb_directory final : public i_directory {
public:
using smb_directory_t = std::unique_ptr<smb_directory>;
[[nodiscard]] static auto
open(std::string_view host, std::string_view user, std::string_view password,
std::string_view path,
stop_type *stop_requested = nullptr) -> smb_directory_t;
[[nodiscard]] static auto
open(std::wstring_view host, std::wstring_view user,
std::wstring_view password, std::wstring_view path,
stop_type *stop_requested = nullptr) -> smb_directory_t;
public:
smb_directory() noexcept = default;
smb_directory(const smb_directory &) noexcept = delete;
smb_directory(smb_directory &&) noexcept = default;
~smb_directory() override = default;
private:
smb_directory(std::string path, smb_session_t session,
std::string_view share_name, smb_tid tid,
stop_type *stop_requested)
: path_(std::move(path)),
session_(std::move(session)),
share_name_(share_name),
tid_(tid),
stop_requested_(stop_requested) {}
private:
std::string path_{};
smb_session_t session_{};
std::string share_name_{};
smb_tid tid_{};
stop_type *stop_requested_{nullptr};
public:
[[nodiscard]] auto
count(bool recursive = false) const -> std::uint64_t override;
[[nodiscard]] auto copy_to(std::string_view new_path,
bool overwrite) const -> bool override;
[[nodiscard]] auto
create_directory(std::string_view path = "") const -> fs_directory_t override;
[[nodiscard]] auto create_file(std::string_view file_name,
bool read_only) const -> fs_file_t override;
[[nodiscard]] auto exists() const -> bool override;
[[nodiscard]] auto
get_directory(std::string_view path) const -> fs_directory_t override;
[[nodiscard]] auto
get_directories() const -> std::vector<fs_directory_t> override;
[[nodiscard]] auto
get_file(std::string_view path) const -> fs_file_t override;
[[nodiscard]] auto get_files() const -> std::vector<fs_file_t> override;
[[nodiscard]] auto get_items() const -> std::vector<fs_item_t> override;
[[nodiscard]] auto get_path() const -> std::string override { return path_; }
[[nodiscard]] auto
get_time(time_type type) const -> std::optional<std::uint64_t> override;
[[nodiscard]] auto get_unc_path() const -> std::string {
return smb_get_unc_path(path_);
}
[[nodiscard]] auto get_uri_path() const -> std::string {
return smb_get_uri_path(path_);
}
[[nodiscard]] auto
get_uri_path(std::string_view user,
std::string_view password) const -> std::string {
return smb_get_uri_path(path_, user, password);
}
[[nodiscard]] auto is_stop_requested() const -> bool override;
[[nodiscard]] auto is_symlink() const -> bool override;
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
[[nodiscard]] auto remove() -> bool override;
[[nodiscard]] auto remove_recursively() -> bool override;
[[nodiscard]] auto
size(bool recursive = false) const -> std::uint64_t override;
public:
auto operator=(const smb_directory &) noexcept -> smb_directory & = delete;
auto
operator=(smb_directory &&move_dir) noexcept -> smb_directory & = default;
[[nodiscard]] operator bool() const override { return session_ != nullptr; }
};
} // namespace repertory::utils::file
#endif // defined(PROJECT_ENABLE_LIBDSM)
#endif // REPERTORY_INCLUDE_UTILS_FILE_SMB_DIRECTORY_HPP_

View File

@ -0,0 +1,157 @@
/*
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_SMB_FILE_HPP_
#define REPERTORY_INCLUDE_UTILS_FILE_SMB_FILE_HPP_
#if defined(PROJECT_ENABLE_LIBDSM)
#include "utils/file.hpp"
namespace repertory::utils::file {
class smb_file final : public i_file {
public:
smb_file() = default;
smb_file(std::optional<smb_fd> fd, std::string path, smb_session_t session,
std::string_view share_name, smb_tid tid)
: fd_(std::move(fd)),
path_(std::move(path)),
session_(std::move(session)),
share_name_(share_name),
tid_(tid) {}
smb_file(const smb_file &) = delete;
smb_file(smb_file &&f) noexcept
: fd_(std::move(f.fd_)),
path_(std::move(f.path_)),
read_buffer_size(f.get_read_buffer_size()),
read_only_(f.read_only_),
session_(std::move(f.session_)),
share_name_(std::move(f.share_name_)),
tid_(f.tid_) {}
~smb_file() override { close(); }
private:
std::optional<smb_fd> fd_;
std::string path_;
std::atomic_uint32_t read_buffer_size{65536U};
bool read_only_;
smb_session_t session_;
std::string share_name_;
smb_tid tid_;
public:
void close() override;
[[nodiscard]] auto copy_to(std::string_view new_path,
bool overwrite) const -> bool override;
[[nodiscard]] auto exists() const -> bool override;
void flush() const override;
[[nodiscard]] auto get_handle() const -> native_handle override {
return INVALID_HANDLE_VALUE;
}
[[nodiscard]] auto get_path() const -> std::string override { return path_; }
[[nodiscard]] auto get_read_buffer_size() const -> std::uint32_t override {
return read_buffer_size;
}
[[nodiscard]] static auto
get_time(smb_session *session, smb_tid tid, std::string path,
time_type type) -> std::optional<std::uint64_t>;
[[nodiscard]] auto
get_time(time_type type) const -> std::optional<std::uint64_t> override {
return get_time(session_.get(), tid_, path_, type);
}
[[nodiscard]] auto get_unc_path() const -> std::string {
return smb_get_unc_path(path_);
}
[[nodiscard]] auto get_uri_path() const -> std::string {
return smb_get_uri_path(path_);
}
[[nodiscard]] auto
get_uri_path(std::string_view user,
std::string_view password) const -> std::string {
return smb_get_uri_path(path_, user, password);
}
[[nodiscard]] auto is_read_only() const -> bool override {
return read_only_;
}
[[nodiscard]] auto is_symlink() const -> bool override;
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
[[nodiscard]] auto open(bool read_only) -> bool;
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool override;
[[nodiscard]] auto remove() -> bool override;
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
read_buffer_size = size;
return read_buffer_size;
}
[[nodiscard]] auto size() const -> std::optional<std::uint64_t> override;
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
[[nodiscard]] auto
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
std::size_t *total_written = nullptr) -> bool override;
public:
auto operator=(const smb_file &) noexcept -> smb_file & = delete;
auto operator=(smb_file &&move_file) noexcept -> smb_file & {
if (this != &move_file) {
fd_ = std::move(move_file.fd_);
path_ = std::move(move_file.path_);
read_buffer_size = move_file.get_read_buffer_size();
read_only_ = move_file.read_only_;
session_ = std::move(move_file.session_);
share_name_ = std::move(move_file.share_name_);
tid_ = move_file.tid_;
}
return *this;
}
[[nodiscard]] operator bool() const override { return fd_.has_value(); }
};
} // namespace repertory::utils::file
#endif // defined(PROJECT_ENABLE_LIBDSM)
#endif // REPERTORY_INCLUDE_UTILS_FILE_SMB_FILE_HPP_

View File

@ -0,0 +1,147 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef REPERTORY_INCLUDE_UTILS_FILE_THREAD_FILE_HPP_
#define REPERTORY_INCLUDE_UTILS_FILE_THREAD_FILE_HPP_
#include "utils/file.hpp"
namespace repertory::utils::file {
class thread_file final : public i_file {
public:
// [[nodiscard]] static auto
// attach_file(native_handle handle,
// bool read_only = false) -> fs_file_t;
[[nodiscard]] static auto attach_file(fs_file_t file) -> fs_file_t;
[[nodiscard]] static auto open_file(std::string_view path,
bool read_only = false) -> fs_file_t;
[[nodiscard]] static auto open_file(std::wstring_view path,
bool read_only = false) -> fs_file_t {
return open_file(utils::string::to_utf8(path), read_only);
}
[[nodiscard]] static auto
open_or_create_file(std::string_view path,
bool read_only = false) -> fs_file_t;
[[nodiscard]] static auto
open_or_create_file(std::wstring_view path,
bool read_only = false) -> fs_file_t {
return open_or_create_file(utils::string::to_utf8(path), read_only);
}
public:
thread_file() noexcept = default;
thread_file(std::string_view path);
thread_file(std::wstring_view path);
protected:
thread_file(fs_file_t file);
public:
thread_file(const thread_file &) = delete;
thread_file(thread_file &&move_file) noexcept
: file_(std::move(move_file.file_)) {}
~thread_file() override { close(); }
private:
fs_file_t file_;
public:
void close() override;
[[nodiscard]] auto copy_to(std::string_view new_path,
bool overwrite) const -> bool override;
[[nodiscard]] auto exists() const -> bool override { return file_->exists(); }
void flush() const override;
[[nodiscard]] auto get_handle() const -> native_handle override {
return file_->get_handle();
}
[[nodiscard]] auto get_path() const -> std::string override {
return file_->get_path();
}
[[nodiscard]] auto get_read_buffer_size() const -> std::uint32_t override {
return file_->get_read_buffer_size();
}
[[nodiscard]] auto
get_time(time_type type) const -> std::optional<std::uint64_t> override {
return file_->get_time(type);
}
[[nodiscard]] auto is_read_only() const -> bool override {
return file_->is_read_only();
}
[[nodiscard]] auto is_symlink() const -> bool override {
return file_->is_symlink();
}
[[nodiscard]] auto move_to(std::string_view new_path) -> bool override;
[[nodiscard]] auto read(unsigned char *data, std::size_t to_read,
std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool override;
[[nodiscard]] auto remove() -> bool override;
auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t override {
return file_->set_read_buffer_size(size);
}
[[nodiscard]] auto size() const -> std::optional<std::uint64_t> override;
[[nodiscard]] auto truncate(std::size_t size) -> bool override;
[[nodiscard]] auto
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
std::size_t *total_written = nullptr) -> bool override;
public:
[[nodiscard]] operator bool() const override {
return static_cast<bool>(*file_);
}
auto operator=(const thread_file &) noexcept -> thread_file & = delete;
auto operator=(thread_file &&move_file) noexcept -> thread_file & {
if (&move_file != this) {
file_ = std::move(move_file.file_);
}
return *this;
}
};
} // namespace repertory::utils::file
#endif // REPERTORY_INCLUDE_UTILS_FILE_THREAD_FILE_HPP_

View File

@ -0,0 +1,181 @@
/*
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_HASH_HPP_
#define REPERTORY_INCLUDE_UTILS_HASH_HPP_
#if defined(PROJECT_ENABLE_LIBSODIUM)
#include "utils/config.hpp"
#include "utils/error.hpp"
namespace repertory::utils::encryption {
using hash_256_t = std::array<unsigned char, 32U>;
using hash_384_t = std::array<unsigned char, 48U>;
using hash_512_t = std::array<unsigned char, 64U>;
[[nodiscard]] auto create_hash_blake2b_256(std::string_view data) -> hash_256_t;
[[nodiscard]] auto
create_hash_blake2b_256(std::wstring_view data) -> hash_256_t;
[[nodiscard]] auto
create_hash_blake2b_256(const data_buffer &data) -> hash_256_t;
[[nodiscard]] auto create_hash_blake2b_384(std::string_view data) -> hash_384_t;
[[nodiscard]] auto
create_hash_blake2b_384(std::wstring_view data) -> hash_384_t;
[[nodiscard]] auto
create_hash_blake2b_384(const data_buffer &data) -> hash_384_t;
[[nodiscard]] auto
create_hash_blake2b_512(std::wstring_view data) -> hash_512_t;
[[nodiscard]] auto
create_hash_blake2b_512(const data_buffer &data) -> hash_512_t;
[[nodiscard]] auto create_hash_blake2b_512(std::string_view data) -> hash_512_t;
template <typename hash_t>
[[nodiscard]] auto create_hash_blake2b_t(const unsigned char *data,
std::size_t data_size) -> hash_t;
[[nodiscard]] auto create_hash_sha256(std::string_view data) -> hash_256_t;
[[nodiscard]] auto create_hash_sha256(std::wstring_view data) -> hash_256_t;
[[nodiscard]] auto create_hash_sha256(const data_buffer &data) -> hash_256_t;
[[nodiscard]] auto create_hash_sha256(const unsigned char *data,
std::size_t data_size) -> hash_256_t;
[[nodiscard]] auto create_hash_sha512(std::string_view data) -> hash_512_t;
[[nodiscard]] auto create_hash_sha512(std::wstring_view data) -> hash_512_t;
[[nodiscard]] auto create_hash_sha512(const data_buffer &data) -> hash_512_t;
[[nodiscard]] auto create_hash_sha512(const unsigned char *data,
std::size_t data_size) -> hash_512_t;
template <typename hash_t>
[[nodiscard]] inline auto default_create_hash() -> const
std::function<hash_t(const unsigned char *data, std::size_t size)> &;
template <typename hash_t>
auto create_hash_blake2b_t(const unsigned char *data,
std::size_t data_size) -> hash_t {
REPERTORY_USES_FUNCTION_NAME();
hash_t hash{};
crypto_generichash_blake2b_state state{};
auto res = crypto_generichash_blake2b_init(&state, nullptr, 0U, hash.size());
if (res != 0) {
throw utils::error::create_exception(function_name,
{
"failed to initialize blake2b",
std::to_string(hash.size() * 8U),
std::to_string(res),
});
}
res = crypto_generichash_blake2b_update(&state, data, data_size);
if (res != 0) {
throw utils::error::create_exception(function_name,
{
"failed to update blake2b",
std::to_string(hash.size() * 8U),
std::to_string(res),
});
}
res = crypto_generichash_blake2b_final(&state, hash.data(), hash.size());
if (res != 0) {
throw utils::error::create_exception(function_name,
{
"failed to finalize blake2b",
std::to_string(hash.size() * 8U),
std::to_string(res),
});
}
return hash;
}
inline const std::function<hash_256_t(const unsigned char *data,
std::size_t size)>
blake2b_256_hasher =
[](const unsigned char *data, std::size_t data_size) -> hash_256_t {
return create_hash_blake2b_t<hash_256_t>(data, data_size);
};
inline const std::function<hash_384_t(const unsigned char *data,
std::size_t size)>
blake2b_384_hasher =
[](const unsigned char *data, std::size_t data_size) -> hash_384_t {
return create_hash_blake2b_t<hash_384_t>(data, data_size);
};
inline const std::function<hash_512_t(const unsigned char *data,
std::size_t size)>
blake2b_512_hasher =
[](const unsigned char *data, std::size_t data_size) -> hash_512_t {
return create_hash_blake2b_t<hash_512_t>(data, data_size);
};
inline const std::function<hash_256_t(const unsigned char *data,
std::size_t size)>
sha256_hasher =
[](const unsigned char *data, std::size_t data_size) -> hash_256_t {
return create_hash_sha256(data, data_size);
};
inline const std::function<hash_512_t(const unsigned char *data,
std::size_t size)>
sha512_hasher =
[](const unsigned char *data, std::size_t data_size) -> hash_512_t {
return create_hash_sha512(data, data_size);
};
template <>
[[nodiscard]] inline auto default_create_hash<hash_256_t>() -> const
std::function<hash_256_t(const unsigned char *data, std::size_t size)> & {
return blake2b_256_hasher;
}
template <>
[[nodiscard]] inline auto default_create_hash<hash_384_t>() -> const
std::function<hash_384_t(const unsigned char *data, std::size_t size)> & {
return blake2b_384_hasher;
}
template <>
[[nodiscard]] inline auto default_create_hash<hash_512_t>() -> const
std::function<hash_512_t(const unsigned char *data, std::size_t size)> & {
return blake2b_512_hasher;
}
} // namespace repertory::utils::encryption
#endif // defined(PROJECT_ENABLE_LIBSODIUM)
#endif // REPERTORY_INCLUDE_UTILS_HASH_HPP_

View File

@ -0,0 +1,526 @@
/*
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_backslash{".\\"};
inline constexpr const std::wstring_view dot_backslash_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 long_notation{"\\\\?\\"};
inline constexpr const std::wstring_view long_notation_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};
inline constexpr const std::string_view unc_notation{"\\\\"};
inline constexpr const std::wstring_view unc_notation_w{L"\\\\"};
#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_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;
}
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_backslash() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_dot_backslash<char>() -> std::basic_string_view<char> {
return dot_backslash;
}
template <>
[[nodiscard]] inline constexpr auto
get_dot_backslash<wchar_t>() -> std::basic_string_view<wchar_t> {
return dot_backslash_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_long_notation() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_long_notation<char>() -> std::basic_string_view<char> {
return long_notation;
}
template <>
[[nodiscard]] inline constexpr auto
get_long_notation<wchar_t>() -> std::basic_string_view<wchar_t> {
return long_notation_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;
}
#if defined(_WIN32)
template <typename char_t>
[[nodiscard]] inline constexpr auto
get_unc_notation() -> std::basic_string_view<char_t>;
template <>
[[nodiscard]] inline constexpr auto
get_unc_notation<char>() -> std::basic_string_view<char> {
return unc_notation;
}
template <>
[[nodiscard]] inline constexpr auto
get_unc_notation<wchar_t>() -> std::basic_string_view<wchar_t> {
return unc_notation_w;
}
#endif // defined(_WIN32)
template <typename string_t>
[[nodiscard]] inline auto get_current_path() -> string_t;
[[nodiscard]] auto absolute(std::string_view path) -> std::string;
[[nodiscard]] auto absolute(std::wstring_view path) -> std::wstring;
[[nodiscard]] inline auto
combine(std::string_view path,
const std::vector<std::string_view> &paths) -> std::string;
[[nodiscard]] inline auto
combine(std::wstring_view path,
const std::vector<std::wstring_view> &paths) -> std::wstring;
[[nodiscard]] auto contains_trash_directory(std::string_view path) -> bool;
[[nodiscard]] auto contains_trash_directory(std::wstring_view path) -> bool;
[[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]] auto exists(std::string_view path) -> bool;
[[nodiscard]] auto exists(std::wstring_view path) -> 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_path(std::string_view path) -> std::string;
[[nodiscard]] auto get_parent_path(std::wstring_view path) -> std::wstring;
[[nodiscard]] inline auto
get_parts(std::string_view path) -> std::vector<std::string>;
[[nodiscard]] inline auto
get_parts_w(std::wstring_view path) -> std::vector<std::wstring>;
[[nodiscard]] auto get_relative_path(std::string_view path,
std::string_view root_path) -> std::string;
[[nodiscard]] auto
get_relative_path(std::wstring_view path,
std::wstring_view root_path) -> std::wstring;
[[nodiscard]] auto make_file_uri(std::string_view path) -> std::string;
[[nodiscard]] auto make_file_uri(std::wstring_view path) -> std::wstring;
[[nodiscard]] auto strip_to_file_name(std::string path) -> std::string;
[[nodiscard]] auto strip_to_file_name(std::wstring path) -> std::wstring;
[[nodiscard]] auto unmake_file_uri(std::string_view uri) -> std::string;
[[nodiscard]] auto unmake_file_uri(std::wstring_view uri) -> std::wstring;
template <typename string_t>
[[nodiscard]] inline auto combine_t(
std::basic_string_view<typename string_t::value_type> path,
const std::vector<std::basic_string_view<typename string_t::value_type>>
&paths) -> string_t {
auto dir_sep_t =
string_t{get_directory_seperator<typename string_t::value_type>()};
return absolute(
std::accumulate(paths.begin(), paths.end(),
std::basic_string<typename string_t::value_type>{path},
[&dir_sep_t](auto next_path, auto &&path_part) {
if (next_path.empty()) {
return string_t{path_part};
}
return next_path + dir_sep_t + string_t{path_part};
}));
}
inline auto combine(std::string_view path,
const std::vector<std::string_view> &paths) -> std::string {
return combine_t<std::string>(path, paths);
}
inline auto
combine(std::wstring_view 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 {
auto backslash_t = get_backslash<typename string_t::value_type>();
auto dot_backslash_t = get_dot_backslash<typename string_t::value_type>();
auto dot_slash_t = get_dot_slash<typename string_t::value_type>();
auto dot_t = get_dot<typename string_t::value_type>();
auto slash_t = get_slash<typename string_t::value_type>();
#if defined(_WIN32)
auto long_notation_t = get_long_notation<typename string_t::value_type>();
if (utils::string::begins_with(path, long_notation_t)) {
path = path.substr(long_notation_t.size());
}
#endif // defined(_WIN32)
if (path.empty() || path == backslash_t || path == dot_t ||
path == dot_slash_t || path == slash_t || path == dot_backslash_t) {
return string_t{slash_t};
}
string_t api_path{path};
#if defined(_WIN32)
if ((api_path.size() >= 2U) && (api_path.at(1U) == ':')) {
api_path = api_path.substr(2U);
}
#endif // defined(_WIN32)
format_path(api_path, slash_t, backslash_t);
while (utils::string::begins_with(api_path, dot_slash_t)) {
api_path = api_path.substr(dot_slash_t.size());
}
if (api_path.at(0U) != slash_t.at(0U)) {
return string_t{slash_t} + 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 finalize_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
string_t dir_sep_t{get_directory_seperator<typename string_t::value_type>()};
string_t fmt_path{path};
if (fmt_path.empty()) {
return fmt_path;
}
format_path(fmt_path, dir_sep_t,
get_not_directory_seperator<typename string_t::value_type>());
#if defined(_WIN32)
auto unc_notation_t = get_unc_notation<typename string_t::value_type>();
if (utils::string::begins_with(fmt_path, unc_notation_t)) {
return fmt_path;
}
auto dot_t = get_dot<typename string_t::value_type>();
auto dot_sep_t = string_t{dot_t} + dir_sep_t;
if (fmt_path == dot_t || fmt_path == dot_sep_t) {
return get_current_path<string_t>();
}
if (fmt_path == dir_sep_t) {
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return get_current_path<string_t>().substr(0U, long_notation.size() + 2U);
#else // !defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return get_current_path<string_t>().substr(0U, 2U);
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
}
if (utils::string::begins_with(fmt_path, dir_sep_t)) {
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return get_current_path<string_t>().substr(0U, long_notation.size() + 2U) +
fmt_path;
#else // !defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return get_current_path<string_t>().substr(0U, 2U) + fmt_path;
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
}
if (utils::string::begins_with(fmt_path, dot_sep_t)) {
return get_current_path<string_t>() + dir_sep_t + fmt_path.substr(2U);
}
#if defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
return string_t{get_long_notation<typename string_t::value_type>()} +
fmt_path;
#endif // defined(PROJECT_ENABLE_WIN32_LONG_PATH_NAMES)
#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);
#if defined(_WIN32)
auto is_unc{false};
auto long_notation_t = get_long_notation<typename string_t::value_type>();
auto unc_notation_t = get_unc_notation<typename string_t::value_type>();
if (utils::string::begins_with(path, long_notation_t)) {
path = path.substr(long_notation_t.size());
} else if (utils::string::begins_with(path, unc_notation_t)) {
path = path.substr(unc_notation_t.size());
utils::string::left_trim(path, sep.at(0U));
is_unc = true;
}
#endif // defined(_WIN32)
string_t double_sep(2U, sep.at(0U));
while (utils::string::contains(path, double_sep)) {
utils::string::replace(path, double_sep, sep);
}
if (path != sep) {
utils::string::right_trim(path, sep.at(0U));
}
#if defined(_WIN32)
if (is_unc) {
path = string_t{unc_notation_t} + path;
} else if ((path.size() >= 2U) && (path.at(1U) == ':')) {
path[0U] = utils::string::to_lower(string_t(1U, path.at(0U))).at(0U);
}
#endif // defined(_WIN32)
return path;
}
template <>
[[nodiscard]] inline auto get_current_path<std::string>() -> std::string {
#if defined(_WIN32)
std::string path;
path.resize(repertory::max_path_length + 1U);
::GetCurrentDirectoryA(static_cast<DWORD>(path.size()), path.data());
path = path.c_str();
return finalize(path);
#else // !defined(_WIN32)
return finalize(std::filesystem::current_path().string());
#endif // defined(_WIN32)
}
template <>
[[nodiscard]] inline auto get_current_path<std::wstring>() -> std::wstring {
return utils::string::from_utf8(get_current_path<std::string>());
}
template <typename string_t>
[[nodiscard]] inline auto get_parent_api_path_t(
std::basic_string_view<typename string_t::value_type> path) -> string_t {
auto slash_t = get_slash<typename string_t::value_type>();
string_t ret{path};
utils::string::right_trim(ret, slash_t.at(0U));
if (ret == slash_t || ret.empty()) {
return string_t{path};
}
auto sub_path = ret.substr(0, ret.rfind(slash_t) + 1);
if (sub_path == slash_t) {
return string_t{sub_path};
}
return sub_path;
}
inline auto get_parent_api_path(std::string_view path) -> std::string {
return create_api_path(get_parent_api_path_t<std::string>(path));
}
inline auto get_parent_api_path(std::wstring_view path) -> std::wstring {
return create_api_path(get_parent_api_path_t<std::wstring>(path));
}
template <typename string_t>
[[nodiscard]] inline auto
get_parts_t(std::basic_string_view<typename string_t::value_type> path)
-> std::vector<string_t> {
return utils::string::split(
path, get_directory_seperator<typename string_t::value_type>().at(0U),
false);
}
inline auto get_parts(std::string_view path) -> std::vector<std::string> {
return get_parts_t<std::string>(path);
}
inline auto get_parts_w(std::wstring_view path) -> std::vector<std::wstring> {
return get_parts_t<std::wstring>(path);
}
} // namespace repertory::utils::path
#endif // REPERTORY_INCLUDE_UTILS_PATH_HPP_

View File

@ -0,0 +1,469 @@
/*
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 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>
[[nodiscard]] inline auto zero_pad(string_t str, std::size_t count) -> string_t;
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 (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 (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 string_t>
inline auto zero_pad(string_t str, std::size_t count) -> string_t {
str.insert(str.begin(), count - str.length(), '0');
return str;
}
} // namespace repertory::utils::string
#endif // REPERTORY_INCLUDE_UTILS_STRING_HPP_

View File

@ -0,0 +1,69 @@
/*
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{1000000000ULL};
inline constexpr const auto WIN32_TIME_CONVERSION{116444736000000000ULL};
inline constexpr const auto WIN32_TIME_NANOS_PER_TICK{100ULL};
#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(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)
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 unix_time_to_filetime(std::uint64_t unix_time) -> FILETIME;
[[nodiscard]] auto
windows_file_time_to_unix_time(FILETIME win_time) -> std::uint64_t;
[[nodiscard]] auto
windows_time_t_to_unix_time(__time64_t win_time) -> std::uint64_t;
#endif // defined(_WIN32)
[[nodiscard]] auto
unix_time_to_windows_time(std::uint64_t unix_time) -> std::uint64_t;
[[nodiscard]] auto
windows_time_to_unix_time(std::uint64_t win_time) -> std::uint64_t;
} // namespace repertory::utils::time
#endif // REPERTORY_INCLUDE_UTILS_TIME_HPP_

View File

@ -0,0 +1,81 @@
/*
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_TYPES_FILE_I_DIRECTORY_HPP_
#define REPERTORY_INCLUDE_TYPES_FILE_I_DIRECTORY_HPP_
#include "utils/config.hpp"
#include "utils/types/file/i_file.hpp"
#include "utils/types/file/i_fs_item.hpp"
namespace repertory::utils::file {
struct i_directory : public i_fs_item {
using fs_directory_t = std::unique_ptr<i_directory>;
using fs_file_t = i_file::fs_file_t;
virtual ~i_directory() = default;
[[nodiscard]] virtual auto
count(bool recursive = false) const -> std::uint64_t = 0;
[[nodiscard]] virtual auto
create_directory(std::string_view path = "") const -> fs_directory_t = 0;
[[nodiscard]] virtual auto create_file(std::string_view file_name,
bool read_only) const -> fs_file_t = 0;
[[nodiscard]] virtual auto
get_directory(std::string_view path) const -> fs_directory_t = 0;
[[nodiscard]] virtual auto
get_directories() const -> std::vector<fs_directory_t> = 0;
[[nodiscard]] virtual auto
get_file(std::string_view path) const -> fs_file_t = 0;
[[nodiscard]] virtual auto get_files() const -> std::vector<fs_file_t> = 0;
[[nodiscard]] virtual auto get_items() const -> std::vector<fs_item_t> = 0;
[[nodiscard]] auto is_directory_item() const -> bool override { return true; }
[[nodiscard]] virtual auto is_stop_requested() const -> bool = 0;
[[nodiscard]] virtual auto remove_recursively() -> bool = 0;
[[nodiscard]] virtual auto
size(bool recursive = false) const -> std::uint64_t = 0;
protected:
i_directory() noexcept = default;
i_directory(const i_directory &) noexcept = default;
i_directory(i_directory &&) noexcept = default;
auto operator=(i_directory &&) noexcept -> i_directory & = default;
auto operator=(const i_directory &) noexcept -> i_directory & = default;
};
} // namespace repertory::utils::file
#endif // REPERTORY_INCLUDE_TYPES_FILE_I_DIRECTORY_HPP_

View File

@ -0,0 +1,93 @@
/*
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_TYPES_FILE_I_FILE_HPP_
#define REPERTORY_INCLUDE_TYPES_FILE_I_FILE_HPP_
#include "utils/config.hpp"
#include "utils/types/file/i_fs_item.hpp"
namespace repertory::utils::file {
struct i_file : public i_fs_item {
using fs_file_t = std::unique_ptr<i_file>;
virtual ~i_file() = default;
virtual void close() = 0;
virtual void flush() const = 0;
[[nodiscard]] virtual auto get_handle() const -> native_handle = 0;
[[nodiscard]] virtual auto get_read_buffer_size() const -> std::uint32_t = 0;
[[nodiscard]] auto is_directory_item() const -> bool override {
return false;
}
[[nodiscard]] virtual auto is_read_only() const -> bool = 0;
[[nodiscard]] virtual 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]] virtual auto
read(unsigned char *data, std::size_t to_read, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool = 0;
[[nodiscard]] virtual auto
read_all(data_buffer &data, std::uint64_t offset,
std::size_t *total_read = nullptr) -> bool;
virtual auto set_read_buffer_size(std::uint32_t size) -> std::uint32_t = 0;
[[nodiscard]] virtual auto size() const -> std::optional<std::uint64_t> = 0;
[[nodiscard]] virtual auto truncate() -> bool { return truncate(0U); }
[[nodiscard]] virtual auto truncate(std::size_t size) -> bool = 0;
[[nodiscard]] virtual 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]] virtual auto
write(const unsigned char *data, std::size_t to_write, std::size_t offset,
std::size_t *total_written = nullptr) -> bool = 0;
protected:
i_file() noexcept = default;
i_file(const i_file &) noexcept = default;
i_file(i_file &&) noexcept = default;
auto operator=(i_file &&) noexcept -> i_file & = default;
auto operator=(const i_file &) noexcept -> i_file & = default;
};
} // namespace repertory::utils::file
#endif // REPERTORY_INCLUDE_TYPES_FILE_I_FILE_HPP_

View File

@ -0,0 +1,117 @@
/*
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_TYPES_FILE_I_FS_ITEM_HPP_
#define REPERTORY_INCLUDE_TYPES_FILE_I_FS_ITEM_HPP_
#include "utils/config.hpp"
#include "utils/error.hpp"
#include "utils/string.hpp"
namespace repertory::utils::file {
enum class time_type {
accessed,
created,
modified,
written,
};
struct file_times final {
std::uint64_t accessed{};
std::uint64_t created{};
std::uint64_t modified{};
std::uint64_t written{};
[[nodiscard]] auto get(time_type type) const -> std::uint64_t {
REPERTORY_USES_FUNCTION_NAME();
switch (type) {
case time_type::accessed:
return accessed;
case time_type::created:
return created;
case time_type::modified:
return modified;
case time_type::written:
return written;
}
throw utils::error::create_exception(function_name,
{
"type_type not supported",
});
}
};
struct i_fs_item {
using fs_item_t = std::unique_ptr<i_fs_item>;
virtual ~i_fs_item() = default;
[[nodiscard]] virtual auto copy_to(std::string_view to_path,
bool overwrite) const -> bool = 0;
[[nodiscard]] virtual auto copy_to(std::wstring_view new_path,
bool overwrite) -> bool {
return copy_to(utils::string::to_utf8(new_path), overwrite);
}
[[nodiscard]] virtual auto exists() const -> bool = 0;
[[nodiscard]] virtual auto get_path() const -> std::string = 0;
[[nodiscard]] virtual auto
get_time(time_type type) const -> std::optional<std::uint64_t>;
[[nodiscard]] virtual auto is_directory_item() const -> bool = 0;
[[nodiscard]] auto is_file_item() const -> bool {
return not is_directory_item();
}
[[nodiscard]] virtual auto is_symlink() const -> bool = 0;
[[nodiscard]] virtual auto move_to(std::string_view new_path) -> bool = 0;
[[nodiscard]] virtual auto move_to(std::wstring_view new_path) -> bool {
return move_to(utils::string::to_utf8(new_path));
}
[[nodiscard]] virtual auto remove() -> bool = 0;
public:
[[nodiscard]] virtual operator bool() const = 0;
protected:
i_fs_item() noexcept = default;
i_fs_item(const i_fs_item &) noexcept = default;
i_fs_item(i_fs_item &&) noexcept = default;
auto operator=(i_fs_item &&) noexcept -> i_fs_item & = default;
auto operator=(const i_fs_item &) noexcept -> i_fs_item & = default;
};
} // namespace repertory::utils::file
#endif // REPERTORY_INCLUDE_TYPES_FILE_I_FS_ITEM_HPP_

View File

@ -0,0 +1,63 @@
/*
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(uid_t uid, gid_t gid) -> bool;
void set_last_error_code(int error_code);
[[nodiscard]] auto use_getpwuid(uid_t uid, passwd_callback_t callback)
-> utils::result;
// template implementations
#if defined(__APPLE__)
template <typename t>
[[nodiscard]] auto convert_to_uint64(const thread_t *thread_ptr)
-> std::uint64_t {
return static_cast<std::uint64_t>(
reinterpret_cast<std::uintptr_t>(thread_ptr));
}
#endif // defined(__APPLE__)
} // namespace repertory::utils
#endif // !defined(_WIN32)
#endif // REPERTORY_INCLUDE_UTILS_UNIX_HPP_

View File

@ -0,0 +1,47 @@
/*
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 {
void create_console();
void free_console();
[[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_