/* * Copyright (C) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "object.h" #include #include "TrueRootObject.h" #include "function.h" #include "utils.h" namespace NapiApi { Object::Object(napi_env env) : env_(env) { if (!env_) { return; } napi_create_object(env, &object_); if (object_) { napi_typeof(env, object_, &jstype); } if (jstype != napi_object) { // value was not an object! env_ = {}; object_ = nullptr; jstype = napi_undefined; } } Object::Object(napi_env env, napi_value v) : env_(env), object_(v) { if (!env_) { return; } if (v) { napi_typeof(env_, v, &jstype); } if (jstype != napi_object) { // value was not an object! env_ = {}; object_ = nullptr; jstype = napi_undefined; } } Object::Object(napi_env env, BASE_NS::string_view className, const JsFuncArgs& args) : env_(env) { NapiApi::MyInstanceState* mis {}; NapiApi::MyInstanceState::GetInstance(env, (void**)&mis); if (mis) { const auto ctor = NapiApi::Function(env, mis->FetchCtor(className)); napi_new_instance(env_, ctor, args.argc, args.argv, &object_); if (object_) { napi_typeof(env_, object_, &jstype); } if (jstype != napi_object) { // value was not an object! env_ = {}; object_ = nullptr; jstype = napi_undefined; } } } napi_value Object::ToNapiValue() const { return object_; } napi_env Object::GetEnv() const { return env_; } TrueRootObject* Object::GetRoot() const { return GetInterface(); } META_NS::IObject::Ptr Object::GetNative() const { if (auto tro = GetRoot()) { return tro->GetNativeObject(); } return {}; } napi_value Object::Get(const BASE_NS::string_view name) { auto tmp = GetNamedPropertyAndType(name); if (tmp.jstype == napi_null) { return nullptr; } if (tmp.jstype == napi_undefined) { return nullptr; } return tmp.res; } void Object::Set(const BASE_NS::string_view name, napi_value value) { if (!env_ || !object_) { return; } // could check if it is declared. and optionally add it. (now it just adds it if not declared) napi_set_named_property(env_, object_, BASE_NS::string(name).c_str(), value); } void Object::Set(const BASE_NS::string_view name, const Object& value) { Set(name, value.ToNapiValue()); } void Object::Set(const BASE_NS::string_view name, const BASE_NS::string_view v) { if (!env_ || !object_) { return; } napi_status status; napi_value value = MakeTempString(v); status = napi_set_named_property(env_, object_, BASE_NS::string(name).c_str(), value); } Object::operator bool() const { if (!env_ || !object_) { return false; } return (napi_object == jstype); } bool Object::Has(const BASE_NS::string_view name) { if (!env_ || !object_) { return false; } bool res; napi_value key = MakeTempString(name); napi_status status = napi_has_property(env_, object_, key, &res); if (napi_ok != status) { return false; } return res; } bool Object::IsNull() const { return (napi_null == jstype); } bool Object::IsNull(const BASE_NS::string_view name) { auto tmp = GetNamedPropertyAndType(name); if (!tmp.success) { return true; } return (tmp.jstype == napi_null); } bool Object::IsDefined() const { return (napi_undefined != jstype); } bool Object::IsUndefined(const BASE_NS::string_view name) { auto tmp = GetNamedPropertyAndType(name); if (!tmp.success) { return true; } return (tmp.jstype == napi_undefined); } bool Object::IsUndefinedOrNull(const BASE_NS::string_view name) { auto tmp = GetNamedPropertyAndType(name); if (!tmp.success) { return true; } return ((tmp.jstype == napi_null) || (tmp.jstype == napi_undefined)); } bool Object::IsSame(const Object& other) const { return object_ == other.object_; } bool Object::StrictEqual(const Object& other) const { if (!env_) { CORE_LOG_F("Unitialized object, can't compare strict equality"); assert(false); return false; } bool equal = false; napi_strict_equals(env_, object_, other.object_, &equal); return equal; } void Object::AddProperty(const napi_property_descriptor desc) { if (!env_ || !object_) { return; } napi_status status = napi_define_properties(env_, object_, 1, &desc); } bool Object::DeleteProperty(const BASE_NS::string_view name) { if (!env_ || !object_) { return false; } // remove property from object. napi_status status; bool result { false }; napi_value key = MakeTempString(name); status = napi_delete_property(env_, object_, key, &result); return result; } Object::NameAndType Object::GetNamedPropertyAndType(const BASE_NS::string_view name) { napi_value res; napi_status status; napi_valuetype jstype; if (!env_ || !object_) { return { false, nullptr, napi_undefined }; } status = napi_get_named_property(env_, object_, BASE_NS::string(name).c_str(), &res); if ((!res) || (napi_ok != status)) { return { false, nullptr, napi_undefined }; } napi_typeof(env_, res, &jstype); return { true, res, jstype }; } napi_value Object::MakeTempString(const BASE_NS::string_view v) { return env_.GetString(v); } } // namespace NapiApi