diff options
author | crupest <crupest@outlook.com> | 2024-06-01 17:09:44 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2024-06-08 17:01:55 +0800 |
commit | d1f409530db6f9b712fd672c4c3154cac7eebad1 (patch) | |
tree | 1e48a3e2ff14e66aac2503a74df28cca7d85d02c /include/cru/common | |
parent | ad796a167e33b54c7fa23ea21c73d57dba4fc928 (diff) | |
download | cru-d1f409530db6f9b712fd672c4c3154cac7eebad1.tar.gz cru-d1f409530db6f9b712fd672c4c3154cac7eebad1.tar.bz2 cru-d1f409530db6f9b712fd672c4c3154cac7eebad1.zip |
HALF WORK: refactor something and implement part of subprocess.
Diffstat (limited to 'include/cru/common')
-rw-r--r-- | include/cru/common/Buffer.h | 11 | ||||
-rw-r--r-- | include/cru/common/Exception.h | 10 | ||||
-rw-r--r-- | include/cru/common/Guard.h | 26 | ||||
-rw-r--r-- | include/cru/common/String.h | 3 | ||||
-rw-r--r-- | include/cru/common/StringUtil.h | 29 | ||||
-rw-r--r-- | include/cru/common/SubProcess.h | 12 | ||||
-rw-r--r-- | include/cru/common/io/Stream.h | 6 | ||||
-rw-r--r-- | include/cru/common/platform/Exception.h | 3 |
8 files changed, 68 insertions, 32 deletions
diff --git a/include/cru/common/Buffer.h b/include/cru/common/Buffer.h index 5c1f7ba3..a03b69eb 100644 --- a/include/cru/common/Buffer.h +++ b/include/cru/common/Buffer.h @@ -77,6 +77,8 @@ class Buffer final { Index PushFront(const std::byte* other, Index other_size, bool use_memmove = false); + bool PushBack(std::byte b); + /** * @brief Append data to the back of used bytes and increase used size. * @return The actual size of data saved. @@ -129,6 +131,15 @@ class Buffer final { operator std::byte*() { return GetPtr(); } operator const std::byte*() const { return GetPtr(); } + /** + * @brief Detach internal buffer and return it. + * @param size If not null, size of the buffer is written to it. + * @return The buffer pointer. May be nullptr. + * + * After detach, you are responsible to delete[] it. + */ + std::byte* Detach(Index* size = nullptr); + private: void Copy_(const Buffer& other); void Move_(Buffer&& other) noexcept; diff --git a/include/cru/common/Exception.h b/include/cru/common/Exception.h index 0aee871c..609fd2c9 100644 --- a/include/cru/common/Exception.h +++ b/include/cru/common/Exception.h @@ -1,6 +1,7 @@ #pragma once #include "String.h" +#include <exception> #include <optional> namespace cru { @@ -9,16 +10,16 @@ namespace cru { #endif class CRU_BASE_API Exception : public std::exception { public: - explicit Exception(String message = {}); - - CRU_DEFAULT_COPY(Exception) - CRU_DEFAULT_MOVE(Exception) + explicit Exception(String message = {}, + std::unique_ptr<std::exception> inner = nullptr); ~Exception() override; public: String GetMessage() const { return message_; } + std::exception* GetInner() const noexcept { return inner_.get(); } + const char* what() const noexcept override; protected: @@ -30,6 +31,7 @@ class CRU_BASE_API Exception : public std::exception { private: String message_; mutable std::string utf8_message_; + std::unique_ptr<std::exception> inner_; }; class CRU_BASE_API TextEncodeException : public Exception { diff --git a/include/cru/common/Guard.h b/include/cru/common/Guard.h new file mode 100644 index 00000000..5a9f9c5d --- /dev/null +++ b/include/cru/common/Guard.h @@ -0,0 +1,26 @@ +#pragma once + +#include <functional> + +namespace cru { +struct Guard { + using ExitFunc = std::function<void()>; + + Guard() = default; + explicit Guard(const ExitFunc& f) : on_exit(f) {} + explicit Guard(ExitFunc&& f) : on_exit(std::move(f)) {} + Guard(const Guard&) = delete; + Guard(Guard&&) = default; + Guard& operator=(const Guard&) = delete; + Guard& operator=(Guard&&) = default; + ~Guard() { + if (on_exit) { + on_exit(); + } + } + + void Drop() { on_exit = {}; } + + ExitFunc on_exit; +}; +} // namespace cru diff --git a/include/cru/common/String.h b/include/cru/common/String.h index c1ea839c..2156f060 100644 --- a/include/cru/common/String.h +++ b/include/cru/common/String.h @@ -1,6 +1,7 @@ #pragma once #include "Base.h" +#include "Buffer.h" #include "Range.h" #include "StringToNumberConverter.h" #include "StringUtil.h" @@ -241,6 +242,7 @@ class CRU_BASE_API String { String Format(T&&... args) const; std::string ToUtf8() const; + Buffer ToUtf8Buffer(bool end_zero = true) const; int Compare(const String& other) const; int CaseInsensitiveCompare(const String& other) const; @@ -374,6 +376,7 @@ class CRU_BASE_API StringView { std::vector<double> ParseToDoubleList(value_type separator = u' ') const; std::string ToUtf8() const; + Buffer ToUtf8Buffer(bool end_zero = true) const; private: const char16_t* ptr_; diff --git a/include/cru/common/StringUtil.h b/include/cru/common/StringUtil.h index 19948250..8f085283 100644 --- a/include/cru/common/StringUtil.h +++ b/include/cru/common/StringUtil.h @@ -2,6 +2,7 @@ #include "Base.h" #include <functional> +#include <type_traits> namespace cru { using CodePoint = std::int32_t; @@ -123,18 +124,19 @@ inline std::enable_if_t<std::is_unsigned_v<UInt>, ReturnType> ExtractBits( } } // namespace details -template <typename TStr> -bool Utf8EncodeCodePointAppend(CodePoint code_point, TStr& str) { - auto write_continue_byte = [&str](std::uint8_t byte6) { - str.push_back((1u << 7) + (((1u << 6) - 1) & byte6)); +template <typename CharWriter> +std::enable_if_t<std::is_invocable_v<CharWriter, char>, bool> +Utf8EncodeCodePointAppend(CodePoint code_point, CharWriter&& writer) { + auto write_continue_byte = [&writer](std::uint8_t byte6) { + writer((1u << 7) + (((1u << 6) - 1) & byte6)); }; if (code_point >= 0 && code_point <= 0x007F) { - str.push_back(static_cast<char>(code_point)); + writer(static_cast<char>(code_point)); return true; } else if (code_point >= 0x0080 && code_point <= 0x07FF) { std::uint32_t unsigned_code_point = code_point; - str.push_back( + writer( static_cast<char>(details::ExtractBits<std::uint32_t, 5, std::uint8_t>( (unsigned_code_point >> 6)) + 0b11000000)); @@ -143,7 +145,7 @@ bool Utf8EncodeCodePointAppend(CodePoint code_point, TStr& str) { return true; } else if (code_point >= 0x0800 && code_point <= 0xFFFF) { std::uint32_t unsigned_code_point = code_point; - str.push_back( + writer( static_cast<char>(details::ExtractBits<std::uint32_t, 4, std::uint8_t>( (unsigned_code_point >> (6 * 2))) + 0b11100000)); @@ -154,7 +156,7 @@ bool Utf8EncodeCodePointAppend(CodePoint code_point, TStr& str) { return true; } else if (code_point >= 0x10000 && code_point <= 0x10FFFF) { std::uint32_t unsigned_code_point = code_point; - str.push_back( + writer( static_cast<char>(details::ExtractBits<std::uint32_t, 3, std::uint8_t>( (unsigned_code_point >> (6 * 3))) + 0b11110000)); @@ -170,18 +172,19 @@ bool Utf8EncodeCodePointAppend(CodePoint code_point, TStr& str) { } } -template <typename TStr> -bool Utf16EncodeCodePointAppend(CodePoint code_point, TStr& str) { +template <typename CharWriter> +std::enable_if_t<std::is_invocable_v<CharWriter, char16_t>, bool> +Utf16EncodeCodePointAppend(CodePoint code_point, CharWriter&& writer) { if ((code_point >= 0 && code_point <= 0xD7FF) || (code_point >= 0xE000 && code_point <= 0xFFFF)) { - str.push_back(static_cast<char16_t>(code_point)); + writer(static_cast<char16_t>(code_point)); return true; } else if (code_point >= 0x10000 && code_point <= 0x10FFFF) { std::uint32_t u = code_point - 0x10000; - str.push_back(static_cast<char16_t>( + writer(static_cast<char16_t>( details::ExtractBits<std::uint32_t, 10, std::uint32_t>(u >> 10) + 0xD800u)); - str.push_back(static_cast<char16_t>( + writer(static_cast<char16_t>( details::ExtractBits<std::uint32_t, 10, std::uint32_t>(u) + 0xDC00u)); return true; } else { diff --git a/include/cru/common/SubProcess.h b/include/cru/common/SubProcess.h index 8e5e49f5..ba46d049 100644 --- a/include/cru/common/SubProcess.h +++ b/include/cru/common/SubProcess.h @@ -9,6 +9,7 @@ #include <mutex> #include <optional> #include <thread> +#include <unordered_map> #include <vector> namespace cru { @@ -33,20 +34,19 @@ enum class PlatformSubProcessStatus { class CRU_BASE_API SubProcessException : public Exception { public: - SubProcessException(String message = {}); - ~SubProcessException() override; + using Exception::Exception; }; -class CRU_BASE_API SubProcessFailedToStartException : public Exception { +class CRU_BASE_API SubProcessFailedToStartException + : public SubProcessException { public: - SubProcessFailedToStartException(String message = {}); - ~SubProcessFailedToStartException() override; + using SubProcessException::SubProcessException; }; struct PlatformSubProcessStartInfo { String program; std::vector<String> arguments; - std::vector<String> environments; + std::unordered_map<String, String> environments; }; struct PlatformSubProcessExitResult { diff --git a/include/cru/common/io/Stream.h b/include/cru/common/io/Stream.h index b8e324d1..9f9807ae 100644 --- a/include/cru/common/io/Stream.h +++ b/include/cru/common/io/Stream.h @@ -13,9 +13,6 @@ class CRU_BASE_API StreamOperationNotSupportedException : public Exception { public: explicit StreamOperationNotSupportedException(String operation); - CRU_DEFAULT_COPY(StreamOperationNotSupportedException) - CRU_DEFAULT_MOVE(StreamOperationNotSupportedException) - CRU_DEFAULT_DESTRUCTOR(StreamOperationNotSupportedException) public: @@ -34,9 +31,6 @@ class CRU_BASE_API StreamAlreadyClosedException : public Exception { public: StreamAlreadyClosedException(); - CRU_DEFAULT_COPY(StreamAlreadyClosedException) - CRU_DEFAULT_MOVE(StreamAlreadyClosedException) - CRU_DEFAULT_DESTRUCTOR(StreamAlreadyClosedException) static void Check(bool closed); diff --git a/include/cru/common/platform/Exception.h b/include/cru/common/platform/Exception.h index c1b649f3..74dd6ad4 100644 --- a/include/cru/common/platform/Exception.h +++ b/include/cru/common/platform/Exception.h @@ -7,9 +7,6 @@ class CRU_BASE_API PlatformException : public Exception { public: using Exception::Exception; // inherit constructors - CRU_DEFAULT_COPY(PlatformException) - CRU_DEFAULT_MOVE(PlatformException) - CRU_DEFAULT_DESTRUCTOR(PlatformException) }; } // namespace cru::platform |