/* 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;
}