aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2024-06-10 13:40:32 +0800
committercrupest <crupest@outlook.com>2024-06-10 13:40:32 +0800
commit633c77d7cd2dd5cd22018aca17da1490e34d94ec (patch)
treeac007e9c84dbf662662f8b2ff06c2321945d2c6a
parent4725b4bc48722356fea4570ed7770137a0999491 (diff)
downloadcru-633c77d7cd2dd5cd22018aca17da1490e34d94ec.tar.gz
cru-633c77d7cd2dd5cd22018aca17da1490e34d94ec.tar.bz2
cru-633c77d7cd2dd5cd22018aca17da1490e34d94ec.zip
test: develop SubProcess test, fix various error.
NEED TEST: BufferStream, AutoReadStream, SubProcess.
-rw-r--r--include/cru/common/Buffer.h1
-rw-r--r--include/cru/common/String.h2
-rw-r--r--include/cru/common/SubProcess.h5
-rw-r--r--include/cru/common/io/Stream.h4
-rw-r--r--src/common/Buffer.cpp5
-rw-r--r--src/common/String.cpp14
-rw-r--r--src/common/SubProcess.cpp9
-rw-r--r--src/common/io/Stream.cpp22
-rw-r--r--src/common/platform/unix/PosixSpawnSubProcess.cpp5
-rw-r--r--src/ui/ThemeResourceDictionary.cpp2
-rw-r--r--test/common/CMakeLists.txt1
-rw-r--r--test/common/SubProcessTest.cpp13
12 files changed, 68 insertions, 15 deletions
diff --git a/include/cru/common/Buffer.h b/include/cru/common/Buffer.h
index a03b69eb..2c3b7b87 100644
--- a/include/cru/common/Buffer.h
+++ b/include/cru/common/Buffer.h
@@ -7,6 +7,7 @@ class Buffer final {
friend void swap(Buffer& left, Buffer& right) noexcept;
public:
+ Buffer();
explicit Buffer(Index size);
Buffer(const Buffer& other);
diff --git a/include/cru/common/String.h b/include/cru/common/String.h
index 2156f060..5d9fc549 100644
--- a/include/cru/common/String.h
+++ b/include/cru/common/String.h
@@ -35,9 +35,11 @@ class CRU_BASE_API String {
public:
static String FromUtf8(const char* str);
static String FromUtf8(const char* str, Index size);
+ static String FromUtf8(const std::byte* str, Index size);
static String FromUtf8(std::string_view str) {
return FromUtf8(str.data(), str.size());
}
+ static String FromUtf8(const Buffer& buffer);
static String FromUtf16(const char16_t* str) { return String(str); }
static String FromUtf16(const char16_t* str, Index size) {
diff --git a/include/cru/common/SubProcess.h b/include/cru/common/SubProcess.h
index 0f87b184..1f7193b5 100644
--- a/include/cru/common/SubProcess.h
+++ b/include/cru/common/SubProcess.h
@@ -197,6 +197,11 @@ class CRU_BASE_API SubProcess : public Object {
CRU_DEFINE_CLASS_LOG_TAG(u"SubProcess")
public:
+ static SubProcess Create(
+ String program, std::vector<String> arguments = {},
+ std::unordered_map<String, String> environments = {});
+
+ public:
SubProcess(SubProcessStartInfo start_info);
CRU_DELETE_COPY(SubProcess)
diff --git a/include/cru/common/io/Stream.h b/include/cru/common/io/Stream.h
index 9f9807ae..014cd472 100644
--- a/include/cru/common/io/Stream.h
+++ b/include/cru/common/io/Stream.h
@@ -64,10 +64,10 @@ class CRU_BASE_API Stream : public Object {
Index Write(const char* buffer, Index offset, Index size);
Index Write(const char* buffer, Index size);
- virtual std::vector<std::byte> ReadAll();
+ virtual Buffer ReadToEnd(Index grow_size = 256);
// Utf8 encoding.
- String ReadAllAsString();
+ String ReadToEndAsUtf8String();
virtual void Flush();
diff --git a/src/common/Buffer.cpp b/src/common/Buffer.cpp
index 49a0f8ae..af0871ca 100644
--- a/src/common/Buffer.cpp
+++ b/src/common/Buffer.cpp
@@ -12,6 +12,11 @@ void CheckSize(Index size) {
}
} // namespace
+Buffer::Buffer() {
+ ptr_ = nullptr;
+ size_ = used_begin_ = used_end_ = 0;
+}
+
Buffer::Buffer(Index size) {
CheckSize(size);
if (size == 0) {
diff --git a/src/common/String.cpp b/src/common/String.cpp
index b2e52e67..8736c775 100644
--- a/src/common/String.cpp
+++ b/src/common/String.cpp
@@ -33,11 +33,19 @@ String String::FromUtf8(const char* str, Index size) {
Utf8CodePointIterator iter(str, size);
for (auto cp : iter) {
Utf16EncodeCodePointAppend(
- cp, std::bind(&String::push_back, result, std::placeholders::_1));
+ 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());
}
@@ -301,7 +309,7 @@ String& String::Trim() {
void String::AppendCodePoint(CodePoint code_point) {
if (!Utf16EncodeCodePointAppend(
code_point,
- std::bind(&String::push_back, *this, std::placeholders::_1))) {
+ std::bind(&String::push_back, this, std::placeholders::_1))) {
throw TextEncodeException(u"Code point out of range.");
}
}
@@ -532,7 +540,7 @@ std::string StringView::ToUtf8() const {
std::string result;
for (auto cp : CodePointIterator()) {
Utf8EncodeCodePointAppend(
- cp, std::bind(&std::string::push_back, result, std::placeholders::_1));
+ cp, std::bind(&std::string::push_back, std::ref(result), std::placeholders::_1));
}
return result;
}
diff --git a/src/common/SubProcess.cpp b/src/common/SubProcess.cpp
index fbe15859..e2738248 100644
--- a/src/common/SubProcess.cpp
+++ b/src/common/SubProcess.cpp
@@ -137,6 +137,15 @@ void PlatformSubProcessBase::SetDeleteSelfOnExit(bool enable) {
using PlatformSubProcess = platform::unix::PosixSpawnSubProcess;
#endif
+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));
+}
+
SubProcess::SubProcess(SubProcessStartInfo start_info) {
platform_process_.reset(new PlatformSubProcess(std::move(start_info)));
platform_process_->Start();
diff --git a/src/common/io/Stream.cpp b/src/common/io/Stream.cpp
index 97669944..b2a67a18 100644
--- a/src/common/io/Stream.cpp
+++ b/src/common/io/Stream.cpp
@@ -58,17 +58,23 @@ Index Stream::Write(const char* buffer, Index size) {
return Write(reinterpret_cast<const std::byte*>(buffer), size);
}
-std::vector<std::byte> Stream::ReadAll() {
- std::vector<std::byte> buffer;
- buffer.resize(GetSize());
- Read(buffer.data(), 0, buffer.size());
+Buffer Stream::ReadToEnd(Index grow_size) {
+ Buffer buffer(grow_size);
+ while (true) {
+ auto read = Read(buffer.GetUsedEndPtr(), buffer.GetBackFree());
+ if (read == 0) {
+ break;
+ }
+ if (buffer.IsUsedReachEnd()) {
+ buffer.ResizeBuffer(buffer.GetBufferSize() + grow_size, true);
+ }
+ }
return buffer;
}
-String Stream::ReadAllAsString() {
- auto buffer = ReadAll();
- return String::FromUtf8(reinterpret_cast<const char*>(buffer.data()),
- buffer.size());
+String Stream::ReadToEndAsUtf8String() {
+ auto buffer = ReadToEnd();
+ return String::FromUtf8(buffer);
}
void Stream::Flush() {}
diff --git a/src/common/platform/unix/PosixSpawnSubProcess.cpp b/src/common/platform/unix/PosixSpawnSubProcess.cpp
index 9b9a52ae..fba536e5 100644
--- a/src/common/platform/unix/PosixSpawnSubProcess.cpp
+++ b/src/common/platform/unix/PosixSpawnSubProcess.cpp
@@ -119,8 +119,11 @@ void PosixSpawnSubProcess::PlatformCreateProcess() {
#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(start_info_.arguments);
+ auto argv = CreateCstrArray(arguments);
Guard argv_guard([argv] { DestroyCstrArray(argv); });
auto envp = CreateCstrArray(start_info_.environments);
diff --git a/src/ui/ThemeResourceDictionary.cpp b/src/ui/ThemeResourceDictionary.cpp
index f91fcb1c..86a19083 100644
--- a/src/ui/ThemeResourceDictionary.cpp
+++ b/src/ui/ThemeResourceDictionary.cpp
@@ -9,7 +9,7 @@ namespace cru::ui {
std::unique_ptr<ThemeResourceDictionary> ThemeResourceDictionary::FromFile(
const String& file_path) {
io::CFileStream stream(file_path.ToUtf8().c_str(), "r");
- auto xml_string = stream.ReadAllAsString();
+ auto xml_string = stream.ReadToEndAsUtf8String();
auto parser = xml::XmlParser(xml_string);
return std::make_unique<ThemeResourceDictionary>(parser.Parse(), false);
}
diff --git a/test/common/CMakeLists.txt b/test/common/CMakeLists.txt
index f2fda47d..d2351b38 100644
--- a/test/common/CMakeLists.txt
+++ b/test/common/CMakeLists.txt
@@ -6,6 +6,7 @@ add_executable(CruBaseTest
StringTest.cpp
StringToNumberConverterTest.cpp
StringUtilTest.cpp
+ SubProcessTest.cpp
)
target_link_libraries(CruBaseTest PRIVATE CruBase CruTestBase)
diff --git a/test/common/SubProcessTest.cpp b/test/common/SubProcessTest.cpp
new file mode 100644
index 00000000..35bf88b9
--- /dev/null
+++ b/test/common/SubProcessTest.cpp
@@ -0,0 +1,13 @@
+#include "cru/common/SubProcess.h"
+
+#include <catch2/catch_test_macros.hpp>
+
+using cru::SubProcess;
+
+TEST_CASE("SubProcess", "[subprocess]") {
+ SECTION("should work.") {
+ SubProcess process = SubProcess::Create(u"echo", {u"abc"});
+ auto output = process.GetStdoutStream()->ReadToEndAsUtf8String();
+ REQUIRE(output == u"abc");
+ }
+}