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 ANIUTIL_CLASS_H 17 #define ANIUTIL_CLASS_H 18 19 #include <ani.h> 20 21 #include <cstdarg> 22 23 #include "base.h" 24 25 namespace OHOS { 26 namespace AniUtil { 27 28 class TypeFinder { 29 public: TypeFinder(ani_env * env)30 TypeFinder(ani_env* env) : env_(env) 31 { 32 } 33 FindNamespace(const char * nsName)34 expected<ani_namespace, ani_status> FindNamespace(const char* nsName) 35 { 36 ani_namespace ns; 37 ani_status status = env_->FindNamespace(nsName, &ns); 38 if (ANI_OK != status) { 39 return status; 40 } 41 return ns; 42 } 43 44 template <typename... Names> FindNamespace(const char * firstNs,const char * nextNs,Names...restNs)45 expected<ani_namespace, ani_status> FindNamespace(const char* firstNs, const char* nextNs, Names... restNs) 46 { 47 ani_namespace ns; 48 ani_status status = env_->FindNamespace(firstNs, &ns); 49 if (ANI_OK != status) { 50 return status; 51 } 52 return FindNamespace(ns, nextNs, restNs...); 53 } 54 FindClass(const char * clsName)55 expected<ani_class, ani_status> FindClass(const char* clsName) 56 { 57 ani_class cls; 58 ani_status status = env_->FindClass(clsName, &cls); 59 if (ANI_OK != status) { 60 return status; 61 } 62 return cls; 63 } 64 FindClass(const char * nsName,const char * clsName)65 expected<ani_class, ani_status> FindClass(const char* nsName, const char* clsName) 66 { 67 auto ns = FindNamespace(nsName, clsName); 68 if (!ns.has_value()) { 69 return ns.error(); 70 } 71 return FindClass(ns.value(), clsName); 72 } 73 74 template <typename... Names> FindClass(const char * firstNs,const char * secondNs,Names...restNs,const char * clsName)75 expected<ani_class, ani_status> FindClass(const char* firstNs, const char* secondNs, 76 Names... restNs, const char* clsName) 77 { 78 auto ns = FindNamespace(firstNs, secondNs, restNs...); 79 if (!ns.has_value()) { 80 return ns.error(); 81 } 82 return FindClass(ns.value(), clsName); 83 } 84 FindClass(ani_namespace ns,const char * clsName)85 expected<ani_class, ani_status> FindClass(ani_namespace ns, const char* clsName) 86 { 87 ani_class cls; 88 ani_status status = env_->Namespace_FindClass(ns, clsName, &cls); 89 if (ANI_OK != status) { 90 return status; 91 } 92 return cls; 93 } 94 FindEnum(ani_namespace ns,const char * enumName)95 expected<ani_enum, ani_status> FindEnum(ani_namespace ns, const char* enumName) 96 { 97 ani_enum aniEnum{}; 98 ani_status status = env_->Namespace_FindEnum(ns, enumName, &aniEnum); 99 if (ANI_OK != status) { 100 return status; 101 } 102 return aniEnum; 103 } 104 105 private: 106 template <typename... Names> FindNamespace(ani_namespace currentNs,const char * nextNs,Names...restNs)107 expected<ani_namespace, ani_status> FindNamespace(ani_namespace currentNs, const char *nextNs, Names... restNs) 108 { 109 ani_namespace ns; 110 ani_status status = env_->Namespace_FindNamespace(currentNs, nextNs, &ns); 111 if (ANI_OK != status) { 112 return status; 113 } 114 return FindNamespace(ns, restNs...); 115 } 116 FindNamespace(ani_namespace currentNs)117 expected<ani_namespace, ani_status> FindNamespace(ani_namespace currentNs) 118 { 119 return currentNs; 120 } 121 122 private: 123 ani_env* env_ = nullptr; 124 }; 125 126 127 class ObjectFactory { 128 public: ObjectFactory(ani_env * env)129 ObjectFactory(ani_env *env) 130 : env_(env) 131 { 132 } 133 Create(const char * clsName,...)134 expected<ani_object, ani_status> Create(const char* clsName, ...) 135 { 136 auto cls = TypeFinder(env_).FindClass(clsName); 137 if (!cls.has_value()) { 138 return cls.error(); 139 } 140 141 va_list args; 142 va_start(args, clsName); 143 auto obj = CreateV(cls.value(), args); 144 va_end(args); 145 return obj; 146 } 147 148 template<typename... Names> Create(const char * nsName,Names...restNs,const char * clsName,...)149 expected<ani_object, ani_status> Create(const char* nsName, Names... restNs, const char* clsName, ...) 150 { 151 auto cls = TypeFinder(env_).FindClass(nsName, restNs..., clsName); 152 if (!cls.has_value()) { 153 return cls.error(); 154 } 155 156 va_list args; 157 va_start(args, clsName); 158 auto obj = CreateV(cls.value(), args); 159 va_end(args); 160 return obj; 161 } 162 Create(ani_class cls,...)163 expected<ani_object, ani_status> Create(ani_class cls, ...) 164 { 165 va_list args; 166 va_start(args, cls); 167 auto obj = CreateV(cls, args); 168 va_end(args); 169 return obj; 170 } 171 172 private: CreateV(ani_class cls,va_list args)173 expected<ani_object, ani_status> CreateV(ani_class cls, va_list args) 174 { 175 ani_method ctor; 176 ani_status status = env_->Class_FindMethod(cls, "<ctor>", nullptr, &ctor); 177 if (ANI_OK != status) { 178 return status; 179 } 180 181 ani_object obj; 182 status = env_->Object_New_V(cls, ctor, &obj, args); 183 if (ANI_OK != status) { 184 return status; 185 } 186 return obj; 187 } 188 189 private: 190 ani_env *env_ = nullptr; 191 }; 192 193 } // namespace AniUtil 194 } // namespace OHOS 195 196 #endif