From 048ded16ea661133bba4c1cc65b0ef49ceac3628 Mon Sep 17 00:00:00 2001 From: nadolskyanton Date: Wed, 19 Feb 2025 16:51:55 +0300 Subject: [PATCH] ANI: Implement String_GetUTF8 Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/IBKHAA Description: Implemented ANI String_GetUTF8 Signed-off-by: nadolskyanton --- .../ets/runtime/ani/ani_interaction_api.cpp | 23 +++- .../tests/ani/tests/string_ops/CMakeLists.txt | 5 + .../tests/string_ops/string_get_utf8_test.cpp | 114 ++++++++++++++++++ .../tests/string_ops/string_get_utf8_test.sts | 19 +++ 4 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 static_core/plugins/ets/tests/ani/tests/string_ops/string_get_utf8_test.cpp create mode 100644 static_core/plugins/ets/tests/ani/tests/string_ops/string_get_utf8_test.sts diff --git a/static_core/plugins/ets/runtime/ani/ani_interaction_api.cpp b/static_core/plugins/ets/runtime/ani/ani_interaction_api.cpp index 177a5dc4f4..5167d9b808 100644 --- a/static_core/plugins/ets/runtime/ani/ani_interaction_api.cpp +++ b/static_core/plugins/ets/runtime/ani/ani_interaction_api.cpp @@ -2303,6 +2303,27 @@ NO_UB_SANITIZE static ani_status String_GetUTF8Size(ani_env *env, ani_string str *result = internalString->GetUtf8Length(); return ANI_OK; } +// NOLINTNEXTLINE(readability-identifier-naming) +NO_UB_SANITIZE static ani_status String_GetUTF8(ani_env *env, ani_string string, char *utf8Buffer, + ani_size utf8BufferSize, ani_size *result) +{ + ANI_DEBUG_TRACE(env); + CHECK_ENV(env); + CHECK_PTR_ARG(string); + CHECK_PTR_ARG(utf8Buffer); + CHECK_PTR_ARG(result); + + ScopedManagedCodeFix s(env); + auto internalString = s.ToInternalType(string); + auto utf8Length = internalString->GetUtf8Length(); + if (UNLIKELY(utf8BufferSize < utf8Length || (utf8BufferSize - utf8Length) < 1)) { + return ANI_BUFFER_TO_SMALL; + } + ani_size actualCopiedSize = internalString->CopyDataRegionUtf8(utf8Buffer, 0, utf8Length, utf8Length); + utf8Buffer[actualCopiedSize] = '\0'; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) + *result = actualCopiedSize; + return ANI_OK; +} // NOLINTNEXTLINE(readability-identifier-naming) NO_UB_SANITIZE static ani_status String_GetUTF8SubString(ani_env *env, ani_string string, ani_size substr_offset, @@ -3479,7 +3500,7 @@ const __ani_interaction_api INTERACTION_API = { NotImplementedAdapter<72>, String_NewUTF8, String_GetUTF8Size, - NotImplementedAdapter<75>, + String_GetUTF8, String_GetUTF8SubString, Array_GetLength, Array_New_Boolean, diff --git a/static_core/plugins/ets/tests/ani/tests/string_ops/CMakeLists.txt b/static_core/plugins/ets/tests/ani/tests/string_ops/CMakeLists.txt index d4ffb9a4fb..75bb134c2f 100644 --- a/static_core/plugins/ets/tests/ani/tests/string_ops/CMakeLists.txt +++ b/static_core/plugins/ets/tests/ani/tests/string_ops/CMakeLists.txt @@ -23,6 +23,11 @@ ani_add_gtest(ani_test_string_ops_get_utf16_size CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/string_get_utf16_size_test.cpp ) +ani_add_gtest(ani_test_string_ops_get_utf8 + CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/string_get_utf8_test.cpp + ETS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/string_get_utf8_test.sts +) + ani_add_gtest(ani_test_string_ops_get_utf8_substr CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/string_get_utf8_substr.cpp ) diff --git a/static_core/plugins/ets/tests/ani/tests/string_ops/string_get_utf8_test.cpp b/static_core/plugins/ets/tests/ani/tests/string_ops/string_get_utf8_test.cpp new file mode 100644 index 0000000000..c55797d1ca --- /dev/null +++ b/static_core/plugins/ets/tests/ani/tests/string_ops/string_get_utf8_test.cpp @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License" + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_gtest.h" + +// NOLINTBEGIN(cppcoreguidelines-pro-type-vararg, modernize-avoid-c-arrays) +namespace ark::ets::ani::testing { + +class StringGetUtf8StringTest : public AniTest {}; + +TEST_F(StringGetUtf8StringTest, StringGetUtf8_MultiByte) +{ + const std::string example {"🙂🙂"}; + ani_string string = nullptr; + auto status = env_->String_NewUTF8(example.c_str(), example.size(), &string); + ASSERT_EQ(status, ANI_OK); + const uint32_t bufferSize = 30U; + char utfBuffer[bufferSize]; // NOLINT(modernize-avoid-c-arrays) + ani_size result = 0U; + status = env_->String_GetUTF8(string, utfBuffer, bufferSize, &result); + ASSERT_EQ(status, ANI_OK); + ASSERT_EQ(result, example.size()); + ASSERT_STREQ(utfBuffer, "🙂🙂"); +} + +TEST_F(StringGetUtf8StringTest, StringGetUtf8_BasicString) +{ + const std::string example {"example"}; + ani_string string = nullptr; + auto status = env_->String_NewUTF8(example.c_str(), example.size(), &string); + ASSERT_EQ(status, ANI_OK); + const uint32_t bufferSize = 10U; + char utfBuffer[bufferSize] = {0U}; // NOLINT(modernize-avoid-c-arrays) + ani_size result = 0U; + status = env_->String_GetUTF8(string, utfBuffer, bufferSize, &result); + ASSERT_EQ(status, ANI_OK); + ASSERT_EQ(result, example.size()); + ASSERT_STREQ(utfBuffer, "example"); +} + +TEST_F(StringGetUtf8StringTest, StringGetUtf8_NullString) +{ + const uint32_t bufferSize = 100U; + char utfBuffer[bufferSize]; // NOLINT(modernize-avoid-c-arrays) + ani_size result = 0U; + ani_status status = env_->String_GetUTF8(nullptr, utfBuffer, bufferSize, &result); + ASSERT_EQ(status, ANI_INVALID_ARGS); +} + +TEST_F(StringGetUtf8StringTest, StringGetUtf8_NullBuffer) +{ + const std::string example {"example"}; + ani_string string = nullptr; + auto status = env_->String_NewUTF8(example.c_str(), example.size(), &string); + ASSERT_EQ(status, ANI_OK); + + ani_size result = 0U; + const ani_size bufferSize = 100U; + status = env_->String_GetUTF8(string, nullptr, bufferSize, &result); + ASSERT_EQ(status, ANI_INVALID_ARGS); +} + +TEST_F(StringGetUtf8StringTest, StringGetUtf8_NullResultPointer) +{ + const std::string example {"example"}; + ani_string string = nullptr; + auto status = env_->String_NewUTF8(example.c_str(), example.size(), &string); + ASSERT_EQ(status, ANI_OK); + + const uint32_t bufferSize = 100U; + char utfBuffer[bufferSize]; + status = env_->String_GetUTF8(string, utfBuffer, bufferSize, nullptr); + ASSERT_EQ(status, ANI_INVALID_ARGS); +} + +TEST_F(StringGetUtf8StringTest, StringGetUtf8_BufferTooSmall) +{ + const std::string example {"example"}; + ani_string string = nullptr; + auto status = env_->String_NewUTF8(example.c_str(), example.size(), &string); + ASSERT_EQ(status, ANI_OK); + const uint32_t bufferSize = 3U; + char utfBuffer[bufferSize] = {0U}; // NOLINT(modernize-avoid-c-arrays) + ani_size result = 0U; + status = env_->String_GetUTF8(string, utfBuffer, bufferSize, &result); + ASSERT_EQ(status, ANI_BUFFER_TO_SMALL); +} + +TEST_F(StringGetUtf8StringTest, StringGetUtf8_Managed) +{ + const auto string = static_cast(CallEtsFunction("GetString")); + const uint32_t bufferSize = 10U; + char utfBuffer[bufferSize]; // NOLINT(modernize-avoid-c-arrays) + ani_size result = 0U; + ani_status status = env_->String_GetUTF8(string, utfBuffer, bufferSize, &result); + ASSERT_EQ(status, ANI_OK); + ASSERT_EQ(result, 4U); + ASSERT_STREQ(utfBuffer, "test"); +} +} // namespace ark::ets::ani::testing + +// NOLINTEND(cppcoreguidelines-pro-type-vararg, modernize-avoid-c-arrays) diff --git a/static_core/plugins/ets/tests/ani/tests/string_ops/string_get_utf8_test.sts b/static_core/plugins/ets/tests/ani/tests/string_ops/string_get_utf8_test.sts new file mode 100644 index 0000000000..540887bf13 --- /dev/null +++ b/static_core/plugins/ets/tests/ani/tests/string_ops/string_get_utf8_test.sts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function GetString(): String { + return "test"; +} + -- Gitee