diff options
author | crupest <crupest@outlook.com> | 2022-01-08 17:35:10 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2022-01-08 17:35:10 +0800 |
commit | c38f1f7c273e85c0a6d197cb27424c9ca69e234d (patch) | |
tree | e87685469d9b442966b97f11a48d0bc48ffaf074 | |
parent | 431cbdbe7d3ae8c45458dcf914717b0365ecd99a (diff) | |
download | cru-c38f1f7c273e85c0a6d197cb27424c9ca69e234d.tar.gz cru-c38f1f7c273e85c0a6d197cb27424c9ca69e234d.tar.bz2 cru-c38f1f7c273e85c0a6d197cb27424c9ca69e234d.zip |
...
-rw-r--r-- | include/cru/common/String.hpp | 6 | ||||
-rw-r--r-- | src/common/String.cpp | 78 | ||||
-rw-r--r-- | test/common/StringTest.cpp | 37 |
3 files changed, 120 insertions, 1 deletions
diff --git a/include/cru/common/String.hpp b/include/cru/common/String.hpp index bd079243..86e0a134 100644 --- a/include/cru/common/String.hpp +++ b/include/cru/common/String.hpp @@ -181,7 +181,13 @@ class CRU_BASE_API String { } public: + Index Find(value_type value, Index start = 0) const; + + String& TrimStart(); String& TrimEnd(); + String& Trim(); + + std::vector<String> SplitToLines(bool remove_space_line = false) const; public: void AppendCodePoint(CodePoint code_point); diff --git a/src/common/String.cpp b/src/common/String.cpp index 8d674369..ade2a72d 100644 --- a/src/common/String.cpp +++ b/src/common/String.cpp @@ -113,6 +113,8 @@ String::~String() { 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); @@ -211,6 +213,32 @@ String::iterator String::erase(const_iterator start, const_iterator end) { return s; } +Index String::Find(value_type value, Index start) const { + Expects(start >= 0 && start <= size_); + + for (Index i = start; i < size_; ++i) { + if (buffer_[i] == value) return i; + } + return -1; +} + +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])) { @@ -220,6 +248,56 @@ String& String::TrimEnd() { return *this; } +String& String::Trim() { + TrimStart(); + TrimEnd(); + return *this; +} + +std::vector<String> String::SplitToLines(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 (buffer_[line_end] == '\n') { + if (remove_space_line) { + bool add = false; + for (Index i = line_start; i < line_end; i++) { + if (!IsWhitespace(buffer_[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(buffer_[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::string String::ToUtf8() const { return cru::ToUtf8(buffer_, size_); } void String::AppendCodePoint(CodePoint code_point) { diff --git a/test/common/StringTest.cpp b/test/common/StringTest.cpp index 53ed359f..f11f9197 100644 --- a/test/common/StringTest.cpp +++ b/test/common/StringTest.cpp @@ -19,7 +19,6 @@ TEST(String, IndexConvert) { ASSERT_EQ(s.IndexFromCodeUnitToCodePoint(1), 1); ASSERT_EQ(s.IndexFromCodeUnitToCodePoint(3), 3); ASSERT_EQ(s.IndexFromCodeUnitToCodePoint(3), 3); - } TEST(String, Format) { @@ -28,3 +27,39 @@ TEST(String, Format) { ASSERT_EQ(Format(u"{} + {} = {}", 123, 321, 444), String(u"123 + 321 = 444")); } + +TEST(String, SplitToLines) { + using cru::String; + + String s(u"abc\ndef\nghi"); + auto lines = s.SplitToLines(); + ASSERT_EQ(lines.size(), 3); + ASSERT_EQ(lines[0], String(u"abc")); + ASSERT_EQ(lines[1], String(u"def")); + ASSERT_EQ(lines[2], String(u"ghi")); +} + +TEST(String, SplitToLinesWithEmptyLine) { + using cru::String; + + String s(u"abc\n \ndef\n\nghi\n"); + auto lines = s.SplitToLines(); + ASSERT_EQ(lines.size(), 6); + ASSERT_EQ(lines[0], String(u"abc")); + ASSERT_EQ(lines[1], String(u" ")); + ASSERT_EQ(lines[2], String(u"def")); + ASSERT_EQ(lines[3], String(u"")); + ASSERT_EQ(lines[4], String(u"ghi")); + ASSERT_EQ(lines[5], String(u"")); +} + +TEST(String, SplitToLinesRemoveSpaceLine) { + using cru::String; + + String s(u"abc\n \ndef\n\nghi\n"); + auto lines = s.SplitToLines(true); + ASSERT_EQ(lines.size(), 3); + ASSERT_EQ(lines[0], String(u"abc")); + ASSERT_EQ(lines[1], String(u"def")); + ASSERT_EQ(lines[2], String(u"ghi")); +} |