This commit is contained in:
		
							
								
								
									
										4509
									
								
								support/3rd_party/include/backward.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4509
									
								
								support/3rd_party/include/backward.hpp
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										36
									
								
								support/3rd_party/include/utils/all.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								support/3rd_party/include/utils/all.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,36 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_ALL_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_ALL_HPP_ | ||||
|  | ||||
| #include "utils/config.hpp" | ||||
|  | ||||
| #include "utils/collection.hpp" | ||||
| #include "utils/com_init_wrapper.hpp" | ||||
| #include "utils/common.hpp" | ||||
| #include "utils/path.hpp" | ||||
| #include "utils/string.hpp" | ||||
| #include "utils/time.hpp" | ||||
| #include "utils/unix.hpp" | ||||
| #include "utils/windows.hpp" | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_ALL_HPP_ | ||||
							
								
								
									
										174
									
								
								support/3rd_party/include/utils/base64.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										174
									
								
								support/3rd_party/include/utils/base64.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,174 +0,0 @@ | ||||
| // 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 | ||||
							
								
								
									
										133
									
								
								support/3rd_party/include/utils/collection.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										133
									
								
								support/3rd_party/include/utils/collection.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,133 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_COLLECTION_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_COLLECTION_HPP_ | ||||
|  | ||||
| #include "utils/config.hpp" | ||||
|  | ||||
| namespace repertory::utils::collection { | ||||
| template <typename col_t> | ||||
| [[nodiscard]] inline auto | ||||
| excludes(const col_t &collection, | ||||
|          const typename col_t::value_type &val) -> bool; | ||||
|  | ||||
| template <typename col_t> | ||||
| [[nodiscard]] inline auto | ||||
| includes(const col_t &collection, | ||||
|          const typename col_t::value_type &val) -> bool; | ||||
|  | ||||
| template <typename val_t> | ||||
| [[nodiscard]] inline auto from_hex_string(std::string_view str, | ||||
|                                           val_t &val) -> bool; | ||||
|  | ||||
| template <typename val_t> | ||||
| [[nodiscard]] inline auto from_hex_string(std::wstring_view str, | ||||
|                                           val_t &val) -> bool; | ||||
| template <typename col_t> | ||||
| inline auto remove_element(col_t &collection, | ||||
|                            const typename col_t::value_type &value) -> col_t &; | ||||
|  | ||||
| template <typename col_t> | ||||
| [[nodiscard]] inline auto to_hex_string(const col_t &collection) -> std::string; | ||||
|  | ||||
| template <typename col_t> | ||||
| [[nodiscard]] inline auto | ||||
| to_hex_wstring(const col_t &collection) -> std::wstring; | ||||
|  | ||||
| template <typename col_t> | ||||
| inline auto excludes(const col_t &collection, | ||||
|                      const typename col_t::value_type &val) -> bool { | ||||
|   return std::find(collection.begin(), collection.end(), val) == | ||||
|          collection.end(); | ||||
| } | ||||
|  | ||||
| template <typename col_t> | ||||
| inline auto includes(const col_t &collection, | ||||
|                      const typename col_t::value_type &val) -> bool { | ||||
|   return std::find(collection.begin(), collection.end(), val) != | ||||
|          collection.end(); | ||||
| } | ||||
|  | ||||
| template <typename val_t, typename string_t> | ||||
| [[nodiscard]] inline auto | ||||
| from_hex_string_t(std::basic_string_view<typename string_t::value_type> str, | ||||
|                   val_t &val) -> bool { | ||||
|   static constexpr const auto base16{16}; | ||||
|  | ||||
|   val.clear(); | ||||
|   if (not(str.length() % 2U)) { | ||||
|     for (std::size_t i = 0U; i < str.length(); i += 2U) { | ||||
|       val.emplace_back(static_cast<typename val_t::value_type>( | ||||
|           std::strtol(string_t{str.substr(i, 2U)}.c_str(), nullptr, base16))); | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| template <typename col_t> | ||||
| inline auto remove_element(col_t &collection, | ||||
|                            const typename col_t::value_type &value) -> col_t & { | ||||
|   collection.erase(std::remove(collection.begin(), collection.end(), value), | ||||
|                    collection.end()); | ||||
|   return collection; | ||||
| } | ||||
|  | ||||
| template <typename col_t, typename string_t> | ||||
| [[nodiscard]] inline auto to_hex_string_t(const col_t &collection) -> string_t { | ||||
|   static_assert(sizeof(typename col_t::value_type) == 1U, | ||||
|                 "value_type must be 1 byte in size"); | ||||
|   static constexpr const auto mask = 0xFF; | ||||
|  | ||||
|   std::basic_stringstream<typename string_t::value_type> stream{}; | ||||
|   for (auto &&val : collection) { | ||||
|     stream << std::setfill('0') << std::setw(2) << std::hex | ||||
|            << (static_cast<std::uint32_t>(val) & mask); | ||||
|   } | ||||
|  | ||||
|   return stream.str(); | ||||
| } | ||||
|  | ||||
| template <typename val_t> | ||||
| inline auto from_hex_string(std::string_view str, val_t &val) -> bool { | ||||
|   return from_hex_string_t<val_t, std::string>(str, val); | ||||
| } | ||||
|  | ||||
| template <typename val_t> | ||||
| inline auto from_hex_string(std::wstring_view str, val_t &val) -> bool { | ||||
|   return from_hex_string_t<val_t, std::wstring>(str, val); | ||||
| } | ||||
|  | ||||
| template <typename col_t> | ||||
| inline auto to_hex_string(const col_t &collection) -> std::string { | ||||
|   return to_hex_string_t<col_t, std::string>(collection); | ||||
| } | ||||
|  | ||||
| template <typename col_t> | ||||
| inline auto to_hex_wstring(const col_t &collection) -> std::wstring { | ||||
|   return to_hex_string_t<col_t, std::wstring>(collection); | ||||
| } | ||||
| } // namespace repertory::utils::collection | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_COLLECTION_HPP_ | ||||
| @@ -1,47 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef 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 { | ||||
| class com_init_wrapper { | ||||
| public: | ||||
|   com_init_wrapper() | ||||
|       : uninit_( | ||||
|             SUCCEEDED(::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED))) {} | ||||
|  | ||||
|   ~com_init_wrapper() { | ||||
|     if (uninit_) { | ||||
|       ::CoUninitialize(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| private: | ||||
|   BOOL uninit_; | ||||
| }; | ||||
| } // namespace repertory::utils | ||||
|  | ||||
| #endif // defined(_WIN32) | ||||
| #endif // REPERTORY_INCLUDE_UTILS_COM_INIT_WRAPPER_HPP_ | ||||
							
								
								
									
										115
									
								
								support/3rd_party/include/utils/common.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										115
									
								
								support/3rd_party/include/utils/common.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,115 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_COMMON_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_COMMON_HPP_ | ||||
|  | ||||
| #include "utils/config.hpp" | ||||
|  | ||||
| namespace repertory::utils { | ||||
| struct result final { | ||||
|   std::string_view function_name; | ||||
|   bool ok{false}; | ||||
|   std::string reason{}; | ||||
|  | ||||
|   [[nodiscard]] operator bool() const { return ok; } | ||||
| }; | ||||
|  | ||||
| [[nodiscard]] inline auto | ||||
| calculate_read_size(std::uint64_t total_size, std::size_t read_size, | ||||
|                     std::uint64_t offset) -> std::size_t { | ||||
|   return static_cast<std::size_t>( | ||||
|       ((offset + read_size) > total_size) | ||||
|           ? ((offset < total_size) ? total_size - offset : 0U) | ||||
|           : read_size); | ||||
| } | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| compare_version_strings(std::string version1, | ||||
|                         std::string version2) -> std::int32_t; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| compare_version_strings(std::wstring_view version1, | ||||
|                         std::wstring_view version2) -> std::int32_t; | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_STDUUID) | ||||
| [[nodiscard]] auto create_uuid_string() -> std::string; | ||||
|  | ||||
| [[nodiscard]] auto create_uuid_wstring() -> std::wstring; | ||||
| #endif // defined(PROJECT_ENABLE_STDUUID) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) | ||||
| template <typename data_type> | ||||
| [[nodiscard]] inline auto generate_random() -> data_type; | ||||
|  | ||||
| template <typename data_type> | ||||
| [[nodiscard]] inline auto | ||||
| generate_random_between(const data_type &begin, | ||||
|                         const data_type &end) -> data_type; | ||||
|  | ||||
| [[nodiscard]] auto generate_random_string(std::uint16_t length) -> std::string; | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| get_environment_variable(std::string_view variable) -> std::string; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| get_environment_variable(std::wstring_view variable) -> std::wstring; | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_BOOST) | ||||
| [[nodiscard]] auto | ||||
| get_next_available_port(std::uint16_t first_port, | ||||
|                         std::uint16_t &available_port) -> bool; | ||||
| #endif // defined(PROJECT_ENABLE_BOOST) | ||||
|  | ||||
| [[nodiscard]] auto resolve_variables(std::string str) -> std::string; | ||||
|  | ||||
| [[nodiscard]] auto resolve_variables(std::wstring_view str) -> std::wstring; | ||||
|  | ||||
| template <typename result_t, typename data_t> | ||||
| [[nodiscard]] 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); | ||||
| } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) | ||||
| template <typename data_type> | ||||
| [[nodiscard]] inline auto generate_random() -> data_type { | ||||
|   data_type ret{}; | ||||
|   randombytes_buf(&ret, sizeof(ret)); | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| template <typename data_type> | ||||
| [[nodiscard]] inline auto | ||||
| generate_random_between(const data_type &begin, | ||||
|                         const data_type &end) -> data_type { | ||||
|   return begin + generate_random<data_type>() % ((end + data_type{1}) - begin); | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) | ||||
| } // namespace repertory::utils | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_COMMON_HPP_ | ||||
							
								
								
									
										321
									
								
								support/3rd_party/include/utils/config.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										321
									
								
								support/3rd_party/include/utils/config.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,321 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_CONFIG_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_CONFIG_HPP_ | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| #define WINVER 0x0602 | ||||
| #define _WIN32_WINNT WINVER | ||||
| #define WIN32_LEAN_AND_MEAN | ||||
|  | ||||
| #include <winsock2.h> | ||||
| #include <ws2tcpip.h> | ||||
|  | ||||
| #include <windows.h> | ||||
| #if defined(PROJECT_ENABLE_WINFSP) | ||||
| #include <sddl.h> | ||||
| #endif // defined(PROJECT_ENABLE_WINFSP) | ||||
|  | ||||
| #include <direct.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <io.h> | ||||
| #include <iphlpapi.h> | ||||
| #include <objbase.h> | ||||
| #include <psapi.h> | ||||
| #include <rpc.h> | ||||
| #include <share.h> | ||||
| #include <shellapi.h> | ||||
| #include <shlobj.h> | ||||
| #include <shlwapi.h> | ||||
| #include <stdio.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/types.h> | ||||
| #include <time.h> | ||||
| #else // !defined(_WIN32) | ||||
| #include <arpa/inet.h> | ||||
| #include <dirent.h> | ||||
| #include <fcntl.h> | ||||
| #include <grp.h> | ||||
| #include <libgen.h> | ||||
| #include <netinet/in.h> | ||||
| #include <pwd.h> | ||||
| #include <sys/file.h> | ||||
| #include <sys/socket.h> | ||||
| #if defined(__LFS64__) | ||||
| #include <sys/stat64.h> | ||||
| #else | ||||
| #include <sys/stat.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(__linux__) | ||||
| #include <sys/statfs.h> | ||||
| #endif //  defined(HAS_SETXATTR) | ||||
|  | ||||
| #if defined(HAS_SETXATTR) | ||||
| #include <sys/types.h> | ||||
| #include <sys/xattr.h> | ||||
| #endif // defined(HAS_SETXATTR) | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
| #include <libproc.h> | ||||
| #include <sys/attr.h> | ||||
| #include <sys/mount.h> | ||||
| #include <sys/statvfs.h> | ||||
| #include <sys/vnode.h> | ||||
| #endif // defined(__APPLE__) | ||||
|  | ||||
| #include <unistd.h> | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
| #if defined(HAS_WORDEXP_H) | ||||
| #include <wordexp.h> | ||||
| #endif // defined(HAS_WORDEXP_H) | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| #include <algorithm> | ||||
| #include <array> | ||||
| #include <atomic> | ||||
| #include <bit> | ||||
| #include <chrono> | ||||
| #include <ciso646> | ||||
| #include <climits> | ||||
| #include <codecvt> | ||||
| #include <condition_variable> | ||||
| #include <cstdint> | ||||
| #include <cstdlib> | ||||
| #include <cstring> | ||||
| #include <ctime> | ||||
| #include <deque> | ||||
| #include <filesystem> | ||||
| #include <fstream> | ||||
| #include <functional> | ||||
| #include <future> | ||||
| #include <iomanip> | ||||
| #include <iostream> | ||||
| #include <iterator> | ||||
| #include <limits> | ||||
| #include <locale> | ||||
| #include <map> | ||||
| #include <memory> | ||||
| #include <mutex> | ||||
| #include <numeric> | ||||
| #include <optional> | ||||
| #include <ostream> | ||||
| #include <queue> | ||||
| #include <random> | ||||
| #include <ranges> | ||||
| #include <regex> | ||||
| #include <span> | ||||
| #include <sstream> | ||||
| #include <stdexcept> | ||||
| #include <string> | ||||
| #include <string_view> | ||||
| #include <thread> | ||||
| #include <type_traits> | ||||
| #include <unordered_map> | ||||
| #include <utility> | ||||
| #include <variant> | ||||
| #include <vector> | ||||
| #endif // defined(__cplusplus) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_CURL) | ||||
| #include "curl/curl.h" | ||||
| #include "curl/multi.h" | ||||
| #endif // defined(PROJECT_ENABLE_CURL) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_FUSE) | ||||
| #if FUSE_USE_VERSION >= 30 | ||||
| #include <fuse.h> | ||||
| #include <fuse_lowlevel.h> | ||||
| #else | ||||
| #include <fuse/fuse.h> | ||||
| #endif | ||||
| #endif // defined(PROJECT_ENABLE_FUSE) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_FZF) | ||||
| #if defined(__cplusplus) | ||||
| extern "C" { | ||||
| #endif // defined(__cplusplus) | ||||
| #include "fzf.h" | ||||
| #if defined(__cplusplus) | ||||
| } | ||||
| #endif // defined(__cplusplus) | ||||
| #endif // defined(PROJECT_ENABLE_FZF) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_LIBEVENT) | ||||
| #include "event2/buffer.h" | ||||
| #include "event2/bufferevent.h" | ||||
| #include "event2/listener.h" | ||||
| #include "event2/thread.h" | ||||
| #include "event2/util.h" | ||||
| #endif // defined(PROJECT_ENABLE_LIBEVENT) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_SDL) | ||||
| #include "SDL.h" | ||||
| #include "SDL_gamecontroller.h" | ||||
| #include "SDL_joystick.h" | ||||
| #endif // defined(PROJECT_ENABLE_SDL) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) | ||||
| #include "sodium.h" | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_SQLITE) | ||||
| #include "sqlite3.h" | ||||
| #endif // defined(PROJECT_ENABLE_SQLITE) | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| #if defined(PROJECT_ENABLE_BOOST) | ||||
| #include "boost/archive/text_iarchive.hpp" | ||||
| #include "boost/archive/text_oarchive.hpp" | ||||
| #include "boost/asio.hpp" | ||||
| #include "boost/asio/io_context.hpp" | ||||
| #include "boost/bind/bind.hpp" | ||||
| #include "boost/dynamic_bitset.hpp" | ||||
| #include "boost/dynamic_bitset/serialization.hpp" | ||||
| #include "boost/endian/conversion.hpp" | ||||
| #include "boost/integer.hpp" | ||||
| #include "boost/interprocess/sync/named_mutex.hpp" | ||||
| #include "boost/interprocess/sync/scoped_lock.hpp" | ||||
| #include "boost/multiprecision/cpp_dec_float.hpp" | ||||
| #include "boost/multiprecision/cpp_int.hpp" | ||||
| #include "boost/serialization/vector.hpp" | ||||
| #endif // defined(PROJECT_ENABLE_BOOST) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_CPP_HTTPLIB) | ||||
| #include "httplib.h" | ||||
| #endif // defined(PROJECT_ENABLE_JSON) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_DTL) | ||||
| #include "dtl/dtl.hpp" | ||||
| #endif // defined(PROJECT_ENABLE_DTL) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_JSON) | ||||
| #include "json.hpp" | ||||
| #endif // defined(PROJECT_ENABLE_JSON) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_NANA) | ||||
| #include "nana/gui.hpp" | ||||
| #include "nana/gui/timer.hpp" | ||||
| #include "nana/gui/widgets/button.hpp" | ||||
| #include "nana/gui/widgets/combox.hpp" | ||||
| #include "nana/gui/widgets/group.hpp" | ||||
| #include "nana/gui/widgets/label.hpp" | ||||
| #include "nana/gui/widgets/panel.hpp" | ||||
| #include "nana/gui/widgets/picture.hpp" | ||||
| #include "nana/gui/widgets/tabbar.hpp" | ||||
| #endif // defined(PROJECT_ENABLE_NANA) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_PUGIXML) | ||||
| #include "pugixml.hpp" | ||||
| #endif // defined(PROJECT_ENABLE_PUGIXML) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_ROCKSDB) | ||||
| #include "rocksdb/db.h" | ||||
| #include "rocksdb/utilities/transaction_db.h" | ||||
| #endif // defined(PROJECT_ENABLE_ROCKSDB) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_SFML) | ||||
| #include "RoundedRectangleShape.hpp" | ||||
| #include "SFML/Graphics.hpp" | ||||
| #include "Text2.hpp" | ||||
| #endif // defined(PROJECT_ENABLE_SFML) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_SAGO_PLATFORM_FOLDERS) | ||||
| #include "platform_folders.hpp" | ||||
| #endif // defined(PROJECT_ENABLE_SAGO_PLATFORM_FOLDERS) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_SPDLOG) | ||||
| #include "spdlog/async.h" | ||||
| #include "spdlog/fmt/bundled/core.h" | ||||
| #include "spdlog/fmt/bundled/format.h" | ||||
| #include "spdlog/fmt/chrono.h" | ||||
| #include "spdlog/sinks/rotating_file_sink.h" | ||||
| #include "spdlog/sinks/stdout_color_sinks.h" | ||||
| #include "spdlog/spdlog.h" | ||||
| #endif // defined(PROJECT_ENABLE_SPDLOG) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_STDUUID) | ||||
| #include "uuid.h" | ||||
| #endif // defined(PROJECT_ENABLE_STDUUID) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_TPL) | ||||
| #include "process.hpp" | ||||
| #endif // defined(PROJECT_ENABLE_TPL) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_WINFSP) | ||||
| #include "winfsp/winfsp.hpp" | ||||
| #endif // defined(PROJECT_ENABLE_WINFSP) | ||||
|  | ||||
| #if !defined(fstat64) | ||||
| #define fstat64 fstat | ||||
| #endif // !defined(fstat64) | ||||
|  | ||||
| #if !defined(pread64) | ||||
| #define pread64 pread | ||||
| #endif // !defined(pread64) | ||||
|  | ||||
| #if !defined(pwrite64) | ||||
| #define pwrite64 pwrite | ||||
| #endif // !defined(pwrite64) | ||||
|  | ||||
| #if !defined(stat64) | ||||
| #define stat64 stat | ||||
| #endif // !defined(stat64) | ||||
|  | ||||
| #if !defined(statfs64) | ||||
| #define statfs64 statfs | ||||
| #endif // !defined(statfs64) | ||||
|  | ||||
| #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) | ||||
|  | ||||
| namespace repertory { | ||||
| using data_buffer = std::vector<unsigned char>; | ||||
| using mutex_lock = std::lock_guard<std::mutex>; | ||||
| using recur_mutex_lock = std::lock_guard<std::recursive_mutex>; | ||||
| using unique_mutex_lock = std::unique_lock<std::mutex>; | ||||
| using unique_recur_mutex_lock = std::unique_lock<std::recursive_mutex>; | ||||
|  | ||||
| template <class... Ts> struct overloaded : Ts... { | ||||
|   using Ts::operator()...; | ||||
| }; | ||||
| template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>; | ||||
|  | ||||
| struct file_deleter final { | ||||
|   void operator()(FILE *file) { | ||||
|     if (file != nullptr) { | ||||
|       fclose(file); | ||||
|     } | ||||
|   } | ||||
| }; | ||||
| using file_t = std::unique_ptr<FILE, file_deleter>; | ||||
| } // namespace repertory | ||||
| #endif // defined(__cplusplus) | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_CONFIG_HPP_ | ||||
							
								
								
									
										160
									
								
								support/3rd_party/include/utils/encryption.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										160
									
								
								support/3rd_party/include/utils/encryption.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,160 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_ENCRYPTION_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_ENCRYPTION_HPP_ | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) | ||||
