• 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 "strong_ref.h"
17 
18 namespace NapiApi {
19 
StrongRef(napi_env env,napi_value obj)20 StrongRef::StrongRef(napi_env env, napi_value obj)
21 {
22     if (env && obj) {
23         env_ = env;
24         napi_create_reference(env_, obj, 1, &ref_);
25     }
26 }
27 
StrongRef(napi_env env,napi_ref ref)28 StrongRef::StrongRef(napi_env env, napi_ref ref)
29 {
30     if (env && ref) {
31         env_ = env;
32         ref_ = ref;
33         Ref();
34     }
35 }
36 
StrongRef(const NapiApi::Object & obj)37 StrongRef::StrongRef(const NapiApi::Object& obj)
38 {
39     if (obj) {
40         env_ = obj.GetEnv();
41         napi_create_reference(env_, obj.ToNapiValue(), 1, &ref_);
42     }
43 }
44 
StrongRef(const NapiApi::Value<NapiApi::Object> objValue)45 StrongRef::StrongRef(const NapiApi::Value<NapiApi::Object> objValue)
46     : StrongRef(objValue.GetEnv(), objValue.ToNapiValue())
47 {}
48 
StrongRef(const NapiApi::StrongRef & ref)49 StrongRef::StrongRef(const NapiApi::StrongRef& ref)
50 {
51     if (!ref.IsEmpty()) {
52         env_ = ref.env_;
53         ref_ = ref.ref_;
54         Ref();
55     }
56 }
57 
StrongRef(NapiApi::StrongRef && ref)58 StrongRef::StrongRef(NapiApi::StrongRef&& ref) noexcept
59 {
60     if (!ref.IsEmpty()) {
61         env_ = ref.env_;
62         ref_ = ref.ref_;
63         ref.env_ = nullptr;
64         ref.ref_ = nullptr;
65     }
66 }
67 
operator =(const NapiApi::StrongRef & ref)68 StrongRef& StrongRef::operator=(const NapiApi::StrongRef& ref)
69 {
70     if (&ref != this) {
71         Reset();
72         if (!ref.IsEmpty()) {
73             env_ = ref.env_;
74             ref_ = ref.ref_;
75             Ref();
76         }
77     }
78     return *this;
79 }
80 
operator =(NapiApi::StrongRef && ref)81 StrongRef& StrongRef::operator=(NapiApi::StrongRef&& ref) noexcept
82 {
83     if (&ref != this) {
84         Reset();
85         env_ = ref.env_;
86         ref_ = ref.ref_;
87         ref.env_ = nullptr;
88         ref.ref_ = nullptr;
89     }
90     return *this;
91 }
92 
~StrongRef()93 StrongRef::~StrongRef()
94 {
95     if (!IsEmpty()) {
96         Reset();
97     }
98 }
99 
Reset()100 void StrongRef::Reset()
101 {
102     if (IsEmpty()) {
103         return;
104     }
105     uint32_t cnt;
106     napi_status stat = napi_reference_unref(env_, ref_, &cnt);
107     if (stat != napi_ok) {
108         return;
109     }
110     if (cnt == 0) {
111         // that was the last reference.
112         napi_delete_reference(env_, ref_);
113     }
114     env_ = nullptr;
115     ref_ = nullptr;
116 }
117 
IsEmpty() const118 bool StrongRef::IsEmpty() const
119 {
120     return !(env_ && ref_);
121 }
122 
GetEnv() const123 napi_env StrongRef::GetEnv() const
124 {
125     return env_;
126 }
127 
GetValue() const128 napi_value StrongRef::GetValue() const
129 {
130     if (IsEmpty()) {
131         return {};
132     }
133     napi_value value;
134     napi_get_reference_value(env_, ref_, &value);
135     return value;
136 }
137 
GetObject() const138 NapiApi::Object StrongRef::GetObject() const
139 {
140     return NapiApi::Object(env_, (napi_value)GetValue());
141 }
142 
GetRefCount() const143 uint32_t StrongRef::GetRefCount() const
144 {
145     // this is racy, but for debug use "fine"
146     if (!IsEmpty()) {
147         uint32_t cnt;
148         napi_reference_ref(env_, ref_, &cnt);
149         napi_reference_unref(env_, ref_, &cnt);
150         return cnt;
151     }
152     return 0;
153 }
154 
Ref()155 void StrongRef::Ref()
156 {
157     uint32_t cnt;
158     napi_status stat = napi_reference_ref(env_, ref_, &cnt);
159 }
160 
161 } // namespace NapiApi
162