| 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 |