|  | ||||
| #include "utils/config.hpp" | ||||
|  | ||||
| namespace repertory::utils::encryption { | ||||
| using hash_256_t = std::array<unsigned char, 32U>; | ||||
| using hash_256_func_t = std::function<hash_256_t(std::string_view)>; | ||||
| using key_type = std::array<unsigned char, 32U>; | ||||
|  | ||||
| inline constexpr const std::uint32_t encryption_header_size{ | ||||
|     crypto_aead_xchacha20poly1305_IETF_NPUBBYTES + | ||||
|         crypto_aead_xchacha20poly1305_IETF_ABYTES, | ||||
| }; | ||||
|  | ||||
| [[nodiscard]] auto generate_key(std::string_view encryption_token) -> key_type; | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_BOOST) | ||||
| [[nodiscard]] auto decrypt_data( | ||||
|     std::string_view data, std::string_view password, | ||||
|     std::optional<hash_256_func_t> hasher = std::nullopt) -> data_buffer; | ||||
|  | ||||
| [[nodiscard]] auto encrypt_data( | ||||
|     std::string_view data, std::string_view password, | ||||
|     std::optional<hash_256_func_t> hasher = std::nullopt) -> data_buffer; | ||||
|  | ||||
| template <typename result> | ||||
| [[nodiscard]] inline auto | ||||
| decrypt_data(const key_type &key, const unsigned char *buffer, | ||||
|              std::size_t buffer_size, result &res) -> bool { | ||||
|   if (buffer_size > encryption_header_size) { | ||||
|     const std::uint32_t size = | ||||
|         boost::endian::native_to_big(static_cast<std::uint32_t>(buffer_size)); | ||||
|     res.resize(buffer_size - encryption_header_size); | ||||
|     return crypto_aead_xchacha20poly1305_ietf_decrypt_detached( | ||||
|                reinterpret_cast<unsigned char *>(res.data()), nullptr, | ||||
|                &buffer[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, typename result> | ||||
| [[nodiscard]] inline auto decrypt_data(const key_type &key, const buffer &buf, | ||||
|                                        result &res) -> bool { | ||||
|   return decrypt_data<result>( | ||||
|       key, reinterpret_cast<const unsigned char *>(buf.data()), buf.size(), | ||||
|       res); | ||||
| } | ||||
|  | ||||
| template <typename buffer, typename result> | ||||
| [[nodiscard]] inline auto decrypt_data(std::string_view encryption_token, | ||||
|                                        const buffer &buf, result &res) -> bool { | ||||
|   return decrypt_data<buffer, result>(generate_key(encryption_token), buf, res); | ||||
| } | ||||
|  | ||||
| template <typename result> | ||||
| [[nodiscard]] inline auto | ||||
| decrypt_data(std::string_view encryption_token, const unsigned char *buffer, | ||||
|              std::size_t buffer_size, result &res) -> bool { | ||||
|   return decrypt_data<result>(generate_key(encryption_token), buffer, | ||||
|                               buffer_size, res); | ||||
| } | ||||
|  | ||||
| template <typename result> | ||||
| inline void | ||||
| encrypt_data(const std::array<unsigned char, | ||||
|                               crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv, | ||||
|              const key_type &key, const unsigned char *buffer, | ||||
|              std::size_t buffer_size, result &res) { | ||||
|   std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_ABYTES> mac{}; | ||||
|  | ||||
|   const std::uint32_t size = boost::endian::native_to_big( | ||||
|       static_cast<std::uint32_t>(buffer_size + encryption_header_size)); | ||||
|  | ||||
|   res.resize(buffer_size + 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 std::runtime_error("encryption failed"); | ||||
|   } | ||||
|  | ||||
|   std::memcpy(res.data(), iv.data(), iv.size()); | ||||
|   std::memcpy(&res[iv.size()], mac.data(), mac.size()); | ||||
| } | ||||
|  | ||||
| template <typename result> | ||||
| inline void encrypt_data(const key_type &key, const unsigned char *buffer, | ||||
|                          std::size_t buffer_size, result &res) { | ||||
|   std::array<unsigned char, crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> iv{}; | ||||
|   randombytes_buf(iv.data(), iv.size()); | ||||
|  | ||||
|   encrypt_data<result>(iv, key, buffer, buffer_size, res); | ||||
| } | ||||
|  | ||||
| template <typename result> | ||||
| inline void encrypt_data(std::string_view encryption_token, | ||||
|                          const unsigned char *buffer, std::size_t buffer_size, | ||||
|                          result &res) { | ||||
|   encrypt_data<result>(generate_key(encryption_token), buffer, buffer_size, | ||||
|                        res); | ||||
| } | ||||
|  | ||||
| template <typename buffer, typename result> | ||||
| inline void encrypt_data(std::string_view encryption_token, const buffer &buf, | ||||
|                          result &res) { | ||||
|   encrypt_data<result>(generate_key(encryption_token), | ||||
|                        reinterpret_cast<const unsigned char *>(buf.data()), | ||||
|                        buf.size(), res); | ||||
| } | ||||
|  | ||||
| template <typename buffer, typename result> | ||||
| inline void encrypt_data(const key_type &key, const buffer &buf, result &res) { | ||||
|   encrypt_data<result>(key, reinterpret_cast<const unsigned char *>(buf.data()), | ||||
|                        buf.size(), res); | ||||
| } | ||||
|  | ||||
| template <typename buffer, typename result> | ||||
| inline void | ||||
| encrypt_data(const std::array<unsigned char, | ||||
|                               crypto_aead_xchacha20poly1305_IETF_NPUBBYTES> &iv, | ||||
|              const key_type &key, const buffer &buf, result &res) { | ||||
|   encrypt_data<result>(iv, key, | ||||
|                        reinterpret_cast<const unsigned char *>(buf.data()), | ||||
|                        buf.size(), res); | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_BOOST) | ||||
| } // namespace repertory::utils::encryption | ||||
|  | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) | ||||
| #endif // REPERTORY_INCLUDE_UTILS_ENCRYPTION_HPP_ | ||||
							
								
								
									
										52
									
								
								support/3rd_party/include/utils/error.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								support/3rd_party/include/utils/error.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,52 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_ERROR_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_ERROR_HPP_ | ||||
|  | ||||
| #include "utils/config.hpp" | ||||
|  | ||||
| namespace repertory::utils::error { | ||||
| struct i_exception_handler { | ||||
|   virtual ~i_exception_handler() {} | ||||
|  | ||||
|   i_exception_handler(const i_exception_handler &) noexcept = delete; | ||||
|   i_exception_handler(i_exception_handler &&) noexcept = delete; | ||||
|   auto operator=(const i_exception_handler &) noexcept = delete; | ||||
|   auto operator=(i_exception_handler &&) noexcept = delete; | ||||
|  | ||||
|   virtual void handle_exception(std::string_view function_name) const = 0; | ||||
|  | ||||
|   virtual void handle_exception(std::string_view function_name, | ||||
|                                 const std::exception &ex) const = 0; | ||||
|  | ||||
| protected: | ||||
|   i_exception_handler() = default; | ||||
| }; | ||||
|  | ||||
| void handle_exception(std::string_view function_name); | ||||
|  | ||||
| void handle_exception(std::string_view function_name, const std::exception &ex); | ||||
|  | ||||
| void set_exception_handler(i_exception_handler *handler); | ||||
| } // namespace repertory::utils::error | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_ERROR_HPP_ | ||||
							
								
								
									
										151
									
								
								support/3rd_party/include/utils/file.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										151
									
								
								support/3rd_party/include/utils/file.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,151 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_FILE_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_FILE_HPP_ | ||||
|  | ||||
| #include "utils/config.hpp" | ||||
|  | ||||
| namespace repertory::utils::file { | ||||
| class file final { | ||||
| public: | ||||
|   [[nodiscard]] static auto open_file(std::filesystem::path path) -> file; | ||||
|  | ||||
|   [[nodiscard]] static auto | ||||
|   open_or_create_file(std::filesystem::path path) -> file; | ||||
|  | ||||
| protected: | ||||
|   file(std::fstream stream, std::filesystem::path path) | ||||
|       : path_(std::move(path)), stream_(std::move(stream)) {} | ||||
|   file() = default; | ||||
|  | ||||
| public: | ||||
|   file(const file &) = delete; | ||||
|   file(file &&file_) noexcept = default; | ||||
|  | ||||
|   ~file() { close(); } | ||||
|  | ||||
|   auto operator=(const file &) noexcept -> file & = delete; | ||||
|   auto operator=(file &&file_) noexcept -> file & = default; | ||||
|  | ||||
| private: | ||||
|   std::error_code error_{}; | ||||
|   std::filesystem::path path_; | ||||
|   std::fstream stream_; | ||||
|  | ||||
| public: | ||||
|   void close(); | ||||
|  | ||||
|   [[nodiscard]] auto get_error_code() const -> std::error_code { | ||||
|     return error_; | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto get_path() const -> std::filesystem::path { return path_; } | ||||
|  | ||||
|   [[nodiscard]] auto move_to(std::filesystem::path new_path) -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto read(data_buffer &data, std::uint64_t offset, | ||||
|                           std::size_t *total_read = nullptr) -> bool { | ||||
|     return read_(reinterpret_cast<unsigned char *>(data.data()), data.size(), | ||||
|                  offset, total_read); | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] auto remove() -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto truncate() -> bool { return truncate(0U); } | ||||
|  | ||||
|   [[nodiscard]] auto truncate(std::size_t size) -> bool; | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_JSON) | ||||
|   [[nodiscard]] auto write(const nlohmann::json &data, | ||||
|                            std::size_t *total_written = nullptr) -> bool { | ||||
|     auto str_data = data.dump(); | ||||
|     return write_(reinterpret_cast<const unsigned char *>(str_data.c_str()), | ||||
|                   str_data.size(), 0U, total_written); | ||||
|   } | ||||
| #endif // defined(PROJECT_ENABLE_JSON) | ||||
|  | ||||
|   [[nodiscard]] auto write(const data_buffer &data, std::uint64_t offset, | ||||
|                            std::size_t *total_written = nullptr) -> bool { | ||||
|     return write_(reinterpret_cast<const unsigned char *>(data.data()), | ||||
|                   data.size(), offset, total_written); | ||||
|   } | ||||
|  | ||||
|   [[nodiscard]] operator bool() const { return stream_.is_open(); } | ||||
|  | ||||
| private: | ||||
|   [[nodiscard]] auto read_(unsigned char *data, std::size_t to_read, | ||||
|                            std::uint64_t offset, | ||||
|                            std::size_t *total_read) -> bool; | ||||
|  | ||||
|   [[nodiscard]] auto write_(const unsigned char *data, std::size_t to_write, | ||||
|                             std::size_t offset, | ||||
|                             std::size_t *total_written) -> bool; | ||||
| }; | ||||
|  | ||||
| [[nodiscard]] auto get_file_size(std::string_view path, | ||||
|                                  std::uint64_t &file_size) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto get_file_size(std::wstring_view path, | ||||
|                                  std::uint64_t &file_size) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto is_directory(std::string_view path) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto is_directory(std::wstring_view path) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto is_file(std::string_view path) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto is_file(std::wstring_view path) -> bool; | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_JSON) | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
| [[nodiscard]] auto | ||||
| read_json_file(std::string_view path, nlohmann::json &data, | ||||
|                std::optional<std::string_view> password = std::nullopt) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto read_json_file( | ||||
|     std::wstring_view path, nlohmann::json &data, | ||||
|     std::optional<std::wstring_view> password = std::nullopt) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto write_json_file( | ||||
|     std::string_view path, const nlohmann::json &data, | ||||
|     std::optional<std::string_view> password = std::nullopt) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto write_json_file( | ||||
|     std::wstring_view path, const nlohmann::json &data, | ||||
|     std::optional<std::wstring_view> password = std::nullopt) -> bool; | ||||
| #else  // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
| [[nodiscard]] auto read_json_file(std::string_view path, | ||||
|                                   nlohmann::json &data) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto read_json_file(std::wstring_view path, | ||||
|                                   nlohmann::json &data) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto write_json_file(std::string_view path, | ||||
|                                    const nlohmann::json &data) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto write_json_file(std::wstring_view path, | ||||
|                                    const nlohmann::json &data) -> bool; | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
| #endif // defined(PROJECT_ENABLE_JSON) | ||||
| } // namespace repertory::utils::file | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_FILE_HPP_ | ||||
							
								
								
									
										408
									
								
								support/3rd_party/include/utils/path.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										408
									
								
								support/3rd_party/include/utils/path.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,408 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_PATH_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_PATH_HPP_ | ||||
|  | ||||
| #include "utils/config.hpp" | ||||
| #include "utils/string.hpp" | ||||
|  | ||||
| namespace repertory::utils::path { | ||||
| inline constexpr const std::string_view backslash{"\\"}; | ||||
| inline constexpr const std::wstring_view backslash_w{L"\\"}; | ||||
| inline constexpr const std::string_view dot{"."}; | ||||
| inline constexpr const std::wstring_view dot_w{L"."}; | ||||
| inline constexpr const std::string_view dot_slash{"./"}; | ||||
| inline constexpr const std::wstring_view dot_slash_w{L"./"}; | ||||
| inline constexpr const std::string_view slash{"/"}; | ||||
| inline constexpr const std::wstring_view slash_w{L"/"}; | ||||
| #if defined(_WIN32) | ||||
| inline constexpr const std::string_view directory_seperator{backslash}; | ||||
| inline constexpr const std::wstring_view directory_seperator_w{backslash_w}; | ||||
| inline constexpr const std::string_view not_directory_seperator{slash}; | ||||
| inline constexpr const std::wstring_view not_directory_seperator_w{slash_w}; | ||||
| #else  // !defined(_WIN32) | ||||
| inline constexpr const std::string_view directory_seperator{slash}; | ||||
| inline constexpr const std::wstring_view directory_seperator_w{slash_w}; | ||||
| inline constexpr const std::string_view not_directory_seperator{backslash}; | ||||
| inline constexpr const std::wstring_view not_directory_seperator_w{backslash_w}; | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
| template <typename char_t> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_backslash() -> std::basic_string_view<char_t>; | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_backslash<char>() -> std::basic_string_view<char> { | ||||
|   return backslash; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_backslash<wchar_t>() -> std::basic_string_view<wchar_t> { | ||||
|   return backslash_w; | ||||
| } | ||||
|  | ||||
| template <typename char_t> | ||||
| [[nodiscard]] inline constexpr auto get_dot() -> std::basic_string_view<char_t>; | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_dot<char>() -> std::basic_string_view<char> { | ||||
|   return dot; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_dot<wchar_t>() -> std::basic_string_view<wchar_t> { | ||||
|   return dot_w; | ||||
| } | ||||
|  | ||||
| template <typename char_t> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_dot_slash() -> std::basic_string_view<char_t>; | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_dot_slash<char>() -> std::basic_string_view<char> { | ||||
|   return dot_slash; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_dot_slash<wchar_t>() -> std::basic_string_view<wchar_t> { | ||||
|   return dot_slash_w; | ||||
| } | ||||
|  | ||||
| template <typename char_t> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_slash() -> std::basic_string_view<char_t>; | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_slash<char>() -> std::basic_string_view<char> { | ||||
|   return slash; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_slash<wchar_t>() -> std::basic_string_view<wchar_t> { | ||||
|   return slash_w; | ||||
| } | ||||
|  | ||||
| template <typename char_t> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_directory_seperator() -> std::basic_string_view<char_t>; | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_directory_seperator<char>() -> std::basic_string_view<char> { | ||||
|   return directory_seperator; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_directory_seperator<wchar_t>() -> std::basic_string_view<wchar_t> { | ||||
|   return directory_seperator_w; | ||||
| } | ||||
|  | ||||
| template <typename char_t> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_not_directory_seperator() -> std::basic_string_view<char_t>; | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_not_directory_seperator<char>() -> std::basic_string_view<char> { | ||||
|   return not_directory_seperator; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| [[nodiscard]] inline constexpr auto | ||||
| get_not_directory_seperator<wchar_t>() -> std::basic_string_view<wchar_t> { | ||||
|   return not_directory_seperator_w; | ||||
| } | ||||
|  | ||||
| [[nodiscard]] auto absolute(std::string_view path) -> std::string; | ||||
|  | ||||
| [[nodiscard]] auto absolute(std::wstring_view path) -> std::wstring; | ||||
|  | ||||
| [[nodiscard]] inline auto | ||||
| combine(std::string path, | ||||
|         const std::vector<std::string_view> &paths) -> std::string; | ||||
|  | ||||
| [[nodiscard]] inline auto | ||||
| combine(std::wstring path, | ||||
|         const std::vector<std::wstring_view> &paths) -> std::wstring; | ||||
|  | ||||
| [[nodiscard]] auto inline create_api_path(std::string_view path) -> std::string; | ||||
|  | ||||
| [[nodiscard]] auto inline create_api_path(std::wstring_view path) | ||||
|     -> std::wstring; | ||||
|  | ||||
| [[nodiscard]] inline auto | ||||
| directory_exists_in_path(std::string_view path, | ||||
|                          std::string_view sub_directory) -> bool; | ||||
|  | ||||
| [[nodiscard]] inline auto | ||||
| directory_exists_in_path(std::wstring_view path, | ||||
|                          std::wstring_view sub_directory) -> bool; | ||||
|  | ||||
| [[nodiscard]] inline auto | ||||
| file_exists_in_path(std::string_view path, std::string_view file_name) -> bool; | ||||
|  | ||||
| [[nodiscard]] inline auto | ||||
| file_exists_in_path(std::wstring_view path, | ||||
|                     std::wstring_view file_name) -> bool; | ||||
|  | ||||
| [[nodiscard]] inline auto finalize(std::string_view path) -> std::string; | ||||
|  | ||||
| [[nodiscard]] inline auto finalize(std::wstring_view path) -> std::wstring; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| find_program_in_path(const std::string &name_without_extension) -> std::string; | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| find_program_in_path(std::wstring_view name_without_extension) -> std::wstring; | ||||
|  | ||||
| template <typename string_t> | ||||
| inline auto | ||||
| format_path(string_t &path, | ||||
|             std::basic_string_view<typename string_t::value_type> sep, | ||||
|             std::basic_string_view<typename string_t::value_type> not_sep) | ||||
|     -> string_t &; | ||||
|  | ||||
| [[nodiscard]] inline auto | ||||
| get_parent_api_path(std::string_view path) -> std::string; | ||||
|  | ||||
| [[nodiscard]] inline auto | ||||
| get_parent_api_path(std::wstring_view path) -> std::wstring; | ||||
|  | ||||
| [[nodiscard]] auto get_parent_directory(std::string_view path) -> std::string; | ||||
|  | ||||
| [[nodiscard]] auto get_parent_directory(std::wstring_view path) -> std::wstring; | ||||
|  | ||||
| [[nodiscard]] auto is_trash_directory(std::string_view path) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto is_trash_directory(std::wstring_view path) -> bool; | ||||
|  | ||||
| [[nodiscard]] auto make_file_uri(std::string_view path) -> std::string; | ||||
|  | ||||
| [[nodiscard]] auto make_file_uri(std::wstring_view path) -> std::wstring; | ||||
|  | ||||
| [[nodiscard]] auto remove_file_name(std::string_view path) -> std::string; | ||||
|  | ||||
| [[nodiscard]] auto remove_file_name(std::wstring_view path) -> std::wstring; | ||||
|  | ||||
| [[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( | ||||
|     string_t path, | ||||
|     const std::vector<std::basic_string_view<typename string_t::value_type>> | ||||
|         &paths) -> string_t { | ||||
|   format_path(path, get_directory_seperator<typename string_t::value_type>(), | ||||
|               get_not_directory_seperator<typename string_t::value_type>()); | ||||
|  | ||||
|   return absolute(std::accumulate( | ||||
|       paths.begin(), paths.end(), path, [](auto next_path, auto &&path_part) { | ||||
|         if (next_path.empty()) { | ||||
|           return string_t{path_part}; | ||||
|         } | ||||
|  | ||||
|         return next_path + | ||||
|                string_t{ | ||||
|                    get_directory_seperator<typename string_t::value_type>()} + | ||||
|                string_t{path_part}; | ||||
|       })); | ||||
| } | ||||
|  | ||||
| inline auto combine(std::string path, | ||||
|                     const std::vector<std::string_view> &paths) -> std::string { | ||||
|   return combine_t<std::string>(path, paths); | ||||
| } | ||||
|  | ||||
| inline auto | ||||
| combine(std::wstring path, | ||||
|         const std::vector<std::wstring_view> &paths) -> std::wstring { | ||||
|   return combine_t<std::wstring>(path, paths); | ||||
| } | ||||
|  | ||||
| template <typename string_t> | ||||
| [[nodiscard]] inline auto create_api_path_t( | ||||
|     std::basic_string_view<typename string_t::value_type> path) -> string_t { | ||||
|   auto backslash_t = get_backslash<typename string_t::value_type>(); | ||||
|   auto dot_t = get_dot<typename string_t::value_type>(); | ||||
|   auto dot_slash_t = get_dot_slash<typename string_t::value_type>(); | ||||
|   auto slash_t = get_slash<typename string_t::value_type>(); | ||||
|  | ||||
|   if (path.empty() || path == backslash_t || path == dot_t || | ||||
|       path == dot_slash_t || path == slash_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) | ||||
|  | ||||
|   while (utils::string::begins_with(api_path, dot_slash_t)) { | ||||
|     api_path = api_path.substr(dot_slash_t.size()); | ||||
|   } | ||||
|  | ||||
|   while (utils::string::begins_with(api_path, dot_t)) { | ||||
|     api_path = api_path.substr(dot_t.size()); | ||||
|   } | ||||
|  | ||||
|   format_path(api_path, slash_t, backslash_t); | ||||
|  | ||||
|   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 directory_exists_in_path_t( | ||||
|     std::basic_string_view<typename string_t::value_type> path, | ||||
|     std::basic_string_view<typename string_t::value_type> sub_directory) | ||||
|     -> bool { | ||||
|   return std::filesystem::is_directory( | ||||
|       std::filesystem::path(path).append(sub_directory)); | ||||
| } | ||||
|  | ||||
| inline auto directory_exists_in_path(std::string_view path, | ||||
|                                      std::string_view sub_directory) -> bool { | ||||
|   return directory_exists_in_path_t<std::string>(path, sub_directory); | ||||
| } | ||||
|  | ||||
| inline auto directory_exists_in_path(std::wstring_view path, | ||||
|                                      std::wstring_view sub_directory) -> bool { | ||||
|   return directory_exists_in_path_t<std::wstring>(path, sub_directory); | ||||
| } | ||||
|  | ||||
| template <typename string_t> | ||||
| [[nodiscard]] inline auto file_exists_in_path_t( | ||||
|     std::basic_string_view<typename string_t::value_type> path, | ||||
|     std::basic_string_view<typename string_t::value_type> file_name) -> bool { | ||||
|   return std::filesystem::is_regular_file( | ||||
|       std::filesystem::path(path).append(file_name)); | ||||
| } | ||||
|  | ||||
| inline auto file_exists_in_path(std::string_view path, | ||||
|                                 std::string_view file_name) -> bool { | ||||
|   return file_exists_in_path_t<std::string>(path, file_name); | ||||
| } | ||||
|  | ||||
| inline auto file_exists_in_path(std::wstring_view path, | ||||
|                                 std::wstring_view file_name) -> bool { | ||||
|   return file_exists_in_path_t<std::wstring>(path, file_name); | ||||
| } | ||||
|  | ||||
| template <typename string_t> | ||||
| [[nodiscard]] inline auto finalize_t( | ||||
|     std::basic_string_view<typename string_t::value_type> path) -> string_t { | ||||
|   string_t fmt_path{path}; | ||||
|   format_path(fmt_path, | ||||
|               get_directory_seperator<typename string_t::value_type>(), | ||||
|               get_not_directory_seperator<typename string_t::value_type>()); | ||||
|   return fmt_path; | ||||
| } | ||||
|  | ||||
| inline auto finalize(std::string_view path) -> std::string { | ||||
|   return finalize_t<std::string>(path); | ||||
| } | ||||
|  | ||||
| inline auto finalize(std::wstring_view path) -> std::wstring { | ||||
|   return finalize_t<std::wstring>(path); | ||||
| } | ||||
|  | ||||
| template <typename string_t> | ||||
| inline auto | ||||
| format_path(string_t &path, | ||||
|             std::basic_string_view<typename string_t::value_type> sep, | ||||
|             std::basic_string_view<typename string_t::value_type> not_sep) | ||||
|     -> string_t & { | ||||
|   utils::string::replace(path, not_sep, sep); | ||||
|  | ||||
|   string_t double_sep(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 ((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 <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; | ||||
|   if (path == slash_t) { | ||||
|     return ret; | ||||
|   } | ||||
|  | ||||
|   ret = path.substr(0, path.rfind('/') + 1); | ||||
|   if (ret == slash_t) { | ||||
|     return ret; | ||||
|   } | ||||
|  | ||||
|   return utils::string::right_trim(ret, '/'); | ||||
| } | ||||
|  | ||||
| inline auto get_parent_api_path(std::string_view path) -> std::string { | ||||
|   return get_parent_api_path_t<std::string>(path); | ||||
| } | ||||
|  | ||||
| inline auto get_parent_api_path(std::wstring_view path) -> std::wstring { | ||||
|   return get_parent_api_path_t<std::wstring>(path); | ||||
| } | ||||
| } // namespace repertory::utils::path | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_PATH_HPP_ | ||||
							
								
								
									
										469
									
								
								support/3rd_party/include/utils/string.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										469
									
								
								support/3rd_party/include/utils/string.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,469 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef 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_ | ||||
							
								
								
									
										64
									
								
								support/3rd_party/include/utils/time.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								support/3rd_party/include/utils/time.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,64 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_TIME_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_TIME_HPP_ | ||||
|  | ||||
| #include "utils/config.hpp" | ||||
|  | ||||
| namespace repertory::utils::time { | ||||
| inline constexpr const auto NANOS_PER_SECOND = 1000000000L; | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT) | ||||
| [[nodiscard]] inline auto convert_to_utc(time_t time) -> std::time_t { | ||||
|   auto calendar_time = fmt::gmtime(time); | ||||
|   return std::mktime(&calendar_time); | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT) | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| [[nodiscard]] auto | ||||
| filetime_to_unix_time(const FILETIME &file_time) -> std::uint64_t; | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT) | ||||
| [[nodiscard]] inline auto get_current_time_utc() -> std::time_t { | ||||
|   auto calendar_time = fmt::gmtime(std::time(nullptr)); | ||||
|   return std::mktime(&calendar_time); | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_SPDLOG) || defined(PROJECT_ENABLE_FMT) | ||||
|  | ||||
| [[nodiscard]] auto get_file_time_now() -> std::uint64_t; | ||||
|  | ||||
| void get_local_time_now(struct tm &local_time); | ||||
|  | ||||
| [[nodiscard]] auto get_time_now() -> std::uint64_t; | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| auto strptime(const char *s, const char *f, struct tm *tm) -> const char *; | ||||
|  | ||||
| [[nodiscard]] auto time64_to_unix_time(const __time64_t &time) -> std::uint64_t; | ||||
|  | ||||
| [[nodiscard]] auto unix_time_to_filetime(std::uint64_t unix_time) -> FILETIME; | ||||
| #endif // defined(_WIN32) | ||||
| } // namespace repertory::utils::time | ||||
|  | ||||
| #endif // REPERTORY_INCLUDE_UTILS_TIME_HPP_ | ||||
							
								
								
									
										64
									
								
								support/3rd_party/include/utils/unix.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										64
									
								
								support/3rd_party/include/utils/unix.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,64 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_UNIX_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_UNIX_HPP_ | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #include "utils/common.hpp" | ||||
| #include "utils/config.hpp" | ||||
|  | ||||
| namespace repertory::utils { | ||||
| using passwd_callback_t = std::function<void(struct passwd *pass)>; | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
| template <typename thread_t> | ||||
| [[nodiscard]] auto | ||||
| convert_to_uint64(const thread_t *thread_ptr) -> std::uint64_t; | ||||
| #else  // !defined(__APPLE__) | ||||
| [[nodiscard]] auto convert_to_uint64(const pthread_t &thread) -> std::uint64_t; | ||||
| #endif // defined(__APPLE__) | ||||
|  | ||||
| [[nodiscard]] auto get_last_error_code() -> int; | ||||
|  | ||||
| [[nodiscard]] auto get_thread_id() -> std::uint64_t; | ||||
|  | ||||
| [[nodiscard]] auto is_uid_member_of_group(const uid_t &uid, | ||||
|                                           const gid_t &gid) -> bool; | ||||
|  | ||||
| void set_last_error_code(int error_code); | ||||
|  | ||||
| [[nodiscard]] auto use_getpwuid(uid_t uid, | ||||
|                                 passwd_callback_t callback) -> utils::result; | ||||
|  | ||||
| // template implementations | ||||
| #if defined(__APPLE__) | ||||
| template <typename t> | ||||
| [[nodiscard]] auto | ||||
| convert_to_uint64(const thread_t *thread_ptr) -> std::uint64_t { | ||||
|   return static_cast<std::uint64_t>( | ||||
|       reinterpret_cast<std::uintptr_t>(thread_ptr)); | ||||
| } | ||||
| #endif // defined(__APPLE__) | ||||
| } // namespace repertory::utils | ||||
|  | ||||
| #endif // !defined(_WIN32) | ||||
| #endif // REPERTORY_INCLUDE_UTILS_UNIX_HPP_ | ||||
							
								
								
									
										43
									
								
								support/3rd_party/include/utils/windows.hpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								support/3rd_party/include/utils/windows.hpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,43 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #ifndef REPERTORY_INCLUDE_UTILS_WINDOWS_HPP_ | ||||
| #define REPERTORY_INCLUDE_UTILS_WINDOWS_HPP_ | ||||
| #if defined(_WIN32) | ||||
|  | ||||
| #include "utils/config.hpp" | ||||
|  | ||||
| namespace repertory::utils { | ||||
| [[nodiscard]] auto get_local_app_data_directory() -> const std::string &; | ||||
|  | ||||
| [[nodiscard]] auto get_last_error_code() -> DWORD; | ||||
|  | ||||
| [[nodiscard]] auto get_thread_id() -> std::uint64_t; | ||||
|  | ||||
| [[nodiscard]] auto is_process_elevated() -> bool; | ||||
|  | ||||
| [[nodiscard]] auto run_process_elevated(std::vector<const char *> args) -> int; | ||||
|  | ||||
| void set_last_error_code(DWORD errorCode); | ||||
| } // namespace repertory::utils | ||||
|  | ||||
| #endif // defined(_WIN32) | ||||
| #endif // REPERTORY_INCLUDE_UTILS_WINDOWS_HPP_ | ||||
							
								
								
									
										45
									
								
								support/3rd_party/src/backward.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										45
									
								
								support/3rd_party/src/backward.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,45 +0,0 @@ | ||||
| // Pick your poison. | ||||
| // | ||||
| // On GNU/Linux, you have few choices to get the most out of your stack trace. | ||||
| // | ||||
| // By default you get: | ||||
| //	- object filename | ||||
| //	- function name | ||||
| // | ||||
| // In order to add: | ||||
| //	- source filename | ||||
| //	- line and column numbers | ||||
| //	- source code snippet (assuming the file is accessible) | ||||
|  | ||||
| // Install one of the following libraries then uncomment one of the macro (or | ||||
| // better, add the detection of the lib and the macro definition in your build | ||||
| // system) | ||||
|  | ||||
| // - apt-get install libdw-dev ... | ||||
| // - g++/clang++ -ldw ... | ||||
| // #define BACKWARD_HAS_DW 1 | ||||
|  | ||||
| // - apt-get install binutils-dev ... | ||||
| // - g++/clang++ -lbfd ... | ||||
| // #define BACKWARD_HAS_BFD 1 | ||||
|  | ||||
| // - apt-get install libdwarf-dev ... | ||||
| // - g++/clang++ -ldwarf ... | ||||
| // #define BACKWARD_HAS_DWARF 1 | ||||
|  | ||||
| // Regardless of the library you choose to read the debug information, | ||||
| // for potentially more detailed stack traces you can use libunwind | ||||
| // - apt-get install libunwind-dev | ||||
| // - g++/clang++ -lunwind | ||||
| // #define BACKWARD_HAS_LIBUNWIND 1 | ||||
| #include "backward.hpp" | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_BACKWARD_CPP) | ||||
|  | ||||
| namespace backward { | ||||
|  | ||||
| backward::SignalHandling sh; | ||||
|  | ||||
| } // namespace backward | ||||
|  | ||||
| #endif // defined(PROJECT_ENABLE_BACKWARD_CPP) | ||||
							
								
								
									
										149
									
								
								support/3rd_party/src/utils/common.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										149
									
								
								support/3rd_party/src/utils/common.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,149 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "utils/common.hpp" | ||||
|  | ||||
| #include "utils/path.hpp" | ||||
| #include "utils/string.hpp" | ||||
|  | ||||
| namespace repertory::utils { | ||||
| auto compare_version_strings(std::string version1, | ||||
|                              std::string version2) -> std::int32_t { | ||||
|  | ||||
|   if (utils::string::contains(version1, "-")) { | ||||
|     version1 = utils::string::split(version1, '-', true)[0U]; | ||||
|   } | ||||
|  | ||||
|   if (utils::string::contains(version2, "-")) { | ||||
|     version2 = utils::string::split(version2, '-', true)[0U]; | ||||
|   } | ||||
|  | ||||
|   auto nums1 = utils::string::split(version1, '.', true); | ||||
|   auto nums2 = utils::string::split(version2, '.', true); | ||||
|  | ||||
|   while (nums1.size() > nums2.size()) { | ||||
|     nums2.emplace_back("0"); | ||||
|   } | ||||
|  | ||||
|   while (nums2.size() > nums1.size()) { | ||||
|     nums1.emplace_back("0"); | ||||
|   } | ||||
|  | ||||
|   for (std::size_t idx = 0U; idx < nums1.size(); idx++) { | ||||
|     auto int1 = utils::string::to_uint32(nums1[idx]); | ||||
|     auto int2 = utils::string::to_uint32(nums2[idx]); | ||||
|     auto res = std::memcmp(&int1, &int2, sizeof(int1)); | ||||
|     if (res != 0) { | ||||
|       return res; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| auto compare_version_strings(std::wstring_view version1, | ||||
|                              std::wstring_view version2) -> std::int32_t { | ||||
|   return compare_version_strings(utils::string::to_utf8(version1), | ||||
|                                  utils::string::to_utf8(version2)); | ||||
| } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_STDUUID) | ||||
| auto create_uuid_string() -> std::string { | ||||
|   std::random_device random_device; | ||||
|   auto seed_data = std::array<int, std::mt19937::state_size>{}; | ||||
|   std::generate(std::begin(seed_data), std::end(seed_data), | ||||
|                 std::ref(random_device)); | ||||
|   std::seed_seq seq(std::begin(seed_data), std::end(seed_data)); | ||||
|   std::mt19937 generator(seq); | ||||
|   uuids::uuid_random_generator gen{generator}; | ||||
|  | ||||
|   return uuids::to_string(gen()); | ||||
| } | ||||
|  | ||||
| auto create_uuid_wstring() -> std::wstring { | ||||
|   return utils::string::from_utf8(create_uuid_string()); | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_STDUUID) | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) | ||||
| auto generate_random_string(std::uint16_t length) -> std::string { | ||||
|   std::string ret; | ||||
|   ret.resize(length); | ||||
|   for (std::uint16_t i = 0U; i < length; i++) { | ||||
|     do { | ||||
|       ret[i] = static_cast<char>(generate_random<std::uint8_t>() % 74 + 48); | ||||
|     } while (((ret[i] >= 91) && (ret[i] <= 96)) || | ||||
|              ((ret[i] >= 58) && (ret[i] <= 64))); | ||||
|   } | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) | ||||
|  | ||||
| auto get_environment_variable(std::string_view variable) -> std::string { | ||||
|   static std::mutex mtx{}; | ||||
|   mutex_lock lock{mtx}; | ||||
|  | ||||
|   const auto *val = std::getenv(std::string{variable}.c_str()); | ||||
|   return std::string{val == nullptr ? "" : val}; | ||||
| } | ||||
|  | ||||
| auto get_environment_variable(std::wstring_view variable) -> std::wstring { | ||||
|   return utils::string::from_utf8( | ||||
|       get_environment_variable(utils::string::to_utf8(variable))); | ||||
| } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_BOOST) | ||||
| auto get_next_available_port(std::uint16_t first_port, | ||||
|                              std::uint16_t &available_port) -> bool { | ||||
|   using namespace boost::asio; | ||||
|   using ip::tcp; | ||||
|  | ||||
|   boost::system::error_code error_code{}; | ||||
|   while (first_port != 0U) { | ||||
|     io_service svc{}; | ||||
|     tcp::acceptor acceptor(svc); | ||||
|     acceptor.open(tcp::v4(), error_code) || | ||||
|         acceptor.bind({tcp::v4(), first_port}, error_code); | ||||
|     if (not error_code) { | ||||
|       break; | ||||
|     } | ||||
|  | ||||
|     ++first_port; | ||||
|   } | ||||
|  | ||||
|   if (not error_code) { | ||||
|     available_port = first_port; | ||||
|   } | ||||
|  | ||||
|   return not error_code; | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_BOOST) | ||||
|  | ||||
| auto resolve_variables(std::string str) -> std::string { | ||||
|   return utils::path::absolute(str); | ||||
| } | ||||
|  | ||||
| auto resolve_variables(std::wstring_view str) -> std::wstring { | ||||
|   return utils::string::from_utf8( | ||||
|       resolve_variables(utils::string::to_utf8(str))); | ||||
| } | ||||
| } // namespace repertory::utils | ||||
							
								
								
									
										101
									
								
								support/3rd_party/src/utils/encryption.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										101
									
								
								support/3rd_party/src/utils/encryption.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,101 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "utils/encryption.hpp" | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) | ||||
| namespace { | ||||
| using nonce_t = | ||||
|     std::array<unsigned char, crypto_aead_xchacha20poly1305_ietf_NPUBBYTES>; | ||||
|  | ||||
| static constexpr const auto nonce_size{sizeof(nonce_t)}; | ||||
|  | ||||
| [[nodiscard]] static auto create_hash_256(std::string_view data) | ||||
|     -> repertory::utils::encryption::hash_256_t { | ||||
|   repertory::utils::encryption::hash_256_t hash{}; | ||||
|  | ||||
|   crypto_generichash_blake2b_state state{}; | ||||
|   crypto_generichash_blake2b_init(&state, nullptr, 0U, hash.size()); | ||||
|   crypto_generichash_blake2b_update( | ||||
|       &state, reinterpret_cast<const unsigned char *>(data.data()), | ||||
|       data.size()); | ||||
|   crypto_generichash_blake2b_final(&state, hash.data(), hash.size()); | ||||
|  | ||||
|   return hash; | ||||
| } | ||||
| } // namespace | ||||
|  | ||||
| namespace repertory::utils::encryption { | ||||
| #if defined(PROJECT_ENABLE_BOOST) | ||||
| auto decrypt_data(std::string_view data, std::string_view password, | ||||
|                   std::optional<hash_256_func_t> hasher) -> data_buffer { | ||||
|   auto key = | ||||
|       hasher.has_value() ? (*hasher)(password) : create_hash_256(password); | ||||
|  | ||||
|   data_buffer buf{}; | ||||
|   if (not decrypt_data(key, | ||||
|                        reinterpret_cast<const unsigned char *>(data.data()), | ||||
|                        data.size(), buf)) { | ||||
|     throw std::runtime_error("decryption failed"); | ||||
|   } | ||||
|  | ||||
|   return buf; | ||||
| } | ||||
|  | ||||
| auto encrypt_data(std::string_view data, std::string_view password, | ||||
|                   std::optional<hash_256_func_t> hasher) -> data_buffer { | ||||
|   auto key = | ||||
|       hasher.has_value() ? (*hasher)(password) : create_hash_256(password); | ||||
|  | ||||
|   data_buffer buf{}; | ||||
|   encrypt_data(key, reinterpret_cast<const unsigned char *>(data.data()), | ||||
|                data.size(), buf); | ||||
|  | ||||
|   return buf; | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_BOOST) | ||||
|  | ||||
| auto generate_key(std::string_view encryption_token) -> key_type { | ||||
|   crypto_hash_sha256_state state{}; | ||||
|   auto res = crypto_hash_sha256_init(&state); | ||||
|   if (res != 0) { | ||||
|     throw std::runtime_error("failed to initialize sha256|" + | ||||
|                              std::to_string(res)); | ||||
|   } | ||||
|   res = crypto_hash_sha256_update( | ||||
|       &state, reinterpret_cast<const unsigned char *>(encryption_token.data()), | ||||
|       encryption_token.size()); | ||||
|   if (res != 0) { | ||||
|     throw std::runtime_error("failed to update sha256|" + std::to_string(res)); | ||||
|   } | ||||
|  | ||||
|   key_type ret{}; | ||||
|   res = crypto_hash_sha256_final(&state, ret.data()); | ||||
|   if (res != 0) { | ||||
|     throw std::runtime_error("failed to finalize sha256|" + | ||||
|                              std::to_string(res)); | ||||
|   } | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
| } // namespace repertory::utils::encryption | ||||
|  | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) | ||||
							
								
								
									
										71
									
								
								support/3rd_party/src/utils/error.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										71
									
								
								support/3rd_party/src/utils/error.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,71 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "utils/error.hpp" | ||||
|  | ||||
| namespace { | ||||
| struct default_exception_handler final | ||||
|     : repertory::utils::error::i_exception_handler { | ||||
|   void handle_exception(std::string_view function_name) const override { | ||||
|     std::cerr << function_name << "|exception|unknown" << std::endl; | ||||
|   } | ||||
|  | ||||
|   void handle_exception(std::string_view function_name, | ||||
|                         const std::exception &ex) const override { | ||||
|     std::cerr << function_name << "|exception|" | ||||
|               << (ex.what() == nullptr ? "unknown" : ex.what()) << std::endl; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| static default_exception_handler default_handler{}; | ||||
|  | ||||
| static std::atomic<repertory::utils::error::i_exception_handler *> | ||||
|     exception_handler{ | ||||
|         &default_handler, | ||||
|     }; | ||||
| } // namespace | ||||
|  | ||||
| namespace repertory::utils::error { | ||||
| void handle_exception(std::string_view function_name) { | ||||
|   i_exception_handler *handler{exception_handler}; | ||||
|   if (handler != nullptr) { | ||||
|     handler->handle_exception(function_name); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   default_handler.handle_exception(function_name); | ||||
| } | ||||
|  | ||||
| void handle_exception(std::string_view function_name, | ||||
|                       const std::exception &ex) { | ||||
|   i_exception_handler *handler{exception_handler}; | ||||
|   if (handler != nullptr) { | ||||
|     handler->handle_exception(function_name, ex); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   default_handler.handle_exception(function_name, ex); | ||||
| } | ||||
|  | ||||
| void set_exception_handler(i_exception_handler *handler) { | ||||
|   exception_handler = handler; | ||||
| } | ||||
| } // namespace repertory::utils::error | ||||
							
								
								
									
										371
									
								
								support/3rd_party/src/utils/file.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										371
									
								
								support/3rd_party/src/utils/file.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,371 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "utils/file.hpp" | ||||
|  | ||||
| #include "utils/encryption.hpp" | ||||
| #include "utils/error.hpp" | ||||
| #include "utils/path.hpp" | ||||
| #include "utils/string.hpp" | ||||
|  | ||||
| namespace repertory::utils::file { | ||||
| auto file::open_file(std::filesystem::path path) -> file { | ||||
|   path = utils::path::absolute(path.string()); | ||||
|   if (not is_file(path.string())) { | ||||
|     throw std::runtime_error("file not found: " + path.string()); | ||||
|   } | ||||
|  | ||||
|   auto stream = std::fstream{ | ||||
|       path, | ||||
|       std::ios_base::binary | std::ios_base::in | std::ios_base::out, | ||||
|   }; | ||||
|   return { | ||||
|       std::move(stream), | ||||
|       path, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| auto file::open_or_create_file(std::filesystem::path path) -> file { | ||||
|   path = utils::path::absolute(path.string()); | ||||
|   auto stream = std::fstream{ | ||||
|       path.string().c_str(), | ||||
|       std::ios_base::binary | std::ios_base::trunc | std::ios_base::in | | ||||
|           std::ios_base::out, | ||||
|   }; | ||||
|  | ||||
|   return { | ||||
|       std::move(stream), | ||||
|       path, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| void file::close() { | ||||
|   if (stream_.is_open()) { | ||||
|     stream_.close(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| auto file::move_to(std::filesystem::path new_path) -> bool { | ||||
|   new_path = utils::path::absolute(new_path.string()); | ||||
|  | ||||
|   auto reopen{false}; | ||||
|   if (stream_.is_open()) { | ||||
|     reopen = true; | ||||
|     close(); | ||||
|   } | ||||
|  | ||||
|   std::filesystem::rename(path_, new_path, error_); | ||||
|   if (not error_) { | ||||
|     path_ = new_path; | ||||
|     if (reopen) { | ||||
|       *this = open_file(path_); | ||||
|     } | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   if (reopen) { | ||||
|     *this = open_file(path_); | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| auto file::read_(unsigned char *data, std::size_t to_read, std::uint64_t offset, | ||||
|                  std::size_t *total_read) -> bool { | ||||
|   static constexpr const std::string_view function_name{ | ||||
|       static_cast<const char *>(__FUNCTION__), | ||||
|   }; | ||||
|  | ||||
|   if (total_read != nullptr) { | ||||
|     (*total_read) = 0U; | ||||
|   } | ||||
|  | ||||
|   try { | ||||
|     stream_.seekg(static_cast<std::streamoff>(offset)); | ||||
|  | ||||
|     auto before = stream_.tellg(); | ||||
|     if (before == -1) { | ||||
|       throw std::runtime_error("failed to tellg() before read"); | ||||
|     } | ||||
|  | ||||
|     stream_.read(reinterpret_cast<char *>(data), | ||||
|                  static_cast<std::streamoff>(to_read)); | ||||
|     if (total_read != nullptr) { | ||||
|       auto after = stream_.tellg(); | ||||
|       if (after >= 0) { | ||||
|         (*total_read) = static_cast<std::size_t>(after - before); | ||||
|       } else if (after == -1 && stream_.fail()) { | ||||
|         throw std::runtime_error("failed to tellg() after read"); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } catch (const std::exception &e) { | ||||
|     utils::error::handle_exception(function_name, e); | ||||
|   } catch (...) { | ||||
|     utils::error::handle_exception(function_name); | ||||
|   } | ||||
|  | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| auto file::remove() -> bool { | ||||
|   close(); | ||||
|   return std::filesystem::remove(path_, error_); | ||||
| } | ||||
|  | ||||
| auto file::truncate(std::size_t size) -> bool { | ||||
|   auto reopen{false}; | ||||
|   if (stream_.is_open()) { | ||||
|     reopen = true; | ||||
|     close(); | ||||
|   } | ||||
|  | ||||
|   std::filesystem::resize_file(path_, size, error_); | ||||
|   if (reopen) { | ||||
|     *this = open_file(path_); | ||||
|   } | ||||
|  | ||||
|   return not error_; | ||||
| } | ||||
|  | ||||
| auto file::write_(const unsigned char *data, std::size_t to_write, | ||||
|                   std::size_t offset, std::size_t *total_written) -> bool { | ||||
|   static constexpr const std::string_view function_name{ | ||||
|       static_cast<const char *>(__FUNCTION__), | ||||
|   }; | ||||
|  | ||||
|   if (total_written != nullptr) { | ||||
|     (*total_written) = 0U; | ||||
|   } | ||||
|  | ||||
|   try { | ||||
|     stream_.seekp(static_cast<std::streamoff>(offset)); | ||||
|     auto before = stream_.tellp(); | ||||
|     if (before == -1) { | ||||
|       throw std::runtime_error("failed to tellp() before write"); | ||||
|     } | ||||
|  | ||||
|     stream_.write(reinterpret_cast<const char *>(data), | ||||
|                   static_cast<std::streamoff>(to_write)); | ||||
|  | ||||
|     auto after = stream_.tellp(); | ||||
|     if (after == -1) { | ||||
|       throw std::runtime_error("failed to tellp() after write"); | ||||
|     } | ||||
|  | ||||
|     if (total_written != nullptr) { | ||||
|       (*total_written) = static_cast<std::size_t>(after - before); | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|   } catch (const std::exception &e) { | ||||
|     utils::error::handle_exception(function_name, e); | ||||
|   } catch (...) { | ||||
|     utils::error::handle_exception(function_name); | ||||
|   } | ||||
|  | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| auto get_file_size(std::string_view path, std::uint64_t &file_size) -> bool { | ||||
|   auto abs_path = utils::path::absolute(path); | ||||
|  | ||||
|   file_size = 0U; | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|   struct _stat64 st {}; | ||||
|   if (_stat64(abs_path.c_str(), &st) != 0) { | ||||
| #else  // !defined(_WIN32) | ||||
|   struct stat st {}; | ||||
|   if (stat(abs_path.c_str(), &st) != 0) { | ||||
| #endif // defined(_WIN32) | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   if (st.st_size >= 0) { | ||||
|     file_size = static_cast<std::uint64_t>(st.st_size); | ||||
|   } | ||||
|  | ||||
|   return (st.st_size >= 0); | ||||
| } | ||||
|  | ||||
| auto get_file_size(std::wstring_view path, std::uint64_t &file_size) -> bool { | ||||
|   return get_file_size(utils::string::to_utf8(path), file_size); | ||||
| } | ||||
|  | ||||
| auto is_directory(std::string_view path) -> bool { | ||||
|   auto abs_path = utils::path::absolute(path); | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|   return ::PathIsDirectory(abs_path.c_str()) != 0; | ||||
| #else  // !defined(_WIN32) | ||||
|   struct stat st {}; | ||||
|   return (stat(abs_path.c_str(), &st) == 0 && S_ISDIR(st.st_mode)); | ||||
| #endif // defined(_WIN32) | ||||
| } | ||||
|  | ||||
| auto is_directory(std::wstring_view path) -> bool { | ||||
|   return is_directory(utils::string::to_utf8(path)); | ||||
| } | ||||
|  | ||||
| auto is_file(std::string_view path) -> bool { | ||||
|   auto abs_path = utils::path::absolute(path); | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|   return (::PathFileExists(abs_path.c_str()) && | ||||
|           not ::PathIsDirectory(abs_path.c_str())); | ||||
| #else  // !defined(_WIN32) | ||||
|   struct stat st {}; | ||||
|   return (stat(abs_path.c_str(), &st) == 0 && not S_ISDIR(st.st_mode)); | ||||
| #endif // defined(_WIN32) | ||||
| } | ||||
|  | ||||
| auto is_file(std::wstring_view path) -> bool { | ||||
|   return is_file(utils::string::to_utf8(path)); | ||||
| } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_JSON) | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
| auto read_json_file(std::string_view path, nlohmann::json &data, | ||||
|                     std::optional<std::string_view> password) -> bool { | ||||
| #else  // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
| auto read_json_file(std::string_view path, nlohmann::json &data) -> bool { | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
|   static constexpr const std::string_view function_name{ | ||||
|       static_cast<const char *>(__FUNCTION__), | ||||
|   }; | ||||
|  | ||||
|   try { | ||||
|     auto abs_path = utils::path::absolute(path); | ||||
|     if (not is_file(abs_path)) { | ||||
|       return true; | ||||
|     } | ||||
|  | ||||
|     std::ifstream file_stream{ | ||||
|         abs_path.c_str(), | ||||
|         std::ios_base::binary | std::ios::in, | ||||
|     }; | ||||
|     if (not file_stream.is_open()) { | ||||
|       throw std::runtime_error("failed to open file: " + abs_path); | ||||
|     } | ||||
|  | ||||
|     auto ret{true}; | ||||
|     try { | ||||
|       std::stringstream stream; | ||||
|       stream << file_stream.rdbuf(); | ||||
|  | ||||
|       auto json_text = stream.str(); | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
|       if (password.has_value()) { | ||||
|         auto decrypted_data = | ||||
|             utils::encryption::decrypt_data(json_text, *password); | ||||
|         json_text = {decrypted_data.begin(), decrypted_data.end()}; | ||||
|       } | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
|       if (not json_text.empty()) { | ||||
|         data = nlohmann::json::parse(json_text.c_str()); | ||||
|       } | ||||
|     } catch (const std::exception &e) { | ||||
|       utils::error::handle_exception(function_name, e); | ||||
|       ret = false; | ||||
|     } catch (...) { | ||||
|       utils::error::handle_exception(function_name); | ||||
|       ret = false; | ||||
|     } | ||||
|  | ||||
|     file_stream.close(); | ||||
|     return ret; | ||||
|   } catch (const std::exception &e) { | ||||
|     utils::error::handle_exception(function_name, e); | ||||
|   } catch (...) { | ||||
|     utils::error::handle_exception(function_name); | ||||
|   } | ||||
|  | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
| auto write_json_file(std::string_view path, const nlohmann::json &data, | ||||
|                      std::optional<std::string_view> password) -> bool { | ||||
| #else  // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
| auto write_json_file(std::string_view path, | ||||
|                      const nlohmann::json &data) -> bool { | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
|   static constexpr const std::string_view function_name{ | ||||
|       static_cast<const char *>(__FUNCTION__), | ||||
|   }; | ||||
|  | ||||
|   try { | ||||
|     auto file = file::open_or_create_file(path); | ||||
|     if (not file.truncate()) { | ||||
|       throw std::runtime_error("failed to truncate file: " + | ||||
|                                file.get_error_code().message()); | ||||
|     } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
|     if (password.has_value()) { | ||||
|       return file.write(utils::encryption::encrypt_data(data.dump(), *password), | ||||
|                         0U); | ||||
|     } | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
|  | ||||
|     return file.write(data, 0U); | ||||
|   } catch (const std::exception &e) { | ||||
|     utils::error::handle_exception(function_name, e); | ||||
|   } catch (...) { | ||||
|     utils::error::handle_exception(function_name); | ||||
|   } | ||||
|  | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
| auto read_json_file(std::wstring_view path, nlohmann::json &data, | ||||
|                     std::optional<std::wstring_view> password) -> bool { | ||||
|   if (password.has_value()) { | ||||
|     auto password_a = utils::string::to_utf8(*password); | ||||
|     return read_json_file(utils::string::to_utf8(path), data, password_a); | ||||
|   } | ||||
|  | ||||
|   return read_json_file(utils::string::to_utf8(path), data, std::nullopt); | ||||
| } | ||||
|  | ||||
| auto write_json_file(std::wstring_view path, const nlohmann::json &data, | ||||
|                      std::optional<std::wstring_view> password) -> bool { | ||||
|   if (password.has_value()) { | ||||
|     auto password_a = utils::string::to_utf8(*password); | ||||
|     return write_json_file(utils::string::to_utf8(path), data, password_a); | ||||
|   } | ||||
|  | ||||
|   return write_json_file(utils::string::to_utf8(path), data, std::nullopt); | ||||
| } | ||||
| #else  // !defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
| auto read_json_file(std::wstring_view path, nlohmann::json &data) -> bool { | ||||
|   return read_json_file(utils::string::to_utf8(path), data); | ||||
| } | ||||
|  | ||||
| auto write_json_file(std::wstring_view path, | ||||
|                      const nlohmann::json &data) -> bool { | ||||
|   return write_json_file(utils::string::to_utf8(path), data); | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
| #endif // defined(PROJECT_ENABLE_JSON) | ||||
| } // namespace repertory::utils::file | ||||
							
								
								
									
										271
									
								
								support/3rd_party/src/utils/path.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										271
									
								
								support/3rd_party/src/utils/path.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,271 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "utils/path.hpp" | ||||
|  | ||||
| #include "utils/common.hpp" | ||||
| #include "utils/error.hpp" | ||||
| #include "utils/string.hpp" | ||||
| #include "utils/unix.hpp" | ||||
|  | ||||
| namespace { | ||||
| static const std::string directory_seperator_str{ | ||||
|     repertory::utils::path::directory_seperator, | ||||
| }; | ||||
|  | ||||
| static const std::wstring directory_seperator_str_w{ | ||||
|     repertory::utils::path::directory_seperator_w, | ||||
| }; | ||||
|  | ||||
| [[nodiscard]] auto resolve(std::string path) -> std::string { | ||||
| #if defined(_WIN32) | ||||
|   if (repertory::utils::string::contains(path, "~") || | ||||
|       repertory::utils::string::contains(path, "%")) { | ||||
|     repertory::utils::string::replace(path, "~", "%USERPROFILE%"); | ||||
|  | ||||
|     std::string dest; | ||||
|     dest.resize(::ExpandEnvironmentStringsA(path.c_str(), nullptr, 0)); | ||||
|     ::ExpandEnvironmentStringsA(path.c_str(), dest.data(), | ||||
|                                 static_cast<DWORD>(dest.size())); | ||||
|     path = dest.c_str(); | ||||
|   } | ||||
| #else  // !defined (_WIN32) | ||||
|   if (repertory::utils::string::contains(path, "~")) { | ||||
|     std::string home{}; | ||||
|     repertory::utils::use_getpwuid(getuid(), [&home](struct passwd *pw) { | ||||
|       home = (pw->pw_dir ? pw->pw_dir : ""); | ||||
|       if (home.empty() || ((home == "/") && (getuid() != 0))) { | ||||
|         home = repertory::utils::path::combine("/home", {pw->pw_name}); | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     return repertory::utils::string::replace(path, "~", home); | ||||
|   } | ||||
| #endif // defined (_WIN32) | ||||
|  | ||||
|   return path; | ||||
| } | ||||
| } // namespace | ||||
|  | ||||
| namespace repertory::utils::path { | ||||
| auto absolute(std::string_view path) -> std::string { | ||||
|   std::string abs_path{path}; | ||||
| #if defined(_WIN32) | ||||
|   if (not abs_path.empty() && ::PathIsRelative(abs_path.c_str())) { | ||||
|     std::string temp; | ||||
|     temp.resize(MAX_PATH + 1); | ||||
|     abs_path = _fullpath(temp.data(), abs_path.c_str(), MAX_PATH); | ||||
|   } | ||||
| #else  // !defined(_WIN32) | ||||
|   abs_path = resolve(finalize(abs_path)); | ||||
|   if (not abs_path.empty() && (abs_path.at(0U) != '/')) { | ||||
|     auto found{false}; | ||||
|     std::string tmp{abs_path}; | ||||
|     do { | ||||
|       auto *res = realpath(tmp.c_str(), nullptr); | ||||
|       if (res) { | ||||
|         abs_path = combine(res, {abs_path.substr(tmp.size())}); | ||||
|         free(res); | ||||
|         found = true; | ||||
|       } else if (tmp == ".") { | ||||
|         found = true; | ||||
|       } else { | ||||
|         tmp = dirname(tmp.data()); | ||||
|       } | ||||
|     } while (not found); | ||||
|   } | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
|   return abs_path; | ||||
| } | ||||
|  | ||||
| auto absolute(std::wstring_view path) -> std::wstring { | ||||
|   return utils::string::from_utf8(absolute(utils::string::to_utf8(path))); | ||||
| } | ||||
|  | ||||
| auto find_program_in_path(const std::string &name_without_extension) | ||||
|     -> std::string { | ||||
|   static std::mutex mtx{}; | ||||
|   static std::unordered_map<std::string, std::string> found_items{}; | ||||
|  | ||||
|   mutex_lock lock(mtx); | ||||
|   if (found_items.contains(name_without_extension)) { | ||||
|     return found_items.at(name_without_extension); | ||||
|   } | ||||
|  | ||||
|   auto path = utils::get_environment_variable("PATH"); | ||||
|   if (path.empty()) { | ||||
|     return path; | ||||
|   } | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|   static constexpr const std::array<std::string_view, 4U> extension_list{ | ||||
|       ".bat", | ||||
|       ".cmd", | ||||
|       ".exe", | ||||
|       ".ps1", | ||||
|   }; | ||||
|   static constexpr const auto split_char = ';'; | ||||
| #else  // !defined(_WIN32) | ||||
|   static constexpr const std::array<std::string_view, 2U> extension_list{ | ||||
|       "", | ||||
|       ".sh", | ||||
|   }; | ||||
|   static constexpr const auto split_char = ':'; | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
|   const auto search_path_list = utils::string::split(path, split_char, false); | ||||
|   for (auto &&search_path : search_path_list) { | ||||
|     for (auto &&extension : extension_list) { | ||||
|       auto exec_path = combine( | ||||
|           search_path, {name_without_extension + std::string{extension}}); | ||||
|       if (std::filesystem::exists(exec_path)) { | ||||
|         found_items[name_without_extension] = exec_path; | ||||
|         return exec_path; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return ""; | ||||
| } | ||||
|  | ||||
| [[nodiscard]] auto | ||||
| find_program_in_path(std::wstring_view name_without_extension) -> std::wstring { | ||||
|   return utils::string::from_utf8( | ||||
|       find_program_in_path(utils::string::to_utf8(name_without_extension))); | ||||
| } | ||||
|  | ||||
| auto get_parent_directory(std::string_view path) -> std::string { | ||||
|   auto ret = std::filesystem::path{path}.parent_path().string(); | ||||
| #if !defined(_WIN32) | ||||
|   if (ret == ".") { | ||||
|     ret = "/"; | ||||
|   } | ||||
| #endif // !defined(_WIN32) | ||||
|  | ||||
|   return absolute(ret); | ||||
| } | ||||
|  | ||||
| auto get_parent_directory(std::wstring_view path) -> std::wstring { | ||||
|   return utils::string::from_utf8( | ||||
|       get_parent_directory(utils::string::to_utf8(path))); | ||||
| } | ||||
|  | ||||
| auto is_trash_directory(std::string_view path) -> bool { | ||||
|   auto trash_path = utils::string::to_lower(absolute(path)); | ||||
|   return utils::string::begins_with(trash_path, | ||||
|                                     directory_seperator_str + ".trash-") || | ||||
|          utils::string::begins_with(trash_path, | ||||
|                                     directory_seperator_str + ".trashes") || | ||||
|          utils::string::begins_with(trash_path, | ||||
|                                     directory_seperator_str + "$recycle.bin"); | ||||
| } | ||||
|  | ||||
| auto is_trash_directory(std::wstring_view path) -> bool { | ||||
|   return is_trash_directory(utils::string::to_utf8(path)); | ||||
| } | ||||
|  | ||||
| auto make_file_uri(std::string_view path) -> std::string { | ||||
|   auto abs_path = absolute(path); | ||||
| #if defined(_WIN32) | ||||
|   utils::string::replace(abs_path, '\\', '/'); | ||||
|   abs_path = '/' + abs_path; | ||||
| #endif // defined(_WIN32) | ||||
|   return "file://" + abs_path; | ||||
| } | ||||
|  | ||||
| auto make_file_uri(std::wstring_view path) -> std::wstring { | ||||
|   return utils::string::from_utf8(make_file_uri(utils::string::to_utf8(path))); | ||||
| } | ||||
|  | ||||
| auto remove_file_name(std::string_view path) -> std::string { | ||||
|   auto abs_path = absolute(path); | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|   ::PathRemoveFileSpec(abs_path.data()); | ||||
|   abs_path = abs_path.c_str(); | ||||
| #else  // !defined(_WIN32) | ||||
|   if (abs_path != "/") { | ||||
|     auto idx{abs_path.size() - 1U}; | ||||
|     while ((idx != 0U) && (abs_path.at(idx) != '/')) { | ||||
|       idx--; | ||||
|     } | ||||
|  | ||||
|     abs_path = (idx > 0U) ? absolute(abs_path.substr(0U, idx)) : "/"; | ||||
|   } | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
|   return abs_path; | ||||
| } | ||||
|  | ||||
| auto strip_to_file_name(std::string path) -> std::string { | ||||
| #if defined(_WIN32) | ||||
|   return ::PathFindFileName(path.c_str()); | ||||
| #else  // !defined(_WIN32) | ||||
|   return utils::string::contains(path, "/") ? basename(path.data()) : path; | ||||
| #endif // defined(_WIN32) | ||||
| } | ||||
|  | ||||
| auto strip_to_file_name(std::wstring path) -> std::wstring { | ||||
|   return utils::string::from_utf8( | ||||
|       strip_to_file_name(utils::string::to_utf8(path))); | ||||
| } | ||||
|  | ||||
| auto unmake_file_uri(std::string_view uri) -> std::string { | ||||
|   static constexpr const std::array<std::string_view, 23U> escape_characters = { | ||||
|       { | ||||
|           " ", "<", ">", "#", "%", "+", "{", "}", "|", "\\", "^", "~", | ||||
|           "[", "]", "`", ";", "/", "?", ":", "@", "=", "&",  "$", | ||||
|       }}; | ||||
|   static constexpr const std::array<std::string_view, 23U> | ||||
|       escape_sequences_lower = {{ | ||||
|           "%20", "%3c", "%3e", "%23", "%25", "%2b", "%7b", "%7d", | ||||
|           "%7c", "%5c", "%5e", "%7e", "%5b", "%5d", "%60", "%3b", | ||||
|           "%2f", "%3f", "%3a", "%40", "%3d", "%26", "%24", | ||||
|       }}; | ||||
|   static constexpr const std::array<std::string_view, 23U> | ||||
|       escape_sequences_upper = {{ | ||||
|           "%20", "%3C", "%3E", "%23", "%25", "%2B", "%7B", "%7D", | ||||
|           "%7C", "%5C", "%5E", "%7E", "%5B", "%5D", "%60", "%3B", | ||||
|           "%2F", "%3F", "%3A", "%40", "%3D", "%26", "%24", | ||||
|       }}; | ||||
|  | ||||
|   std::string ret_uri{uri}; | ||||
| #if defined(_WIN32) | ||||
|   ret_uri = ret_uri.substr(8U); | ||||
| #else | ||||
|   ret_uri = ret_uri.substr(7U); | ||||
| #endif | ||||
|  | ||||
|   for (std::size_t idx = 0U; idx < escape_characters.size(); idx++) { | ||||
|     utils::string::replace(ret_uri, escape_sequences_lower.at(idx), | ||||
|                            escape_characters.at(idx)); | ||||
|     utils::string::replace(ret_uri, escape_sequences_upper.at(idx), | ||||
|                            escape_characters.at(idx)); | ||||
|   } | ||||
|  | ||||
|   return absolute(ret_uri); | ||||
| } | ||||
|  | ||||
| auto unmake_file_uri(std::wstring_view uri) -> std::wstring { | ||||
|   return utils::string::from_utf8(unmake_file_uri(utils::string::to_utf8(uri))); | ||||
| } | ||||
| } // namespace repertory::utils::path | ||||
							
								
								
									
										138
									
								
								support/3rd_party/src/utils/string.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										138
									
								
								support/3rd_party/src/utils/string.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,138 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "utils/string.hpp" | ||||
|  | ||||
| namespace repertory::utils::string { | ||||
| auto from_bool(bool val) -> std::string { | ||||
|   return std::to_string(static_cast<int>(val)); | ||||
| } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_BOOST) | ||||
| auto from_dynamic_bitset(const boost::dynamic_bitset<> &bitset) -> std::string { | ||||
|   std::stringstream stream; | ||||
|   boost::archive::text_oarchive archive(stream); | ||||
|   archive << bitset; | ||||
|   return stream.str(); | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_BOOST) | ||||
|  | ||||
| auto from_utf8(std::string_view str) -> std::wstring { | ||||
|   return str.empty() | ||||
|              ? L"" | ||||
|              : std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>() | ||||
|                    .from_bytes(std::string{str}); | ||||
| } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_SFML) | ||||
| auto replace_sf(sf::String &src, const sf::String &find, const sf::String &with, | ||||
|                 std::size_t start_pos) -> sf::String & { | ||||
|   if (not src.isEmpty() && (start_pos < src.getSize())) { | ||||
|     while ((start_pos = src.find(find, start_pos)) != std::string::npos) { | ||||
|       src.replace(start_pos, find.getSize(), with); | ||||
|       start_pos += with.getSize(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return src; | ||||
| } | ||||
|  | ||||
| auto split_sf(sf::String str, wchar_t delim, | ||||
|               bool should_trim) -> std::vector<sf::String> { | ||||
|   auto result = std::views::split(str.toWideString(), delim); | ||||
|  | ||||
|   std::vector<sf::String> ret{}; | ||||
|   for (auto &&word : result) { | ||||
|     auto val = std::wstring{word.begin(), word.end()}; | ||||
|     if (should_trim) { | ||||
|       trim(val); | ||||
|     } | ||||
|     ret.emplace_back(val); | ||||
|   } | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_SFML) | ||||
|  | ||||
| auto to_bool(std::string val) -> bool { | ||||
|   auto ret = false; | ||||
|  | ||||
|   trim(val); | ||||
|   if (is_numeric(val)) { | ||||
|     if (contains(val, ".")) { | ||||
|       ret = (to_double(val) != 0.0); | ||||
|     } else { | ||||
|       std::istringstream(val) >> ret; | ||||
|     } | ||||
|   } else { | ||||
|     std::istringstream(to_lower(val)) >> std::boolalpha >> ret; | ||||
|   } | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| auto to_double(const std::string &str) -> double { return std::stod(str); } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_BOOST) | ||||
| auto to_dynamic_bitset(const std::string &val) -> boost::dynamic_bitset<> { | ||||
|   std::stringstream stream(val); | ||||
|   boost::dynamic_bitset<> bitset; | ||||
|   boost::archive::text_iarchive archive(stream); | ||||
|   archive >> bitset; | ||||
|   return bitset; | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_BOOST) | ||||
|  | ||||
| auto to_int32(const std::string &val) -> std::int32_t { return std::stoi(val); } | ||||
|  | ||||
| auto to_int64(const std::string &val) -> std::int64_t { | ||||
|   return std::stoll(val); | ||||
| } | ||||
|  | ||||
| auto to_size_t(const std::string &val) -> std::size_t { | ||||
|   return static_cast<std::size_t>(std::stoull(val)); | ||||
| } | ||||
|  | ||||
| auto to_uint8(const std::string &val) -> std::uint8_t { | ||||
|   return static_cast<std::uint8_t>(std::stoul(val)); | ||||
| } | ||||
|  | ||||
| auto to_uint16(const std::string &val) -> std::uint16_t { | ||||
|   return static_cast<std::uint16_t>(std::stoul(val)); | ||||
| } | ||||
|  | ||||
| auto to_uint32(const std::string &val) -> std::uint32_t { | ||||
|   return static_cast<std::uint32_t>(std::stoul(val)); | ||||
| } | ||||
|  | ||||
| auto to_uint64(const std::string &val) -> std::uint64_t { | ||||
|   return std::stoull(val); | ||||
| } | ||||
|  | ||||
| auto to_utf8(std::string_view str) -> std::string { return std::string{str}; } | ||||
|  | ||||
| auto to_utf8(std::wstring_view str) -> std::string { | ||||
|   return str.empty() | ||||
|              ? "" | ||||
|              : std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t>() | ||||
|                    .to_bytes(std::wstring{str}); | ||||
| } | ||||
| } // namespace repertory::utils::string | ||||
							
								
								
									
										107
									
								
								support/3rd_party/src/utils/time.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										107
									
								
								support/3rd_party/src/utils/time.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,107 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "utils/time.hpp" | ||||
|  | ||||
| namespace repertory::utils::time { | ||||
| #if defined(_WIN32) | ||||
| // https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/ | ||||
| auto filetime_to_unix_time(const FILETIME &file_time) -> std::uint64_t { | ||||
|   LARGE_INTEGER date{}; | ||||
|   date.HighPart = static_cast<LONG>(file_time.dwHighDateTime); | ||||
|   date.LowPart = file_time.dwLowDateTime; | ||||
|   date.QuadPart -= 116444736000000000LL; | ||||
|  | ||||
|   return static_cast<std::uint64_t>(date.QuadPart) * 100ULL; | ||||
| } | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
| auto get_file_time_now() -> std::uint64_t { | ||||
| #if defined(_WIN32) | ||||
|   SYSTEMTIME sys_time{}; | ||||
|   ::GetSystemTime(&sys_time); | ||||
|  | ||||
|   FILETIME file_time{}; | ||||
|   ::SystemTimeToFileTime(&sys_time, &file_time); | ||||
|   return static_cast<std::uint64_t>( | ||||
|       (reinterpret_cast<LARGE_INTEGER *>(&file_time))->QuadPart); | ||||
| #else  // !defined(_WIN32) | ||||
|   return get_time_now(); | ||||
| #endif // defined(_WIN32) | ||||
| } | ||||
|  | ||||
| void get_local_time_now(struct tm &local_time) { | ||||
|   std::memset(&local_time, 0, sizeof(local_time)); | ||||
|  | ||||
|   const auto now = | ||||
|       std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); | ||||
| #if defined(_WIN32) | ||||
|   localtime_s(&local_time, &now); | ||||
| #else  // !defined(_WIN32) | ||||
|   localtime_r(&now, &local_time); | ||||
| #endif // defined(_WIN32) | ||||
| } | ||||
|  | ||||
| auto get_time_now() -> std::uint64_t { | ||||
| #if defined(_WIN32) | ||||
|   return static_cast<std::uint64_t>( | ||||
|       std::chrono::system_clock::to_time_t(std::chrono::system_clock::now())); | ||||
| #endif // defined(_WIN32) | ||||
|  | ||||
| #if defined(__APPLE__) | ||||
|   return std::chrono::nanoseconds( | ||||
|              std::chrono::system_clock::now().time_since_epoch()) | ||||
|       .count(); | ||||
| #else  // !defined(__APPLE__) | ||||
|   return static_cast<std::uint64_t>( | ||||
|       std::chrono::nanoseconds( | ||||
|           std::chrono::high_resolution_clock::now().time_since_epoch()) | ||||
|           .count()); | ||||
| #endif // defined(__APPLE__) | ||||
| } | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| // https://stackoverflow.com/questions/321849/strptime-equivalent-on-windows | ||||
| auto strptime(const char *s, const char *f, struct tm *tm) -> const char * { | ||||
|   std::istringstream input{s}; | ||||
|   input.imbue(std::locale(setlocale(LC_ALL, nullptr))); | ||||
|   input >> std::get_time(tm, f); | ||||
|   if (input.fail()) { | ||||
|     return nullptr; | ||||
|   } | ||||
|  | ||||
|   return reinterpret_cast<const char *>(s + input.tellg()); | ||||
| } | ||||
|  | ||||
| auto time64_to_unix_time(const __time64_t &time) -> std::uint64_t { | ||||
|   return static_cast<std::uint64_t>(time * NANOS_PER_SECOND); | ||||
| } | ||||
|  | ||||
| // https://www.frenk.com/2009/12/convert-filetime-to-unix-timestamp/ | ||||
| auto unix_time_to_filetime(std::uint64_t unix_time) -> FILETIME { | ||||
|   const auto win_time = (unix_time / 100ULL) + 116444736000000000ULL; | ||||
|   FILETIME file_time{}; | ||||
|   file_time.dwHighDateTime = static_cast<DWORD>(win_time >> 32U); | ||||
|   file_time.dwLowDateTime = win_time & 0xFFFFFFFF; | ||||
|   return file_time; | ||||
| } | ||||
| #endif // defined(_WIN32) | ||||
| } // namespace repertory::utils::time | ||||
							
								
								
									
										76
									
								
								support/3rd_party/src/utils/unix.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										76
									
								
								support/3rd_party/src/utils/unix.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,76 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #if !defined(_WIN32) | ||||
|  | ||||
| #include "utils/unix.hpp" | ||||
| #include "utils/collection.hpp" | ||||
|  | ||||
| namespace repertory::utils { | ||||
| #if !defined(__APPLE__) | ||||
| auto convert_to_uint64(const pthread_t &thread) -> std::uint64_t { | ||||
|   return static_cast<std::uint64_t>(thread); | ||||
| } | ||||
| #endif // !defined(__APPLE__) | ||||
|  | ||||
| auto get_last_error_code() -> int { return errno; } | ||||
|  | ||||
| auto get_thread_id() -> std::uint64_t { | ||||
|   return convert_to_uint64(pthread_self()); | ||||
| } | ||||
|  | ||||
| auto is_uid_member_of_group(const uid_t &uid, const gid_t &gid) -> bool { | ||||
|   std::vector<gid_t> groups{}; | ||||
|   use_getpwuid(uid, [&groups](struct passwd *pass) { | ||||
|     int group_count{}; | ||||
|     if (getgrouplist(pass->pw_name, pass->pw_gid, nullptr, &group_count) < 0) { | ||||
|       groups.resize(static_cast<std::size_t>(group_count)); | ||||
| #if defined(__APPLE__) | ||||
|       getgrouplist(pass->pw_name, pass->pw_gid, | ||||
|                    reinterpret_cast<int *>(groups.data()), &group_count); | ||||
| #else  // !defined(__APPLE__) | ||||
|       getgrouplist(pass->pw_name, pass->pw_gid, groups.data(), &group_count); | ||||
| #endif // defined(__APPLE__) | ||||
|     } | ||||
|   }); | ||||
|  | ||||
|   return collection::includes(groups, gid); | ||||
| } | ||||
|  | ||||
| auto use_getpwuid(uid_t uid, passwd_callback_t callback) -> result { | ||||
|   static constexpr const std::string_view function_name{ | ||||
|       static_cast<const char *>(__FUNCTION__), | ||||
|   }; | ||||
|  | ||||
|   static std::mutex mtx{}; | ||||
|   mutex_lock lock{mtx}; | ||||
|  | ||||
|   auto *temp_pw = getpwuid(uid); | ||||
|   if (temp_pw == nullptr) { | ||||
|     return {function_name, false, "'getpwuid' returned nullptr"}; | ||||
|   } | ||||
|  | ||||
|   callback(temp_pw); | ||||
|   return {function_name}; | ||||
| } | ||||
| } // namespace repertory::utils | ||||
|  | ||||
| #endif // !defined(_WIN32) | ||||
							
								
								
									
										105
									
								
								support/3rd_party/src/utils/windows.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										105
									
								
								support/3rd_party/src/utils/windows.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,105 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #if defined(_WIN32) | ||||
| #include "utils/windows.hpp" | ||||
|  | ||||
| #include "utils/com_init_wrapper.hpp" | ||||
| #include "utils/string.hpp" | ||||
|  | ||||
| namespace repertory::utils { | ||||
| auto get_last_error_code() -> DWORD { return ::GetLastError(); } | ||||
|  | ||||
| auto get_local_app_data_directory() -> const std::string & { | ||||
|   static std::string app_data = ([]() -> std::string { | ||||
|     com_init_wrapper cw; | ||||
|     PWSTR local_app_data{}; | ||||
|     if (SUCCEEDED(::SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, | ||||
|                                          &local_app_data))) { | ||||
|       auto ret = utils::string::to_utf8(local_app_data); | ||||
|       ::CoTaskMemFree(local_app_data); | ||||
|       return ret; | ||||
|     } | ||||
|  | ||||
|     throw std::runtime_error("unable to detect local application data folder"); | ||||
|   })(); | ||||
|  | ||||
|   return app_data; | ||||
| } | ||||
|  | ||||
| auto get_thread_id() -> std::uint64_t { | ||||
|   return static_cast<std::uint64_t>(::GetCurrentThreadId()); | ||||
| } | ||||
|  | ||||
| auto is_process_elevated() -> bool { | ||||
|   auto ret{false}; | ||||
|   HANDLE token{INVALID_HANDLE_VALUE}; | ||||
|   if (::OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { | ||||
|     TOKEN_ELEVATION te{}; | ||||
|     DWORD sz = sizeof(te); | ||||
|     if (::GetTokenInformation(token, TokenElevation, &te, sizeof(te), &sz)) { | ||||
|       ret = (te.TokenIsElevated != 0); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (token != INVALID_HANDLE_VALUE) { | ||||
|     ::CloseHandle(token); | ||||
|   } | ||||
|  | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| auto run_process_elevated(std::vector<const char *> args) -> int { | ||||
|   std::cout << "Elevating Process" << std::endl; | ||||
|   std::string parameters{"-hidden"}; | ||||
|   for (std::size_t idx = 1U; idx < args.size(); idx++) { | ||||
|     parameters += | ||||
|         (parameters.empty() ? args.at(idx) : " " + std::string(args.at(idx))); | ||||
|   } | ||||
|  | ||||
|   std::string full_path; | ||||
|   full_path.resize(MAX_PATH + 1); | ||||
|  | ||||
|   if (::GetModuleFileName(nullptr, full_path.data(), MAX_PATH)) { | ||||
|     SHELLEXECUTEINFO sei{}; | ||||
|     sei.fMask = SEE_MASK_NOCLOSEPROCESS; | ||||
|     sei.cbSize = sizeof(sei); | ||||
|     sei.lpVerb = "runas"; | ||||
|     sei.lpFile = full_path.c_str(); | ||||
|     sei.lpParameters = parameters.c_str(); | ||||
|     sei.hwnd = nullptr; | ||||
|     sei.nShow = SW_NORMAL; | ||||
|     if (::ShellExecuteEx(&sei)) { | ||||
|       ::WaitForSingleObject(sei.hProcess, INFINITE); | ||||
|       DWORD exit_code{}; | ||||
|       ::GetExitCodeProcess(sei.hProcess, &exit_code); | ||||
|       ::CloseHandle(sei.hProcess); | ||||
|       return static_cast<int>(exit_code); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return static_cast<int>(::GetLastError()); | ||||
| } | ||||
|  | ||||
| void set_last_error_code(DWORD error_code) { ::SetLastError(error_code); } | ||||
| } // namespace repertory::utils | ||||
|  | ||||
| #endif // defined(_WIN32) | ||||
							
								
								
									
										67
									
								
								support/3rd_party/test/src/utils/common_test.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										67
									
								
								support/3rd_party/test/src/utils/common_test.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,67 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "gtest/gtest.h" | ||||
|  | ||||
| #include "utils/common.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| TEST(utils_common, version_equal) { | ||||
|   EXPECT_EQ(0, utils::compare_version_strings("1.0", "1.0")); | ||||
|   EXPECT_EQ(0, utils::compare_version_strings("1.0.0", "1.0")); | ||||
|   EXPECT_EQ(0, utils::compare_version_strings("1.0.0.0", "1.0")); | ||||
|   EXPECT_EQ(0, utils::compare_version_strings("1.0.0.0", "1.0.0")); | ||||
| } | ||||
|  | ||||
| TEST(utils_common, version_greater) { | ||||
|   EXPECT_EQ(1, utils::compare_version_strings("1.0.1", "1.0")); | ||||
|   EXPECT_EQ(1, utils::compare_version_strings("1.0.1", "1.0.0")); | ||||
|   EXPECT_EQ(1, utils::compare_version_strings("1.0.1", "1.0.0.0")); | ||||
|   EXPECT_EQ(1, utils::compare_version_strings("1.0.1.0", "1.0")); | ||||
|   EXPECT_EQ(1, utils::compare_version_strings("1.0.1.0", "1.0.0")); | ||||
|   EXPECT_EQ(1, utils::compare_version_strings("1.0.1.0", "1.0.0.0")); | ||||
|   EXPECT_EQ(1, utils::compare_version_strings("1.0", "0.9.9")); | ||||
|   EXPECT_EQ(1, utils::compare_version_strings("1.0.1", "0.9.9")); | ||||
|   EXPECT_EQ(1, utils::compare_version_strings("1.0.1.0", "0.9.9")); | ||||
| } | ||||
|  | ||||
| TEST(utils_common, version_less) { | ||||
|   EXPECT_EQ(-1, utils::compare_version_strings("0.9.9", "1.0")); | ||||
|   EXPECT_EQ(-1, utils::compare_version_strings("0.9.9", "1.0.1")); | ||||
|   EXPECT_EQ(-1, utils::compare_version_strings("0.9.9", "1.0.1.0")); | ||||
|   EXPECT_EQ(-1, utils::compare_version_strings("1.0", "1.0.1")); | ||||
|   EXPECT_EQ(-1, utils::compare_version_strings("1.0", "1.0.1.0")); | ||||
|   EXPECT_EQ(-1, utils::compare_version_strings("1.0.0", "1.0.1")); | ||||
|   EXPECT_EQ(-1, utils::compare_version_strings("1.0.0", "1.0.1.0")); | ||||
|   EXPECT_EQ(-1, utils::compare_version_strings("1.0.0.0", "1.0.1")); | ||||
|   EXPECT_EQ(-1, utils::compare_version_strings("1.0.0.0", "1.0.1.0")); | ||||
| } | ||||
|  | ||||
| #if defined(PROJECT_ENABLE_STDUUID) | ||||
| TEST(utils_common, create_uuid_string) { | ||||
|   const auto uuid1 = utils::create_uuid_string(); | ||||
|   const auto uuid2 = utils::create_uuid_string(); | ||||
|   ASSERT_EQ(36U, uuid1.size()); | ||||
|   ASSERT_EQ(36U, uuid2.size()); | ||||
|   ASSERT_STRNE(uuid1.c_str(), uuid2.c_str()); | ||||
| } | ||||
| #endif // defined(PROJECT_ENABLE_STDUUID) | ||||
| } // namespace repertory | ||||
							
								
								
									
										139
									
								
								support/3rd_party/test/src/utils/encryption_test.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										139
									
								
								support/3rd_party/test/src/utils/encryption_test.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,139 +0,0 @@ | ||||
| /* | ||||
|  Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  of this software and associated documentation files (the "Software"), to deal | ||||
|  in the Software without restriction, including without limitation the rights to | ||||
|  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||||
|  of the Software, and to permit persons to whom the Software is furnished to do | ||||
|  so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|  copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  SOFTWARE. | ||||
| */ | ||||
| #if defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
|  | ||||
| #include "gtest/gtest.h" | ||||
|  | ||||
| #include "utils/collection.hpp" | ||||
| #include "utils/encryption.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| static const std::string buffer = "cow moose dog chicken"; | ||||
| static const std::string token = "moose"; | ||||
|  | ||||
| static void test_encrypted_result(const data_buffer &result) { | ||||
|   EXPECT_EQ(buffer.size() + utils::encryption::encryption_header_size, | ||||
|             result.size()); | ||||
|   std::string data; | ||||
|   EXPECT_TRUE(utils::encryption::decrypt_data(token, result, data)); | ||||
|   EXPECT_EQ(buffer.size(), data.size()); | ||||
|   EXPECT_STREQ(buffer.c_str(), data.c_str()); | ||||
| } | ||||
|  | ||||
| TEST(utils_encryption, generate_key) { | ||||
|   const auto key = utils::encryption::generate_key(token); | ||||
|   const auto str = utils::collection::to_hex_string(key); | ||||
|   EXPECT_STREQ( | ||||
|       "182072537ada59e4d6b18034a80302ebae935f66adbdf0f271d3d36309c2d481", | ||||
|       str.c_str()); | ||||
| } | ||||
|  | ||||
| TEST(utils_encryption, encrypt_data_buffer) { | ||||
|   data_buffer result; | ||||
|   utils::encryption::encrypt_data(token, buffer, result); | ||||
|   test_encrypted_result(result); | ||||
| } | ||||
|  | ||||
| TEST(utils_encryption, encrypt_data_buffer_with_key) { | ||||
|   const auto key = utils::encryption::generate_key(token); | ||||
|   data_buffer result; | ||||
|   utils::encryption::encrypt_data(key, buffer, result); | ||||
|   test_encrypted_result(result); | ||||
| } | ||||
|  | ||||
| TEST(utils_encryption, encrypt_data_pointer) { | ||||
|   data_buffer result; | ||||
|   utils::encryption::encrypt_data( | ||||
|       token, reinterpret_cast<const unsigned char *>(buffer.data()), | ||||
|       buffer.size(), result); | ||||
|   test_encrypted_result(result); | ||||
| } | ||||
|  | ||||
| TEST(utils_encryption, encrypt_data_pointer_with_key) { | ||||
|   const auto key = utils::encryption::generate_key(token); | ||||
|   data_buffer result; | ||||
|   utils::encryption::encrypt_data( | ||||
|       key, reinterpret_cast<const unsigned char *>(buffer.data()), | ||||
|       buffer.size(), result); | ||||
|   test_encrypted_result(result); | ||||
| } | ||||
|  | ||||
| TEST(utils_encryption, decrypt_data_pointer) { | ||||
|   const auto key = utils::encryption::generate_key(token); | ||||
|   data_buffer result; | ||||
|   utils::encryption::encrypt_data( | ||||
|       key, reinterpret_cast<const unsigned char *>(buffer.data()), | ||||
|       buffer.size(), result); | ||||
|  | ||||
|   std::string data; | ||||
|   EXPECT_TRUE(utils::encryption::decrypt_data(token, result.data(), | ||||
|                                               result.size(), data)); | ||||
|  | ||||
|   EXPECT_EQ(buffer.size(), data.size()); | ||||
|   EXPECT_STREQ(buffer.c_str(), data.c_str()); | ||||
| } | ||||
|  | ||||
| TEST(utils_encryption, decrypt_data_buffer_with_key) { | ||||
|   const auto key = utils::encryption::generate_key(token); | ||||
|   data_buffer result; | ||||
|   utils::encryption::encrypt_data( | ||||
|       key, reinterpret_cast<const unsigned char *>(buffer.data()), | ||||
|       buffer.size(), result); | ||||
|  | ||||
|   std::string data; | ||||
|   EXPECT_TRUE(utils::encryption::decrypt_data(key, result, data)); | ||||
|  | ||||
|   EXPECT_EQ(buffer.size(), data.size()); | ||||
|   EXPECT_STREQ(buffer.c_str(), data.c_str()); | ||||
| } | ||||
|  | ||||
| TEST(utils_encryption, decrypt_data_pointer_with_key) { | ||||
|   const auto key = utils::encryption::generate_key(token); | ||||
|   data_buffer result; | ||||
|   utils::encryption::encrypt_data( | ||||
|       key, reinterpret_cast<const unsigned char *>(buffer.data()), | ||||
|       buffer.size(), result); | ||||
|  | ||||
|   std::string data; | ||||
|   EXPECT_TRUE( | ||||
|       utils::encryption::decrypt_data(key, result.data(), result.size(), data)); | ||||
|  | ||||
|   EXPECT_EQ(buffer.size(), data.size()); | ||||
|   EXPECT_STREQ(buffer.c_str(), data.c_str()); | ||||
| } | ||||
|  | ||||
| TEST(utils_encryption, decryption_failure) { | ||||
|   const auto key = utils::encryption::generate_key(token); | ||||
|   data_buffer result; | ||||
|   utils::encryption::encrypt_data( | ||||
|       key, reinterpret_cast<const unsigned char *>(buffer.data()), | ||||
|       buffer.size(), result); | ||||
|   result[0U] = 0U; | ||||
|   result[1U] = 1U; | ||||
|   result[2U] = 2U; | ||||
|  | ||||
|   std::string data; | ||||
|   EXPECT_FALSE(utils::encryption::decrypt_data(key, result, data)); | ||||
| } | ||||
| } // namespace repertory | ||||
|  | ||||
| #endif // defined(PROJECT_ENABLE_LIBSODIUM) && defined(PROJECT_ENABLE_BOOST) | ||||
							
								
								
									
										264
									
								
								support/3rd_party/test/src/utils/path_test.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										264
									
								
								support/3rd_party/test/src/utils/path_test.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,264 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "gtest/gtest.h" | ||||
|  | ||||
| #include "utils/common.hpp" | ||||
| #include "utils/path.hpp" | ||||
| #include "utils/string.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| TEST(utils_path, constants) { | ||||
|   EXPECT_EQ(std::string_view{"\\"}, utils::path::backslash); | ||||
|   EXPECT_EQ(std::wstring_view{L"\\"}, utils::path::backslash_w); | ||||
|   EXPECT_EQ(std::string_view{"."}, utils::path::dot); | ||||
|   EXPECT_EQ(std::wstring_view{L"."}, utils::path::dot_w); | ||||
|   EXPECT_EQ(std::string_view{"./"}, utils::path::dot_slash); | ||||
|   EXPECT_EQ(std::wstring_view{L"./"}, utils::path::dot_slash_w); | ||||
|   EXPECT_EQ(std::string_view{"/"}, utils::path::slash); | ||||
|   EXPECT_EQ(std::wstring_view{L"/"}, utils::path::slash_w); | ||||
| } | ||||
|  | ||||
| TEST(utils_path, directory_seperator) { | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_EQ(utils::path::backslash, utils::path::directory_seperator); | ||||
|   EXPECT_EQ(utils::path::backslash_w, utils::path::directory_seperator_w); | ||||
|  | ||||
|   EXPECT_EQ(utils::path::slash, utils::path::not_directory_seperator); | ||||
|   EXPECT_EQ(utils::path::slash_w, utils::path::not_directory_seperator_w); | ||||
| #else  // !defined(_WIN32) | ||||
|   EXPECT_EQ(utils::path::slash, utils::path::directory_seperator); | ||||
|   EXPECT_EQ(utils::path::slash_w, utils::path::directory_seperator_w); | ||||
|  | ||||
|   EXPECT_EQ(utils::path::backslash, utils::path::not_directory_seperator); | ||||
|   EXPECT_EQ(utils::path::backslash_w, utils::path::not_directory_seperator_w); | ||||
| #endif // defined(_WIN32) | ||||
| } | ||||
|  | ||||
| TEST(utils_path, get_directory_seperator) { | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_EQ(utils::path::backslash, | ||||
|             utils::path::get_directory_seperator<char>()); | ||||
|   EXPECT_EQ(utils::path::backslash_w, | ||||
|             utils::path::get_directory_seperator<wchar_t>()); | ||||
|  | ||||
|   EXPECT_EQ(utils::path::slash, | ||||
|             utils::path::get_not_directory_seperator<char>()); | ||||
|   EXPECT_EQ(utils::path::slash_w, | ||||
|             utils::path::get_not_directory_seperator<wchar_t>()); | ||||
| #else  // !defined(_WIN32) | ||||
|   EXPECT_EQ(utils::path::slash, utils::path::get_directory_seperator<char>()); | ||||
|   EXPECT_EQ(utils::path::slash_w, | ||||
|             utils::path::get_directory_seperator<wchar_t>()); | ||||
|  | ||||
|   EXPECT_EQ(utils::path::backslash, | ||||
|             utils::path::get_not_directory_seperator<char>()); | ||||
|   EXPECT_EQ(utils::path::backslash_w, | ||||
|             utils::path::get_not_directory_seperator<wchar_t>()); | ||||
| #endif // defined(_WIN32) | ||||
| } | ||||
|  | ||||
| TEST(utils_path, get_backslash) { | ||||
|   EXPECT_EQ(utils::path::backslash, utils::path::get_backslash<char>()); | ||||
|   EXPECT_EQ(utils::path::backslash_w, utils::path::get_backslash<wchar_t>()); | ||||
| } | ||||
|  | ||||
| TEST(utils_path, get_dot) { | ||||
|   EXPECT_EQ(utils::path::dot, utils::path::get_dot<char>()); | ||||
|   EXPECT_EQ(utils::path::dot_w, utils::path::get_dot<wchar_t>()); | ||||
| } | ||||
|  | ||||
| TEST(utils_path, get_dot_slash) { | ||||
|   EXPECT_EQ(utils::path::dot_slash, utils::path::get_dot_slash<char>()); | ||||
|   EXPECT_EQ(utils::path::dot_slash_w, utils::path::get_dot_slash<wchar_t>()); | ||||
| } | ||||
|  | ||||
| TEST(utils_path, get_slash) { | ||||
|   EXPECT_EQ(utils::path::slash, utils::path::get_slash<char>()); | ||||
|   EXPECT_EQ(utils::path::slash_w, utils::path::get_slash<wchar_t>()); | ||||
| } | ||||
|  | ||||
| TEST(utils_path, combine) { | ||||
|   auto s = utils::path::combine(R"(\test\path)", {}); | ||||
|  | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_STREQ(R"(\test\path)", s.c_str()); | ||||
| #else | ||||
|   EXPECT_STREQ("/test/path", s.c_str()); | ||||
| #endif | ||||
|  | ||||
|   s = utils::path::combine(R"(\test)", {R"(\path)"}); | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_STREQ(R"(\test\path)", s.c_str()); | ||||
| #else | ||||
|   EXPECT_STREQ("/test/path", s.c_str()); | ||||
| #endif | ||||
|  | ||||
|   s = utils::path::combine(R"(\test)", {R"(\path)", R"(\again\)"}); | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_STREQ(R"(\test\path\again)", s.c_str()); | ||||
| #else | ||||
|   EXPECT_STREQ("/test/path/again", s.c_str()); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| TEST(utils_path, format_path) { | ||||
|   std::string path{"./"}; | ||||
|   utils::path::format_path(path, utils::path::slash, utils::path::backslash); | ||||
|   EXPECT_STREQ(".", path.c_str()); | ||||
|  | ||||
|   path = "~/.test"; | ||||
|   utils::path::format_path(path, utils::path::slash, utils::path::backslash); | ||||
|   EXPECT_STREQ("~/.test", path.c_str()); | ||||
|  | ||||
|   path = "\\"; | ||||
|   utils::path::format_path(path, utils::path::slash, utils::path::backslash); | ||||
|   EXPECT_STREQ("/", path.c_str()); | ||||
|  | ||||
|   path = "\\\\"; | ||||
|   utils::path::format_path(path, utils::path::slash, utils::path::backslash); | ||||
|   EXPECT_STREQ("/", path.c_str()); | ||||
|  | ||||
|   path = "\\\\\\"; | ||||
|   utils::path::format_path(path, utils::path::slash, utils::path::backslash); | ||||
|   EXPECT_STREQ("/", path.c_str()); | ||||
|  | ||||
|   path = "\\\\\\\\"; | ||||
|   utils::path::format_path(path, utils::path::slash, utils::path::backslash); | ||||
|   EXPECT_STREQ("/", path.c_str()); | ||||
|  | ||||
|   path = "/"; | ||||
|   utils::path::format_path(path, utils::path::slash, utils::path::backslash); | ||||
|   EXPECT_STREQ("/", path.c_str()); | ||||
|   path = "//"; | ||||
|   utils::path::format_path(path, utils::path::slash, utils::path::backslash); | ||||
|   EXPECT_STREQ("/", path.c_str()); | ||||
|  | ||||
|   path = "///"; | ||||
|   utils::path::format_path(path, utils::path::slash, utils::path::backslash); | ||||
|   EXPECT_STREQ("/", path.c_str()); | ||||
|  | ||||
|   path = "////"; | ||||
|   utils::path::format_path(path, utils::path::slash, utils::path::backslash); | ||||
|   EXPECT_STREQ("/", path.c_str()); | ||||
| } | ||||
|  | ||||
| TEST(utils_path, create_api_path) { | ||||
|   auto s = utils::path::create_api_path(""); | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
|  | ||||
|   s = utils::path::create_api_path(R"(\)"); | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
|  | ||||
|   s = utils::path::create_api_path("/"); | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
|  | ||||
|   s = utils::path::create_api_path("."); | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
|  | ||||
|   s = utils::path::create_api_path("./"); | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
|  | ||||
|   s = utils::path::create_api_path(R"(\\)"); | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
|  | ||||
|   s = utils::path::create_api_path("//"); | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
|  | ||||
|   s = utils::path::create_api_path("/cow///moose/////dog/chicken"); | ||||
|   EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str()); | ||||
|  | ||||
|   s = utils::path::create_api_path("\\cow\\\\\\moose\\\\\\\\dog\\chicken/"); | ||||
|   EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str()); | ||||
|  | ||||
|   s = utils::path::create_api_path("/cow\\\\/moose\\\\/\\dog\\chicken\\"); | ||||
|   EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str()); | ||||
| } | ||||
|  | ||||
| TEST(utils_path, finalize) { | ||||
|   auto s = utils::path::finalize(""); | ||||
|   EXPECT_STREQ("", s.c_str()); | ||||
|  | ||||
|   s = utils::path::finalize(R"(\)"); | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_STREQ(R"(\)", s.c_str()); | ||||
| #else | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
| #endif | ||||
|  | ||||
|   s = utils::path::finalize("/"); | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_STREQ(R"(\)", s.c_str()); | ||||
| #else | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
| #endif | ||||
|  | ||||
|   s = utils::path::finalize(R"(\\)"); | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_STREQ(R"(\)", s.c_str()); | ||||
| #else | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
| #endif | ||||
|  | ||||
|   s = utils::path::finalize("//"); | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_STREQ(R"(\)", s.c_str()); | ||||
| #else | ||||
|   EXPECT_STREQ("/", s.c_str()); | ||||
| #endif | ||||
|  | ||||
|   s = utils::path::finalize("/cow///moose/////dog/chicken"); | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_STREQ(R"(\cow\moose\dog\chicken)", s.c_str()); | ||||
| #else | ||||
|   EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str()); | ||||
| #endif | ||||
|  | ||||
|   s = utils::path::finalize("\\cow\\\\\\moose\\\\\\\\dog\\chicken/"); | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_STREQ(R"(\cow\moose\dog\chicken)", s.c_str()); | ||||
| #else | ||||
|   EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str()); | ||||
| #endif | ||||
|  | ||||
|   s = utils::path::finalize("/cow\\\\/moose\\\\/\\dog\\chicken\\"); | ||||
| #if defined(_WIN32) | ||||
|   EXPECT_STREQ(R"(\cow\moose\dog\chicken)", s.c_str()); | ||||
| #else | ||||
|   EXPECT_STREQ("/cow/moose/dog/chicken", s.c_str()); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| TEST(utils_path, absolute) { | ||||
|   auto dir = utils::path::absolute(std::filesystem::current_path().string()); | ||||
|   auto path = utils::path::absolute("."); | ||||
|   EXPECT_STREQ(dir.c_str(), path.c_str()); | ||||
|  | ||||
|   path = utils::path::absolute("./"); | ||||
|   EXPECT_STREQ(dir.c_str(), path.c_str()); | ||||
|  | ||||
|   auto home = utils::path::absolute(utils::get_environment_variable("HOME")); | ||||
|   path = utils::path::absolute("~"); | ||||
|   EXPECT_STREQ(home.c_str(), path.c_str()); | ||||
|  | ||||
|   // path = utils::path::absolute("~/.local"); | ||||
| } | ||||
| } // namespace repertory | ||||
							
								
								
									
										139
									
								
								support/3rd_party/test/src/utils/string_test.cpp
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										139
									
								
								support/3rd_party/test/src/utils/string_test.cpp
									
									
									
									
										vendored
									
									
								
							| @@ -1,139 +0,0 @@ | ||||
| /* | ||||
|   Copyright <2018-2024> <scott.e.graves@protonmail.com> | ||||
|  | ||||
|   Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|   of this software and associated documentation files (the "Software"), to deal | ||||
|   in the Software without restriction, including without limitation the rights | ||||
|   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|   copies of the Software, and to permit persons to whom the Software is | ||||
|   furnished to do so, subject to the following conditions: | ||||
|  | ||||
|   The above copyright notice and this permission notice shall be included in all | ||||
|   copies or substantial portions of the Software. | ||||
|  | ||||
|   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|   SOFTWARE. | ||||
| */ | ||||
| #include "gtest/gtest.h" | ||||
|  | ||||
| #include "utils/string.hpp" | ||||
|  | ||||
| namespace repertory { | ||||
| TEST(utils_string, begins_with) { | ||||
|   std::string str{"moose"}; | ||||
|   EXPECT_TRUE(utils::string::begins_with(str, "m")); | ||||
|   EXPECT_TRUE(utils::string::begins_with(str, "mo")); | ||||
|   EXPECT_TRUE(utils::string::begins_with(str, "moo")); | ||||
|   EXPECT_TRUE(utils::string::begins_with(str, "moos")); | ||||
|   EXPECT_TRUE(utils::string::begins_with(str, "moose")); | ||||
|  | ||||
|   EXPECT_FALSE(utils::string::begins_with(str, "a")); | ||||
|   EXPECT_FALSE(utils::string::begins_with(str, "ma")); | ||||
|   EXPECT_FALSE(utils::string::begins_with(str, "moose1")); | ||||
|  | ||||
|   std::wstring str_w{L"moose"}; | ||||
|   EXPECT_TRUE(utils::string::begins_with(str_w, L"m")); | ||||
|   EXPECT_TRUE(utils::string::begins_with(str_w, L"mo")); | ||||
|   EXPECT_TRUE(utils::string::begins_with(str_w, L"moo")); | ||||
|   EXPECT_TRUE(utils::string::begins_with(str_w, L"moos")); | ||||
|   EXPECT_TRUE(utils::string::begins_with(str_w, L"moose")); | ||||
|  | ||||
|   EXPECT_FALSE(utils::string::begins_with(str_w, L"a")); | ||||
|   EXPECT_FALSE(utils::string::begins_with(str_w, L"ma")); | ||||
|   EXPECT_FALSE(utils::string::begins_with(str_w, L"moose1")); | ||||
| } | ||||
|  | ||||
| TEST(utils_string, contains) { | ||||
|   std::string str{R"(\\)"}; | ||||
|   EXPECT_TRUE(utils::string::contains(str, "\\")); | ||||
|   EXPECT_FALSE(utils::string::contains(str, "/")); | ||||
|  | ||||
|   std::wstring str_w{LR"(\\)"}; | ||||
|   EXPECT_TRUE(utils::string::contains(str_w, L"\\")); | ||||
|   EXPECT_FALSE(utils::string::contains(str_w, L"/")); | ||||
| } | ||||
|  | ||||
| TEST(utils_string, replace) { | ||||
|   std::string str{"moose"}; | ||||
|   utils::string::replace(str, 'o', '0'); | ||||
|   EXPECT_STREQ("m00se", str.c_str()); | ||||
|  | ||||
|   std::wstring str_w{L"moose"}; | ||||
|   utils::string::replace(str_w, 'o', '0'); | ||||
|   EXPECT_STREQ(L"m00se", str_w.c_str()); | ||||
|  | ||||
|   std::string str2{"\\\\\\"}; | ||||
|   utils::string::replace(str2, '\\', '/'); | ||||
|   EXPECT_STREQ("///", str2.c_str()); | ||||
|  | ||||
|   std::wstring str_w2{L"\\\\\\"}; | ||||
|   utils::string::replace(str_w2, '\\', '/'); | ||||
|   EXPECT_STREQ(L"///", str_w2.c_str()); | ||||
|  | ||||
|   std::string str3{"///"}; | ||||
|   utils::string::replace(str3, '/', '\\'); | ||||
|   EXPECT_STREQ("\\\\\\", str3.c_str()); | ||||
|  | ||||
|   std::wstring str_w3{L"///"}; | ||||
|   utils::string::replace(str_w3, '/', '\\'); | ||||
|   EXPECT_STREQ(L"\\\\\\", str_w3.c_str()); | ||||
|  | ||||
|   str.clear(); | ||||
|   utils::string::replace(str, '/', '\\'); | ||||
|   EXPECT_STREQ("", str.c_str()); | ||||
|  | ||||
|   str_w.clear(); | ||||
|   utils::string::replace(str_w, '/', '\\'); | ||||
|   EXPECT_STREQ(L"", str_w.c_str()); | ||||
| } | ||||
|  | ||||
| TEST(utils_string, replace_string) { | ||||
|   std::string str{"moose"}; | ||||
|   utils::string::replace(str, "o", "0"); | ||||
|   EXPECT_STREQ("m00se", str.c_str()); | ||||
|  | ||||
|   std::wstring str_w{L"moose"}; | ||||
|   utils::string::replace(str_w, L"o", L"0"); | ||||
|   EXPECT_STREQ(L"m00se", str_w.c_str()); | ||||
| } | ||||
|  | ||||
| TEST(utils_string, is_numeric) { | ||||
|   EXPECT_TRUE(utils::string::is_numeric("100")); | ||||
|   EXPECT_TRUE(utils::string::is_numeric("+100")); | ||||
|   EXPECT_TRUE(utils::string::is_numeric("-100")); | ||||
|  | ||||
|   EXPECT_TRUE(utils::string::is_numeric("100.00")); | ||||
|   EXPECT_TRUE(utils::string::is_numeric("+100.00")); | ||||
|   EXPECT_TRUE(utils::string::is_numeric("-100.00")); | ||||
|  | ||||
|   EXPECT_FALSE(utils::string::is_numeric("1.00.00")); | ||||
|   EXPECT_FALSE(utils::string::is_numeric("+1.00.00")); | ||||
|   EXPECT_FALSE(utils::string::is_numeric("-1.00.00")); | ||||
|  | ||||
|   EXPECT_FALSE(utils::string::is_numeric("a1")); | ||||
|   EXPECT_FALSE(utils::string::is_numeric("1a")); | ||||
|  | ||||
|   EXPECT_FALSE(utils::string::is_numeric("+")); | ||||
|   EXPECT_FALSE(utils::string::is_numeric("-")); | ||||
|  | ||||
|   EXPECT_FALSE(utils::string::is_numeric("")); | ||||
| } | ||||
|  | ||||
| TEST(utils_string, to_bool) { | ||||
|   EXPECT_TRUE(utils::string::to_bool("1")); | ||||
|   EXPECT_TRUE(utils::string::to_bool("-1")); | ||||
|   EXPECT_TRUE(utils::string::to_bool("0.1")); | ||||
|   EXPECT_TRUE(utils::string::to_bool("-0.1")); | ||||
|   EXPECT_TRUE(utils::string::to_bool("00000.1000000")); | ||||
|   EXPECT_TRUE(utils::string::to_bool("true")); | ||||
|  | ||||
|   EXPECT_FALSE(utils::string::to_bool("false")); | ||||
|   EXPECT_FALSE(utils::string::to_bool("0")); | ||||
|   EXPECT_FALSE(utils::string::to_bool("00000.00000")); | ||||
| } | ||||
| } // namespace repertory | ||||
		Reference in New Issue
	
	Block a user