2 * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
27 #include "halcc-object.h"
28 #include "halcc-parser.h"
29 #include "halcc-util.h"
31 #define HALCC_TRANSPORT_DEFAULT HALCC_TRANSPORT_PASSTHROUGH
33 typedef struct halcc_version {
37 * Can be used interchangeably.
38 * min_minor might be useful if max_minor is specified.
46 typedef struct halcc_interface {
51 typedef struct halcc_hal {
53 halcc_version version;
54 halcc_transport_e transport;
55 halcc_dependency_state_e dependency_state;
56 GHashTable *dependencies;
57 GHashTable *interfaces;
60 typedef struct halcc_manifest {
61 halcc_manifest_type_e manifest_type;
62 halcc_version version;
67 typedef enum halcc_hash_compare_type_e {
68 HALCC_HASH_COMPARE_TYPE_BACKWARD_MINOR_VERSION,
69 HALCC_HASH_COMPARE_TYPE_EXACT_MINOR_VERSION,
70 HALCC_HASH_COMPARE_TYPE_FORWARD_MINOR_VERSION,
71 } halcc_hash_compare_type_e;
73 typedef struct hash_hal_key {
75 halcc_hash_compare_type_e compare_type;
78 #define HASH_HAL_KEY(_name, _major, _minor, _compare_type) \
81 .name = (char *) _name, \
82 .version.major = _major, \
83 .version.minor = _minor, \
85 .compare_type = _compare_type, \
88 #define HASH_HAL_KEY_RAW(_hal, _compare_type) \
89 HASH_HAL_KEY((_hal)->name, \
90 (_hal)->version.major, \
91 (_hal)->version.minor, \
95 static void hashtable_foreach(GHashTable *table, halcc_iter_cb cb, void *user_data)
103 g_hash_table_iter_init(&iter, table);
104 while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &data))
108 static guint hal_hash(gconstpointer key)
110 const halcc_hal *hal = (const halcc_hal *) key;
115 return g_str_hash(hal->name);
118 static gboolean hal_hash_equal(gconstpointer a, gconstpointer b)
120 const halcc_hal *hal = (const halcc_hal *) a;
121 const hash_hal_key *key = (const hash_hal_key *) b;
127 if (strncmp(hal->name, key->hal.name, strlen(hal->name) + 1) != 0)
130 if (hal->version.major != key->hal.version.major)
133 compare_type = key->compare_type;
135 switch (compare_type) {
136 case HALCC_HASH_COMPARE_TYPE_EXACT_MINOR_VERSION:
137 return hal->version.minor == key->hal.version.minor;
138 case HALCC_HASH_COMPARE_TYPE_BACKWARD_MINOR_VERSION:
139 return hal->version.minor <= key->hal.version.minor;
140 case HALCC_HASH_COMPARE_TYPE_FORWARD_MINOR_VERSION:
141 return hal->version.minor >= key->hal.version.minor;
146 assert(0); // unreachable
151 static void hal_hash_value_free(gpointer data)
153 halcc_hal *hal = (halcc_hal *) data;
158 static GHashTable* hashtable_hal_new(void)
160 return g_hash_table_new_full(hal_hash, hal_hash_equal, NULL, hal_hash_value_free);
163 static int hashtable_hal_insert(GHashTable *hal_table, halcc_hal *hal)
167 if (!hal_table || !hal)
170 key = HASH_HAL_KEY_RAW(hal, HALCC_HASH_COMPARE_TYPE_EXACT_MINOR_VERSION);
172 if (g_hash_table_lookup_extended(hal_table, &key, NULL, NULL))
175 g_hash_table_insert(hal_table, hal, hal);
180 static halcc_hal* hashtable_hal_lookup(GHashTable *hal_table,
181 const char *name, int major, int minor, halcc_hash_compare_type_e type)
185 if (!hal_table || !name)
188 key = HASH_HAL_KEY(name, major, minor, type);
190 return g_hash_table_lookup(hal_table, &key);
193 static halcc_hal* hashtable_hal_steal(GHashTable *hal_table, const char *name, int major, int minor)
196 halcc_hal *hal = NULL;
198 if (!hal_table || !name)
201 key = HASH_HAL_KEY(name, major, minor, HALCC_HASH_COMPARE_TYPE_EXACT_MINOR_VERSION);
203 if (!g_hash_table_steal_extended(hal_table, &key, NULL, (gpointer*) &hal))
209 static void hashtable_hal_remove(GHashTable *hal_table, const char *name, int major, int minor)
213 if (!hal_table || !name)
216 key = HASH_HAL_KEY(name, major, minor, HALCC_HASH_COMPARE_TYPE_EXACT_MINOR_VERSION);
218 g_hash_table_remove(hal_table, &key);
221 static guint interface_hash(gconstpointer key)
223 const halcc_interface *interface = (const halcc_interface *) key;
224 char interface_str[HALCC_NAME_MAX * 2] = { 0 , };
227 assert(interface->name);
229 if (interface->instance_id)
230 snprintf(interface_str, sizeof(interface_str), "%s.%s", interface->name, interface->instance_id);
232 snprintf(interface_str, sizeof(interface_str), "%s.default", interface->name);
234 return g_str_hash(interface_str);
237 static gboolean interface_hash_equal(gconstpointer a, gconstpointer b)
239 const halcc_interface *interface = (const halcc_interface *) a;
240 const halcc_interface *key = (const halcc_interface *) b;
245 return strncmp(interface->name, key->name, strlen(interface->name) + 1) == 0;
248 static void interface_hash_value_free(gpointer data)
250 halcc_interface *interface = (halcc_interface *) data;
252 halcc_interface_free(interface);
255 static GHashTable* hashtable_interface_new(void)
257 return g_hash_table_new_full(interface_hash,
258 interface_hash_equal, NULL, interface_hash_value_free);
261 static int hashtable_interface_insert(GHashTable *interface_table, halcc_interface *interface)
263 g_hash_table_insert(interface_table, interface, interface);
269 static halcc_interface* hashtable_interface_lookup(GHashTable *interface_table,
270 const char *name, const char *instance_id)
274 if (!interface_table || !name)
277 key = (halcc_interface) {
278 .name = (char *) name,
279 .instance_id = (char *) instance_id,
282 return g_hash_table_lookup(interface_table, &key);
286 static void hashtable_interface_remove(GHashTable *interface_table,
287 const char *name, const char *instance_id)
291 if (!interface_table || !name)
294 key = (halcc_interface) {
295 .name = (char *) name,
296 .instance_id = (char *) instance_id,
299 g_hash_table_remove(interface_table, &key);
302 int halcc_manifest_new(halcc_manifest **manifest)
309 m = calloc(1, sizeof(halcc_manifest));
313 *m = (halcc_manifest) {
314 .manifest_type = HALCC_UNINITIALIZED_INT,
315 .version.major = HALCC_UNINITIALIZED_INT,
316 .version.minor = HALCC_UNINITIALIZED_INT,
317 .level = HALCC_UNINITIALIZED_INT,
318 .hals = hashtable_hal_new(),
321 *manifest = g_steal_pointer(&m);
326 void halcc_manifest_free(halcc_manifest *manifest)
331 g_hash_table_destroy(g_steal_pointer(&manifest->hals));
336 int halcc_manifest_set_type(halcc_manifest *manifest, halcc_manifest_type_e type)
341 if (type < HALCC_MANIFEST_TYPE_HAL_API || type > HALCC_MANIFEST_TYPE_HAL_BACKEND)
345 return halcc_util_set_int_once(&manifest->manifest_type, type, "manifest.type");
348 int halcc_manifest_get_type(halcc_manifest *manifest, halcc_manifest_type_e *type)
350 if (!manifest || !type)
353 *type = manifest->manifest_type;
358 int halcc_manifest_set_version(halcc_manifest *manifest, int major, int minor)
365 if (major < 0 || minor < 0)
368 ret = halcc_util_set_int_once(&manifest->version.major, major, "manifest.version.major");
372 ret = halcc_util_set_int_once(&manifest->version.minor, minor, "manifest.version.minor");
379 int halcc_manifest_get_version(halcc_manifest *manifest, int *major, int *minor)
381 if (!manifest || !major || !minor)
384 *major = manifest->version.major;
385 *minor = manifest->version.minor;
390 int halcc_manifest_set_level(halcc_manifest *manifest, int level)
395 return halcc_util_set_int_once(&manifest->level, level, "manifest.level");
398 int halcc_manifest_get_level(halcc_manifest *manifest, int *level)
400 if (!manifest || !level)
403 *level = manifest->level;
408 int halcc_manifest_add_hal(halcc_manifest *manifest, halcc_hal *hal)
410 if (!manifest || !hal)
413 assert(manifest->hals);
418 return hashtable_hal_insert(manifest->hals, hal);
421 int halcc_manifest_find_hal(halcc_manifest *manifest,
422 const char *hal_name, int major, int minor, halcc_hal **hal)
426 if (!manifest || !hal_name)
429 h = hashtable_hal_lookup(manifest->hals,
430 hal_name, major, minor, HALCC_HASH_COMPARE_TYPE_EXACT_MINOR_VERSION);
435 *hal = g_steal_pointer(&h);
440 int halcc_manifest_find_hal_raw(halcc_manifest *manifest,
441 halcc_hal *raw, halcc_hal **hal)
443 return halcc_manifest_find_hal(manifest,
444 raw->name, raw->version.major, raw->version.minor, hal);
447 int halcc_manifest_find_hal_backward_compatible(halcc_manifest *manifest,
448 const char *hal_name, int major, int minor, halcc_hal **hal)
452 if (!manifest || !hal_name)
455 h = hashtable_hal_lookup(manifest->hals,
456 hal_name, major, minor, HALCC_HASH_COMPARE_TYPE_BACKWARD_MINOR_VERSION);
461 *hal = g_steal_pointer(&h);
466 int halcc_manifest_find_hal_backward_compatible_raw(halcc_manifest *manifest,
467 halcc_hal *raw, halcc_hal **hal)
469 return halcc_manifest_find_hal_backward_compatible(manifest,
470 raw->name, raw->version.major, raw->version.minor, hal);
473 int halcc_manifest_find_hal_forward_compatible(halcc_manifest *manifest,
474 const char *hal_name, int major, int minor, halcc_hal **hal)
478 if (!manifest || !hal_name)
481 h = hashtable_hal_lookup(manifest->hals,
482 hal_name, major, minor, HALCC_HASH_COMPARE_TYPE_FORWARD_MINOR_VERSION);
487 *hal = g_steal_pointer(&h);
492 int halcc_manifest_find_hal_forward_compatible_raw(halcc_manifest *manifest,
493 halcc_hal *raw, halcc_hal **hal)
495 return halcc_manifest_find_hal_forward_compatible(manifest,
496 raw->name, raw->version.major, raw->version.minor, hal);
499 int halcc_manifest_steal_hal(halcc_manifest *manifest,
500 const char *hal_name, int major, int minor, halcc_hal **hal)
504 if (!manifest || !hal_name)
507 h = hashtable_hal_steal(manifest->hals, hal_name, major, minor);
512 *hal = g_steal_pointer(&h);
517 void halcc_manifest_remove_hal(halcc_manifest *manifest,
518 const char *hal_name, int major, int minor)
520 if (!manifest || !hal_name)
523 hashtable_hal_remove(manifest->hals, hal_name, major, minor);
526 void halcc_manifest_foreach_hal(halcc_manifest *manifest,
527 halcc_iter_cb cb, void *user_data)
529 if (!manifest || !manifest->hals || !cb)
532 hashtable_foreach(manifest->hals, cb, user_data);
535 int halcc_hal_new(halcc_hal **hal)
542 h = calloc(1, sizeof(halcc_hal));
546 h->transport = HALCC_TRANSPORT_DEFAULT;
547 h->dependency_state = HALCC_DEPENDENCY_STATE_NONE;
548 h->dependencies = hashtable_hal_new();
549 h->interfaces = hashtable_interface_new();
551 *hal = g_steal_pointer(&h);
556 void halcc_hal_free(halcc_hal *hal)
561 free(g_steal_pointer(&hal->name));
562 g_hash_table_destroy(g_steal_pointer(&hal->dependencies));
563 g_hash_table_destroy(g_steal_pointer(&hal->interfaces));
567 int halcc_hal_set_name(halcc_hal *hal, const char *hal_name)
575 free(g_steal_pointer(&hal->name));
580 n = strndup(hal_name, HALCC_NAME_MAX);
584 hal->name = g_steal_pointer(&n);
589 int halcc_hal_get_name(halcc_hal *hal, const char **hal_name)
591 if (!hal || !hal_name)
594 *hal_name = hal->name;
599 int halcc_hal_set_version(halcc_hal *hal, int major, int min_minor, int max_minor)
604 hal->version.major = major;
605 hal->version.min_minor = min_minor;
606 hal->version.max_minor = max_minor;
611 int halcc_hal_get_version(halcc_hal *hal, int *major, int *min_minor, int *max_minor)
613 if (!hal || !major || !min_minor)
616 *major = hal->version.major;
617 *min_minor = hal->version.min_minor;
619 *max_minor = hal->version.max_minor;
624 int halcc_hal_set_transport(halcc_hal *hal, halcc_transport_e transport)
629 hal->transport = transport;
634 int halcc_hal_get_transport(halcc_hal *hal, halcc_transport_e *transport)
636 if (!hal || !transport)
639 assert(hal->transport >= HALCC_TRANSPORT_PASSTHROUGH);
640 assert(hal->transport <= HALCC_TRANSPORT_IPC);
642 *transport = hal->transport;
647 int halcc_hal_add_dependency(halcc_hal *hal, halcc_hal *dependency)
649 if (!hal || !dependency)
652 return hashtable_hal_insert(hal->dependencies, dependency);
655 void halcc_hal_remove_dependency(halcc_hal *hal,
656 const char *dependency_hal_name, int major, int minor)
658 if (!hal || !dependency_hal_name)
661 hashtable_hal_remove(hal->dependencies, dependency_hal_name, major, minor);
664 void halcc_hal_foreach_dependency(halcc_hal *hal, halcc_iter_cb cb, void *user_data)
666 if (!hal || !hal->dependencies || !cb)
669 hashtable_foreach(hal->dependencies, cb, user_data);
672 int halcc_hal_add_interface(halcc_hal *hal, halcc_interface *interface)
674 if (!hal || !interface)
677 return hashtable_interface_insert(hal->interfaces, interface);
680 void halcc_hal_remove_interface(halcc_hal *hal,
681 const char *interface_name, const char *instance_id)
683 if (!hal || !interface_name)
686 hashtable_interface_remove(hal->interfaces, interface_name, instance_id);
689 void halcc_hal_foreach_interface(halcc_hal *hal, halcc_iter_cb cb, void *user_data)
691 if (!hal || !hal->interfaces || !cb)
694 hashtable_foreach(hal->interfaces, cb, user_data);
697 int halcc_interface_new(halcc_interface **interface)
699 halcc_interface *iface;
704 iface = calloc(1, sizeof(halcc_interface));
708 *interface = g_steal_pointer(&iface);
713 void halcc_interface_free(halcc_interface *interface)
718 free(g_steal_pointer(&interface->name));
719 free(g_steal_pointer(&interface->instance_id));
720 free(g_steal_pointer(&interface));
723 int halcc_interface_set_name(halcc_interface *interface, const char *interface_name)
727 if (!interface || !interface_name)
730 n = strndup(interface_name, HALCC_NAME_MAX);
734 interface->name = g_steal_pointer(&n);
739 int halcc_interface_get_name(halcc_interface *interface, const char **interface_name)
741 if (!interface || !interface_name)
744 *interface_name = interface->name;
749 int halcc_interface_set_instance_id(halcc_interface *interface, const char *instance_id)
753 if (!interface || !instance_id)
756 id = strndup(instance_id, HALCC_NAME_MAX);
760 interface->instance_id = g_steal_pointer(&id);
765 int halcc_interface_get_instance_id(halcc_interface *interface, const char **instance_id)
767 if (!interface || !instance_id)
770 *instance_id = interface->instance_id;