• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef OHOS_ANI_TEXT_UTILS_H
17 #define OHOS_ANI_TEXT_UTILS_H
18 #include <ani.h>
19 #include <memory>
20 #include <string>
21 #include <vector>
22 
23 #include "ani_common.h"
24 #include "utils/text_log.h"
25 
26 namespace OHOS::Text::ANI {
27 class AniTextUtils final {
28 public:
29     static ani_status ThrowBusinessError(ani_env* env, TextErrorCode errorCode, const char* message);
30     static ani_status CreateBusinessError(ani_env* env, int32_t error, const char* message, ani_object& err);
31     template <typename T>
32     static T* GetNativeFromObj(ani_env* env, ani_object obj);
33 
34     static ani_object CreateAniUndefined(ani_env* env);
35     template <typename... Args>
36     static ani_object CreateAniObject(ani_env* env, const std::string name, const char* signature, Args... params);
37     static ani_object CreateAniArray(ani_env* env, size_t size);
38     template <typename T, typename Converter>
39     static ani_object CreateAniArrayAndInitData(ani_env* env, const std::vector<T>& t, size_t size, Converter convert);
40     static ani_object CreateAniMap(ani_env* env);
41     static ani_enum_item CreateAniEnum(ani_env* env, const char* enum_descriptor, ani_size index);
42     static ani_object CreateAniDoubleObj(ani_env* env, double val);
43     static ani_object CreateAniIntObj(ani_env* env, int val);
44     static ani_object CreateAniBooleanObj(ani_env* env, bool val);
45     static ani_string CreateAniStringObj(ani_env* env, const std::string& str);
46     static ani_string CreateAniStringObj(ani_env* env, const std::u16string& str);
47 
48     static ani_status AniToStdStringUtf8(ani_env* env, const ani_string& str, std::string& utf8Str);
49     static ani_status AniToStdStringUtf16(ani_env* env, const ani_string& str, std::u16string& utf16Str);
50     static bool ReadFile(const std::string& filePath, size_t& dataLen, std::unique_ptr<uint8_t[]>& data);
51     static bool SplitAbsoluteFontPath(std::string& absolutePath);
52 
53     static ani_status ReadOptionalField(ani_env* env, ani_object obj, const char* fieldName, ani_ref& ref);
54     static ani_status ReadOptionalDoubleField(ani_env* env, ani_object obj, const char* fieldName, double& value);
55     static ani_status ReadOptionalStringField(ani_env* env, ani_object obj, const char* fieldName, std::string& str);
56     static ani_status ReadOptionalU16StringField(
57         ani_env* env, ani_object obj, const char* fieldName, std::u16string& str);
58     static ani_status ReadOptionalBoolField(ani_env* env, ani_object obj, const char* fieldName, bool& value);
59     template <typename EnumType>
60     static ani_status ReadOptionalEnumField(ani_env* env, ani_object obj, const char* fieldName, EnumType& value);
61     template <typename T, typename Converter>
62     static ani_status ReadOptionalArrayField(
63         ani_env* env, ani_object obj, const char* fieldName, std::vector<T>& array, Converter convert);
64 };
65 
66 template <typename... Args>
CreateAniObject(ani_env * env,const std::string name,const char * signature,Args...params)67 ani_object AniTextUtils::CreateAniObject(ani_env* env, const std::string name, const char* signature, Args... params)
68 {
69     ani_class cls = nullptr;
70     if (env->FindClass(name.c_str(), &cls) != ANI_OK) {
71         TEXT_LOGE("Failed to found %{public}s", name.c_str());
72         return CreateAniUndefined(env);
73     }
74     ani_method ctor;
75     if (env->Class_FindMethod(cls, "<ctor>", signature, &ctor) != ANI_OK) {
76         TEXT_LOGE("Failed to get ctor %{public}s", name.c_str());
77         return CreateAniUndefined(env);
78     }
79     ani_object obj = {};
80     if (env->Object_New(cls, ctor, &obj, params...) != ANI_OK) {
81         TEXT_LOGE("Failed to create object %{public}s", name.c_str());
82         return CreateAniUndefined(env);
83     }
84     return obj;
85 }
86 
87 template <typename T, typename Converter>
CreateAniArrayAndInitData(ani_env * env,const std::vector<T> & t,size_t size,Converter convert)88 ani_object AniTextUtils::CreateAniArrayAndInitData(
89     ani_env* env, const std::vector<T>& t, size_t size, Converter convert)
90 {
91     ani_object arrayObj = CreateAniArray(env, size);
92     ani_size index = 0;
93     for (const T& item : t) {
94         ani_object aniObj = convert(env, item);
95         ani_status ret = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", index, aniObj);
96         if (ret != ANI_OK) {
97             TEXT_LOGE("Array $_set failed, ret:%{public}d", ret);
98             continue;
99         }
100         index++;
101     }
102     return arrayObj;
103 }
104 
105 template <typename T>
GetNativeFromObj(ani_env * env,ani_object obj)106 T* AniTextUtils::GetNativeFromObj(ani_env* env, ani_object obj)
107 {
108     ani_status ret;
109     ani_long nativeObj{};
110     if ((ret = env->Object_GetFieldByName_Long(obj, NATIVE_OBJ, &nativeObj)) != ANI_OK) {
111         TEXT_LOGE("Failed to get native obj");
112         return nullptr;
113     }
114     T* object = reinterpret_cast<T*>(nativeObj);
115     if (object == nullptr) {
116         TEXT_LOGE("object is null");
117         return nullptr;
118     }
119     return object;
120 };
121 
122 template <typename EnumType>
ReadOptionalEnumField(ani_env * env,ani_object obj,const char * fieldName,EnumType & value)123 ani_status AniTextUtils::ReadOptionalEnumField(ani_env* env, ani_object obj, const char* fieldName, EnumType& value)
124 {
125     ani_ref ref = nullptr;
126     ani_status result = AniTextUtils::ReadOptionalField(env, obj, fieldName, ref);
127     if (result == ANI_OK && ref != nullptr) {
128         ani_size index;
129         result = env->EnumItem_GetIndex(reinterpret_cast<ani_enum_item>(ref), &index);
130         if (result == ANI_OK) {
131             value = static_cast<EnumType>(index);
132         }
133     }
134     return result;
135 };
136 
137 template <typename T, typename Converter>
ReadOptionalArrayField(ani_env * env,ani_object obj,const char * fieldName,std::vector<T> & array,Converter convert)138 ani_status AniTextUtils::ReadOptionalArrayField(
139     ani_env* env, ani_object obj, const char* fieldName, std::vector<T>& array, Converter convert)
140 {
141     ani_ref ref = nullptr;
142     ani_status result = AniTextUtils::ReadOptionalField(env, obj, fieldName, ref);
143     if (result != ANI_OK || ref == nullptr) {
144         return result;
145     }
146 
147     ani_object arrayObj = reinterpret_cast<ani_object>(ref);
148     ani_double length;
149     result = env->Object_GetPropertyByName_Double(arrayObj, "length", &length);
150     if (result != ANI_OK) {
151         TEXT_LOGE("Failed to get length,%{public}s", fieldName);
152         return result;
153     }
154 
155     for (size_t i = 0; i < static_cast<size_t>(length); i++) {
156         ani_ref entryRef = nullptr;
157         result = env->Object_CallMethodByName_Ref(arrayObj, "$_get", "I:Lstd/core/Object;", &entryRef, i);
158         if (result != ANI_OK || entryRef == nullptr) {
159             TEXT_LOGE("Failed to get array object,%{public}s", fieldName);
160             continue;
161         }
162         array.emplace_back(convert(env, entryRef));
163     }
164     return ANI_OK;
165 };
166 } // namespace OHOS::Text::ANI
167 #endif // OHOS_ANI_TEXT_UTILS_H