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