* 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 <cstddef>
#include <regex>
#include <ani_signature_builder.h>
#include "ani_utils.h"
namespace OHOS::Ace {
namespace {
const std::regex RESOURCE_APP_STRING_PLACEHOLDER(R"(\%((\d+)(\$)){0,1}([dsf]))", std::regex::icase);
constexpr int32_t DEFAULT_SCOPE = 60;
}
AniAsyncEvent::AniAsyncEvent(ani_env* env, ani_ref ref)
{
env_ = env;
env->GlobalReference_Create(ref, &ref_);
}
AniAsyncEvent::~AniAsyncEvent()
{
env_->GlobalReference_Delete(ref_);
}
ani_status AniAsyncEvent::Call(ani_size argc, ani_ref *argv)
{
auto status = env_->CreateLocalScope(DEFAULT_SCOPE);
if (status != ANI_OK) {
return status;
}
ani_ref result {};
status = env_->FunctionalObject_Call(static_cast<ani_fn_object>(ref_), argc, argv, &result);
env_->DestroyLocalScope();
return status;
}
ani_env* AniAsyncEvent::GetEnv()
{
return env_;
}
bool AniUtils::GetIsUndefinedObject(ani_env *env, ani_ref objectRef)
{
ani_boolean isUndefined;
if (ANI_OK != env->Reference_IsUndefined(objectRef, &isUndefined)) {
return true;
}
return (bool)isUndefined;
}
bool AniUtils::GetIsEnum(ani_env *env, ani_ref objectRef, const char* enumName)
{
ani_enum enumAni;
if (ANI_OK != env->FindEnum(enumName, &enumAni)) {
return false;
}
ani_boolean isEnum;
if (ANI_OK != env->Object_InstanceOf(static_cast<ani_object>(objectRef), enumAni, &isEnum)) {
return false;
}
return (bool)isEnum;
}
ani_status AniUtils::GetInt32(ani_env *env, ani_int arg, int32_t &value)
{
value = static_cast<int32_t>(arg);
return ANI_OK;
}
std::string AniUtils::AniStringToStdString(ani_env *env, ani_string ani_str)
{
ani_size strSize;
env->String_GetUTF8Size(ani_str, &strSize);
std::vector<char> buffer(strSize + 1);
char* utf8Buffer = buffer.data();
ani_size bytesWritten = 0;
env->String_GetUTF8(ani_str, utf8Buffer, strSize + 1, &bytesWritten);
utf8Buffer[bytesWritten] = '\0';
std::string content = std::string(utf8Buffer);
return content;
}
bool AniUtils::ParseOptionalBool(ani_env *env, ani_object object, std::optional<bool> &result)
{
if (GetIsUndefinedObject(env, object)) {
result.reset();
return true;
}
bool boolValue;
if (ANI_OK != GetBool(env, object, boolValue)) {
return false;
}
result = boolValue;
return true;
}
ani_status AniUtils::GetBool(ani_env *env, ani_boolean arg, bool &value)
{
value = (arg == ANI_TRUE);
return ANI_OK;
}
ani_status AniUtils::GetBool(ani_env *env, ani_object arg, bool &value)
{
if (GetIsUndefinedObject(env, arg)) {
return ANI_ERROR;
}
ani_class cls {};
static const std::string className = "std.core.Boolean";
ani_status status = env->FindClass(className.c_str(), &cls);
if (ANI_OK != status) {
return status;
}
ani_method method {};
status = env->Class_FindMethod(cls, "valueOf", nullptr, &method);
if (ANI_OK != status) {
return status;
}
ani_boolean result = 0;
status = env->Object_CallMethod_Boolean(arg, method, &result);
if (ANI_OK != status) {
return status;
}
return GetBool(env, result, value);
}
}