GCC Code Coverage Report


Directory: src/gate/
File: src/gate/directories.c
Date: 2026-10-19 17:06:30
Exec Total Coverage
Lines: 126 140 90.0%
Functions: 21 22 95.5%
Branches: 32 64 50.0%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright (c) 2018-2026, 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 #include "gate/directories.h"
30 #include "gate/debugging.h"
31 #include "gate/strings.h"
32 #include "gate/arrays.h"
33
34 4 gate_directory_propertydef_t* gate_directory_propertydef_create(gate_directory_propertydef_t* propdef,
35 gate_type_id_t type,
36 gate_string_t const* name,
37 gate_enumint_t flags)
38 {
39 4 gate_mem_clear(propdef, sizeof(gate_directory_propertydef_t));
40
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (NULL == gate_string_duplicate(&propdef->name, name))
41 {
42 ✗ return NULL;
43 }
44 4 propdef->data_type = type;
45 4 propdef->flags = flags;
46 4 return propdef;
47 }
48
49 2 gate_directory_propertydef_t* gate_directory_propertydef_copy(
50 gate_directory_propertydef_t* dst_propdef,
51 gate_directory_propertydef_t const * src_propdef)
52 {
53 6 return gate_directory_propertydef_create(dst_propdef,
54 2 src_propdef->data_type,
55 &src_propdef->name,
56 src_propdef->flags);
57 }
58
59
60 6 void gate_directory_propertydef_release(gate_directory_propertydef_t* propdef)
61 {
62 6 gate_string_release(&propdef->name);
63 6 gate_mem_clear(propdef, sizeof(gate_directory_propertydef_t));
64 6 }
65
66 1 static gate_result_t GATE_CALL gate_directory_propertydef_cctor(void* dest, void const* src)
67 {
68 1 gate_directory_propertydef_t* ptr_dst = (gate_directory_propertydef_t*)dest;
69 1 gate_directory_propertydef_t const* ptr_src = (gate_directory_propertydef_t const*)src;
70 1 gate_directory_propertydef_t* ret = NULL;
71
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (ptr_src == NULL)
72 {
73 static const gate_string_t empty_str = GATE_STRING_INIT_EMPTY;
74 ✗ ret = gate_directory_propertydef_create(ptr_dst, GATE_TYPE_EMPTY, &empty_str, 0);
75 }
76 else
77 {
78 1 ret = gate_directory_propertydef_create(ptr_dst, ptr_src->data_type, &ptr_src->name, ptr_src->flags);
79 }
80 return (NULL == ret)
81 ? GATE_RESULT_OUTOFMEMORY
82
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 : GATE_RESULT_OK;
83 }
84
85 1 static void GATE_CALL gate_directory_propertydef_dtor(void* dest)
86 {
87 1 gate_directory_propertydef_release((gate_directory_propertydef_t*)dest);
88 1 }
89
90
91 typedef struct dirclass
92 {
93 GATE_INTERFACE_VTBL(gate_directory_class) const* vtbl;
94
95 gate_atomic_int_t ref_counter;
96 gate_string_t uid;
97 gate_string_t name;
98 gate_enumint_t flags;
99 gate_array_t property_defs; /* array of gate_directory_propertydef_t */
100 gate_array_t superior_classes_uids; /* array of gate_string_t (uids) */
101 gate_array_t containment_classes_uids; /* array of gate_string_t (uids) */
102
103 } dirclass_t;
104
105 1 static char const* dirclass_get_interface_name(void* obj)
106 {
107 1 return GATE_INTERFACE_NAME_DIRECTORYCLASS;
108 }
109
110 1 static void dirclass_destroy(dirclass_t* self)
111 {
112 1 gate_string_release(&self->uid);
113 1 gate_string_release(&self->name);
114 1 gate_array_release(&self->property_defs);
115 1 gate_array_release(&self->superior_classes_uids);
116 1 gate_array_release(&self->containment_classes_uids);
117 1 gate_mem_dealloc(self);
118 1 }
119
120 1 static void dirclass_release(void* obj)
121 {
122 1 dirclass_t* const self = (dirclass_t*)obj;
123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(self != NULL);
124
125
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (gate_atomic_int_dec(&self->ref_counter) == 0)
126 {
127 1 dirclass_destroy(self);
128 }
129 1 }
130
131 ✗ static int dirclass_retain(void* obj)
132 {
133 ✗ dirclass_t* const self = (dirclass_t*)obj;
134 ✗ GATE_DEBUG_ASSERT(self != NULL);
135 ✗ return gate_atomic_int_inc(&self->ref_counter);
136 }
137
138 1 static gate_result_t dirclass_uid(void* obj, gate_string_t* return_uid)
139 {
140 1 dirclass_t* const self = (dirclass_t*)obj;
141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(self != NULL);
142 1 return NULL == gate_string_duplicate(return_uid, &self->uid)
143 ? GATE_RESULT_OUTOFMEMORY
144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 : GATE_RESULT_OK;
145 }
146 1 static gate_result_t dirclass_name(void* obj, gate_string_t* return_name)
147 {
148 1 dirclass_t* const self = (dirclass_t*)obj;
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(self != NULL);
150 1 return NULL == gate_string_duplicate(return_name, &self->name)
151 ? GATE_RESULT_OUTOFMEMORY
152
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 : GATE_RESULT_OK;
153 }
154 1 static gate_result_t dirclass_flags(void* obj, gate_enumint_t* return_flags)
155 {
156 1 dirclass_t* const self = (dirclass_t*)obj;
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(self != NULL);
158 1 *return_flags = self->flags;
159 1 return GATE_RESULT_OK;
160 }
161
162 1 static gate_result_t dirclass_get_properties_count(void* obj, gate_size_t* return_count)
163 {
164 1 dirclass_t* const self = (dirclass_t*)obj;
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(self != NULL);
166 1 *return_count = gate_array_length(&self->property_defs);
167 1 return GATE_RESULT_OK;
168 }
169 1 static gate_result_t dirclass_get_property(void* obj, gate_size_t index, gate_directory_propertydef_t* return_prop_def)
170 {
171 1 dirclass_t* const self = (dirclass_t*)obj;
172 gate_directory_propertydef_t const* ptr_src;
173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(self != NULL);
174 1 ptr_src = gate_array_get(&self->property_defs, index);
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (NULL == ptr_src)
176 {
177 ✗ return GATE_RESULT_NOTAVAILABLE;
178 }
179 else
180 {
181 1 gate_directory_propertydef_t* def = gate_directory_propertydef_copy(return_prop_def, ptr_src);
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 return def == NULL ? GATE_RESULT_OUTOFMEMORY : GATE_RESULT_OK;
183 }
184 }
185
186 2 static int find_propdef_name(void const* ptr_propdef, void const* ptr_str)
187 {
188 2 gate_directory_propertydef_t const* const propdef = (gate_directory_propertydef_t const*)ptr_propdef;
189 2 gate_string_t const* const ptr_name = (gate_string_t const*)ptr_str;
190 2 return gate_string_comp(&propdef->name, ptr_name);
191 }
192
193 2 static gate_result_t dirclass_find_property(void* obj, gate_string_t const* name, gate_directory_propertydef_t* return_prop_def)
194 {
195 2 dirclass_t* const self = (dirclass_t*)obj;
196 gate_size_t ndx;
197
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_DEBUG_ASSERT(self != NULL);
199 2 ndx = gate_array_find(&self->property_defs, find_propdef_name, name, 0);
200
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (ndx == GATE_ARRAY_NPOS)
201 {
202 1 return GATE_RESULT_NOMATCH;
203 }
204 else
205 {
206 1 gate_directory_propertydef_t const* src = gate_array_get(&self->property_defs, ndx);
207 1 return NULL == gate_directory_propertydef_copy(return_prop_def, src)
208 ? GATE_RESULT_OUTOFMEMORY
209
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 : GATE_RESULT_OK;
210 }
211 }
212
213 1 static gate_result_t dirclass_get_superior_classes_count(void* obj, gate_size_t * return_count)
214 {
215 1 dirclass_t* const self = (dirclass_t*)obj;
216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(self != NULL);
217 1 *return_count = gate_array_length(&self->superior_classes_uids);
218 1 return GATE_RESULT_OK;
219 }
220 1 static gate_result_t dirclass_get_superior_class_uid(void* obj, gate_size_t index, gate_string_t * return_class_uid)
221 {
222 1 dirclass_t* const self = (dirclass_t*)obj;
223 gate_string_t const* src;
224
225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(self != NULL);
226 1 src = (gate_string_t const*)gate_array_get(&self->superior_classes_uids, index);
227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (src == NULL)
228 {
229 ✗ return GATE_RESULT_OUTOFBOUNDS;
230 }
231 else
232 {
233 1 return NULL == gate_string_duplicate(return_class_uid, src)
234 ? GATE_RESULT_OUTOFMEMORY
235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 : GATE_RESULT_OK;
236 }
237 }
238
239 1 static gate_result_t dirclass_get_containment_classes_count(void* obj, gate_size_t * return_count)
240 {
241 1 dirclass_t* const self = (dirclass_t*)obj;
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(self != NULL);
243 1 *return_count = gate_array_length(&self->superior_classes_uids);
244 1 return GATE_RESULT_OK;
245 }
246 1 static gate_result_t dirclass_get_containment_class_uid(void* obj, gate_size_t index, gate_string_t* return_class_uid)
247 {
248 1 dirclass_t* const self = (dirclass_t*)obj;
249 gate_string_t const* src;
250
251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_DEBUG_ASSERT(self != NULL);
252 1 src = (gate_string_t const*)gate_array_get(&self->containment_classes_uids, index);
253
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (src == NULL)
254 {
255 ✗ return GATE_RESULT_OUTOFBOUNDS;
256 }
257 else
258 {
259 1 return NULL == gate_string_duplicate(return_class_uid, src)
260 ? GATE_RESULT_OUTOFMEMORY
261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 : GATE_RESULT_OK;
262 }
263 }
264
265 1 static GATE_INTERFACE_VTBL(gate_directory_class)* dirclass_vtbl()
266 {
267 static GATE_INTERFACE_VTBL(gate_directory_class) vtbl;
268
269
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (vtbl.get_interface_name == NULL)
270 {
271 1 GATE_INTERFACE_VTBL(gate_directory_class) local_vtbl =
272 {
273 &dirclass_get_interface_name,
274 &dirclass_release,
275 &dirclass_retain,
276
277 &dirclass_uid,
278 &dirclass_name,
279 &dirclass_flags,
280
281 &dirclass_get_properties_count,
282 &dirclass_get_property,
283 &dirclass_find_property,
284
285 &dirclass_get_superior_classes_count,
286 &dirclass_get_superior_class_uid,
287
288 &dirclass_get_containment_classes_count,
289 &dirclass_get_containment_class_uid
290 };
291 1 vtbl = local_vtbl;
292 }
293 1 return &vtbl;
294 }
295
296 1 gate_directory_class_t* gate_directory_class_create(
297 gate_string_t const* uid,
298 gate_string_t const* name,
299 gate_enumint_t flags,
300 gate_directory_propertydef_t const* prop_defs, gate_size_t prop_defs_count,
301 gate_string_t const* superiors, gate_size_t superiors_count,
302 gate_string_t const* containment, gate_size_t containment_count
303 )
304 {
305 1 gate_directory_class_t* ret = NULL;
306 1 dirclass_t* impl = NULL;
307 do
308 {
309 gate_arraylist_t arrlist;
310
311 1 impl = (dirclass_t*)gate_mem_alloc(sizeof(dirclass_t));
312
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (impl == NULL)
313 {
314 ✗ break;
315 }
316 1 gate_mem_clear(impl, sizeof(dirclass_t));
317 1 impl->vtbl = dirclass_vtbl();
318 1 gate_atomic_int_init(&impl->ref_counter, 1);
319
320 1 gate_string_duplicate(&impl->uid, uid);
321 1 gate_string_duplicate(&impl->name, name);
322 1 impl->flags = flags;
323
324
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_array_create_list(&impl->property_defs,
325 sizeof(gate_directory_propertydef_t), prop_defs, prop_defs_count,
326 &gate_directory_propertydef_cctor, &gate_directory_propertydef_dtor))
327 {
328 ✗ break;
329 }
330
331
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_array_create_list(&impl->superior_classes_uids,
332 sizeof(gate_string_t), superiors, superiors_count,
333 &gate_string_duplicate_constructor, &gate_string_destructor))
334 {
335 ✗ break;
336 }
337
338
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (NULL == gate_array_create_list(&impl->containment_classes_uids,
339 sizeof(gate_string_t), containment, containment_count,
340 &gate_string_duplicate_constructor, &gate_string_destructor))
341 {
342 ✗ break;
343 }
344
345 /* success case */
346 1 ret = (gate_directory_class_t*)impl;
347 1 impl = NULL;
348 } while (0);
349
350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (impl != NULL)
351 {
352 ✗ dirclass_destroy(impl);
353 }
354 1 return ret;
355 }
356