1 /*
2  * Copyright (c) 2021-2022 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 "base_obj.h"
17 
18 #include <cstdio>
19 
20 #include "securec.h"
21 
22 #include "light_refbase.h"
23 
24 namespace OHOS {
25 namespace AAFwk {
26 const InterfaceID g_IID_IObject = {
27     0x8321f710, 0xa0c0, 0x4cbe, 0xbfbc, {0x5, 0xa, 0x7, 0x8, 0xf, 0x1, 0x3, 0x1, 0x2, 0xb, 0x1, 0xb}
28 };
29 
30 const InterfaceID g_IID_IWeakReference = {
31     0x26ab1978, 0x1d11, 0x4a4f, 0x826d, {0x6, 0x1, 0x7, 0x8, 0x5, 0xc, 0x0, 0x4, 0x8, 0xc, 0xc, 0xa}
32 };
33 
34 const InterfaceID g_IID_IWeakReferenceSource = {
35     0xbc3f5250, 0x34d7, 0x42d2, 0x9b40, {0xf, 0xf, 0xc, 0xe, 0x8, 0x3, 0xf, 0xd, 0x4, 0x0, 0x6, 0x1}
36 };
37 
38 class WeakReferenceImpl final : public LightRefCountBase, public IWeakReference {
39 public:
WeakReferenceImpl(IInterface * object,WeakRefCounter * wkRef)40     WeakReferenceImpl(IInterface *object, WeakRefCounter *wkRef) : object_(object), wkRef_(wkRef)
41     {}
42 
~WeakReferenceImpl()43     virtual ~WeakReferenceImpl()
44     {}
45 
46     void IncStrongRef(const void *id = nullptr) override;
47 
48     void DecStrongRef(const void *id = nullptr) override;
49 
50     IInterface *Query(const InterfaceID &iid) override;
51 
52     InterfaceID GetInterfaceID(IInterface *object) override;
53 
54     ErrCode Resolve(const InterfaceID &iid, IInterface **object) override;
55 
56 private:
57     IInterface *object_ = nullptr;
58     WeakRefCounter *wkRef_ = nullptr;
59 };
60 
IncStrongRef(const void * id)61 void WeakReferenceImpl::IncStrongRef(const void *id)
62 {
63     LightRefCountBase::IncStrongRef(id);
64 }
65 
DecStrongRef(const void * id)66 void WeakReferenceImpl::DecStrongRef(const void *id)
67 {
68     LightRefCountBase::DecStrongRef(id);
69 }
70 
Query(const InterfaceID & iid)71 IInterface *WeakReferenceImpl::Query(const InterfaceID &iid)
72 {
73     if ((iid == g_IID_IWeakReference) || (iid == g_IID_IInterface)) {
74         return static_cast<IWeakReference *>(this);
75     }
76     return nullptr;
77 }
78 
GetInterfaceID(IInterface * object)79 InterfaceID WeakReferenceImpl::GetInterfaceID(IInterface *object)
80 {
81     if (object == static_cast<IWeakReference *>(this)) {
82         return g_IID_IWeakReference;
83     }
84     return InterfaceID::Empty;
85 }
86 
Resolve(const InterfaceID & iid,IInterface ** object)87 ErrCode WeakReferenceImpl::Resolve(const InterfaceID &iid, IInterface **object)
88 {
89     VALIDATE_NOT_NULL(object);
90 
91     if ((object_ != nullptr) && wkRef_->AttemptIncStrongRef(this)) {
92         *object = object_->Query(iid);
93         if (*object == nullptr) {
94             object_->DecStrongRef(this);
95         }
96     } else {
97         *object = nullptr;
98     }
99     return ERR_OK;
100 }
101 
IncStrongRef(const void * id)102 void Object::IncStrongRef(const void *id)
103 {
104     RefBase::IncStrongRef(id);
105 }
106 
DecStrongRef(const void * id)107 void Object::DecStrongRef(const void *id)
108 {
109     RefBase::DecStrongRef(id);
110 }
111 
Query(const InterfaceID & iid)112 IInterface *Object::Query(const InterfaceID &iid)
113 {
114     if (iid == g_IID_IObject) {
115         return static_cast<IObject *>(this);
116     }
117     if (iid == g_IID_IWeakReferenceSource) {
118         return static_cast<IWeakReferenceSource *>(this);
119     }
120     if (iid == g_IID_IInterface) {
121         return static_cast<IWeakReferenceSource *>(this);
122     }
123     return nullptr;
124 }
125 
GetInterfaceID(IInterface * object)126 InterfaceID Object::GetInterfaceID(IInterface *object)
127 {
128     if (object == static_cast<IObject *>(this)) {
129         return g_IID_IObject;
130     }
131     if (object == static_cast<IWeakReferenceSource *>(this)) {
132         return g_IID_IWeakReferenceSource;
133     }
134     return InterfaceID::Empty;
135 }
136 
GetClassID()137 ClassID Object::GetClassID()
138 {
139     return ClassID::Empty;
140 }
141 
GetHashCode()142 int Object::GetHashCode()
143 {
144     return reinterpret_cast<HANDLE>(this);
145 }
146 
Equals(IObject & other)147 bool Object::Equals(IObject &other)
148 {
149     Object *otherObj = nullptr;
150     otherObj = static_cast<Object *>(&other);
151     return this == otherObj;
152 }
153 
GetWeakReference(sptr<IWeakReference> & weakRef)154 ErrCode Object::GetWeakReference(sptr<IWeakReference> &weakRef)
155 {
156     void *addr = calloc(sizeof(WeakReferenceImpl), 1);
157     if (addr == nullptr) {
158         return ERR_NO_MEMORY;
159     }
160     weakRef = new (addr) WeakReferenceImpl(static_cast<IObject *>(this), CreateWeakRef(addr));
161     return ERR_OK;
162 }
163 
ToString()164 std::string Object::ToString()
165 {
166     static constexpr int BUFFER_MAX = 1024;
167     std::string str("");
168     char *buf = new (std::nothrow) char[BUFFER_MAX];
169     if (buf != nullptr) {
170         int ret = snprintf_s(buf, BUFFER_MAX, BUFFER_MAX - 1, "[Object %p]", this);
171         if (ret >= 0) {
172             str = buf;
173         }
174         delete[] buf;
175         buf = nullptr;
176     }
177     return str;
178 }
179 
Equals(IInterface & obj1,IInterface & obj2)180 bool Object::Equals(IInterface &obj1, IInterface &obj2)
181 {
182     if (IInterface::Query(&obj1) == IInterface::Query(&obj2)) {
183         return true;
184     }
185 
186     IObject *o1 = IObject::Query(obj1);
187     if (o1 == nullptr) {
188         return false;
189     }
190     return o1->Equals(*(IObject::Query(obj2)));
191 }
192 
ToString(IInterface & object)193 std::string Object::ToString(IInterface &object)
194 {
195     IObject *obj = IObject::Query(object);
196     return ((obj != nullptr) ? obj->ToString() : "");
197 }
198 }  // namespace AAFwk
199 }  // namespace OHOS