Line | Branch | Exec | Source |
---|---|---|---|
1 | /* GATE PROJECT LICENSE: | ||
2 | +----------------------------------------------------------------------------+ | ||
3 | | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> | | ||
4 | | All rights reserved. | | ||
5 | | | | ||
6 | | Redistribution and use in source and binary forms, with or without | | ||
7 | | modification, are permitted provided that the following conditions are met:| | ||
8 | | | | ||
9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
10 | | this list of conditions and the following disclaimer. | | ||
11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
12 | | notice, this list of conditions and the following disclaimer in the | | ||
13 | | documentation and/or other materials provided with the distribution. | | ||
14 | | | | ||
15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
26 | +----------------------------------------------------------------------------+ | ||
27 | */ | ||
28 | |||
29 | /** @file | ||
30 | * @brief Object interface wrappers, utilities and implementations | ||
31 | * @ingroup gatecore_cpp | ||
32 | */ | ||
33 | |||
34 | |||
35 | #ifndef GATE_OBJECTS_HPP_INCLUDED | ||
36 | #define GATE_OBJECTS_HPP_INCLUDED | ||
37 | |||
38 | #include "gate/gate_core_api.hpp" | ||
39 | #include "gate/objects.h" | ||
40 | #include "gate/gatetypes.hpp" | ||
41 | #include "gate/strings.hpp" | ||
42 | #include "gate/memalloc.hpp" | ||
43 | #include "gate/atomics.hpp" | ||
44 | |||
45 | namespace gate | ||
46 | { | ||
47 | |||
48 | /// @brief | ||
49 | class GATE_CORE_CPP_API Object | ||
50 | { | ||
51 | public: | ||
52 | Object(gate_object_ptr_t obj_ptr) noexcept; // takes ownership of an object pointer | ||
53 | Object(Object const& obj) noexcept; | ||
54 | Object& operator=(Object const& obj) noexcept; | ||
55 | ~Object() noexcept; | ||
56 | |||
57 | String getInterfaceName(); | ||
58 | gate_object_ptr_t c_impl() noexcept; | ||
59 | |||
60 | bool_t operator!() const noexcept; | ||
61 | bool_t empty() const noexcept; | ||
62 | |||
63 | protected: | ||
64 | void swap(Object& that) noexcept; | ||
65 | |||
66 | private: | ||
67 | gate_object_ptr_t object_ref_ptr; | ||
68 | }; | ||
69 | |||
70 | |||
71 | /// @brief | ||
72 | /// @tparam T | ||
73 | template<class T> class GATE_CORE_CPP_API ObjectImpl : public Object | ||
74 | { | ||
75 | public: | ||
76 | typedef T impl_t; | ||
77 | typedef ObjectImpl<T> object_impl_t; | ||
78 | |||
79 | protected: | ||
80 | impl_t* impl_ptr; | ||
81 | |||
82 | protected: | ||
83 | ✗ | void swap(object_impl_t& that) noexcept | |
84 | { | ||
85 | ✗ | Object::swap(that); | |
86 | ✗ | swapRefs(this->impl_ptr, that.impl_ptr); | |
87 | ✗ | } | |
88 | |||
89 | public: | ||
90 | 143 | ObjectImpl(impl_t* impl) noexcept | |
91 | 143 | : Object((gate_object_ptr_t)impl), impl_ptr(impl) | |
92 | { | ||
93 | 143 | } | |
94 | 20 | ObjectImpl(ObjectImpl const& src) noexcept | |
95 | 20 | : Object(src), impl_ptr(src.impl_ptr) | |
96 | { | ||
97 | 20 | } | |
98 | 13 | ObjectImpl& operator=(ObjectImpl const& that) noexcept | |
99 | { | ||
100 | 13 | Object::operator=(that); | |
101 | 13 | this->impl_ptr = that.impl_ptr; | |
102 | 13 | return *this; | |
103 | } | ||
104 | 163 | ~ObjectImpl() noexcept | |
105 | { | ||
106 | 163 | } | |
107 | 152 | impl_t* c_impl() const noexcept | |
108 | { | ||
109 | 152 | return this->impl_ptr; | |
110 | } | ||
111 | }; | ||
112 | |||
113 | |||
114 | /// @brief | ||
115 | class GATE_CORE_CPP_API IObject | ||
116 | { | ||
117 | public: | ||
118 | virtual ~IObject(); | ||
119 | |||
120 | virtual void release() noexcept = 0; | ||
121 | virtual int retain() noexcept = 0; | ||
122 | virtual String getInterfaceName() noexcept = 0; | ||
123 | }; | ||
124 | |||
125 | |||
126 | /// @brief | ||
127 | /// @tparam ObjectStruct | ||
128 | /// @tparam VtblStruct | ||
129 | template<class ObjectStruct, class VtblStruct> | ||
130 | class GATE_CORE_CPP_API IObjectBuilder : public IObject | ||
131 | { | ||
132 | public: | ||
133 | typedef ObjectStruct obj_struct_t; | ||
134 | typedef VtblStruct obj_vtbl_t; | ||
135 | |||
136 | typedef IObjectBuilder<obj_struct_t, obj_vtbl_t> ObjectBuilder; | ||
137 | |||
138 | 12 | virtual ~IObjectBuilder() | |
139 | { | ||
140 | 12 | } | |
141 | |||
142 | 26 | virtual void release() noexcept | |
143 | { | ||
144 |
2/2✓ Branch 1 taken 6 times.
✓ Branch 2 taken 9 times.
|
26 | if (--this->refCounter == 0) |
145 | { | ||
146 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
10 | delete this; |
147 | } | ||
148 | 26 | } | |
149 | 16 | virtual int retain() noexcept | |
150 | { | ||
151 | 16 | return ++this->refCounter; | |
152 | } | ||
153 | ✗ | virtual String getInterfaceName() noexcept | |
154 | { | ||
155 | ✗ | return this->interfaceName; | |
156 | } | ||
157 | |||
158 | protected: | ||
159 | struct GATE_CORE_CPP_API cpp_object : public obj_struct_t | ||
160 | { | ||
161 | ObjectBuilder* parent; | ||
162 | |||
163 | 12 | cpp_object(obj_vtbl_t const* vtbl_ptr, ObjectBuilder* parent_ptr) | |
164 | 12 | : parent(parent_ptr) | |
165 | { | ||
166 | 12 | this->vtbl = vtbl_ptr; | |
167 | 12 | } | |
168 | }; | ||
169 | |||
170 | 30 | static void object_release(void* obj_ptr) noexcept | |
171 | { | ||
172 | 30 | cpp_object* obj = static_cast<cpp_object*>(obj_ptr); | |
173 | 30 | obj->parent->release(); | |
174 | 30 | } | |
175 | 18 | static int object_retain(void* obj_ptr) noexcept | |
176 | { | ||
177 | 18 | cpp_object* obj = static_cast<cpp_object*>(obj_ptr); | |
178 | 18 | return obj->parent->retain(); | |
179 | } | ||
180 | ✗ | static char const* object_get_interface_name(void* obj_ptr) noexcept | |
181 | { | ||
182 | ✗ | cpp_object* obj = static_cast<cpp_object*>(obj_ptr); | |
183 | ✗ | return obj->parent->interfaceName.c_str(); | |
184 | } | ||
185 | |||
186 | 14 | template<class T> static T* getInterface(cpp_object* obj) | |
187 | { | ||
188 | 14 | T* ret = NULL; | |
189 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
14 | if (obj) |
190 | { | ||
191 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
14 | ret = dynamic_cast<T*>(obj->parent); |
192 | } | ||
193 | 14 | return ret; | |
194 | } | ||
195 | |||
196 | |||
197 | struct GATE_CORE_CPP_API VtblObject : public obj_vtbl_t | ||
198 | { | ||
199 | 16 | VtblObject() | |
200 | { | ||
201 | 16 | GATE_INTERFACE_VTBL(gate_object)* this_ptr = reinterpret_cast<GATE_INTERFACE_VTBL(gate_object)*>(this); | |
202 | 16 | this_ptr->release = &object_release; | |
203 | 16 | this_ptr->retain = &object_retain; | |
204 | 16 | this_ptr->get_interface_name = &object_get_interface_name; | |
205 | 16 | } | |
206 | }; | ||
207 | |||
208 | private: | ||
209 | cpp_object c_interface; | ||
210 | AtomicInt refCounter; | ||
211 | String interfaceName; | ||
212 | |||
213 | protected: | ||
214 | 12 | IObjectBuilder(obj_vtbl_t const* vtbl_ptr, char const* name) | |
215 | 12 | : c_interface(vtbl_ptr, NULL), refCounter(1), interfaceName(String::createStatic(name)) | |
216 | { | ||
217 | 12 | this->c_interface.parent = this; | |
218 | 12 | } | |
219 | |||
220 | public: | ||
221 | 6 | virtual ObjectStruct* c_impl() | |
222 | { | ||
223 | 6 | return &this->c_interface; | |
224 | } | ||
225 | |||
226 | }; | ||
227 | |||
228 | |||
229 | /// @brief | ||
230 | class GATE_CORE_CPP_API Startable : public ObjectImpl<gate_startable_t> | ||
231 | { | ||
232 | public: | ||
233 | Startable(gate_startable_t* obj); | ||
234 | Startable(Startable const& src); | ||
235 | Startable& operator=(Startable const& src); | ||
236 | |||
237 | void start(); | ||
238 | void stop(); | ||
239 | enumint_t getStatus(); | ||
240 | }; | ||
241 | |||
242 | |||
243 | /// @brief | ||
244 | class GATE_CORE_CPP_API MemoryBlock : public ObjectImpl<gate_memoryblock_t> | ||
245 | { | ||
246 | public: | ||
247 | MemoryBlock(void const* sourceBlockBytes, size_t blockLength); | ||
248 | MemoryBlock(size_t blockLength = 0); | ||
249 | |||
250 | MemoryBlock(gate_memoryblock_t* obj); | ||
251 | MemoryBlock(MemoryBlock const& src); | ||
252 | MemoryBlock& operator=(MemoryBlock const& src); | ||
253 | |||
254 | size_t getSize() const; | ||
255 | void* getContent(); | ||
256 | void const* getContent() const; | ||
257 | |||
258 | intptr_t compare(MemoryBlock const& block) const; | ||
259 | intptr_t compare(void const* block, size_t blockLength) const; | ||
260 | |||
261 | bool equals(MemoryBlock const& block) const; | ||
262 | bool equals(void const* block, size_t blockLength) const; | ||
263 | |||
264 | }; | ||
265 | |||
266 | |||
267 | /// @brief | ||
268 | /// @tparam T | ||
269 | template<class T> class TypedMemoryBlock : public MemoryBlock | ||
270 | { | ||
271 | public: | ||
272 | typedef TypedMemoryBlock<T> self_t; | ||
273 | |||
274 | TypedMemoryBlock() | ||
275 | { | ||
276 | } | ||
277 | |||
278 | TypedMemoryBlock(self_t const& src) | ||
279 | : MemoryBlock(src) | ||
280 | { | ||
281 | } | ||
282 | |||
283 | self_t& operator=(self_t const& src) | ||
284 | { | ||
285 | MemoryBlock::operator=(src); | ||
286 | return *this; | ||
287 | } | ||
288 | |||
289 | T* getContent() | ||
290 | { | ||
291 | return static_cast<T*>(MemoryBlock::getContent()); | ||
292 | } | ||
293 | |||
294 | T const* getContent() const | ||
295 | { | ||
296 | return static_cast<T const*>(MemoryBlock::getContent()); | ||
297 | } | ||
298 | |||
299 | bool equals(MemoryBlock const& block) const; | ||
300 | bool equals(void const* block, size_t blockLength) const; | ||
301 | |||
302 | |||
303 | T* operator->() | ||
304 | { | ||
305 | return this->getContent(); | ||
306 | } | ||
307 | T const* operator->() const | ||
308 | { | ||
309 | return this->getContent(); | ||
310 | } | ||
311 | |||
312 | T& operator*() | ||
313 | { | ||
314 | return *this->getContent(); | ||
315 | } | ||
316 | T const& operator*() const | ||
317 | { | ||
318 | return *this->getContent(); | ||
319 | } | ||
320 | }; | ||
321 | |||
322 | } // end of namespace gate | ||
323 | |||
324 | #endif | ||
325 |