From 27e0a449351dea48c744192366547dff8868e2bf Mon Sep 17 00:00:00 2001 From: wujianlin Date: Sat, 25 May 2024 16:31:09 +0800 Subject: [PATCH] Added string conversion interface Issue:https://gitee.com/openharmony/commonlibrary_c_utils/issues/I9S4WY?from=project-issue Signed-off-by: wujianlin --- base/include/string_ex.h | 21 +++++++ base/src/string_ex.cpp | 32 +++++++++++ base/src/unicode_ex.h | 4 ++ .../unittest/common/utils_string_test.cpp | 57 +++++++++++++++++++ 4 files changed, 114 insertions(+) diff --git a/base/include/string_ex.h b/base/include/string_ex.h index cf99110..2b70e5d 100644 --- a/base/include/string_ex.h +++ b/base/include/string_ex.h @@ -242,6 +242,27 @@ std::string Str16ToStr8(const std::u16string& str16); * @return Returns an empty `std::u16string` object if the operation fails. */ std::u16string Str8ToStr16(const std::string& str); + +/** + * @ingroup StringOperation + * @brief get the length of utf8 from utf16. + * + * @param str16 Indicates a `std::u16string` object. + * @return Returns -1 if the str16 is empty or the result is greater than INT MAX. + */ +int GetUtf16ToUtf8Length(const std::u16string& str16); + +/** + * @ingroup StringOperation + * @brief Converts a string from UTF-16 to UTF-8 encoded. + * + * @param str16 Indicates a `std::u16string` object. + * @param buffer Converted UTF-8 encoded buffer. + * @param bufferLen Buffer size. + * @return Returns the length of the converted UTF-8 encoding including the terminator '\0'; + * Returns -1 if the operation fails. + */ +int Char16ToChar8(const std::u16string& str16, char *buffer, int bufferLen); #endif } // namespace OHOS diff --git a/base/src/string_ex.cpp b/base/src/string_ex.cpp index 0aa076b..46ac620 100644 --- a/base/src/string_ex.cpp +++ b/base/src/string_ex.cpp @@ -271,5 +271,37 @@ string Str16ToStr8(const u16string& str16) return str8Value; } + +int GetUtf16ToUtf8Length(const u16string& str16) +{ + size_t str16Len = str16.length(); + if (str16Len == 0) { + return -1; + } + const char16_t *utf16Str = str16.c_str(); + return Utf16ToUtf8Length(utf16Str, str16Len); +} + +int Char16ToChar8(const u16string& str16, char *buffer, int bufferLen) +{ + if (buffer == nullptr || bufferLen <= 0) { + UTILS_LOGE("param is invalid!"); + return -1; + } + size_t str16Len = str16.length(); + if (str16Len == 0) { + UTILS_LOGE("str16 is empty!"); + return -1; + } + const char16_t *utf16Str = str16.c_str(); + int utf8Len = Utf16ToUtf8Length(utf16Str, str16Len); + if (utf8Len < 0 || (utf8Len + 1) > bufferLen) { + UTILS_LOGE("utf8buffer len:%{public}d, actual buffer len:%{public}d!", utf8Len + 1, bufferLen); + return -1; + } + StrncpyStr16ToStr8(utf16Str, str16Len, buffer, utf8Len + 1); + return utf8Len + 1; +} + #endif } // namespace OHOS diff --git a/base/src/unicode_ex.h b/base/src/unicode_ex.h index 6db9e5c..3ce54ae 100644 --- a/base/src/unicode_ex.h +++ b/base/src/unicode_ex.h @@ -18,5 +18,9 @@ namespace OHOS { bool String8ToString16(const std::string& str8, std::u16string& str16); bool String16ToString8(const std::u16string& str16, std::string& str8); +extern "C" { + void StrncpyStr16ToStr8(const char16_t* utf16Str, size_t str16Len, char* utf8Str, size_t str8Len); + int Utf16ToUtf8Length(const char16_t* str16, size_t str16Len); +} } #endif // UTILS_BASE_LOG_H diff --git a/base/test/unittest/common/utils_string_test.cpp b/base/test/unittest/common/utils_string_test.cpp index e7ae3d8..8b54675 100644 --- a/base/test/unittest/common/utils_string_test.cpp +++ b/base/test/unittest/common/utils_string_test.cpp @@ -16,6 +16,8 @@ #include #include "string_ex.h" #include +#include + using namespace testing::ext; using namespace std; @@ -531,6 +533,61 @@ HWTEST_F(UtilsStringTest, test_strcovert_04, TestSize.Level0) EXPECT_EQ(0, str8Result.compare(str8Value)); } +HWTEST_F(UtilsStringTest, test_getintstrcovert_01, TestSize.Level0) +{ + u16string str16Value = u"你好"; + string str8Result = Str16ToStr8(str16Value); + int str8Length = str8Result.length(); + int bufferLen = 255; + char buffer[bufferLen]; + memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)); + int int8Result = Char16ToChar8(str16Value, buffer, bufferLen); + + EXPECT_EQ(0, str8Result.compare(buffer)); + EXPECT_EQ(str8Length + 1, int8Result); +} + +HWTEST_F(UtilsStringTest, test_getintstrcovert_02, TestSize.Level0) +{ + u16string str16Value = u"某某技术有限公司"; + string str8Result = Str16ToStr8(str16Value); + int str8Length = str8Result.length(); + int bufferLen = 255; + char buffer[bufferLen]; + memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)); + int int8Result = Char16ToChar8(str16Value, buffer, bufferLen); + + EXPECT_EQ(0, str8Result.compare(buffer)); + EXPECT_EQ(str8Length + 1, int8Result); +} + +HWTEST_F(UtilsStringTest, test_getintstrcovert_03, TestSize.Level0) +{ + u16string str16Value = u"hello world!"; + string str8Result = Str16ToStr8(str16Value); + int str8Length = str8Result.length(); + int bufferLen = 255; + char buffer[bufferLen]; + memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)); + int int8Result = Char16ToChar8(str16Value, buffer, bufferLen); + + EXPECT_EQ(0, str8Result.compare(buffer)); + EXPECT_EQ(str8Length + 1, int8Result); +} + +HWTEST_F(UtilsStringTest, test_getintstrcovert_04, TestSize.Level0) +{ + u16string str16Value = u"1234567890!@#$%^&*()."; + string str8Result = Str16ToStr8(str16Value); + int str8Length = str8Result.length(); + int bufferLen = 255; + char buffer[bufferLen]; + memset_s(buffer, sizeof(buffer), 0, sizeof(buffer)); + int int8Result = Char16ToChar8(str16Value, buffer, bufferLen); + + EXPECT_EQ(0, str8Result.compare(buffer)); + EXPECT_EQ(str8Length + 1, int8Result); +} HWTEST_F(UtilsStringTest, test_getsubstr_01, TestSize.Level0) { -- Gitee