From d1f409530db6f9b712fd672c4c3154cac7eebad1 Mon Sep 17 00:00:00 2001 From: crupest Date: Sat, 1 Jun 2024 17:09:44 +0800 Subject: HALF WORK: refactor something and implement part of subprocess. --- include/cru/common/Buffer.h | 11 +++++++++++ include/cru/common/Exception.h | 10 ++++++---- include/cru/common/Guard.h | 26 ++++++++++++++++++++++++++ include/cru/common/String.h | 3 +++ include/cru/common/StringUtil.h | 29 ++++++++++++++++------------- include/cru/common/SubProcess.h | 12 ++++++------ include/cru/common/io/Stream.h | 6 ------ include/cru/common/platform/Exception.h | 3 --- include/cru/platform/Exception.h | 3 --- 9 files changed, 68 insertions(+), 35 deletions(-) create mode 100644 include/cru/common/Guard.h (limited to 'include') 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 #include 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 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 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 + +namespace cru { +struct Guard { + using ExitFunc = std::function; + + 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 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 +#include namespace cru { using CodePoint = std::int32_t; @@ -123,18 +124,19 @@ inline std::enable_if_t, ReturnType> ExtractBits( } } // namespace details -template -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 +std::enable_if_t, 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(code_point)); + writer(static_cast(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(details::ExtractBits( (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(details::ExtractBits( (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(details::ExtractBits( (unsigned_code_point >> (6 * 3))) + 0b11110000)); @@ -170,18 +172,19 @@ bool Utf8EncodeCodePointAppend(CodePoint code_point, TStr& str) { } } -template -bool Utf16EncodeCodePointAppend(CodePoint code_point, TStr& str) { +template +std::enable_if_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(code_point)); + writer(static_cast(code_point)); return true; } else if (code_point >= 0x10000 && code_point <= 0x10FFFF) { std::uint32_t u = code_point - 0x10000; - str.push_back(static_cast( + writer(static_cast( details::ExtractBits(u >> 10) + 0xD800u)); - str.push_back(static_cast( + writer(static_cast( details::ExtractBits(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 #include #include +#include #include 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 arguments; - std::vector environments; + std::unordered_map 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 diff --git a/include/cru/platform/Exception.h b/include/cru/platform/Exception.h index d6cda815..a957c95a 100644 --- a/include/cru/platform/Exception.h +++ b/include/cru/platform/Exception.h @@ -34,9 +34,6 @@ class CRU_PLATFORM_API ReuseException : public Exception { public: using Exception::Exception; // inherit constructors - CRU_DEFAULT_COPY(ReuseException) - CRU_DEFAULT_MOVE(ReuseException) - CRU_DEFAULT_DESTRUCTOR(ReuseException) }; -- cgit v1.2.3