diff --git a/base/include/string_ex.h b/base/include/string_ex.h index cf99110c3561048b2eec33507de2a2b1e8fa6196..2b70e5d2a50e523d1de41546bac8055a009bf538 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 0aa076b9b812939f336a3c04adc353ef84a4c8ec..46ac620af216fd9d600fee5063f32580d3d89c39 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 6db9e5c0b30a24065ab20d6a3aff4f237a5f8474..3ce54ae945c888e3be1b9cab3ac7f7490da256c5 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 e7ae3d8311bda879cb49e03fcbddf163981913d3..8b54675c233fa46a7d57071188cb756ec701bf67 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) {