diff options
Diffstat (limited to 'src/glibext/singleton.c')
-rw-r--r-- | src/glibext/singleton.c | 204 |
1 files changed, 19 insertions, 185 deletions
diff --git a/src/glibext/singleton.c b/src/glibext/singleton.c index 78a3ad4..65b83e7 100644 --- a/src/glibext/singleton.c +++ b/src/glibext/singleton.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * singleton.c - réduction du nombre d'instances d'un même type * - * Copyright (C) 2021 Cyrille Bagard + * Copyright (C) 2021-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -25,6 +25,8 @@ #include <assert.h> +#include <malloc.h> +#include <stdbool.h> #include "singleton-int.h" @@ -33,44 +35,21 @@ /* ------------------ INTERFACE POUR CANDIDAT A UNE CENTRALISATION ------------------ */ + /* Procède à l'initialisation de l'interface de rassemblement. */ static void g_singleton_candidate_default_init(GSingletonCandidateInterface *); /* Met à jour une liste de candidats embarqués par un candidat. */ static void g_singleton_candidate_update_inner_instances(GSingletonCandidate *, GSingletonCandidate **, size_t); -/* Fournit l'empreinte d'un candidat à une centralisation. */ -static guint _g_singleton_candidate_hash(GSingletonCandidate *, GList **); - /* Détermine si deux candidats à l'unicité sont identiques. */ static gboolean _g_singleton_candidate_is_equal(GSingletonCandidate *, GSingletonCandidate *, GList **); -/* Marque un candidat comme figé. */ -static void _g_singleton_candidate_set_read_only(GSingletonCandidate *, GList **); - /* ------------------------- COLLECTION D'INSTANCES UNIQUES ------------------------- */ -/* Définition d'un compacteur d'instances de types (instance) */ -struct _GSingletonFactory -{ - GObject parent; /* A laisser en premier */ - - GHashTable *table; /* Suivi des conservations */ - GMutex access; /* Verrou pour la concurrence */ - -}; - -/* Définition d'un compacteur d'instances de types (classe) */ -struct _GSingletonFactoryClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - /* Initialise la classe des compacteurs d'instances de types. */ static void g_singleton_factory_class_init(GSingletonFactoryClass *); @@ -90,7 +69,7 @@ static void g_singleton_factory_finalize(GSingletonFactory *); /* ---------------------------------------------------------------------------------- */ -/* Détermine le type d'une interface pour la lecture de binaire. */ +/* Détermine le type d'une interface pour la constitution d'objets uniques. */ G_DEFINE_INTERFACE(GSingletonCandidate, g_singleton_candidate, G_TYPE_OBJECT) @@ -128,7 +107,7 @@ static void g_singleton_candidate_default_init(GSingletonCandidateInterface *ifa GSingletonCandidate **g_singleton_candidate_list_inner_instances(const GSingletonCandidate *candidate, size_t *count) { GSingletonCandidate **result; /* Instances à retourner */ - GSingletonCandidateIface *iface; /* Interface utilisée */ + GSingletonCandidateInterface *iface; /* Interface utilisée */ iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate); @@ -162,7 +141,7 @@ GSingletonCandidate **g_singleton_candidate_list_inner_instances(const GSingleto static void g_singleton_candidate_update_inner_instances(GSingletonCandidate *candidate, GSingletonCandidate **instances, size_t count) { - GSingletonCandidateIface *iface; /* Interface utilisée */ + GSingletonCandidateInterface *iface; /* Interface utilisée */ iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate); @@ -181,7 +160,6 @@ static void g_singleton_candidate_update_inner_instances(GSingletonCandidate *ca /****************************************************************************** * * * Paramètres : candidate = objet dont l'instance se veut unique. * -* processed = liste de candidats déjà traités. * * * * Description : Fournit l'empreinte d'un candidat à une centralisation. * * * @@ -191,70 +169,28 @@ static void g_singleton_candidate_update_inner_instances(GSingletonCandidate *ca * * ******************************************************************************/ -static guint _g_singleton_candidate_hash(GSingletonCandidate *candidate, GList **processed) +guint g_singleton_candidate_hash(GSingletonCandidate *candidate) { guint result; /* Valeur à retourner */ - GList *skip; /* Détection de boucle */ - GSingletonCandidateIface *iface; /* Interface utilisée */ + GSingletonCandidateInterface *iface; /* Interface utilisée */ GSingletonCandidate **children; /* Instances internes */ size_t count; /* Quantité de ces instances */ size_t i; /* Boucle de parcours */ - skip = g_list_find(*processed, candidate); - - if (skip != NULL) - result = 0; - - else - { - iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate); - - result = iface->hash(candidate); - - *processed = g_list_append(*processed, candidate); - - children = g_singleton_candidate_list_inner_instances(candidate, &count); + iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate); - for (i = 0; i < count; i++) - { - result ^= _g_singleton_candidate_hash(children[i], processed); - g_object_unref(G_OBJECT(children[i])); - } + result = iface->hash(candidate); - if (children != NULL) - free(children); + children = g_singleton_candidate_list_inner_instances(candidate, &count); + for (i = 0; i < count; i++) + { + result ^= g_singleton_candidate_hash(children[i]); + unref_object(children[i]); } - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : candidate = objet dont l'instance se veut unique. * -* * -* Description : Fournit l'empreinte d'un candidat à une centralisation. * -* * -* Retour : Empreinte de l'élément représenté. * -* * -* Remarques : - * -* * -******************************************************************************/ - -guint g_singleton_candidate_hash(GSingletonCandidate *candidate) -{ - guint result; /* Valeur à retourner */ - GList *processed; /* Suivi des traitements */ - - processed = NULL; - - result = _g_singleton_candidate_hash(candidate, &processed); - - assert(processed != NULL); - - g_list_free(processed); + if (children != NULL) + free(children); return result; @@ -279,7 +215,7 @@ static gboolean _g_singleton_candidate_is_equal(GSingletonCandidate *candidate, { gboolean result; /* Bilan à renvoyer */ GList *skip; /* Détection de boucle */ - GSingletonCandidateIface *iface; /* Interface utilisée */ + GSingletonCandidateInterface *iface; /* Interface utilisée */ GSingletonCandidate **children[2]; /* Instances internes */ size_t count[2]; /* Quantité de ces instances */ size_t i; /* Boucle de parcours */ @@ -380,106 +316,6 @@ gboolean g_singleton_candidate_is_equal(GSingletonCandidate *candidate, GSinglet } -/****************************************************************************** -* * -* Paramètres : candidate = objet dont l'instance se veut unique. * -* processed = liste de candidats déjà traités. * -* * -* Description : Marque un candidat comme figé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void _g_singleton_candidate_set_read_only(GSingletonCandidate *candidate, GList **processed) -{ - GList *skip; /* Détection de boucle */ - GSingletonCandidateIface *iface; /* Interface utilisée */ - GSingletonCandidate **children; /* Instances internes */ - size_t count; /* Quantité de ces instances */ - size_t i; /* Boucle de parcours */ - - skip = g_list_find(*processed, candidate); - - if (skip == NULL) - { - iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate); - - iface->set_ro(candidate); - - *processed = g_list_append(*processed, candidate); - - children = g_singleton_candidate_list_inner_instances(candidate, &count); - - for (i = 0; i < count; i++) - { - _g_singleton_candidate_set_read_only(candidate, processed); - g_object_unref(G_OBJECT(children[i])); - } - - if (children != NULL) - free(children); - - } - -} - - -/****************************************************************************** -* * -* Paramètres : candidate = objet dont l'instance se veut unique. * -* * -* Description : Marque un candidat comme figé. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_singleton_candidate_set_read_only(GSingletonCandidate *candidate) -{ - GList *processed; /* Suivi des traitements */ - - processed = NULL; - - _g_singleton_candidate_set_read_only(candidate, &processed); - - assert(processed != NULL); - - g_list_free(processed); - -} - - -/****************************************************************************** -* * -* Paramètres : candidate = objet dont l'instance se veut unique. * -* * -* Description : Indique si le candidat est figé. * -* * -* Retour : true si le contenu du candidat ne peut plus être modifié. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_singleton_candidate_is_read_only(const GSingletonCandidate *candidate) -{ - bool result; /* Etat à retourner */ - GSingletonCandidateIface *iface; /* Interface utilisée */ - - iface = G_SINGLETON_CANDIDATE_GET_IFACE(candidate); - - result = iface->is_ro(candidate); - - return result; - -} - - /* ---------------------------------------------------------------------------------- */ /* COLLECTION D'INSTANCES UNIQUES */ @@ -688,8 +524,6 @@ GSingletonCandidate *g_singleton_factory_get_instance(GSingletonFactory *factory g_hash_table_add(factory->table, candidate); #endif - g_singleton_candidate_set_read_only(candidate); - result = candidate; } |