/* Chrysalide - Outil d'analyse de fichiers binaires * manager.c - collecte et gestion des instances partagées * * Copyright (C) 2016 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "manager.h" #include /* Gestionnaire d'instances de type identique partagées (instance) */ struct _GShareManager { GObject parent; /* A laisser en premier */ GHashTable *table; /* Collection de partages */ GType managed; /* Type d'instances gérées */ }; /* Gestionnaire d'instances de type identique partagées (classe) */ struct _GShareManagerClass { GObjectClass parent; /* A laisser en premier */ }; /* Procède à l'initialisation d'une classe de suivi de largeurs. */ static void g_share_manager_class_init(GShareManagerClass *); /* Procède à l'initialisation d'un suivi de largeurs de lignes. */ static void g_share_manager_init(GShareManager *); /* Supprime toutes les références externes. */ static void g_share_manager_dispose(GShareManager *); /* Procède à la libération totale de la mémoire. */ static void g_share_manager_finalize(GShareManager *); /* Détermine le type du gestionnaire d'instances partagées. */ G_DEFINE_TYPE(GShareManager, g_share_manager, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : class = classe de composant GTK à initialiser. * * * * Description : Procède à l'initialisation d'une classe de suivi de largeurs.* * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_share_manager_class_init(GShareManagerClass *class) { GObjectClass *object; /* Autre version de la classe */ object = G_OBJECT_CLASS(class); object->dispose = (GObjectFinalizeFunc/* ! */)g_share_manager_dispose; object->finalize = (GObjectFinalizeFunc)g_share_manager_finalize; } /****************************************************************************** * * * Paramètres : manager = composant GLib à initialiser. * * * * Description : Procède à l'initialisation d'un suivi de largeurs de lignes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_share_manager_init(GShareManager *manager) { } /****************************************************************************** * * * Paramètres : manager = instance d'objet GLib à traiter. * * * * Description : Supprime toutes les références externes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_share_manager_dispose(GShareManager *manager) { g_hash_table_unref(manager->table); G_OBJECT_CLASS(g_share_manager_parent_class)->dispose(G_OBJECT(manager)); } /****************************************************************************** * * * Paramètres : manager = instance d'objet GLib à traiter. * * * * Description : Procède à la libération totale de la mémoire. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_share_manager_finalize(GShareManager *manager) { G_OBJECT_CLASS(g_share_manager_parent_class)->finalize(G_OBJECT(manager)); } /****************************************************************************** * * * Paramètres : type = type d'instances encadrées ici. * * * * Description : Crée un nouveau gestionnaire d'instances partagées. * * * * Retour : Composant GLib créé. * * * * Remarques : - * * * ******************************************************************************/ GShareManager *g_share_manager_new(GType type) { GShareManager *result; /* Gestionnaire à renvoyer */ result = g_object_new(G_TYPE_SHARE_MANAGER, NULL); result->table = g_hash_table_new_full((GHashFunc)g_direct_hash, (GEqualFunc)g_shared_instance_is_equal, (GDestroyNotify)g_object_unref, (GDestroyNotify)NULL); result->managed = type; return result; } /****************************************************************************** * * * Paramètres : manager = gestionnaire d'instance à consulter. * * info = informations à retrouver intégralement. * * * * Description : Retrouve ou crée une instance partagée. * * * * Retour : Instance existante déjà partagée ou nouvellement créée. * * * * Remarques : - * * * ******************************************************************************/ GSharedInstance *g_share_manager_get(const GShareManager *manager, const void *info) { GSharedInstance *result; /* Trouvaille à retourner */ gpointer found; /* Elément correspondant ? */ bool status; /* Conclusion d'initialisation */ #ifndef NDEBUG gboolean new; /* Présence de partage existant*/ #endif gboolean find_shared_matching_info(const GSharedInstance *key, gpointer unused, const void *nfo) { return g_shared_instance_compare_info(key, nfo); } found = g_hash_table_find(manager->table, (GHRFunc)find_shared_matching_info, (void *)info); if (found == NULL) { result = g_object_new(manager->managed, NULL); status = g_shared_instance_init(result, info); if (!status) { g_object_unref(result); result = NULL; } else { #ifndef NDEBUG new = g_hash_table_add(manager->table, result); assert(new); #else g_hash_table_add(manager->table, result); #endif } } else result = G_SHARED_INSTANCE(found); if (result != NULL) { g_object_ref(G_OBJECT(result)); g_shared_instance_inc_references(result); } return result; }