aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/Base.cpp7
-rw-r--r--src/common/Buffer.cpp277
-rw-r--r--src/common/CMakeLists.txt80
-rw-r--r--src/common/Exception.cpp36
-rw-r--r--src/common/Format.cpp111
-rw-r--r--src/common/PropertyTree.cpp71
-rw-r--r--src/common/String.cpp672
-rw-r--r--src/common/StringToNumberConverter.cpp170
-rw-r--r--src/common/StringUtil.cpp243
-rw-r--r--src/common/SubProcess.cpp209
-rw-r--r--src/common/io/AutoReadStream.cpp56
-rw-r--r--src/common/io/BufferStream.cpp109
-rw-r--r--src/common/io/CFileStream.cpp96
-rw-r--r--src/common/io/MemoryStream.cpp74
-rw-r--r--src/common/io/OpenFileFlag.cpp19
-rw-r--r--src/common/io/ProxyStream.cpp37
-rw-r--r--src/common/io/Resource.cpp48
-rw-r--r--src/common/io/Stream.cpp199
-rw-r--r--src/common/log/Logger.cpp88
-rw-r--r--src/common/log/StdioLogTarget.cpp27
-rw-r--r--src/common/platform/Exception.cpp1
-rw-r--r--src/common/platform/osx/Convert.cpp29
-rw-r--r--src/common/platform/osx/Exception.cpp1
-rw-r--r--src/common/platform/unix/PosixSpawnSubProcess.cpp204
-rw-r--r--src/common/platform/unix/UnixFileStream.cpp106
-rw-r--r--src/common/platform/unix/UnixPipe.cpp51
-rw-r--r--src/common/platform/web/WebException.cpp1
-rw-r--r--src/common/platform/win/BridgeComStream.cpp106
-rw-r--r--src/common/platform/win/BrigdeComStream.h43
-rw-r--r--src/common/platform/win/ComAutoInit.cpp15
-rw-r--r--src/common/platform/win/DebugLogTarget.cpp10
-rw-r--r--src/common/platform/win/Exception.cpp38
-rw-r--r--src/common/platform/win/StreamConvert.cpp28
-rw-r--r--src/common/platform/win/Win32FileStream.cpp122
-rw-r--r--src/common/platform/win/Win32FileStreamPrivate.h13
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, &current]() -> 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