• 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 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