• 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 ANI_UTILS_H
17 #define ANI_UTILS_H
18 
19 #include <ani.h>
20 #include <string>
21 #include <iostream>
22 #include <sstream>
23 #include <optional>
24 #include <vector>
25 #include "ani_util_class.h"
26 #include "ani_util_native_ptr.h"
27 
28 namespace OHOS {
29 namespace DataShare {
30 class AniObjectUtils {
31 public:
32     static ani_object Create(ani_env *env, const char* nsName, const char* clsName, ...);
33     static ani_object Create(ani_env *env, const char* clsName, ...);
34     static ani_object Create(ani_env *env, ani_class cls, ...);
35     static ani_object From(ani_env *env, bool value);
36     template<typename T>
37     static ani_status Wrap(ani_env *env, ani_object object, T* nativePtr, const char* propName = "nativePtr")
38     {
39         if (env == nullptr) {
40             return ANI_ERROR;
41         }
42 
43         if (nativePtr == nullptr) {
44             return ANI_ERROR;
45         }
46         return env->Object_SetFieldByName_Long(object, propName, reinterpret_cast<ani_long>(nativePtr));
47     }
48 
49     template<typename T>
50     static T* Unwrap(ani_env *env, ani_object object, const char* propName = "nativePtr")
51     {
52         if (env == nullptr) {
53             return nullptr;
54         }
55 
56         ani_long nativePtr;
57         if (ANI_OK != env->Object_GetFieldByName_Long(object, propName, &nativePtr)) {
58             return nullptr;
59         }
60 
61         return reinterpret_cast<T*>(nativePtr);
62     }
63 };
64 
65 class AniStringUtils {
66 public:
67     static std::string ToStd(ani_env *env, ani_string ani_str);
68     static ani_string ToAni(ani_env* env, const std::string& str);
69 };
70 
71 class UnionAccessor {
72 public:
73     UnionAccessor(ani_env *env, ani_object &obj);
74     bool IsInstanceOf(const std::string& cls_name);
75     bool IsInstanceOf(const std::string& cls_name, ani_object obj);
76     template<typename T> bool IsInstanceOfType();
77     template<typename T> bool TryConvert(T &value);
78     template<typename T> bool TryConvertArray(std::vector<T> &value);
79 
80 private:
81     ani_env *env_;
82     ani_object obj_;
83 };
84 class OptionalAccessor {
85 public:
86     OptionalAccessor(ani_env *env, ani_object &obj);
87     bool IsUndefined();
88     bool IsNull();
89     template<typename T> std::optional<T> Convert();
90 
91 private:
92     ani_env *env_;
93     ani_object obj_;
94 };
95 
96 template<typename T>
97 struct Converter {
convertConverter98     static std::string convert(const T& value)
99     {
100         std::ostringstream oss;
101         oss << value;
102         return oss.str();
103     }
104 };
105 
106 template<>
107 struct Converter<bool> {
108     static std::string convert(const bool& value)
109     {
110         return value ? "true" : "false";
111     }
112 };
113 
114 
115 template<>
116 struct Converter<double> {
117     static std::string convert(const double& value)
118     {
119         std::ostringstream buf;
120         buf << value;
121         std::string str = buf.str();
122         return str;
123     }
124 };
125 
126 template<typename T>
127 std::vector<std::string> convertVector(const std::vector<T>& input)
128 {
129     std::vector<std::string> result;
130     result.reserve(input.size());
131 
132     for (const auto& elem : input) {
133         result.push_back(Converter<T>::convert(elem));
134     }
135     return result;
136 }
137 
138 template<typename T> using convertCallback = bool(*)(ani_env*, ani_ref&, ani_ref&, std::shared_ptr<T>);
139 
140 template<typename F, typename T>
141 bool forEachMapEntry(ani_env *env, ani_object map_object, F &&callback, std::shared_ptr<T> records)
142 {
143     if (env == nullptr) {
144         return false;
145     }
146     ani_ref iter;
147     if (ANI_OK != env->Object_CallMethodByName_Ref(map_object, "$_iterator", nullptr, &iter)) {
148         std::cout << "Failed to get keys iterator" << std::endl;
149         return false;
150     }
151 
152     ani_ref next;
153     ani_boolean done;
154     while (ANI_OK == env->Object_CallMethodByName_Ref(static_cast<ani_object>(iter), "next", nullptr, &next)) {
155         if (ANI_OK != env->Object_GetFieldByName_Boolean(static_cast<ani_object>(next), "done", &done)) {
156             std::cout << "Failed to check iterator done" << std::endl;
157             return false;
158         }
159 
160         if (done) {
161             std::cout << "[forEachMapEntry] done break" << std::endl;
162             return true;
163         }
164 
165         ani_ref key_value;
166         if (ANI_OK != env->Object_GetFieldByName_Ref(static_cast<ani_object>(next), "value", &key_value)) {
167             std::cout << "Failed to get key value" << std::endl;
168             return false;
169         }
170 
171         ani_ref ani_key;
172         if (ANI_OK != env->TupleValue_GetItem_Ref(static_cast<ani_tuple_value>(key_value), 0, &ani_key)) {
173             std::cout << "Failed to get key value" << std::endl;
174             return false;
175         }
176 
177         ani_ref ani_val;
178         if (ANI_OK != env->TupleValue_GetItem_Ref(static_cast<ani_tuple_value>(key_value), 1, &ani_val)) {
179             std::cout << "Failed to get key value" << std::endl;
180             return false;
181         }
182 
183         if (!callback(env, ani_key, ani_val, records)) {
184             return false;
185         }
186     }
187 
188     std::cout << "Failed to get next key" << std::endl;
189     return false;
190 }
191 
192 ani_object DoubleToObject(ani_env *env, double value);
193 ani_object BoolToObject(ani_env *env, bool value);
194 ani_object StringToObject(ani_env *env, std::string value);
195 ani_object Uint8ArrayToObject(ani_env *env, const std::vector<uint8_t> &values);
196 }
197 }
198 #endif // ANI_UTILS_H
199