aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/win/string.hpp14
-rw-r--r--src/win/string.cpp40
-rw-r--r--test/win/string.cpp27
3 files changed, 76 insertions, 5 deletions
diff --git a/include/cru/win/string.hpp b/include/cru/win/string.hpp
index 75395052..3fdadbf8 100644
--- a/include/cru/win/string.hpp
+++ b/include/cru/win/string.hpp
@@ -60,9 +60,10 @@ class Utf8Iterator : public Object {
};
class Utf16Iterator : public Object {
- static_assert(sizeof(wchar_t) == 2,
- "Emmm, according to my knowledge, wchar_t should be 2-length on "
- "Windows. If not, Utf16 will be broken.");
+ static_assert(
+ sizeof(wchar_t) == 2,
+ "Emmm, according to my knowledge, wchar_t should be 2-length on "
+ "Windows. If not, Utf16 will be broken.");
public:
Utf16Iterator(const std::wstring_view& string) : string_(string) {}
@@ -86,4 +87,11 @@ class Utf16Iterator : public Object {
std::wstring_view string_;
int position_ = 0;
};
+
+int IndexUtf8ToUtf16(const std::string_view& utf8_string, int utf8_index,
+ const std::wstring_view& utf16_string);
+
+int IndexUtf16ToUtf8(const std::wstring_view& utf16_string, int utf16_index,
+ const std::string_view& utf8_string);
+
} // namespace cru::platform::win
diff --git a/src/win/string.cpp b/src/win/string.cpp
index c8b0ca87..fb9811eb 100644
--- a/src/win/string.cpp
+++ b/src/win/string.cpp
@@ -143,4 +143,44 @@ CodePoint Utf16Iterator::Next() {
}
}
+int IndexUtf8ToUtf16(const std::string_view& utf8_string, int utf8_index,
+ const std::wstring_view& utf16_string) {
+ if (utf8_index >= static_cast<int>(utf8_string.length()))
+ return static_cast<int>(utf16_string.length());
+
+ int cp_index = 0;
+ Utf8Iterator iter{utf8_string};
+ while (iter.CurrentPosition() <= utf8_index) {
+ iter.Next();
+ cp_index++;
+ }
+
+ Utf16Iterator result_iter{utf16_string};
+ for (int i = 0; i < cp_index - 1; i++) {
+ if (result_iter.Next() == k_code_point_end) break;
+ }
+
+ return result_iter.CurrentPosition();
+}
+
+int IndexUtf16ToUtf8(const std::wstring_view& utf16_string, int utf16_index,
+ const std::string_view& utf8_string) {
+ if (utf16_index >= static_cast<int>(utf16_string.length()))
+ return static_cast<int>(utf8_string.length());
+
+ int cp_index = 0;
+ Utf16Iterator iter{utf16_string};
+ while (iter.CurrentPosition() <= utf16_index) {
+ iter.Next();
+ cp_index++;
+ }
+
+ Utf8Iterator result_iter{utf8_string};
+ for (int i = 0; i < cp_index - 1; i++) {
+ if (result_iter.Next() == k_code_point_end) break;
+ }
+
+ return result_iter.CurrentPosition();
+}
+
} // namespace cru::platform::win
diff --git a/test/win/string.cpp b/test/win/string.cpp
index 4e25f8c0..3864b987 100644
--- a/test/win/string.cpp
+++ b/test/win/string.cpp
@@ -4,7 +4,7 @@
using cru::platform::win::k_code_point_end;
-TEST(WinString, Utf8ShouldWork) {
+TEST(WinString, Utf8Iterator) {
using cru::platform::win::Utf8Iterator;
std::string_view text = "aπ你🤣!";
Utf8Iterator i{text};
@@ -16,7 +16,7 @@ TEST(WinString, Utf8ShouldWork) {
ASSERT_EQ(i.Next(), k_code_point_end);
}
-TEST(WinString, Utf16ShouldWork) {
+TEST(WinString, Utf16Iterator) {
using cru::platform::win::Utf16Iterator;
std::wstring_view text = L"aπ你🤣!";
Utf16Iterator i{text};
@@ -28,3 +28,26 @@ TEST(WinString, Utf16ShouldWork) {
ASSERT_EQ(i.Next(), k_code_point_end);
}
+TEST(WinString, IndexUtf8ToUtf16) {
+ using cru::platform::win::IndexUtf8ToUtf16;
+ std::string_view utf8_string = "aπ你🤣!";
+ std::wstring_view utf16_string = L"aπ你🤣!";
+ ASSERT_EQ(IndexUtf8ToUtf16(utf8_string, 0, utf16_string), 0);
+ ASSERT_EQ(IndexUtf8ToUtf16(utf8_string, 1, utf16_string), 1);
+ ASSERT_EQ(IndexUtf8ToUtf16(utf8_string, 3, utf16_string), 2);
+ ASSERT_EQ(IndexUtf8ToUtf16(utf8_string, 6, utf16_string), 3);
+ ASSERT_EQ(IndexUtf8ToUtf16(utf8_string, 10, utf16_string), 5);
+ ASSERT_EQ(IndexUtf8ToUtf16(utf8_string, 11, utf16_string), 6);
+}
+
+TEST(WinString, IndexUtf16ToUtf8) {
+ using cru::platform::win::IndexUtf16ToUtf8;
+ std::string_view utf8_string = "aπ你🤣!";
+ std::wstring_view utf16_string = L"aπ你🤣!";
+ ASSERT_EQ(IndexUtf16ToUtf8(utf16_string, 0, utf8_string), 0);
+ ASSERT_EQ(IndexUtf16ToUtf8(utf16_string, 1, utf8_string), 1);
+ ASSERT_EQ(IndexUtf16ToUtf8(utf16_string, 2, utf8_string), 3);
+ ASSERT_EQ(IndexUtf16ToUtf8(utf16_string, 3, utf8_string), 6);
+ ASSERT_EQ(IndexUtf16ToUtf8(utf16_string, 5, utf8_string), 10);
+ ASSERT_EQ(IndexUtf16ToUtf8(utf16_string, 6, utf8_string), 11);
+}