1 /*
2 * Copyright (c) 2024 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 #include "napi_class.h"
17
18 #include <iostream>
19 #include <sstream>
20
21 namespace OHOS {
22 namespace AppExecFwk {
23 namespace LIBZIP {
24 using namespace std;
GetInstance()25 NapiClass &NapiClass::GetInstance()
26 {
27 static thread_local NapiClass nClass;
28 return nClass;
29 }
30
DefineClass(napi_env env,const string & className,napi_callback constructor,vector<napi_property_descriptor> && properties)31 tuple<bool, napi_value> NapiClass::DefineClass(
32 napi_env env, const string &className, napi_callback constructor, vector<napi_property_descriptor> &&properties)
33 {
34 napi_value classVal = nullptr;
35 napi_status stat = napi_define_class(env,
36 className.c_str(),
37 className.length(),
38 constructor,
39 nullptr,
40 properties.size(),
41 properties.data(),
42 &classVal);
43 if (stat != napi_ok) {
44 APP_LOGE("INNER BUG. Cannot define class %{public}s because of %{public}d", className.c_str(), stat);
45 }
46 return {stat == napi_ok, classVal};
47 }
48
SaveClass(napi_env env,const string & className,napi_value exClass)49 bool NapiClass::SaveClass(napi_env env, const string &className, napi_value exClass)
50 {
51 NapiClass &nClass = NapiClass::GetInstance();
52 lock_guard(nClass.exClassMapLock);
53
54 if (nClass.exClassMap.find(className) != nClass.exClassMap.end()) {
55 return true;
56 }
57
58 napi_ref constructor;
59 napi_status res = napi_create_reference(env, exClass, 1, &constructor);
60 if (res == napi_ok) {
61 nClass.exClassMap.insert({className, constructor});
62 } else {
63 APP_LOGE("INNER BUG. Cannot ref class constructor %{public}s because of %{public}d", className.c_str(), res);
64 }
65
66 return res == napi_ok;
67 }
68
InstantiateClass(napi_env env,const string & className,const vector<napi_value> & args)69 napi_value NapiClass::InstantiateClass(napi_env env, const string &className, const vector<napi_value> &args)
70 {
71 NapiClass &nClass = NapiClass::GetInstance();
72 lock_guard(nClass.exClassMapLock);
73 auto it = nClass.exClassMap.find(className);
74 if (it == nClass.exClassMap.end()) {
75 APP_LOGE("Class %{public}s hasn't been saved yet", className.c_str());
76 return nullptr;
77 }
78
79 napi_value cons = nullptr;
80 napi_status status = napi_get_reference_value(env, it->second, &cons);
81 if (status != napi_ok) {
82 APP_LOGE("INNER BUG. Cannot deref class %{public}s because of %{public}d", className.c_str(), status);
83 return nullptr;
84 }
85
86 napi_value instance = nullptr;
87 status = napi_new_instance(env, cons, args.size(), args.data(), &instance);
88 if (status != napi_ok) {
89 APP_LOGE("INNER BUG. Cannot instantiate the class %{public}s because of %{public}d", className.c_str(), status);
90 return nullptr;
91 }
92
93 return instance;
94 }
95 } // namespace LIBZIP
96 } // namespace AppExecFwk
97 } // namespace OHOS