diff options
Diffstat (limited to 'src/common')
35 files changed, 0 insertions, 3397 deletions
diff --git a/src/common/Base.cpp b/src/common/Base.cpp deleted file mode 100644 index ba4077b4..00000000 --- a/src/common/Base.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include "cru/common/Base.h" - -#include <exception> - -namespace cru { -void UnreachableCode() { std::terminate(); } -} // namespace cru diff --git a/src/common/Buffer.cpp b/src/common/Buffer.cpp deleted file mode 100644 index 7b4248c7..00000000 --- a/src/common/Buffer.cpp +++ /dev/null @@ -1,277 +0,0 @@ -#include "cru/common/Buffer.h" -#include "cru/common/Exception.h" - -#include <cstring> - -namespace cru { -namespace { -void CheckSize(Index size) { - if (size < 0) { - throw Exception(u"Size of buffer can't be smaller than 0."); - } -} -} // namespace - -Buffer::Buffer() { - ptr_ = nullptr; - size_ = used_begin_ = used_end_ = 0; -} - -Buffer::Buffer(Index size) { - CheckSize(size); - if (size == 0) { - ptr_ = nullptr; - size_ = used_begin_ = used_end_ = 0; - } else { - ptr_ = new std::byte[size]; - size_ = size; - used_begin_ = used_end_ = 0; - } - AssertValid(); -} - -Buffer::Buffer(const Buffer& other) { Copy_(other); } - -Buffer::Buffer(Buffer&& other) noexcept { Move_(std::move(other)); } - -Buffer& Buffer::operator=(const Buffer& other) { - if (this != &other) { - Delete_(); - Copy_(other); - } - return *this; -} - -Buffer& Buffer::operator=(Buffer&& other) noexcept { - if (this != &other) { - Delete_(); - Move_(std::move(other)); - } - return *this; -} - -Buffer::~Buffer() { Delete_(); } - -void Buffer::AssignBytes(Index dst_offset, std::byte* src, Index src_offset, - Index src_size, bool use_memmove) { - CheckSize(src_size); - - AssertValid(); - - (use_memmove ? std::memmove : std::memcpy)(ptr_ + dst_offset, - src + src_offset, src_size); - AssertValid(); -} - -void Buffer::ResizeBuffer(Index new_size, bool preserve_used) { - CheckSize(new_size); - - AssertValid(); - - if (new_size == 0) { - Delete_(); - ptr_ = nullptr; - size_ = used_begin_ = used_end_ = 0; - return; - } - - auto old_ptr = ptr_; - - ptr_ = new std::byte[new_size]; - size_ = new_size; - used_begin_ = std::min(new_size, used_begin_); - used_end_ = std::min(new_size, used_end_); - - if (old_ptr) { - if (preserve_used && used_begin_ < used_end_) { - std::memcpy(ptr_ + used_begin_, old_ptr + used_begin_, - used_end_ - used_begin_); - } - delete[] old_ptr; - } - - AssertValid(); -} - -Index Buffer::PushFront(const std::byte* other, Index other_size, - bool use_memmove) { - CheckSize(other_size); - - AssertValid(); - - auto copy_size = std::min(used_begin_, other_size); - - if (copy_size) { - used_begin_ -= copy_size; - (use_memmove ? std::memmove : std::memcpy)(ptr_ + used_begin_, other, - copy_size); - } - - AssertValid(); - - return copy_size; -} - -bool Buffer::PushBack(std::byte b) { - AssertValid(); - if (IsUsedReachEnd()) { - return false; - } - ptr_[used_end_] = b; - used_end_++; - AssertValid(); - return true; -} - -Index Buffer::PushBack(const std::byte* other, Index other_size, - bool use_memmove) { - CheckSize(other_size); - - AssertValid(); - - auto copy_size = std::min(size_ - used_end_, other_size); - - if (copy_size) { - (use_memmove ? std::memmove : std::memcpy)(ptr_ + used_end_, other, - copy_size); - used_end_ += copy_size; - } - - AssertValid(); - - return copy_size; -} - -void Buffer::PushBackCount(Index count) { - if (count < 0 || count > GetBackFree()) { - throw Exception(u"Count out of range in PushBackCount."); - } - used_end_ += count; -} - -Index Buffer::PopFront(Index size) { - CheckSize(size); - - AssertValid(); - - auto move = std::min(used_begin_, size); - used_begin_ -= move; - - AssertValid(); - - return move; -} - -Index Buffer::PopFront(std::byte* buffer, Index size, bool use_memmove) { - CheckSize(size); - - AssertValid(); - - auto pop_size = std::min(GetUsedSize(), size); - - if (pop_size) { - used_begin_ += pop_size; - (use_memmove ? std::memmove : std::memcpy)( - buffer, GetUsedBeginPtr() - pop_size, pop_size); - } - - AssertValid(); - - return pop_size; -} - -Index Buffer::PopEnd(Index size) { - CheckSize(size); - - AssertValid(); - - auto move = std::min(size_ - used_end_, size); - used_end_ += move; - - AssertValid(); - - return move; -} - -Index Buffer::PopEnd(std::byte* buffer, Index size, bool use_memmove) { - CheckSize(size); - - AssertValid(); - - auto pop_size = std::min(GetUsedSize(), size); - - if (pop_size) { - used_end_ -= pop_size; - (use_memmove ? std::memmove : std::memcpy)(buffer, GetUsedEndPtr(), - pop_size); - } - - AssertValid(); - - return pop_size; -} - -std::byte* Buffer::Detach(Index* size) { - AssertValid(); - - auto ptr = this->ptr_; - if (size) { - *size = this->size_; - } - this->ptr_ = nullptr; - this->size_ = this->used_begin_ = this->used_end_ = 0; - - AssertValid(); - - return ptr; -} - -void Buffer::Copy_(const Buffer& other) { - if (other.ptr_ == nullptr) { - ptr_ = nullptr; - size_ = used_begin_ = used_end_ = 0; - } else { - ptr_ = new std::byte[other.size_]; - size_ = other.size_; - used_begin_ = other.used_begin_; - used_end_ = other.used_end_; - std::memcpy(ptr_ + used_begin_, other.ptr_ + used_begin_, - used_end_ - used_begin_); - } - AssertValid(); -} - -void Buffer::Move_(Buffer&& other) noexcept { - ptr_ = other.ptr_; - size_ = other.size_; - used_begin_ = other.used_begin_; - used_end_ = other.used_end_; - other.ptr_ = nullptr; - other.size_ = other.used_begin_ = other.used_end_ = 0; - AssertValid(); -} - -void Buffer::Delete_() noexcept { - if (ptr_) { - delete[] ptr_; - } -} - -void Buffer::AssertValid() { - assert(size_ >= 0); - assert(used_begin_ >= 0); - assert(used_begin_ <= size_); - assert(used_end_ >= 0); - assert(used_end_ <= size_); - assert(used_end_ >= used_begin_); - assert((ptr_ == nullptr && size_ == 0) || (ptr_ != nullptr && size_ > 0)); -} - -void swap(Buffer& left, Buffer& right) noexcept { - using std::swap; - swap(left.ptr_, right.ptr_); - swap(left.size_, right.size_); - swap(left.used_begin_, right.used_begin_); - swap(left.used_end_, right.used_end_); -} -} // namespace cru diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt deleted file mode 100644 index 19feddba..00000000 --- a/src/common/CMakeLists.txt +++ /dev/null @@ -1,80 +0,0 @@ -add_library(CruBase - Base.cpp - Buffer.cpp - Exception.cpp - Format.cpp - PropertyTree.cpp - String.cpp - StringToNumberConverter.cpp - StringUtil.cpp - SubProcess.cpp - io/AutoReadStream.cpp - io/BufferStream.cpp - io/CFileStream.cpp - io/Stream.cpp - io/ProxyStream.cpp - io/Resource.cpp - io/MemoryStream.cpp - log/Logger.cpp - log/StdioLogTarget.cpp - platform/Exception.cpp -) -target_compile_definitions(CruBase PRIVATE CRU_BASE_EXPORT_API) -target_include_directories(CruBase PUBLIC ${CRU_INCLUDE_DIR}) -target_compile_definitions(CruBase PUBLIC $<$<CONFIG:Debug>:CRU_DEBUG>) - -if (UNIX AND NOT EMSCRIPTEN) - target_sources(CruBase PRIVATE - platform/unix/PosixSpawnSubProcess.cpp - platform/unix/UnixFileStream.cpp - platform/unix/UnixPipe.cpp - ) - - if (NOT APPLE) - target_link_libraries(CruBase PUBLIC pthread) - endif() -endif() - -if (APPLE) - find_library(CORE_FOUNDATION CoreFoundation REQUIRED) - target_link_libraries(CruBase PUBLIC ${CORE_FOUNDATION}) - - target_sources(CruBase PRIVATE - platform/osx/Convert.cpp - platform/osx/Exception.cpp - ) -endif() - -if (EMSCRIPTEN) - target_compile_options(CruBase PUBLIC "-fwasm-exceptions") - target_link_options(CruBase PUBLIC "-fwasm-exceptions") - - target_sources(CruBase PRIVATE - platform/web/WebException.cpp - ) -endif() - -if (WIN32) - target_sources(CruBase PRIVATE - platform/win/BridgeComStream.cpp - platform/win/ComAutoInit.cpp - platform/win/DebugLogTarget.cpp - platform/win/Exception.cpp - platform/win/StreamConvert.cpp - platform/win/Win32FileStream.cpp - ) - - target_link_libraries(CruBase PUBLIC Shlwapi.lib) -endif() - -if (WIN32) - target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_WINDOWS) -elseif(APPLE) - target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_OSX) -elseif(EMSCRIPTEN) - target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_EMSCRIPTEN) -else() - target_compile_definitions(CruBase PUBLIC CRU_PLATFORM_LINUX) -endif() - -target_link_libraries(CruBase PUBLIC double-conversion) diff --git a/src/common/Exception.cpp b/src/common/Exception.cpp deleted file mode 100644 index 4110ad56..00000000 --- a/src/common/Exception.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "cru/common/Exception.h" - -#include "cru/common/Format.h" - -#include <cerrno> - -namespace cru { -Exception::Exception(String message, std::unique_ptr<std::exception> inner) - : message_(std::move(message)), inner_(std::move(inner)) {} - -Exception::~Exception() {} - -const char* Exception::what() const noexcept { - if (!message_.empty() && utf8_message_.empty()) { - utf8_message_ = message_.ToUtf8(); - } - - return utf8_message_.c_str(); -} - -void Exception::AppendMessage(StringView additional_message) { - message_ += u" "; - message_ += additional_message; -} - -void Exception::AppendMessage(std::optional<StringView> additional_message) { - if (additional_message) AppendMessage(*additional_message); -} - -ErrnoException::ErrnoException(String message) - : ErrnoException(message, errno) {} - -ErrnoException::ErrnoException(String message, int errno_code) - : Exception(Format(u"{}. Errno is {}.", message, errno_code)), - errno_code_(errno_code) {} -} // namespace cru diff --git a/src/common/Format.cpp b/src/common/Format.cpp deleted file mode 100644 index d58c90b7..00000000 --- a/src/common/Format.cpp +++ /dev/null @@ -1,111 +0,0 @@ -#include "cru/common/Format.h" - -namespace cru { -namespace details { -FormatToken ParsePlaceHolder(String place_holder_string) { - if (place_holder_string.empty()) { - return FormatToken::NonePlaceHolder({}); - } - - if (place_holder_string.StartWith(u":")) { - if (place_holder_string.Find(u':', 1) != -1) { - throw Exception(u"Two ':' inside placeholder."); - } - - return FormatToken::NonePlaceHolder(place_holder_string.substr(1)); - } - if (IsDigit(place_holder_string[0])) { - int position = 0; - int index = 0; - while (index < place_holder_string.size() && - IsDigit(place_holder_string[index])) { - position = position * 10 + place_holder_string[index] - '0'; - index++; - } - - String option; - - if (index != place_holder_string.size()) { - if (place_holder_string[index] != ':') { - throw Exception(u"Invalid placeholder in format."); - } - - option = place_holder_string.substr(index + 1); - } - - return FormatToken::PositionedPlaceHolder(position, std::move(option)); - } - - auto separator_index = place_holder_string.Find(':'); - if (separator_index == -1) { - return FormatToken::NamedPlaceHolder(place_holder_string, {}); - } else { - return FormatToken::NamedPlaceHolder( - place_holder_string.substr(0, separator_index), - place_holder_string.substr(separator_index + 1)); - } -} - -std::vector<FormatToken> ParseToFormatTokenList(StringView str) { - std::vector<FormatToken> result; - - auto push_char = [&result](char16_t c) { - if (result.empty() || result.back().type == FormatTokenType::PlaceHolder) { - result.push_back(FormatToken::Text()); - } - result.back().data.append(c); - }; - - bool try_to_escape = false; - bool is_in_place_holder = false; - String place_holder_string; - - for (auto c : str) { - if (c == u'{') { - if (try_to_escape) { - push_char(u'{'); - try_to_escape = false; - is_in_place_holder = false; - } else { - if (is_in_place_holder) { - throw Exception(u"Invalid format string: '{' inside placeholder."); - } - - try_to_escape = true; - is_in_place_holder = true; - } - } else if (c == u'}') { - if (is_in_place_holder) { - is_in_place_holder = false; - result.push_back(ParsePlaceHolder(std::move(place_holder_string))); - place_holder_string.clear(); - } else { - push_char(u'}'); - } - try_to_escape = false; - } else { - if (is_in_place_holder) { - place_holder_string.push_back(c); - } else { - push_char(c); - } - try_to_escape = false; - } - } - return result; -} - -void FormatAppendFromFormatTokenList( - String& current, const std::vector<FormatToken>& format_token_list, - Index index) { - for (Index i = index; i < static_cast<Index>(format_token_list.size()); i++) { - const auto& token = format_token_list[i]; - if (token.type == FormatTokenType::PlaceHolder) { - throw Exception(u"More placeholder than args."); - } else { - current += token.data; - } - } -} -} // namespace details -} // namespace cru diff --git a/src/common/PropertyTree.cpp b/src/common/PropertyTree.cpp deleted file mode 100644 index b587becb..00000000 --- a/src/common/PropertyTree.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "cru/common/PropertyTree.h" -#include <unordered_map> -#include "cru/common/Exception.h" - -namespace cru { -String PropertySubTreeRef::CombineKey(StringView left, StringView right) { - return PropertyTree::CombineKey(left, right); -} - -PropertySubTreeRef::PropertySubTreeRef(PropertyTree* tree, String path) - : tree_(tree), path_(std::move(path)) { - Expects(tree); -} - -PropertySubTreeRef PropertySubTreeRef::GetParent() const { - for (Index i = path_.size() - 1; i >= 0; i--) { - if (path_[i] == '.') { - return PropertySubTreeRef(tree_, path_.substr(0, i)); - } - } - - return PropertySubTreeRef(tree_, {}); -} - -PropertySubTreeRef PropertySubTreeRef::GetChild(const String& key) const { - return PropertySubTreeRef(tree_, CombineKey(path_, key)); -} - -String PropertySubTreeRef::GetValue(const String& key) const { - return tree_->GetValue(CombineKey(path_, key)); -} - -void PropertySubTreeRef::SetValue(const String& key, String value) { - tree_->SetValue(CombineKey(path_, key), std::move(value)); -} - -void PropertySubTreeRef::DeleteValue(const String& key) { - tree_->DeleteValue(CombineKey(path_, key)); -} - -String PropertyTree::CombineKey(StringView left, StringView right) { - return String(left) + String(left.empty() ? u"" : u".") + String(right); -} - -PropertyTree::PropertyTree(std::unordered_map<String, String> values) - : values_(std::move(values)) {} - -String PropertyTree::GetValue(const String& key) const { - auto it = values_.find(key); - if (it == values_.end()) { - throw Exception(u"Property tree has no value."); - } - return it->second; -} - -void PropertyTree::SetValue(const String& key, String value) { - values_[key] = std::move(value); -} - -void PropertyTree::DeleteValue(const String& key) { - auto it = values_.find(key); - if (it != values_.end()) { - values_.erase(it); - } -} - -PropertySubTreeRef PropertyTree::GetSubTreeRef(const String& path) { - return PropertySubTreeRef(this, path); -} - -} // namespace cru diff --git a/src/common/String.cpp b/src/common/String.cpp deleted file mode 100644 index 27712f01..00000000 --- a/src/common/String.cpp +++ /dev/null @@ -1,672 +0,0 @@ -#include "cru/common/String.h" - -#include "cru/common/Buffer.h" -#include "cru/common/Exception.h" -#include "cru/common/StringToNumberConverter.h" -#include "cru/common/StringUtil.h" - -#include <double-conversion/double-conversion.h> -#include <double-conversion/string-to-double.h> - -#include <algorithm> -#include <cmath> -#include <cstring> -#include <functional> -#include <string_view> - -namespace cru { -template <typename C> -Index GetStrSize(const C* str) { - Index i = 0; - while (str[i]) { - i++; - } - return i; -} - -String String::FromUtf8(const char* str) { - return FromUtf8(str, GetStrSize(str)); -} - -String String::FromUtf8(const char* str, Index size) { - String result; - Utf8CodePointIterator iter(str, size); - for (auto cp : iter) { - Utf16EncodeCodePointAppend( - cp, - std::bind(&String::push_back, std::ref(result), std::placeholders::_1)); - } - return result; -} - -String String::FromUtf8(const std::byte* str, Index size) { - return String::FromUtf8(reinterpret_cast<const char*>(str), size); -} - -String String::FromUtf8(const Buffer& buffer) { - return String::FromUtf8(buffer.GetUsedBeginPtr(), buffer.GetUsedSize()); -} - -String String::FromStdPath(const std::filesystem::path& path) { - return String::FromUtf8(path.string()); -} - -char16_t String::kEmptyBuffer[1] = {0}; - -String::String(const_pointer str) : String(str, GetStrSize(str)) {} - -String::String(const_pointer str, Index size) { - this->buffer_ = new value_type[size + 1]; - std::memcpy(this->buffer_, str, size * sizeof(char16_t)); - this->buffer_[size] = 0; - this->size_ = size; - this->capacity_ = size; -} - -String::String(size_type size, value_type ch) : String() { - reserve(size); - for (Index i = 0; i < size; i++) { - append(ch); - } -} - -String::String(std::initializer_list<char16_t> l) - : String(l.begin(), l.size()) {} - -#ifdef CRU_PLATFORM_WINDOWS -String::String(const wchar_t* str) : String(str, GetStrSize(str)) {} -String::String(const wchar_t* str, Index size) - : String(reinterpret_cast<const char16_t*>(str), size) {} -#endif - -String::String(const String& other) { - if (other.size_ == 0) return; - this->buffer_ = new value_type[other.size_ + 1]; - std::memcpy(this->buffer_, other.buffer_, other.size_ * sizeof(value_type)); - this->buffer_[other.size_] = 0; - this->size_ = other.size_; - this->capacity_ = other.size_; -} - -String::String(String&& other) noexcept { - this->buffer_ = other.buffer_; - this->size_ = other.size_; - this->capacity_ = other.capacity_; - other.buffer_ = kEmptyBuffer; - other.size_ = 0; - other.capacity_ = 0; -} - -String& String::operator=(const String& other) { - if (this != &other) { - if (this->buffer_ != kEmptyBuffer) { - delete[] this->buffer_; - } - - if (other.buffer_ == kEmptyBuffer) { - this->buffer_ = kEmptyBuffer; - this->size_ = 0; - this->capacity_ = 0; - } else { - this->buffer_ = new value_type[other.size_ + 1]; - std::memcpy(this->buffer_, other.buffer_, - other.size_ * sizeof(value_type)); - this->buffer_[other.size_] = 0; - this->size_ = other.size_; - this->capacity_ = other.size_; - } - } - return *this; -} - -String& String::operator=(String&& other) noexcept { - if (this != &other) { - if (this->buffer_ != kEmptyBuffer) { - delete[] this->buffer_; - } - - this->buffer_ = other.buffer_; - this->size_ = other.size_; - this->capacity_ = other.capacity_; - other.buffer_ = kEmptyBuffer; - other.size_ = 0; - other.capacity_ = 0; - } - return *this; -} - -String::~String() { - if (this->buffer_ != kEmptyBuffer) { - delete[] this->buffer_; - } -} - -String::String(from_buffer_tag, pointer buffer, Index size, Index capacity) - : buffer_(buffer), size_(size), capacity_(capacity) {} - -void String::clear() { resize(0); } - -void String::resize(Index new_size) { - Expects(new_size >= 0); - - if (new_size == size_) return; - - if (new_size < size_) { - size_ = new_size; - buffer_[size_] = 0; - } else { - reserve(new_size); - std::memset(buffer_ + size_, 0, sizeof(value_type) * (new_size - size_)); - buffer_[new_size] = 0; - size_ = new_size; - } -} - -void String::shrink_to_fit() { - if (capacity_ == size_) return; - if (size_ == 0) { - delete[] buffer_; - buffer_ = kEmptyBuffer; - size_ = 0; - capacity_ = 0; - } else { - auto new_buffer = new value_type[size_ + 1]; - std::memcpy(new_buffer, buffer_, sizeof(value_type) * size_); - delete[] buffer_; - buffer_ = new_buffer; - capacity_ = size_; - } -} - -void String::reserve(Index new_capacity) { - Expects(new_capacity >= 0); - if (new_capacity <= this->capacity_) return; - if (new_capacity > 0) { - pointer new_buffer = new value_type[new_capacity + 1]; - if (this->buffer_ != kEmptyBuffer) { - memcpy(new_buffer, this->buffer_, this->size_ * sizeof(value_type)); - delete[] this->buffer_; - } - new_buffer[this->size_] = 0; - this->buffer_ = new_buffer; - this->capacity_ = new_capacity; - } -} - -String::iterator String::insert(const_iterator pos, const_iterator str, - Index size) { - Expects(pos >= cbegin() && pos <= cend()); - - std::vector<value_type> backup_buffer; - if (str >= buffer_ && str < buffer_ + size_) { - backup_buffer.resize(size); - std::copy(str, str + size, backup_buffer.begin()); - str = backup_buffer.data(); - } - - Index index = pos - cbegin(); - - Index new_size = size_ + size; - if (new_size > capacity_) { - auto new_capacity = capacity_; - if (new_capacity == 0) { - new_capacity = new_size; - } else { - while (new_capacity < new_size) { - new_capacity *= 2; - } - } - - this->reserve(new_capacity); - } - - std::memmove(begin() + index + size, begin() + index, - (size_ - index) * sizeof(value_type)); - std::memcpy(begin() + index, str, size * sizeof(value_type)); - - buffer_[new_size] = 0; - size_ = new_size; - - return begin() + new_size; -} - -String::iterator String::erase(const_iterator start, const_iterator end) { - Expects(buffer_ <= start && start <= end && end <= buffer_ + size_); - - Index new_size = size_ - (end - start); - - auto s = const_cast<iterator>(start); - auto e = const_cast<iterator>(end); - - std::memmove(s, e, (cend() - end) * sizeof(value_type)); - this->size_ = new_size; - this->buffer_[new_size] = 0; - - return s; -} - -String& String::operator+=(StringView other) { - append(other); - return *this; -} - -StringView String::View() const { return *this; } - -Index String::Find(value_type value, Index start) const { - return View().Find(value, start); -} - -std::vector<String> String::Split(value_type separator, - bool remove_space_line) const { - return View().Split(separator, remove_space_line); -} - -std::vector<String> String::SplitToLines(bool remove_space_line) const { - return View().SplitToLines(remove_space_line); -} - -bool String::StartWith(StringView str) const { return View().StartWith(str); } - -bool String::EndWith(StringView str) const { return View().EndWith(str); } - -std::string String::ToUtf8() const { return View().ToUtf8(); } - -Buffer String::ToUtf8Buffer(bool end_zero) const { - return View().ToUtf8Buffer(); -} - -String& String::TrimStart() { - if (size_ == 0) return *this; - - auto start = begin(); - while (start != end() && IsWhitespace(*start)) { - ++start; - } - - if (start == end()) { - clear(); - } else { - erase(begin(), start); - } - - return *this; -} - -String& String::TrimEnd() { - if (size_ == 0) return *this; - while (size_ > 0 && IsWhitespace(buffer_[size_ - 1])) { - size_--; - } - - return *this; -} - -String& String::Trim() { - TrimStart(); - TrimEnd(); - return *this; -} - -void String::AppendCodePoint(CodePoint code_point) { - if (!Utf16EncodeCodePointAppend( - code_point, - std::bind(&String::push_back, this, std::placeholders::_1))) { - throw TextEncodeException(u"Code point out of range."); - } -} - -Index String::IndexFromCodeUnitToCodePoint(Index code_unit_index) const { - return View().IndexFromCodeUnitToCodePoint(code_unit_index); -} - -Index String::IndexFromCodePointToCodeUnit(Index code_point_index) const { - return View().IndexFromCodePointToCodeUnit(code_point_index); -} - -Range String::RangeFromCodeUnitToCodePoint(Range code_unit_range) const { - return View().RangeFromCodeUnitToCodePoint(code_unit_range); -} - -Range String::RangeFromCodePointToCodeUnit(Range code_point_range) const { - return View().RangeFromCodePointToCodeUnit(code_point_range); -} - -int String::ParseToInt(Index* processed_characters_count, - StringToNumberFlag flags, int base) const { - return View().ParseToInt(processed_characters_count, flags, base); -} - -long long String::ParseToLongLong(Index* processed_characters_count, - StringToNumberFlag flags, int base) const { - return View().ParseToLongLong(processed_characters_count, flags, base); -} - -float String::ParseToFloat(Index* processed_characters_count, - StringToNumberFlag flags) const { - return View().ParseToFloat(processed_characters_count, flags); -} - -double String::ParseToDouble(Index* processed_characters_count, - StringToNumberFlag flags) const { - return View().ParseToDouble(processed_characters_count, flags); -} - -std::vector<float> String::ParseToFloatList(value_type separator) const { - return View().ParseToFloatList(separator); -} - -std::vector<double> String::ParseToDoubleList(value_type separator) const { - return View().ParseToDoubleList(separator); -} - -std::ostream& operator<<(std::ostream& os, const String& value) { - os << value.ToUtf8(); - return os; -} - -namespace { -inline int Compare(char16_t left, char16_t right) { - if (left < right) return -1; - if (left > right) return 1; - return 0; -} - -inline int CaseInsensitiveCompare(char16_t left, char16_t right) { - return Compare(ToLower(left), ToLower(right)); -} -} // namespace - -int String::Compare(const String& other) const { return View().Compare(other); } -int String::CaseInsensitiveCompare(const String& other) const { - return View().CaseInsensitiveCompare(other); -} - -int StringView::Compare(const StringView& other) const { - const_iterator i1 = cbegin(); - const_iterator i2 = other.cbegin(); - - const_iterator end1 = cend(); - const_iterator end2 = other.cend(); - - while (i1 != end1 && i2 != end2) { - int r = cru::Compare(*i1, *i2); - if (r != 0) return r; - i1++; - i2++; - } - - if (i1 == end1) { - if (i2 == end2) { - return 0; - } else { - return -1; - } - } else { - return 1; - } -} - -int StringView::CaseInsensitiveCompare(const StringView& other) const { - const_iterator i1 = cbegin(); - const_iterator i2 = other.cbegin(); - - const_iterator end1 = cend(); - const_iterator end2 = other.cend(); - - while (i1 != end1 && i2 != end2) { - int r = cru::CaseInsensitiveCompare(*i1, *i2); - if (r != 0) return r; - i1++; - i2++; - } - - if (i1 == end1) { - if (i2 == end2) { - return 0; - } else { - return -1; - } - } else { - return 1; - } -} - -StringView StringView::substr(Index pos) { - Expects(pos >= 0 && pos < size_); - return StringView(ptr_ + pos, size_ - pos); -} - -StringView StringView::substr(Index pos, Index size) { - Expects(pos >= 0 && pos < size_); - - return StringView(ptr_ + pos, std::min(size, size_ - pos)); -} - -Index StringView::Find(value_type value, Index start) const { - Expects(start >= 0 && start <= size_); - - for (Index i = start; i < size_; ++i) { - if (ptr_[i] == value) return i; - } - return -1; -} - -std::vector<String> StringView::Split(value_type separator, - bool remove_space_line) const { - std::vector<String> result; - - if (size_ == 0) return result; - - Index line_start = 0; - Index line_end = 0; - while (line_end < size_) { - if (ptr_[line_end] == separator) { - if (remove_space_line) { - bool add = false; - for (Index i = line_start; i < line_end; i++) { - if (!IsWhitespace(ptr_[i])) { - add = true; - break; - } - } - if (add) result.emplace_back(begin() + line_start, begin() + line_end); - } else { - result.emplace_back(begin() + line_start, begin() + line_end); - } - line_start = line_end + 1; - line_end = line_start; - } else { - line_end++; - } - } - - if (remove_space_line) { - bool add = false; - for (Index i = line_start; i < size_; i++) { - if (!IsWhitespace(ptr_[i])) { - add = true; - break; - } - } - if (add) result.emplace_back(begin() + line_start, begin() + size_); - } else { - result.emplace_back(begin() + line_start, begin() + size_); - } - - return result; -} - -std::vector<String> StringView::SplitToLines(bool remove_space_line) const { - return Split(u'\n', remove_space_line); -} - -bool StringView::StartWith(StringView str) const { - if (str.size() > size_) return false; - return std::memcmp(str.data(), ptr_, str.size()) == 0; -} - -bool StringView::EndWith(StringView str) const { - if (str.size() > size_) return false; - return std::memcmp(str.data(), ptr_ + size_ - str.size(), str.size()) == 0; -} - -Index StringView::IndexFromCodeUnitToCodePoint(Index code_unit_index) const { - auto iter = CodePointIterator(); - Index result = 0; - while (iter.GetPosition() < code_unit_index && !iter.IsPastEnd()) { - ++iter; - ++result; - } - return result; -} - -Index StringView::IndexFromCodePointToCodeUnit(Index code_point_index) const { - auto iter = CodePointIterator(); - Index cpi = 0; - while (cpi < code_point_index && !iter.IsPastEnd()) { - ++iter; - ++cpi; - } - return iter.GetPosition(); -} - -Range StringView::RangeFromCodeUnitToCodePoint(Range code_unit_range) const { - return Range::FromTwoSides( - IndexFromCodeUnitToCodePoint(code_unit_range.GetStart()), - IndexFromCodeUnitToCodePoint(code_unit_range.GetEnd())); -} - -Range StringView::RangeFromCodePointToCodeUnit(Range code_point_range) const { - return Range::FromTwoSides( - IndexFromCodePointToCodeUnit(code_point_range.GetStart()), - IndexFromCodePointToCodeUnit(code_point_range.GetEnd())); -} - -std::string StringView::ToUtf8() const { - std::string result; - for (auto cp : CodePointIterator()) { - Utf8EncodeCodePointAppend( - cp, std::bind(&std::string::push_back, std::ref(result), - std::placeholders::_1)); - } - return result; -} - -Buffer StringView::ToUtf8Buffer(bool end_zero) const { - const Index grow_step = 10; - Buffer buffer(grow_step); // Maybe another init value is more reasonable. - auto push_back = [&buffer](char c) { - if (buffer.IsUsedReachEnd()) { - buffer.ResizeBuffer(buffer.GetBufferSize() + grow_step, true); - } - buffer.PushBack(static_cast<std::byte>(c)); - }; - for (auto cp : CodePointIterator()) { - Utf8EncodeCodePointAppend(cp, push_back); - } - if (end_zero) { - push_back(0); - } - return buffer; -} - -int StringView::ParseToInt(Index* processed_characters_count, - StringToNumberFlag flags, int base) const { - return ParseToInteger<int>(processed_characters_count, flags, base); -} - -long long StringView::ParseToLongLong(Index* processed_characters_count, - StringToNumberFlag flags, - int base) const { - return ParseToInteger<long long>(processed_characters_count, flags, base); -} - -static int MapStringToDoubleFlags(StringToNumberFlag flags) { - int f = double_conversion::StringToDoubleConverter::ALLOW_CASE_INSENSIBILITY; - if (flags & StringToNumberFlags::kAllowLeadingSpaces) { - f |= double_conversion::StringToDoubleConverter::ALLOW_LEADING_SPACES; - } - if (flags & StringToNumberFlags::kAllowTrailingSpaces) { - f |= double_conversion::StringToDoubleConverter::ALLOW_TRAILING_SPACES; - } - if (flags & StringToNumberFlags::kAllowTrailingJunk) { - f |= double_conversion::StringToDoubleConverter::ALLOW_TRAILING_JUNK; - } - return f; -} - -static double_conversion::StringToDoubleConverter CreateStringToDoubleConverter( - StringToNumberFlag flags) { - return {MapStringToDoubleFlags(flags), 0.0, NAN, "inf", "nan"}; -} - -float StringView::ParseToFloat(Index* processed_characters_count, - StringToNumberFlag flags) const { - int pcc; - auto result = CreateStringToDoubleConverter(flags).StringToFloat( - reinterpret_cast<const uc16*>(ptr_), static_cast<int>(size_), &pcc); - if (processed_characters_count != nullptr) { - *processed_characters_count = pcc; - } - - if (flags & StringToNumberFlags::kThrowOnError && std::isnan(result)) { - throw Exception(u"Result of string to float conversion is NaN"); - } - - return result; -} - -double StringView::ParseToDouble(Index* processed_characters_count, - StringToNumberFlag flags) const { - int pcc; - auto result = CreateStringToDoubleConverter(flags).StringToDouble( - reinterpret_cast<const uc16*>(ptr_), static_cast<int>(size_), &pcc); - if (processed_characters_count != nullptr) { - *processed_characters_count = pcc; - } - - if (flags & StringToNumberFlags::kThrowOnError && std::isnan(result)) { - throw Exception(u"Result of string to double conversion is NaN"); - } - - return result; -} - -std::vector<float> StringView::ParseToFloatList(value_type separator) const { - std::vector<float> result; - auto list = Split(separator, true); - for (auto& item : list) { - auto value = item.ParseToFloat(); - if (std::isnan(value)) { - throw Exception(u"Invalid double value."); - } - result.push_back(value); - } - return result; -} - -std::vector<double> StringView::ParseToDoubleList(value_type separator) const { - std::vector<double> result; - auto list = Split(separator, true); - for (auto& item : list) { - auto value = item.ParseToDouble(); - if (std::isnan(value)) { - throw Exception(u"Invalid double value."); - } - result.push_back(value); - } - return result; -} - -String ToLower(StringView s) { - String result; - for (auto c : s) result.push_back(ToLower(c)); - return result; -} - -String ToUpper(StringView s) { - String result; - for (auto c : s) result.push_back(ToUpper(c)); - return result; -} -} // namespace cru diff --git a/src/common/StringToNumberConverter.cpp b/src/common/StringToNumberConverter.cpp deleted file mode 100644 index 7a926d3d..00000000 --- a/src/common/StringToNumberConverter.cpp +++ /dev/null @@ -1,170 +0,0 @@ -#include "cru/common/StringToNumberConverter.h" -#include "cru/common/Exception.h" - -namespace cru { -bool StringToIntegerConverter::CheckParams() const { - return base == 0 || base >= 2 & base <= 36; -} - -static bool IsSpace(char c) { - return c == ' ' || c == '\t' || c == '\n' || c == '\r'; -} - -StringToIntegerResult StringToIntegerConverter::Parse( - const char* const str, const Index size, - Index* processed_characters_count) const { - if (str == nullptr) throw std::invalid_argument("Invalid str."); - if (size < 0) throw std::invalid_argument("Invalid size."); - if (!CheckParams()) throw std::invalid_argument("Invalid parsing flags."); - - const bool throw_on_error = flags.Has(StringToNumberFlags::kThrowOnError); - - auto const end = str + size; - - auto current = str; - - if (flags & StringToNumberFlags::kAllowLeadingSpaces) { - while (current != end && IsSpace(*current)) { - current++; - } - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(u"Empty string (after reading leading spaces)."); - } else { - return {false, 0}; - } - } - - bool negate = false; - - if (*current == '-') { - ++current; - negate = true; - } else if (*current == '+') { - ++current; - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(u"Empty string (after reading sign)."); - } else { - return {false, 0}; - } - } - - int real_base = base; - - if (real_base == 0) { - if (*current == '0') { - ++current; - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = current - str; - } - return {negate, 0}; - } else if (*current == 'x' || *current == 'X') { - ++current; - real_base = 16; - } else if (*current == 'b' || *current == 'B') { - ++current; - real_base = 2; - } else { - real_base = 8; - } - } else { - real_base = 10; - } - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(u"Empty string (after reading head base indicator)."); - } else { - return {false, 0}; - } - } - - const bool allow_leading_zero = - flags.Has(StringToNumberFlags::kAllowLeadingZeroForInteger); - - while (current != end && *current == '0') { - current++; - } - - if (current == end) { - if (processed_characters_count) { - *processed_characters_count = current - str; - } - return {negate, 0}; - } - - const bool allow_trailing_junk = - flags.Has(StringToNumberFlags::kAllowTrailingJunk); - const bool allow_trailing_spaces = - flags.Has(StringToNumberFlags::kAllowTrailingSpaces); - - unsigned long long result = 0; - - while (current != end) { - const char c = *current; - if (c >= '0' && c <= (real_base > 10 ? '9' : real_base + '0' - 1)) { - result = result * real_base + c - '0'; - current++; - } else if (real_base > 10 && c >= 'a' && c <= (real_base + 'a' - 10 - 1)) { - result = result * real_base + c - 'a' + 10; - current++; - } else if (real_base > 10 && c >= 'A' && c <= (real_base + 'A' - 10 - 1)) { - result = result * real_base + c - 'A' + 10; - current++; - } else if (allow_trailing_junk) { - break; - } else if (allow_trailing_spaces && IsSpace(c)) { - break; - } else { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(String(u"Read invalid character '") + c + u"'."); - } else { - return {false, 0}; - } - } - } - - if (allow_trailing_spaces) { - while (current != end && IsSpace(*current)) { - current++; - } - - if (current != end) { - if (processed_characters_count) { - *processed_characters_count = 0; - } - if (throw_on_error) { - throw Exception(u"There is trailing junk."); - } else { - return {false, 0}; - } - } - } - - if (processed_characters_count) { - *processed_characters_count = current - str; - } - - return {negate, result}; -} - -} // namespace cru diff --git a/src/common/StringUtil.cpp b/src/common/StringUtil.cpp deleted file mode 100644 index f584fd4e..00000000 --- a/src/common/StringUtil.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include "cru/common/StringUtil.h" -#include "cru/common/Base.h" -#include "cru/common/Exception.h" - -namespace cru { -using details::ExtractBits; - -CodePoint Utf8NextCodePoint(const char* ptr, Index size, Index current, - Index* next_position) { - CodePoint result; - - if (current >= size) { - result = k_invalid_code_point; - } else { - const auto cu0 = static_cast<std::uint8_t>(ptr[current++]); - - auto read_next_folowing_code = [ptr, size, ¤t]() -> CodePoint { - if (current == size) - throw TextEncodeException( - u"Unexpected end when read continuing byte of multi-byte code " - "point."); - - const auto u = static_cast<std::uint8_t>(ptr[current]); - if (!(u & (1u << 7)) || (u & (1u << 6))) { - throw TextEncodeException( - u"Unexpected bad-format (not 0b10xxxxxx) continuing byte of " - "multi-byte code point."); - } - - return ExtractBits<std::uint8_t, 6, CodePoint>(ptr[current++]); - }; - - if ((1u << 7) & cu0) { - if ((1u << 6) & cu0) { // 2~4-length code point - if ((1u << 5) & cu0) { // 3~4-length code point - if ((1u << 4) & cu0) { // 4-length code point - if (cu0 & (1u << 3)) { - throw TextEncodeException( - u"Unexpected bad-format begin byte (not 0b11110xxx) of 4-byte" - "code point."); - } - - const CodePoint s0 = ExtractBits<std::uint8_t, 3, CodePoint>(cu0) - << (6 * 3); - const CodePoint s1 = read_next_folowing_code() << (6 * 2); - const CodePoint s2 = read_next_folowing_code() << 6; - const CodePoint s3 = read_next_folowing_code(); - result = s0 + s1 + s2 + s3; - } else { // 3-length code point - const CodePoint s0 = ExtractBits<std::uint8_t, 4, CodePoint>(cu0) - << (6 * 2); - const CodePoint s1 = read_next_folowing_code() << 6; - const CodePoint s2 = read_next_folowing_code(); - result = s0 + s1 + s2; - } - } else { // 2-length code point - const CodePoint s0 = ExtractBits<std::uint8_t, 5, CodePoint>(cu0) - << 6; - const CodePoint s1 = read_next_folowing_code(); - result = s0 + s1; - } - } else { - throw TextEncodeException( - u"Unexpected bad-format (0b10xxxxxx) begin byte of a code point."); - } - } else { - result = static_cast<CodePoint>(cu0); - } - } - - if (next_position != nullptr) *next_position = current; - return result; -} - -CodePoint Utf16NextCodePoint(const char16_t* ptr, Index size, Index current, - Index* next_position) { - CodePoint result; - - if (current >= size) { - result = k_invalid_code_point; - } else { - const auto cu0 = ptr[current++]; - - if (!IsUtf16SurrogatePairCodeUnit(cu0)) { // 1-length code point - result = static_cast<CodePoint>(cu0); - } else if (IsUtf16SurrogatePairLeading(cu0)) { // 2-length code point - if (current >= size) { - throw TextEncodeException( - u"Unexpected end when reading second code unit of surrogate pair."); - } - const auto cu1 = ptr[current++]; - - if (!IsUtf16SurrogatePairTrailing(cu1)) { - throw TextEncodeException( - u"Unexpected bad-range second code unit of surrogate pair."); - } - - const auto s0 = ExtractBits<std::uint16_t, 10, CodePoint>(cu0) << 10; - const auto s1 = ExtractBits<std::uint16_t, 10, CodePoint>(cu1); - - result = s0 + s1 + 0x10000; - - } else { - throw TextEncodeException( - u"Unexpected bad-range first code unit of surrogate pair."); - } - } - - if (next_position != nullptr) *next_position = current; - return result; -} - -CodePoint Utf16PreviousCodePoint(const char16_t* ptr, Index size, Index current, - Index* previous_position) { - CRU_UNUSED(size) - - CodePoint result; - if (current <= 0) { - result = k_invalid_code_point; - } else { - const auto cu0 = ptr[--current]; - - if (!IsUtf16SurrogatePairCodeUnit(cu0)) { // 1-length code point - result = static_cast<CodePoint>(cu0); - } else if (IsUtf16SurrogatePairTrailing(cu0)) { // 2-length code point - if (current <= 0) { - throw TextEncodeException( - u"Unexpected end when reading first code unit of surrogate pair."); - } - const auto cu1 = ptr[--current]; - - if (!IsUtf16SurrogatePairLeading(cu1)) { - throw TextEncodeException( - u"Unexpected bad-range first code unit of surrogate pair."); - } - - const auto s0 = ExtractBits<std::uint16_t, 10, CodePoint>(cu1) << 10; - const auto s1 = ExtractBits<std::uint16_t, 10, CodePoint>(cu0); - - result = s0 + s1 + 0x10000; - - } else { - throw TextEncodeException( - u"Unexpected bad-range second code unit of surrogate pair."); - } - } - - if (previous_position != nullptr) *previous_position = current; - return result; -} - -bool Utf16IsValidInsertPosition(const char16_t* ptr, Index size, - Index position) { - if (position < 0) return false; - if (position > size) return false; - if (position == 0) return true; - if (position == size) return true; - return !IsUtf16SurrogatePairTrailing(ptr[position]); -} - -Index Utf16BackwardUntil(const char16_t* ptr, Index size, Index position, - const std::function<bool(CodePoint)>& predicate) { - if (position <= 0) return position; - while (true) { - Index p = position; - auto c = Utf16PreviousCodePoint(ptr, size, p, &position); - if (predicate(c)) return p; - if (c == k_invalid_code_point) return p; - } - UnreachableCode(); -} - -Index Utf16ForwardUntil(const char16_t* ptr, Index size, Index position, - const std::function<bool(CodePoint)>& predicate) { - if (position >= size) return position; - while (true) { - Index p = position; - auto c = Utf16NextCodePoint(ptr, size, p, &position); - if (predicate(c)) return p; - if (c == k_invalid_code_point) return p; - } - UnreachableCode(); -} - -inline bool IsSpace(CodePoint c) { return c == 0x20 || c == 0xA; } - -Index Utf16PreviousWord(const char16_t* ptr, Index size, Index position, - bool* is_space) { - if (position <= 0) return position; - auto c = Utf16PreviousCodePoint(ptr, size, position, nullptr); - if (IsSpace(c)) { // TODO: Currently only test against 0x20(space). - if (is_space) *is_space = true; - return Utf16BackwardUntil(ptr, size, position, - [](CodePoint c) { return !IsSpace(c); }); - } else { - if (is_space) *is_space = false; - return Utf16BackwardUntil(ptr, size, position, IsSpace); - } -} - -Index Utf16NextWord(const char16_t* ptr, Index size, Index position, - bool* is_space) { - if (position >= size) return position; - auto c = Utf16NextCodePoint(ptr, size, position, nullptr); - if (IsSpace(c)) { // TODO: Currently only test against 0x20(space). - if (is_space) *is_space = true; - return Utf16ForwardUntil(ptr, size, position, - [](CodePoint c) { return !IsSpace(c); }); - } else { - if (is_space) *is_space = false; - return Utf16ForwardUntil(ptr, size, position, IsSpace); - } -} - -char16_t ToLower(char16_t c) { - if (c >= u'A' && c <= u'Z') { - return c - u'A' + u'a'; - } - return c; -} - -char16_t ToUpper(char16_t c) { - if (c >= u'a' && c <= u'z') { - return c - u'a' + u'A'; - } - return c; -} - -bool IsWhitespace(char16_t c) { - return c == u' ' || c == u'\t' || c == u'\n' || c == u'\r'; -} - -bool IsDigit(char16_t c) { return c >= u'0' && c <= u'9'; } - -Utf8CodePointIterator CreateUtf8Iterator(const std::byte* buffer, Index size) { - return Utf8CodePointIterator(reinterpret_cast<const char*>(buffer), size); -} - -Utf8CodePointIterator CreateUtf8Iterator(const std::vector<std::byte>& buffer) { - return CreateUtf8Iterator(buffer.data(), buffer.size()); -} - -} // namespace cru diff --git a/src/common/SubProcess.cpp b/src/common/SubProcess.cpp deleted file mode 100644 index 33926f39..00000000 --- a/src/common/SubProcess.cpp +++ /dev/null @@ -1,209 +0,0 @@ -#include "cru/common/SubProcess.h" - -#include <thread> - -#ifdef CRU_PLATFORM_UNIX -#include "cru/common/platform/unix/PosixSpawnSubProcess.h" -#endif - -namespace cru { - -#ifdef CRU_PLATFORM_UNIX -using ThisPlatformSubProcessImpl = platform::unix::PosixSpawnSubProcessImpl; -#endif - -PlatformSubProcess::PlatformSubProcess( - SubProcessStartInfo start_info, - std::shared_ptr<IPlatformSubProcessImpl> impl) - : state_(new State(std::move(start_info), std::move(impl))), - lock_(state_->mutex, std::defer_lock) {} - -PlatformSubProcess::~PlatformSubProcess() {} - -void PlatformSubProcess::Start() { - std::lock_guard lock_guard(this->lock_); - - if (this->state_->status != SubProcessStatus::Prepare) { - throw SubProcessException(u"The process has already tried to start."); - } - - try { - this->state_->impl->PlatformCreateProcess(this->state_->start_info); - this->state_->status = SubProcessStatus::Running; - - auto thread = std::thread([state = state_] { - std::unique_lock lock(state->mutex); - state->exit_result = state->impl->PlatformWaitForProcess(); - state->status = SubProcessStatus::Exited; - state->condition_variable.notify_all(); - }); - - thread.detach(); - } catch (const std::exception& e) { - this->state_->status = SubProcessStatus::FailedToStart; - throw SubProcessFailedToStartException(u"Sub-process failed to start. " + - String::FromUtf8(e.what())); - } -} - -void PlatformSubProcess::Wait( - std::optional<std::chrono::milliseconds> wait_time) { - std::lock_guard lock_guard(this->lock_); - - if (this->state_->status == SubProcessStatus::Prepare) { - throw SubProcessException( - u"The process does not start. Can't wait for it."); - } - - if (this->state_->status == SubProcessStatus::FailedToStart) { - throw SubProcessException( - u"The process failed to start. Can't wait for it."); - } - - if (this->state_->status == SubProcessStatus::Exited) { - return; - } - - auto predicate = [this] { - return this->state_->status == SubProcessStatus::Exited; - }; - - if (wait_time) { - this->state_->condition_variable.wait_for(this->lock_, *wait_time, - predicate); - } else { - this->state_->condition_variable.wait(this->lock_, predicate); - } -} - -void PlatformSubProcess::Kill() { - std::lock_guard lock_guard(this->lock_); - - if (this->state_->status == SubProcessStatus::Prepare) { - throw SubProcessException(u"The process does not start. Can't kill it."); - } - - if (this->state_->status == SubProcessStatus::FailedToStart) { - throw SubProcessException(u"The process failed to start. Can't kill it."); - } - - if (this->state_->status == SubProcessStatus::Exited) { - return; - } - - if (this->state_->killed) { - return; - } - - this->state_->impl->PlatformKillProcess(); - this->state_->killed = true; -} - -SubProcessStatus PlatformSubProcess::GetStatus() { - std::lock_guard lock_guard(this->lock_); - return this->state_->status; -} - -SubProcessExitResult PlatformSubProcess::GetExitResult() { - std::lock_guard lock_guard(this->lock_); - - if (this->state_->status == SubProcessStatus::Prepare) { - throw SubProcessException( - u"The process does not start. Can't get exit result."); - } - - if (this->state_->status == SubProcessStatus::FailedToStart) { - throw SubProcessException( - u"The process failed to start. Can't get exit result."); - } - - if (this->state_->status == SubProcessStatus::Running) { - throw SubProcessException( - u"The process is running. Can't get exit result."); - } - - return this->state_->exit_result; -} - -io::Stream* PlatformSubProcess::GetStdinStream() { - return this->state_->impl->GetStdinStream(); -} - -io::Stream* PlatformSubProcess::GetStdoutStream() { - return this->state_->impl->GetStdoutStream(); -} - -io::Stream* PlatformSubProcess::GetStderrStream() { - return this->state_->impl->GetStderrStream(); -} - -SubProcess SubProcess::Create(String program, std::vector<String> arguments, - std::unordered_map<String, String> environments) { - SubProcessStartInfo start_info; - start_info.program = std::move(program); - start_info.arguments = std::move(arguments); - start_info.environments = std::move(environments); - return SubProcess(std::move(start_info)); -} - -SubProcessExitResult SubProcess::Call( - String program, std::vector<String> arguments, - std::unordered_map<String, String> environments) { - auto process = - Create(std::move(program), std::move(arguments), std::move(environments)); - process.Wait(); - return process.GetExitResult(); -} - -SubProcess::SubProcess(SubProcessStartInfo start_info) { - platform_process_.reset(new PlatformSubProcess( - std::move(start_info), std::make_shared<ThisPlatformSubProcessImpl>())); - platform_process_->Start(); -} - -SubProcess::~SubProcess() {} - -void SubProcess::Wait(std::optional<std::chrono::milliseconds> wait_time) { - CheckValid(); - platform_process_->Wait(wait_time); -} - -void SubProcess::Kill() { - CheckValid(); - platform_process_->Kill(); -} - -SubProcessStatus SubProcess::GetStatus() { - CheckValid(); - return platform_process_->GetStatus(); -} - -SubProcessExitResult SubProcess::GetExitResult() { - CheckValid(); - return platform_process_->GetExitResult(); -} - -io::Stream* SubProcess::GetStdinStream() { - CheckValid(); - return platform_process_->GetStdinStream(); -} - -io::Stream* SubProcess::GetStdoutStream() { - CheckValid(); - return platform_process_->GetStdoutStream(); -} - -io::Stream* SubProcess::GetStderrStream() { - CheckValid(); - return platform_process_->GetStderrStream(); -} - -void SubProcess::Detach() { auto p = platform_process_.release(); } - -void SubProcess::CheckValid() const { - if (!IsValid()) { - throw SubProcessException(u"SubProcess instance is invalid."); - } -} - -} // namespace cru diff --git a/src/common/io/AutoReadStream.cpp b/src/common/io/AutoReadStream.cpp deleted file mode 100644 index 18bc18da..00000000 --- a/src/common/io/AutoReadStream.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "cru/common/io/AutoReadStream.h" -#include "cru/common/io/Stream.h" - -#include <thread> - -namespace cru::io { - -AutoReadStream::AutoReadStream(Stream* stream, bool auto_delete, - const AutoReadStreamOptions& options) - : Stream(false, true, stream->CanSeek()) { - auto buffer_stream_options = options.GetBufferStreamOptions(); - stream_ = stream; - size_per_read_ = buffer_stream_options.GetBlockSizeOrDefault(); - buffer_stream_ = std::make_unique<BufferStream>(buffer_stream_options); - background_thread_ = std::thread(&AutoReadStream::BackgroundThreadRun, this); -} - -AutoReadStream::~AutoReadStream() { - if (auto_delete_) { - delete stream_; - } -} - -Index AutoReadStream::DoRead(std::byte* buffer, Index offset, Index size) { - std::unique_lock lock(buffer_stream_mutex_); - return buffer_stream_->Read(buffer, offset, size); -} - -Index AutoReadStream::DoWrite(const std::byte* buffer, Index offset, - Index size) { - return stream_->Write(buffer, offset, size); -} - -void AutoReadStream::DoFlush() { stream_->Flush(); } - -void AutoReadStream::DoClose() {} - -void AutoReadStream::BackgroundThreadRun() { - std::vector<std::byte> buffer(size_per_read_); - while (true) { - try { - auto read = stream_->Read(buffer.data(), buffer.size()); - if (read == 0) { - buffer_stream_->SetEof(); - break; - } else { - buffer_stream_->Write(buffer.data(), read); - } - } catch (const StreamAlreadyClosedException& exception) { - buffer_stream_->SetEof(); - break; - } - } -} - -} // namespace cru::io diff --git a/src/common/io/BufferStream.cpp b/src/common/io/BufferStream.cpp deleted file mode 100644 index 73e5719b..00000000 --- a/src/common/io/BufferStream.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "cru/common/io/BufferStream.h" -#include "cru/common/io/Stream.h" - -namespace cru::io { -BufferStream::BufferStream(const BufferStreamOptions& options) - : Stream(false, true, true) { - block_size_ = options.GetBlockSizeOrDefault(); - max_block_count_ = options.GetMaxBlockCount(); - - eof_ = false; -} - -BufferStream::~BufferStream() { DoClose(); } - -Index BufferStream::DoRead(std::byte* buffer, Index offset, Index size) { - std::unique_lock lock(mutex_); - - condition_variable_.wait(lock, - [this] { return !buffer_list_.empty() || eof_; }); - - if (buffer_list_.empty() && eof_) { - return 0; - } - - auto full = max_block_count_ > 0 && buffer_list_.size() == max_block_count_; - - Index read = 0; - - while (!buffer_list_.empty()) { - auto& stream_buffer = buffer_list_.front(); - auto this_read = - stream_buffer.PopFront(buffer + offset + read, size - read); - if (stream_buffer.GetUsedSize() == 0) { - buffer_list_.pop_front(); - } - read += this_read; - if (read == size) { - break; - } - } - - if (full && buffer_list_.size() < max_block_count_) { - // By convention, there should be at most one producer waiting. So - // notify_one and notify_all should be the same. - condition_variable_.notify_one(); - } - - return read; -} - -Index BufferStream::DoWrite(const std::byte* buffer, Index offset, Index size) { - std::unique_lock lock(mutex_); - - if (eof_) { - throw WriteAfterEofException( - u"Stream has been set eof. Can't write to it any more."); - } - - condition_variable_.wait(lock, [this] { - return max_block_count_ <= 0 || buffer_list_.size() < max_block_count_ || - buffer_list_.back().GetBackFree() > 0; - }); - - auto empty = buffer_list_.empty(); - - Index written = 0; - - if (empty) { - buffer_list_.push_back(Buffer(block_size_)); - } - - while (true) { - if (buffer_list_.back().GetBackFree() == 0) { - if (max_block_count_ > 0 && buffer_list_.size() == max_block_count_) { - break; - } - buffer_list_.push_back(Buffer(block_size_)); - } - auto& stream_buffer = buffer_list_.back(); - auto this_written = - stream_buffer.PushBack(buffer + offset + written, size - written); - written += this_written; - if (written == size) { - break; - } - } - - if (empty) { - // By convention, there should be at most one consumer waiting. So - // notify_one and notify_all should be the same. - condition_variable_.notify_one(); - } - - return written; -} - -void BufferStream::SetEof() { - std::unique_lock lock(mutex_); - - eof_ = true; - if (buffer_list_.empty()) { - // By convention, there should be at most one consumer waiting. So - // notify_one and notify_all should be the same. - condition_variable_.notify_one(); - } -} - -void BufferStream::DoClose() { CRU_STREAM_BEGIN_CLOSE } -} // namespace cru::io diff --git a/src/common/io/CFileStream.cpp b/src/common/io/CFileStream.cpp deleted file mode 100644 index 01456437..00000000 --- a/src/common/io/CFileStream.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "cru/common/io/CFileStream.h" -#include "cru/common/Exception.h" -#include "cru/common/io/Stream.h" - -#include <cstdio> - -namespace cru::io { -static bool ModeCanRead(const char* mode) { - for (const char* p = mode; *p != '\0'; p++) { - if (*p == 'r' || *p == '+') { - return true; - } - } - return false; -} - -static bool ModeCanWrite(const char* mode) { - for (const char* p = mode; *p != '\0'; p++) { - if (*p == 'w' || *p == 'a' || *p == '+') { - return true; - } - } - return false; -} - -CFileStream::CFileStream(const char* path, const char* mode) - : Stream(true, ModeCanRead(mode), ModeCanWrite(mode)), - file_(std::fopen(path, mode)), - auto_close_(true) { - if (file_ == nullptr) { - throw ErrnoException(u"Cannot open file."); - } -} - -CFileStream::CFileStream(std::FILE* file, bool readable, bool writable, - bool auto_close) - : Stream(true, readable, writable), file_(file), auto_close_(auto_close) { - if (file_ == nullptr) { - throw Exception(u"File is NULL."); - } -} - -CFileStream::~CFileStream() { - if (auto_close_ && file_ != nullptr) { - std::fclose(file_); - } -} - -static int ConvertOriginFlag(Stream::SeekOrigin origin) { - switch (origin) { - case Stream::SeekOrigin::Begin: - return SEEK_SET; - case Stream::SeekOrigin::Current: - return SEEK_CUR; - case Stream::SeekOrigin::End: - return SEEK_END; - default: - throw Exception(u"Unknown seek origin."); - } -} - -Index CFileStream::DoSeek(Index offset, SeekOrigin origin) { - if (std::fseek(file_, offset, ConvertOriginFlag(origin))) { - throw ErrnoException(u"Seek failed."); - } - return DoTell(); -} - -Index CFileStream::DoTell() { - long position = std::ftell(file_); - if (position == -1) { - throw ErrnoException(u"Tell failed."); - } - return position; -} - -void CFileStream::DoRewind() { std::rewind(file_); } - -Index CFileStream::DoRead(std::byte* buffer, Index offset, Index size) { - auto count = std::fread(buffer + offset, 1, size, file_); - return count; -} - -Index CFileStream::DoWrite(const std::byte* buffer, Index offset, Index size) { - auto count = std::fwrite(buffer + offset, 1, size, file_); - return count; -} - -void CFileStream::DoFlush() { std::fflush(file_); } - -void CFileStream::DoClose() { - CRU_STREAM_BEGIN_CLOSE - std::fclose(file_); - file_ = nullptr; -} -} // namespace cru::io diff --git a/src/common/io/MemoryStream.cpp b/src/common/io/MemoryStream.cpp deleted file mode 100644 index 4b33d780..00000000 --- a/src/common/io/MemoryStream.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "cru/common/io/MemoryStream.h" - -#include <cstring> -#include "cru/common/Exception.h" -#include "cru/common/io/Stream.h" - -namespace cru::io { -MemoryStream::MemoryStream( - std::byte* buffer, Index size, bool read_only, - std::function<void(std::byte* buffer, Index size)> release_func) - : Stream(true, true, !read_only), - buffer_(buffer), - size_(size), - position_(0), - release_func_(std::move(release_func)) { - if (!buffer) { - throw Exception(u"Buffer is nullptr"); - } - if (size <= 0) { - throw Exception(u"Size is 0 or negative."); - } -} - -MemoryStream::~MemoryStream() {} - -void MemoryStream::Close() { DoClose(); } - -Index MemoryStream::DoSeek(Index offset, SeekOrigin origin) { - switch (origin) { - case SeekOrigin::Current: - position_ += offset; - break; - case SeekOrigin::Begin: - position_ = offset; - break; - case SeekOrigin::End: - position_ = size_ + offset; - break; - } - return position_; -} - -Index MemoryStream::DoRead(std::byte* buffer, Index offset, Index size) { - if (position_ + size > size_) { - size = size_ - position_; - } - if (size <= 0) { - return 0; - } - std::memmove(buffer + offset, buffer_ + position_, size); - position_ += size; - return size; -} - -Index MemoryStream::DoWrite(const std::byte* buffer, Index offset, Index size) { - if (position_ + size > size_) { - size = size_ - position_; - } - if (size <= 0) { - return 0; - } - std::memmove(buffer_ + position_, buffer + offset, size); - position_ += size; - return size; -} - -void MemoryStream::DoClose() { - CRU_STREAM_BEGIN_CLOSE - release_func_(buffer_, size_); - buffer_ = nullptr; - release_func_ = {}; -} - -} // namespace cru::io diff --git a/src/common/io/OpenFileFlag.cpp b/src/common/io/OpenFileFlag.cpp deleted file mode 100644 index 6b9957fe..00000000 --- a/src/common/io/OpenFileFlag.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "cru/common/io/OpenFileFlag.h" - -namespace cru::io { -bool CheckOpenFileFlag(OpenFileFlag flags) { - auto has = [flags](OpenFileFlag flag) { return flags & flag; }; - - if ((has(OpenFileFlags::Append) || has(OpenFileFlags::Truncate) || - has(OpenFileFlags::Create)) && - !has(OpenFileFlags::Write)) { - return false; - } - - if (has(OpenFileFlags::Truncate) && has(OpenFileFlags::Append)) { - return false; - } - - return true; -} -} // namespace cru::io diff --git a/src/common/io/ProxyStream.cpp b/src/common/io/ProxyStream.cpp deleted file mode 100644 index c2e64056..00000000 --- a/src/common/io/ProxyStream.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "cru/common/io/ProxyStream.h" -#include "cru/common/io/Stream.h" - -namespace cru::io { -ProxyStream::ProxyStream(ProxyStreamHandlers handlers) - : Stream(static_cast<bool>(handlers.seek), static_cast<bool>(handlers.read), - static_cast<bool>(handlers.write)), - handlers_(std::move(handlers)) {} - -ProxyStream::~ProxyStream() { DoClose(); } - -Index ProxyStream::DoSeek(Index offset, SeekOrigin origin) { - return handlers_.seek(offset, origin); -} - -Index ProxyStream::DoRead(std::byte* buffer, Index offset, Index size) { - return handlers_.read(buffer, offset, size); -} - -Index ProxyStream::DoWrite(const std::byte* buffer, Index offset, Index size) { - return handlers_.write(buffer, offset, size); -} - -void ProxyStream::DoFlush() { - if (handlers_.flush) { - handlers_.flush(); - } -} - -void ProxyStream::DoClose() { - CRU_STREAM_BEGIN_CLOSE - if (handlers_.close) { - handlers_.close(); - } - handlers_ = {}; -} -} // namespace cru::io diff --git a/src/common/io/Resource.cpp b/src/common/io/Resource.cpp deleted file mode 100644 index b847e1cf..00000000 --- a/src/common/io/Resource.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "cru/common/io/Resource.h" -#include "cru/common/Exception.h" -#include "cru/common/log/Logger.h" - -#if defined(CRU_PLATFORM_OSX) -#include <CoreFoundation/CoreFoundation.h> -#elif defined(CRU_PLATFORM_WINDOWS) -#include <Windows.h> -#endif - -#include <filesystem> - -namespace cru::io { -std::filesystem::path GetResourceDir() { - constexpr auto kLogTag = u"GetResourceDir"; - -#if defined(CRU_PLATFORM_OSX) - CFBundleRef main_bundle = CFBundleGetMainBundle(); - CFURLRef bundle_url = CFBundleCopyBundleURL(main_bundle); - CFStringRef cf_string_ref = - CFURLCopyFileSystemPath(bundle_url, kCFURLPOSIXPathStyle); - std::filesystem::path bundle_path( - CFStringGetCStringPtr(cf_string_ref, kCFStringEncodingUTF8)); - - CFRelease(bundle_url); - CFRelease(cf_string_ref); - - return bundle_path / "Contents/Resources"; -#elif defined(CRU_PLATFORM_WINDOWS) - wchar_t buffer[MAX_PATH]; - DWORD size = ::GetModuleFileNameW(nullptr, buffer, MAX_PATH); - std::filesystem::path module_path(buffer, buffer + size); - auto p = module_path; - while (p.has_parent_path()) { - p = p.parent_path(); - auto resource_dir_path = p / "assets"; - if (std::filesystem::exists(resource_dir_path) && - std::filesystem::is_directory(resource_dir_path)) { - return resource_dir_path; - } - } - - throw Exception(u"Failed to find resource directory."); -#else - throw Exception(u"Not implemented."); -#endif -} -} // namespace cru::io diff --git a/src/common/io/Stream.cpp b/src/common/io/Stream.cpp deleted file mode 100644 index 6b0a513c..00000000 --- a/src/common/io/Stream.cpp +++ /dev/null @@ -1,199 +0,0 @@ -#include "cru/common/io/Stream.h" -#include "cru/common/Exception.h" -#include "cru/common/Format.h" - -#include <utility> - -namespace cru::io { -StreamOperationNotSupportedException::StreamOperationNotSupportedException( - String operation) - : operation_(std::move(operation)) { - SetMessage(Format(u"Stream operation {} not supported.", operation_)); -} - -void StreamOperationNotSupportedException::CheckSeek(bool seekable) { - if (!seekable) throw StreamOperationNotSupportedException(u"seek"); -} - -void StreamOperationNotSupportedException::CheckRead(bool readable) { - if (!readable) throw StreamOperationNotSupportedException(u"read"); -} - -void StreamOperationNotSupportedException::CheckWrite(bool writable) { - if (!writable) throw StreamOperationNotSupportedException(u"write"); -} - -StreamAlreadyClosedException::StreamAlreadyClosedException() - : Exception(u"Stream is already closed.") {} - -void StreamAlreadyClosedException::Check(bool closed) { - if (closed) throw StreamAlreadyClosedException(); -} - -Stream::Stream(SupportedOperations supported_operations) - : supported_operations_(std::move(supported_operations)), closed_(false) {} - -Stream::Stream(std::optional<bool> can_seek, std::optional<bool> can_read, - std::optional<bool> can_write) - : Stream(SupportedOperations{can_seek, can_read, can_write}) {} - -bool Stream::CanSeek() { - CheckClosed(); - return DoCanSeek(); -} - -Index Stream::Seek(Index offset, SeekOrigin origin) { - CheckClosed(); - StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); - return DoSeek(offset, origin); -} - -Index Stream::Tell() { - CheckClosed(); - return DoTell(); -} - -void Stream::Rewind() { - CheckClosed(); - return DoRewind(); -} - -Index Stream::GetSize() { - CheckClosed(); - return DoGetSize(); -} - -bool Stream::CanRead() { - CheckClosed(); - return DoCanRead(); -} - -Index Stream::Read(std::byte* buffer, Index offset, Index size) { - CheckClosed(); - StreamOperationNotSupportedException::CheckRead(DoCanRead()); - return DoRead(buffer, offset, size); -} - -Index Stream::Read(std::byte* buffer, Index size) { - return Read(buffer, 0, size); -} - -Index Stream::Read(char* buffer, Index offset, Index size) { - return Read(reinterpret_cast<std::byte*>(buffer), offset, size); -} - -Index Stream::Read(char* buffer, Index size) { - return Read(reinterpret_cast<std::byte*>(buffer), 0, size); -} - -bool Stream::CanWrite() { - CheckClosed(); - return DoCanWrite(); -} - -Index Stream::Write(const std::byte* buffer, Index offset, Index size) { - CheckClosed(); - StreamOperationNotSupportedException::CheckWrite(DoCanWrite()); - return DoWrite(buffer, offset, size); -} - -Index Stream::Write(const std::byte* buffer, Index size) { - return Write(buffer, 0, size); -} - -Index Stream::Write(const char* buffer, Index offset, Index size) { - return Write(reinterpret_cast<const std::byte*>(buffer), offset, size); -} - -Index Stream::Write(const char* buffer, Index size) { - return Write(reinterpret_cast<const std::byte*>(buffer), size); -} - -void Stream::Flush() { - CheckClosed(); - DoFlush(); -} - -bool Stream::DoCanSeek() { - if (supported_operations_->can_seek) { - return *supported_operations_->can_seek; - } else { - throw Exception( - u"Can seek is neither set in supported_operations nor implemeted in " - u"virtual function."); - } -} - -bool Stream::DoCanRead() { - if (supported_operations_->can_read) { - return *supported_operations_->can_read; - } else { - throw Exception( - u"Can read is neither set in supported_operations nor implemeted in " - u"virtual function."); - } -} - -bool Stream::DoCanWrite() { - if (supported_operations_->can_write) { - return *supported_operations_->can_write; - } else { - throw Exception( - u"Can write is neither set in supported_operations nor implemeted in " - u"virtual function."); - } -} - -Index Stream::DoSeek(Index offset, SeekOrigin origin) { - throw Exception(u"Stream is seekable but DoSeek is not implemented."); -} - -Index Stream::DoTell() { - StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); - return DoSeek(0, SeekOrigin::Current); -} - -void Stream::DoRewind() { - StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); - DoSeek(0, SeekOrigin::Begin); -} - -Index Stream::DoGetSize() { - StreamOperationNotSupportedException::CheckSeek(DoCanSeek()); - Index current_position = DoTell(); - Seek(0, SeekOrigin::End); - Index size = DoTell(); - Seek(current_position, SeekOrigin::Begin); - return size; -} - -Index Stream::DoRead(std::byte* buffer, Index offset, Index size) { - throw Exception(u"Stream is readable but DoSeek is not implemented."); -} - -Index Stream::DoWrite(const std::byte* buffer, Index offset, Index size) { - throw Exception(u"Stream is writable but DoSeek is not implemented."); -} - -void Stream::DoFlush() {} - -Buffer Stream::ReadToEnd(Index grow_size) { - Buffer buffer(grow_size); - while (true) { - auto read = Read(buffer.GetUsedEndPtr(), buffer.GetBackFree()); - buffer.PushBackCount(read); - if (read == 0) { - break; - } - if (buffer.IsUsedReachEnd()) { - buffer.ResizeBuffer(buffer.GetBufferSize() + grow_size, true); - } - } - return buffer; -} - -String Stream::ReadToEndAsUtf8String() { - auto buffer = ReadToEnd(); - return String::FromUtf8(buffer); -} -} // namespace cru::io diff --git a/src/common/log/Logger.cpp b/src/common/log/Logger.cpp deleted file mode 100644 index 4b07ed87..00000000 --- a/src/common/log/Logger.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "cru/common/log/Logger.h" -#include "cru/common/log/StdioLogTarget.h" - -#include <ctime> -#include <algorithm> - -#ifdef CRU_PLATFORM_WINDOWS -#include "cru/common/platform/win/DebugLogTarget.h" -#endif - -namespace cru::log { -Logger *Logger::GetInstance() { - static Logger logger; - - logger.AddLogTarget(std::make_unique<StdioLogTarget>()); - -#ifdef CRU_PLATFORM_WINDOWS - logger.AddLogTarget(std::make_unique<platform::win::WinDebugLogTarget>()); -#endif - - return &logger; -} - -void Logger::AddLogTarget(std::unique_ptr<ILogTarget> target) { - std::lock_guard<std::mutex> lock(target_list_mutex_); - target_list_.push_back(std::move(target)); -} - -void Logger::RemoveLogTarget(ILogTarget *target) { - std::lock_guard<std::mutex> lock(target_list_mutex_); - target_list_.erase( - std::remove_if(target_list_.begin(), target_list_.end(), - [target](const auto &t) { return t.get() == target; }), - target_list_.end()); -} - -namespace { -String LogLevelToString(LogLevel level) { - switch (level) { - case LogLevel::Debug: - return u"DEBUG"; - case LogLevel::Info: - return u"INFO"; - case LogLevel::Warn: - return u"WARN"; - case LogLevel::Error: - return u"ERROR"; - default: - std::terminate(); - } -} - -String GetLogTime() { - auto time = std::time(nullptr); - auto calendar = std::localtime(&time); - return Format(u"{}:{}:{}", calendar->tm_hour, calendar->tm_min, - calendar->tm_sec); -} - -String MakeLogFinalMessage(const LogInfo &log_info) { - return Format(u"[{}] {} {}: {}\n", GetLogTime(), - LogLevelToString(log_info.level), log_info.tag, - log_info.message); -} -} // namespace - -Logger::Logger() - : log_thread_([this] { - while (true) { - auto log_info = log_queue_.Pull(); - std::lock_guard<std::mutex> lock_guard{target_list_mutex_}; - for (const auto &target : target_list_) { - target->Write(log_info.level, MakeLogFinalMessage(log_info)); - } - } - }) {} - -Logger::~Logger() { log_thread_.detach(); } - -void Logger::Log(LogInfo log_info) { -#ifndef CRU_DEBUG - if (log_info.level == LogLevel::Debug) { - return; - } -#endif - log_queue_.Push(std::move(log_info)); -} -} // namespace cru::log diff --git a/src/common/log/StdioLogTarget.cpp b/src/common/log/StdioLogTarget.cpp deleted file mode 100644 index 7f99dbd1..00000000 --- a/src/common/log/StdioLogTarget.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "cru/common/log/StdioLogTarget.h" - -#include <iostream> - -namespace cru::log { -StdioLogTarget::StdioLogTarget() {} - -StdioLogTarget::~StdioLogTarget() {} - -void StdioLogTarget::Write(log::LogLevel level, StringView s) { -#ifdef CRU_PLATFORM_WINDOWS - if (level == log::LogLevel::Error) { - std::wcerr.write(reinterpret_cast<const wchar_t*>(s.data()), s.size()); - } else { - std::wcout.write(reinterpret_cast<const wchar_t*>(s.data()), s.size()); - } -#else - std::string m = s.ToUtf8(); - - if (level == log::LogLevel::Error) { - std::cerr << m; - } else { - std::cout << m; - } -#endif -} -} // namespace cru::log diff --git a/src/common/platform/Exception.cpp b/src/common/platform/Exception.cpp deleted file mode 100644 index 1c5db390..00000000 --- a/src/common/platform/Exception.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "cru/common/platform/Exception.h" diff --git a/src/common/platform/osx/Convert.cpp b/src/common/platform/osx/Convert.cpp deleted file mode 100644 index 4792df1f..00000000 --- a/src/common/platform/osx/Convert.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "cru/common/platform/osx/Convert.h" - -namespace cru::platform::osx { -CFStringRef Convert(const String& string) { - return CFStringCreateWithBytes( - nullptr, reinterpret_cast<const UInt8*>(string.data()), - string.size() * sizeof(std::uint16_t), kCFStringEncodingUTF16, false); -} - -String Convert(CFStringRef string) { - auto length = CFStringGetLength(string); - - String result; - - for (int i = 0; i < length; i++) { - result.AppendCodePoint(CFStringGetCharacterAtIndex(string, i)); - } - - return result; -} - -CFRange Convert(const Range& range) { - return CFRangeMake(range.position, range.count); -} - -Range Convert(const CFRange& range) { - return Range(range.location, range.length); -} -} // namespace cru::platform::osx diff --git a/src/common/platform/osx/Exception.cpp b/src/common/platform/osx/Exception.cpp deleted file mode 100644 index e03faa4c..00000000 --- a/src/common/platform/osx/Exception.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "cru/common/platform//osx/Exception.h" diff --git a/src/common/platform/unix/PosixSpawnSubProcess.cpp b/src/common/platform/unix/PosixSpawnSubProcess.cpp deleted file mode 100644 index b5d68845..00000000 --- a/src/common/platform/unix/PosixSpawnSubProcess.cpp +++ /dev/null @@ -1,204 +0,0 @@ -#include "cru/common/platform/unix/PosixSpawnSubProcess.h" -#include "cru/common/Exception.h" -#include "cru/common/Format.h" -#include "cru/common/Guard.h" -#include "cru/common/String.h" -#include "cru/common/SubProcess.h" -#include "cru/common/log/Logger.h" - -#include <signal.h> -#include <spawn.h> -#include <sys/wait.h> -#include <unistd.h> -#include <memory> -#include <unordered_map> - -namespace cru::platform::unix { -PosixSpawnSubProcessImpl::PosixSpawnSubProcessImpl() - : pid_(0), - exit_code_(0), - stdin_pipe_(UnixPipe::Usage::Send, false), - stdout_pipe_(UnixPipe::Usage::Receive, false), - stderr_pipe_(UnixPipe::Usage::Receive, false) { - stdin_stream_ = std::make_unique<UnixFileStream>( - stdin_pipe_.GetSelfFileDescriptor(), false, false, true, true); - stdout_stream_ = std::make_unique<UnixFileStream>( - stdout_pipe_.GetSelfFileDescriptor(), false, true, false, true); - stderr_stream_ = std::make_unique<UnixFileStream>( - stderr_pipe_.GetSelfFileDescriptor(), false, true, false, true); - - stdout_buffer_stream_ = - std::make_unique<io::AutoReadStream>(stdout_stream_.get(), false); - stderr_buffer_stream_ = - std::make_unique<io::AutoReadStream>(stderr_stream_.get(), false); -} - -PosixSpawnSubProcessImpl::~PosixSpawnSubProcessImpl() {} - -namespace { -char** CreateCstrArray(const std::vector<String>& argv) { - std::vector<Buffer> utf8_argv; - for (const auto& arg : argv) { - utf8_argv.push_back(arg.ToUtf8Buffer()); - } - char** result = new char*[utf8_argv.size() + 1]; - for (int i = 0; i < utf8_argv.size(); i++) { - result[i] = reinterpret_cast<char*>(utf8_argv[i].Detach()); - } - result[utf8_argv.size()] = nullptr; - return result; -} - -char** CreateCstrArray(const std::unordered_map<String, String>& envp) { - std::vector<String> str_array; - for (auto& [key, value] : envp) { - str_array.push_back(cru::Format(u"{}={}", key, value)); - } - return CreateCstrArray(str_array); -} - -void DestroyCstrArray(char** argv) { - int index = 0; - char* arg = argv[index]; - while (arg) { - delete[] arg; - index++; - arg = argv[index]; - } - delete[] argv; -} -} // namespace - -void PosixSpawnSubProcessImpl::PlatformCreateProcess( - const SubProcessStartInfo& start_info) { - int error; - auto check_error = [&error](String message) { - if (error == 0) return; - std::unique_ptr<ErrnoException> inner(new ErrnoException({}, error)); - throw SubProcessFailedToStartException(std::move(message), - std::move(inner)); - }; - - posix_spawn_file_actions_t file_actions; - error = posix_spawn_file_actions_init(&file_actions); - check_error(u"Failed to call posix_spawn_file_actions_init."); - Guard file_actions_guard( - [&file_actions] { posix_spawn_file_actions_destroy(&file_actions); }); - - // dup2 stdin/stdout/stderr - error = posix_spawn_file_actions_adddup2( - &file_actions, stdin_pipe_.GetOtherFileDescriptor(), STDIN_FILENO); - check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stdin."); - error = posix_spawn_file_actions_adddup2( - &file_actions, stdout_pipe_.GetOtherFileDescriptor(), STDOUT_FILENO); - check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stdout."); - error = posix_spawn_file_actions_adddup2( - &file_actions, stderr_pipe_.GetOtherFileDescriptor(), STDERR_FILENO); - check_error(u"Failed to call posix_spawn_file_actions_adddup2 on stderr."); - - error = posix_spawn_file_actions_addclose( - &file_actions, stdin_pipe_.GetOtherFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on self fd of stdin."); - error = posix_spawn_file_actions_addclose( - &file_actions, stdout_pipe_.GetOtherFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on self fd stdout."); - error = posix_spawn_file_actions_addclose( - &file_actions, stderr_pipe_.GetOtherFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on self fd stderr."); - - error = posix_spawn_file_actions_addclose( - &file_actions, stdin_pipe_.GetSelfFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on parent fd of " - u"stdin."); - error = posix_spawn_file_actions_addclose( - &file_actions, stdout_pipe_.GetSelfFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on parent fd of " - u"stdout."); - error = posix_spawn_file_actions_addclose( - &file_actions, stderr_pipe_.GetSelfFileDescriptor()); - check_error( - u"Failed to call posix_spawn_file_actions_addclose on parent fd of " - u"stderr."); - - posix_spawnattr_t attr; - error = posix_spawnattr_init(&attr); - check_error(u"Failed to call posix_spawnattr_init."); - Guard attr_guard([&attr] { posix_spawnattr_destroy(&attr); }); - -#ifdef CRU_PLATFORM_OSX - error = posix_spawnattr_setflags(&attr, POSIX_SPAWN_CLOEXEC_DEFAULT); - check_error(u"Failed to set flag POSIX_SPAWN_CLOEXEC_DEFAULT (osx)."); -#endif - - auto exe = start_info.program.ToUtf8(); - std::vector<String> arguments{start_info.program}; - arguments.insert(arguments.cend(), start_info.arguments.cbegin(), - start_info.arguments.cend()); - - auto argv = CreateCstrArray(arguments); - Guard argv_guard([argv] { DestroyCstrArray(argv); }); - - auto envp = CreateCstrArray(start_info.environments); - Guard envp_guard([envp] { DestroyCstrArray(envp); }); - - error = posix_spawnp(&pid_, exe.c_str(), &file_actions, &attr, argv, envp); - check_error(u"Failed to call posix_spawnp."); - - error = ::close(stdin_pipe_.GetOtherFileDescriptor()); - check_error(u"Failed to close child stdin."); - error = ::close(stdout_pipe_.GetOtherFileDescriptor()); - check_error(u"Failed to close child stdout."); - error = ::close(stderr_pipe_.GetOtherFileDescriptor()); - check_error(u"Failed to close child stderr."); -} - -SubProcessExitResult PosixSpawnSubProcessImpl::PlatformWaitForProcess() { - int wstatus; - - while (waitpid(pid_, &wstatus, 0) == -1) { - if (errno == EINTR) { - CRU_LOG_INFO(u"Waitpid is interrupted by a signal. Call it again."); - continue; - } - - std::unique_ptr<ErrnoException> inner(new ErrnoException({}, errno)); - - throw SubProcessInternalException( - u"Failed to call waitpid on a subprocess.", std::move(inner)); - } - - if (WIFEXITED(wstatus)) { - return SubProcessExitResult::Normal(WEXITSTATUS(wstatus)); - } else if (WIFEXITED(wstatus)) { - return SubProcessExitResult::Signal(WTERMSIG(wstatus), WCOREDUMP(wstatus)); - } else { - return SubProcessExitResult::Unknown(); - } -} - -void PosixSpawnSubProcessImpl::PlatformKillProcess() { - int error = kill(pid_, SIGKILL); - if (error != 0) { - std::unique_ptr<ErrnoException> inner(new ErrnoException({}, errno)); - throw SubProcessInternalException(u"Failed to call kill on a subprocess.", - std::move(inner)); - } -} - -io::Stream* PosixSpawnSubProcessImpl::GetStdinStream() { - return stdin_stream_.get(); -} - -io::Stream* PosixSpawnSubProcessImpl::GetStdoutStream() { - return stdout_buffer_stream_.get(); -} - -io::Stream* PosixSpawnSubProcessImpl::GetStderrStream() { - return stderr_buffer_stream_.get(); -} -} // namespace cru::platform::unix diff --git a/src/common/platform/unix/UnixFileStream.cpp b/src/common/platform/unix/UnixFileStream.cpp deleted file mode 100644 index 804e24f0..00000000 --- a/src/common/platform/unix/UnixFileStream.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "cru/common/platform/unix/UnixFileStream.h" -#include "cru/common/Exception.h" -#include "cru/common/Format.h" -#include "cru/common/io/Stream.h" -#include "cru/common/log/Logger.h" - -#include <fcntl.h> -#include <sys/fcntl.h> -#include <unistd.h> -#include <cerrno> - -namespace cru::platform::unix { -using namespace cru::io; - -namespace { -bool OflagCanSeek([[maybe_unused]] int oflag) { - // Treat every file seekable. - return true; -} - -bool OflagCanRead(int oflag) { - // There is a problem: O_RDONLY is 0. So we must test it specially. - // If it is not write-only. Then it can read. - return !(oflag & O_WRONLY); -} - -bool OflagCanWrite(int oflag) { return oflag & O_WRONLY || oflag & O_RDWR; } - -int MapSeekOrigin(Stream::SeekOrigin origin) { - switch (origin) { - case Stream::SeekOrigin::Begin: - return SEEK_SET; - case Stream::SeekOrigin::Current: - return SEEK_CUR; - case Stream::SeekOrigin::End: - return SEEK_END; - default: - throw Exception(u"Invalid seek origin."); - } -} -} // namespace - -UnixFileStream::UnixFileStream(const char *path, int oflag, mode_t mode) { - file_descriptor_ = ::open(path, oflag, mode); - if (file_descriptor_ == -1) { - throw ErrnoException( - Format(u"Failed to open file {} with oflag {}, mode {}.", - String::FromUtf8(path), oflag, mode)); - } - - SetSupportedOperations( - {OflagCanSeek(oflag), OflagCanRead(oflag), OflagCanWrite(oflag)}); - - auto_close_ = true; -} - -UnixFileStream::UnixFileStream(int fd, bool can_seek, bool can_read, - bool can_write, bool auto_close) - : Stream(can_seek, can_read, can_write) { - file_descriptor_ = fd; - auto_close_ = auto_close; -} - -UnixFileStream::~UnixFileStream() { - if (auto_close_ && file_descriptor_ >= 0) { - if (::close(file_descriptor_) == -1) { - // We are in destructor, so we can not throw. - CRU_LOG_WARN(u"Failed to close file descriptor {}, errno {}.", - file_descriptor_, errno); - } - } -} - -Index UnixFileStream::DoSeek(Index offset, SeekOrigin origin) { - off_t result = ::lseek(file_descriptor_, offset, MapSeekOrigin(origin)); - if (result == -1) { - throw ErrnoException(u"Failed to seek file."); - } - return result; -} - -Index UnixFileStream::DoRead(std::byte *buffer, Index offset, Index size) { - auto result = ::read(file_descriptor_, buffer + offset, size); - if (result == -1) { - throw ErrnoException(u"Failed to read file."); - } - return result; -} - -Index UnixFileStream::DoWrite(const std::byte *buffer, Index offset, - Index size) { - auto result = ::write(file_descriptor_, buffer + offset, size); - if (result == -1) { - throw ErrnoException(u"Failed to write file."); - } - return result; -} - -void UnixFileStream::DoClose() { - CRU_STREAM_BEGIN_CLOSE - if (auto_close_ && ::close(file_descriptor_) == -1) { - throw ErrnoException(u"Failed to close file."); - } - file_descriptor_ = -1; -} -} // namespace cru::platform::unix diff --git a/src/common/platform/unix/UnixPipe.cpp b/src/common/platform/unix/UnixPipe.cpp deleted file mode 100644 index f30c599e..00000000 --- a/src/common/platform/unix/UnixPipe.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "cru/common/platform/unix/UnixPipe.h" -#include "cru/common/Exception.h" -#include "cru/common/log/Logger.h" - -#include <fcntl.h> -#include <sys/fcntl.h> -#include <unistd.h> - -namespace cru::platform::unix { -UnixPipe::UnixPipe(Usage usage, bool auto_close, UnixPipeFlag flags) - : usage_(usage), auto_close_(auto_close), flags_(flags) { - int fds[2]; - if (pipe(fds) != 0) { - throw ErrnoException(u"Failed to create unix pipe."); - } - - if (flags & UnixPipeFlags::NonBlock) { - fcntl(fds[0], F_SETFL, O_NONBLOCK); - fcntl(fds[1], F_SETFL, O_NONBLOCK); - } - - read_fd_ = fds[0]; - write_fd_ = fds[1]; -} - -int UnixPipe::GetSelfFileDescriptor() { - if (usage_ == Usage::Send) { - return write_fd_; - } else { - return read_fd_; - } -} - -int UnixPipe::GetOtherFileDescriptor() { - if (usage_ == Usage::Send) { - return read_fd_; - } else { - return write_fd_; - } -} - -UnixPipe::~UnixPipe() { - if (auto_close_) { - auto self_fd = GetSelfFileDescriptor(); - if (::close(self_fd) != 0) { - CRU_LOG_ERROR(u"Failed to close unix pipe file descriptor {}, errno {}.", - self_fd, errno); - } - } -} -} // namespace cru::platform::unix diff --git a/src/common/platform/web/WebException.cpp b/src/common/platform/web/WebException.cpp deleted file mode 100644 index 30f9d1f0..00000000 --- a/src/common/platform/web/WebException.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "cru/common/platform/web/WebException.h" diff --git a/src/common/platform/win/BridgeComStream.cpp b/src/common/platform/win/BridgeComStream.cpp deleted file mode 100644 index 4c83fd45..00000000 --- a/src/common/platform/win/BridgeComStream.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "BrigdeComStream.h" -#include "cru/common/io/Stream.h" - -namespace cru::platform::win { -BridgeComStream::BridgeComStream(io::Stream *stream) - : stream_(stream), ref_count_(1) {} - -BridgeComStream::~BridgeComStream() {} - -ULONG BridgeComStream::AddRef() { return ++ref_count_; } - -ULONG BridgeComStream::Release() { - --ref_count_; - - if (ref_count_ == 0) { - delete this; - return 0; - } - - return ref_count_; -} - -HRESULT BridgeComStream::QueryInterface(const IID &riid, void **ppvObject) { - if (riid == IID_IStream) { - *ppvObject = static_cast<IStream *>(this); - AddRef(); - return S_OK; - } else if (riid == IID_ISequentialStream) { - *ppvObject = static_cast<ISequentialStream *>(this); - AddRef(); - return S_OK; - } else if (riid == IID_IUnknown) { - *ppvObject = static_cast<IUnknown *>(this); - AddRef(); - return S_OK; - } else { - return E_NOINTERFACE; - } -} - -HRESULT BridgeComStream::Read(void *pv, ULONG cb, ULONG *pcbRead) { - *pcbRead = stream_->Read(static_cast<std::byte *>(pv), cb); - return S_OK; -} - -HRESULT BridgeComStream::Write(const void *pv, ULONG cb, ULONG *pcbWritten) { - *pcbWritten = stream_->Write(static_cast<const std::byte *>(pv), cb); - return S_OK; -} - -HRESULT BridgeComStream::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, - ULARGE_INTEGER *plibNewPosition) { - io::Stream::SeekOrigin so; - - switch (dwOrigin) { - case STREAM_SEEK_SET: - so = io::Stream::SeekOrigin::Begin; - break; - case STREAM_SEEK_CUR: - so = io::Stream::SeekOrigin::Current; - break; - case STREAM_SEEK_END: - so = io::Stream::SeekOrigin::End; - break; - default: - return STG_E_INVALIDFUNCTION; - }; - - plibNewPosition->QuadPart = stream_->Seek(dlibMove.QuadPart, so); - return S_OK; -} - -HRESULT BridgeComStream::SetSize(ULARGE_INTEGER libNewSize) { - return E_NOTIMPL; -} - -HRESULT BridgeComStream::CopyTo(IStream *pstm, ULARGE_INTEGER cb, - ULARGE_INTEGER *pcbRead, - ULARGE_INTEGER *pcbWritten) { - return E_NOTIMPL; -} - -HRESULT BridgeComStream::Commit(DWORD grfCommitFlags) { return S_OK; } - -HRESULT BridgeComStream::Revert() { return S_OK; } - -HRESULT BridgeComStream::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, - DWORD dwLockType) { - return S_OK; -} - -HRESULT BridgeComStream::UnlockRegion(ULARGE_INTEGER libOffset, - ULARGE_INTEGER cb, DWORD dwLockType) { - return S_OK; -} - -HRESULT BridgeComStream::Stat(STATSTG *pstatstg, DWORD grfStatFlag) { - return E_NOTIMPL; -} - -HRESULT BridgeComStream::Clone(IStream **ppstm) { - *ppstm = new BridgeComStream(stream_); - return S_OK; -} - -} // namespace cru::platform::win diff --git a/src/common/platform/win/BrigdeComStream.h b/src/common/platform/win/BrigdeComStream.h deleted file mode 100644 index 7c8a79d1..00000000 --- a/src/common/platform/win/BrigdeComStream.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#include "cru/common/platform/win/WinPreConfig.h" - -#include "cru/common/io/Stream.h" - -#include <objidlbase.h> - -namespace cru::platform::win { -class BridgeComStream : public IStream { - public: - explicit BridgeComStream(io::Stream* stream); - - CRU_DELETE_COPY(BridgeComStream) - CRU_DELETE_MOVE(BridgeComStream) - - ~BridgeComStream(); - - public: - ULONG AddRef() override; - ULONG Release() override; - HRESULT QueryInterface(REFIID riid, void** ppvObject) override; - - HRESULT Read(void* pv, ULONG cb, ULONG* pcbRead) override; - HRESULT Write(const void* pv, ULONG cb, ULONG* pcbWritten) override; - HRESULT Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, - ULARGE_INTEGER* plibNewPosition) override; - HRESULT SetSize(ULARGE_INTEGER libNewSize) override; - HRESULT CopyTo(IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, - ULARGE_INTEGER* pcbWritten) override; - HRESULT Commit(DWORD grfCommitFlags) override; - HRESULT Revert() override; - HRESULT LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, - DWORD dwLockType) override; - HRESULT UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, - DWORD dwLockType) override; - HRESULT Stat(STATSTG* pstatstg, DWORD grfStatFlag) override; - HRESULT Clone(IStream** ppstm) override; - - private: - io::Stream* stream_; - ULONG ref_count_; -}; -} // namespace cru::platform::win diff --git a/src/common/platform/win/ComAutoInit.cpp b/src/common/platform/win/ComAutoInit.cpp deleted file mode 100644 index 55a53a8d..00000000 --- a/src/common/platform/win/ComAutoInit.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "cru/common/platform/win/ComAutoInit.h" -#include "cru/common/platform/win/Exception.h" - -#include <combaseapi.h> - -namespace cru::platform::win { -ComAutoInit::ComAutoInit() { - const auto hresult = ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); - if (FAILED(hresult)) { - throw HResultError(hresult, "Failed to call CoInitializeEx."); - } -} - -ComAutoInit::~ComAutoInit() { ::CoUninitialize(); } -} // namespace cru::platform::win diff --git a/src/common/platform/win/DebugLogTarget.cpp b/src/common/platform/win/DebugLogTarget.cpp deleted file mode 100644 index 92d26449..00000000 --- a/src/common/platform/win/DebugLogTarget.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "cru/common/platform/win/DebugLogTarget.h" - -namespace cru::platform::win { -void WinDebugLogTarget::Write(::cru::log::LogLevel level, StringView s) { - CRU_UNUSED(level) - - String m = s.ToString(); - ::OutputDebugStringW(reinterpret_cast<const wchar_t*>(m.c_str())); -} -} // namespace cru::platform::win diff --git a/src/common/platform/win/Exception.cpp b/src/common/platform/win/Exception.cpp deleted file mode 100644 index a20e8a31..00000000 --- a/src/common/platform/win/Exception.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "cru/common/platform/win/Exception.h" -#include "cru/common/Format.h" - -#include <optional> - -namespace cru::platform::win { - -inline String HResultMakeMessage(HRESULT h_result, - std::optional<String> message) { - if (message.has_value()) - return Format(u"HRESULT: {}. Message: {}", h_result, message->WinCStr()); - else - return Format(u"HRESULT: {}.", h_result); -} - -HResultError::HResultError(HRESULT h_result) - : PlatformException(HResultMakeMessage(h_result, std::nullopt)), - h_result_(h_result) {} - -HResultError::HResultError(HRESULT h_result, - std::string_view additional_message) - : PlatformException(HResultMakeMessage( - h_result, String::FromUtf8(additional_message.data(), - additional_message.size()))), - h_result_(h_result) {} - -inline String Win32MakeMessage(DWORD error_code, String message) { - return Format(u"Last error code: {}.\nMessage: {}\n", error_code, - message.WinCStr()); -} - -Win32Error::Win32Error(String message) - : Win32Error(::GetLastError(), message) {} - -Win32Error::Win32Error(DWORD error_code, String message) - : PlatformException(Win32MakeMessage(error_code, message)), - error_code_(error_code) {} -} // namespace cru::platform::win diff --git a/src/common/platform/win/StreamConvert.cpp b/src/common/platform/win/StreamConvert.cpp deleted file mode 100644 index d547caa5..00000000 --- a/src/common/platform/win/StreamConvert.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "cru/common/platform/win/StreamConvert.h" -#include "BrigdeComStream.h" -#include "Win32FileStreamPrivate.h" -#include "cru/common/Exception.h" -#include "cru/common/io/MemoryStream.h" -#include "cru/common/io/OpenFileFlag.h" -#include "cru/common/platform/win/ComAutoInit.h" -#include "cru/common/platform/win/Exception.h" -#include "cru/common/platform/win/Win32FileStream.h" - -#include <shlwapi.h> -#include <winnt.h> - -namespace cru::platform::win { -IStream* ConvertStreamToComStream(io::Stream* stream) { - static ComAutoInit com_auto_init; - - if (auto memory_stream = dynamic_cast<io::MemoryStream*>(stream)) { - return SHCreateMemStream( - reinterpret_cast<const BYTE*>(memory_stream->GetBuffer()), - memory_stream->GetSize()); - } else if (auto file_stream = dynamic_cast<Win32FileStream*>(stream)) { - return file_stream->GetPrivate_()->stream_; - } else { - return new BridgeComStream(stream); - } -} -} // namespace cru::platform::win diff --git a/src/common/platform/win/Win32FileStream.cpp b/src/common/platform/win/Win32FileStream.cpp deleted file mode 100644 index a118dc02..00000000 --- a/src/common/platform/win/Win32FileStream.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "cru/common/platform/win/Win32FileStream.h" - -#include "Win32FileStreamPrivate.h" -#include "cru/common/io/OpenFileFlag.h" -#include "cru/common/platform/win/Exception.h" - -#include <Windows.h> -#include <coml2api.h> -#include <shlwapi.h> -#include <winnt.h> -#include <filesystem> - -namespace cru::platform::win { -using namespace cru::io; - -Win32FileStream::Win32FileStream(String path, OpenFileFlag flags) - : path_(std::move(path)), - flags_(flags), - p_(new details::Win32FileStreamPrivate()) { - DWORD grfMode = STGM_SHARE_DENY_NONE; - if (flags & io::OpenFileFlags::Read) { - if (flags & io::OpenFileFlags::Write) { - grfMode |= STGM_READWRITE; - } else { - grfMode |= STGM_READ; - } - } else { - if (flags & io::OpenFileFlags::Write) { - grfMode |= STGM_WRITE; - } else { - throw Exception(u"Stream must be readable or writable."); - } - } - - if (flags & io::OpenFileFlags::Truncate) { - grfMode |= STGM_CREATE; - } - - IStream* stream; - - ThrowIfFailed(SHCreateStreamOnFileEx( - path_.WinCStr(), grfMode, FILE_ATTRIBUTE_NORMAL, - flags & io::OpenFileFlags::Create ? TRUE : FALSE, NULL, &stream)); - - p_->stream_ = stream; -} - -Win32FileStream::~Win32FileStream() { - Close(); - delete p_; -} - -bool Win32FileStream::CanSeek() { return true; } - -Index Win32FileStream::Seek(Index offset, SeekOrigin origin) { - CheckClosed(); - - DWORD dwOrigin = 0; - - if (origin == SeekOrigin::Current) { - dwOrigin = STREAM_SEEK_CUR; - } else if (origin == SeekOrigin::End) { - dwOrigin = STREAM_SEEK_END; - } else { - dwOrigin = STREAM_SEEK_SET; - } - - LARGE_INTEGER n_offset; - n_offset.QuadPart = offset; - ULARGE_INTEGER n_new_offset; - - ThrowIfFailed(p_->stream_->Seek(n_offset, dwOrigin, &n_new_offset)); - - return n_new_offset.QuadPart; -} - -bool Win32FileStream::CanRead() { return true; } - -Index Win32FileStream::Read(std::byte* buffer, Index offset, Index size) { - if (size < 0) { - throw Exception(u"Size must be greater than 0."); - } - - CheckClosed(); - - ULONG n_read; - ThrowIfFailed(p_->stream_->Read(buffer + offset, size, &n_read)); - return n_read; -} - -bool Win32FileStream::CanWrite() { return true; } - -Index Win32FileStream::Write(const std::byte* buffer, Index offset, - Index size) { - if (size < 0) { - throw Exception(u"Size must be greater than 0."); - } - - CheckClosed(); - - ULONG n_written; - ThrowIfFailed(p_->stream_->Write(buffer + offset, size, &n_written)); - - return n_written; -} - -void Win32FileStream::Close() { - if (closed_) return; - - if (p_->stream_) { - p_->stream_->Release(); - p_->stream_ = nullptr; - } - - closed_ = true; -} - -void Win32FileStream::CheckClosed() { - if (closed_) throw Exception(u"Stream is closed."); -} - -} // namespace cru::platform::win diff --git a/src/common/platform/win/Win32FileStreamPrivate.h b/src/common/platform/win/Win32FileStreamPrivate.h deleted file mode 100644 index 24492f8d..00000000 --- a/src/common/platform/win/Win32FileStreamPrivate.h +++ /dev/null @@ -1,13 +0,0 @@ -#include "cru/common/platform/win/WinPreConfig.h" - -#include <objidl.h> - -namespace cru::platform::win { - -namespace details { -struct Win32FileStreamPrivate { - IStream* stream_ = nullptr; -}; -} // namespace details - -} // namespace cru::platform::win |