• 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 #include "object.h"
17 
18 #include <base/containers/string.h>
19 
20 #include "TrueRootObject.h"
21 #include "function.h"
22 #include "utils.h"
23 
24 namespace NapiApi {
25 
Object(napi_env env)26 Object::Object(napi_env env) : env_(env)
27 {
28     if (!env_) {
29         return;
30     }
31     napi_create_object(env, &object_);
32     if (object_) {
33         napi_typeof(env, object_, &jstype);
34     }
35     if (jstype != napi_object) {
36         // value was not an object!
37         env_ = {};
38         object_ = nullptr;
39         jstype = napi_undefined;
40     }
41 }
42 
Object(napi_env env,napi_value v)43 Object::Object(napi_env env, napi_value v) : env_(env), object_(v)
44 {
45     if (!env_) {
46         return;
47     }
48     if (v) {
49         napi_typeof(env_, v, &jstype);
50     }
51     if (jstype != napi_object) {
52         // value was not an object!
53         env_ = {};
54         object_ = nullptr;
55         jstype = napi_undefined;
56     }
57 }
58 
Object(napi_env env,BASE_NS::string_view className,const JsFuncArgs & args)59 Object::Object(napi_env env, BASE_NS::string_view className, const JsFuncArgs& args) : env_(env)
60 {
61     NapiApi::MyInstanceState* mis {};
62     NapiApi::MyInstanceState::GetInstance(env, (void**)&mis);
63     if (mis) {
64         const auto ctor = NapiApi::Function(env, mis->FetchCtor(className));
65 
66         napi_new_instance(env_, ctor, args.argc, args.argv, &object_);
67         if (object_) {
68             napi_typeof(env_, object_, &jstype);
69         }
70         if (jstype != napi_object) {
71             // value was not an object!
72             env_ = {};
73             object_ = nullptr;
74             jstype = napi_undefined;
75         }
76     }
77 }
78 
ToNapiValue() const79 napi_value Object::ToNapiValue() const
80 {
81     return object_;
82 }
83 
GetEnv() const84 napi_env Object::GetEnv() const
85 {
86     return env_;
87 }
88 
GetRoot() const89 TrueRootObject* Object::GetRoot() const
90 {
91     return GetInterface<TrueRootObject>();
92 }
93 
GetNative() const94 META_NS::IObject::Ptr Object::GetNative() const
95 {
96     if (auto tro = GetRoot()) {
97         return tro->GetNativeObject();
98     }
99     return {};
100 }
101 
Get(const BASE_NS::string_view name)102 napi_value Object::Get(const BASE_NS::string_view name)
103 {
104     auto tmp = GetNamedPropertyAndType(name);
105     if (tmp.jstype == napi_null) {
106         return nullptr;
107     }
108     if (tmp.jstype == napi_undefined) {
109         return nullptr;
110     }
111     return tmp.res;
112 }
113 
Set(const BASE_NS::string_view name,napi_value value)114 void Object::Set(const BASE_NS::string_view name, napi_value value)
115 {
116     if (!env_ || !object_) {
117         return;
118     }
119     // could check if it is declared. and optionally add it. (now it just adds it if not declared)
120     napi_set_named_property(env_, object_, BASE_NS::string(name).c_str(), value);
121 }
122 
Set(const BASE_NS::string_view name,const Object & value)123 void Object::Set(const BASE_NS::string_view name, const Object& value)
124 {
125     Set(name, value.ToNapiValue());
126 }
127 
Set(const BASE_NS::string_view name,const BASE_NS::string_view v)128 void Object::Set(const BASE_NS::string_view name, const BASE_NS::string_view v)
129 {
130     if (!env_ || !object_) {
131         return;
132     }
133     napi_status status;
134     napi_value value = MakeTempString(v);
135     status = napi_set_named_property(env_, object_, BASE_NS::string(name).c_str(), value);
136 }
137 
operator bool() const138 Object::operator bool() const
139 {
140     if (!env_ || !object_) {
141         return false;
142     }
143     return (napi_object == jstype);
144 }
145 
Has(const BASE_NS::string_view name)146 bool Object::Has(const BASE_NS::string_view name)
147 {
148     if (!env_ || !object_) {
149         return false;
150     }
151     bool res;
152     napi_value key = MakeTempString(name);
153     napi_status status = napi_has_property(env_, object_, key, &res);
154     if (napi_ok != status) {
155         return false;
156     }
157     return res;
158 }
159 
IsNull() const160 bool Object::IsNull() const
161 {
162     return (napi_null == jstype);
163 }
164 
IsNull(const BASE_NS::string_view name)165 bool Object::IsNull(const BASE_NS::string_view name)
166 {
167     auto tmp = GetNamedPropertyAndType(name);
168     if (!tmp.success) {
169         return true;
170     }
171     return (tmp.jstype == napi_null);
172 }
173 
IsDefined() const174 bool Object::IsDefined() const
175 {
176     return (napi_undefined != jstype);
177 }
178 
IsUndefined(const BASE_NS::string_view name)179 bool Object::IsUndefined(const BASE_NS::string_view name)
180 {
181     auto tmp = GetNamedPropertyAndType(name);
182     if (!tmp.success) {
183         return true;
184     }
185     return (tmp.jstype == napi_undefined);
186 }
187 
IsUndefinedOrNull(const BASE_NS::string_view name)188 bool Object::IsUndefinedOrNull(const BASE_NS::string_view name)
189 {
190     auto tmp = GetNamedPropertyAndType(name);
191     if (!tmp.success) {
192         return true;
193     }
194     return ((tmp.jstype == napi_null) || (tmp.jstype == napi_undefined));
195 }
196 
IsSame(const Object & other) const197 bool Object::IsSame(const Object& other) const
198 {
199     return object_ == other.object_;
200 }
201 
StrictEqual(const Object & other) const202 bool Object::StrictEqual(const Object& other) const
203 {
204     if (!env_) {
205         CORE_LOG_F("Unitialized object, can't compare strict equality");
206         assert(false);
207         return false;
208     }
209 
210     bool equal = false;
211     napi_strict_equals(env_, object_, other.object_, &equal);
212     return equal;
213 }
214 
AddProperty(const napi_property_descriptor desc)215 void Object::AddProperty(const napi_property_descriptor desc)
216 {
217     if (!env_ || !object_) {
218         return;
219     }
220     napi_status status = napi_define_properties(env_, object_, 1, &desc);
221 }
222 
DeleteProperty(const BASE_NS::string_view name)223 bool Object::DeleteProperty(const BASE_NS::string_view name)
224 {
225     if (!env_ || !object_) {
226         return false;
227     }
228     // remove property from object.
229     napi_status status;
230     bool result { false };
231     napi_value key = MakeTempString(name);
232     status = napi_delete_property(env_, object_, key, &result);
233     return result;
234 }
235 
GetNamedPropertyAndType(const BASE_NS::string_view name)236 Object::NameAndType Object::GetNamedPropertyAndType(const BASE_NS::string_view name)
237 {
238     napi_value res;
239     napi_status status;
240     napi_valuetype jstype;
241     if (!env_ || !object_) {
242         return { false, nullptr, napi_undefined };
243     }
244     status = napi_get_named_property(env_, object_, BASE_NS::string(name).c_str(), &res);
245     if ((!res) || (napi_ok != status)) {
246         return { false, nullptr, napi_undefined };
247     }
248     napi_typeof(env_, res, &jstype);
249     return { true, res, jstype };
250 }
251 
MakeTempString(const BASE_NS::string_view v)252 napi_value Object::MakeTempString(const BASE_NS::string_view v)
253 {
254     return env_.GetString(v);
255 }
256 
257 } // namespace NapiApi
258