diff options
Diffstat (limited to 'src/analysis')
| -rw-r--r-- | src/analysis/project.c | 901 | 
1 files changed, 525 insertions, 376 deletions
| diff --git a/src/analysis/project.c b/src/analysis/project.c index d2228e2..13887ee 100644 --- a/src/analysis/project.c +++ b/src/analysis/project.c @@ -37,25 +37,14 @@  #include "../core/global.h"  #include "../core/logs.h"  #include "../core/params.h" +#include "../core/queue.h" +#include "../glibext/delayed-int.h"  /* ------------------------- DEFINITION D'UN PROJET INTERNE ------------------------- */ -/* Suivi du chargement de contenus binaires */ -typedef struct _loading_params -{ -    const wgroup_id_t **exp_wids;           /* Identifiants d'exploration  */ -    size_t exp_count;                       /* Quantitié d'identifiants    */ - -    size_t resolved;                        /* Compteur de résolutions     */ - -    xmlDoc *xdoc;                           /* Structure XML chargée ?     */ -    xmlXPathContext *context;               /* Eventuel contexte XML       */ - -} loading_params; -  /* Projet d'étude regroupant les binaires analysés (instance) */  struct _GStudyProject  { @@ -63,10 +52,6 @@ struct _GStudyProject      char *filename;                         /* Lieu d'enregistrement       */ -    loading_params *ld_params;              /* Infos d'accompagnement      */ -    size_t ld_count;                        /* Quantité de ces infos       */ -    GMutex ld_mutex;                        /* Encadrement des accès       */ -      GLoadedContent **contents;              /* Contenus chargés et intégrés*/      size_t count;                           /* Quantité de ces contenus    */      GMutex mutex;                           /* Encadrement des accès       */ @@ -104,26 +89,83 @@ static void g_study_project_finalize(GStudyProject *);  /* ------------------------ INTEGRATION DE CONTENUS BINAIRES ------------------------ */ -/* Prépare le suivi d'une nouvelle phase d'intégration. */ -static loading_params *g_study_project_prepare_content_loading(GStudyProject *); +/* Assure l'intégration de contenus listés dans du XML. */ +static void g_study_project_recover_binary_contents(GStudyProject *, xmlDoc *, xmlXPathContext *); + +/* Réceptionne la recette d'une analyse de contenu. */ +static void on_loaded_content_analyzed(GLoadedContent *, gboolean, GStudyProject *); + -/*  Efface le suivi d'une phase d'intégration obsolète. */ -static void g_study_project_destroy_content_loading(GStudyProject *, loading_params *); -/* Retrouve les infos de chargements liées à une exploration. */ -static loading_params *g_study_project_find_exploration(GStudyProject *, wgroup_id_t, const wgroup_id_t **); +/* ------------------------ CHARGEMENTS DE CONTENUS BINAIRES ------------------------ */ -/* Assure l'intégration de contenus listés dans du XML. */ -static void g_study_project_recover_binary_contents(GStudyProject *, xmlDoc *, xmlXPathContext *); + +#define G_TYPE_LOADING_HANDLER            g_loading_handler_get_type() +#define G_LOADING_HANDLER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LOADING_HANDLER, GLoadingHandler)) +#define G_IS_LOADING_HANDLER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LOADING_HANDLER)) +#define G_LOADING_HANDLER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_LOADING_HANDLER, GLoadingHandlerClass)) +#define G_IS_LOADING_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_LOADING_HANDLER)) +#define G_LOADING_HANDLER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_LOADING_HANDLER, GLoadingHandlerClass)) + + +/* Chargement de contenus binaires (instance) */ +typedef struct _GLoadingHandler +{ +    GDelayedWork parent;                    /* A laisser en premier        */ + +    GStudyProject *project;                 /* Projet à compléter          */ + +    xmlDoc *xdoc;                           /* Structure XML chargée ?     */ +    xmlXPathContext *context;               /* Eventuel contexte XML       */ + +    const wgroup_id_t **exp_wids;           /* Identifiants d'exploration  */ +    size_t exp_count;                       /* Quantitié d'identifiants    */ +    size_t resolved;                        /* Compteur de résolutions     */ +    GCond wait_cond;                        /* Réveil d'attente de fin     */ +    GMutex mutex;                           /* Encadrement des accès       */ + +} GLoadingHandler; + +/* Chargement de contenus binaires (classe) */ +typedef struct _GLoadingHandlerClass +{ +    GDelayedWorkClass parent;               /* A laisser en premier        */ + +} GLoadingHandlerClass; + + +/* Indique le type défini pour les tâches de chargement de contenus binaires. */ +GType g_loading_handler_get_type(void); + +/* Initialise la classe des tâches de chargement de contenus. */ +static void g_loading_handler_class_init(GLoadingHandlerClass *); + +/* Initialise une tâche de chargement de contenus binaires. */ +static void g_loading_handler_init(GLoadingHandler *); + +/* Supprime toutes les références externes. */ +static void g_loading_handler_dispose(GLoadingHandler *); + +/* Procède à la libération totale de la mémoire. */ +static void g_loading_handler_finalize(GLoadingHandler *); + +/* Crée une tâche de chargement de contenu bianire. */ +static GLoadingHandler *g_loading_handler_new_discovering(GStudyProject *, GBinContent *); + +/* Crée une tâche de chargement de contenu bianire. */ +static GLoadingHandler *g_loading_handler_new_recovering(GStudyProject *, xmlDoc *, xmlXPathContext *); + +/* Assure le chargement de contenus binaires en différé. */ +static void g_loading_handler_process(GLoadingHandler *, GtkStatusStack *); + +/* Détermine si un encadrement est adapté pour un identifiant. */ +static bool g_loading_handler_check(GLoadingHandler *, wgroup_id_t, const wgroup_id_t **);  /* Note la fin d'une phase d'exploration de contenu. */ -static void on_new_content_explored(GContentExplorer *, wgroup_id_t, GStudyProject *); +static void on_new_content_explored(GContentExplorer *, wgroup_id_t, GLoadingHandler *);  /* Note la fin d'une phase de resolution de contenu. */ -static void on_new_content_resolved(GContentResolver *, wgroup_id_t, GStudyProject *); - -/* Réceptionne la recette d'une analyse de contenu. */ -static void on_loaded_content_analyzed(GLoadedContent *, gboolean, GStudyProject *); +static void on_new_content_resolved(GContentResolver *, wgroup_id_t, GLoadingHandler *); @@ -190,27 +232,12 @@ static void g_study_project_class_init(GStudyProjectClass *klass)  static void g_study_project_init(GStudyProject *project)  { -    GContentExplorer *explorer;             /* Explorateur de contenus     */ -    GContentResolver *resolver;             /* Resolveur de contenus       */ -      project->filename = NULL; -    project->ld_params = NULL; -    project->ld_count = 0; -    g_mutex_init(&project->ld_mutex); -      project->contents = NULL;      project->count = 0;      g_mutex_init(&project->mutex); -    explorer = get_current_content_explorer(); -    g_signal_connect(explorer, "explored", G_CALLBACK(on_new_content_explored), project); -    g_object_unref(G_OBJECT(explorer)); - -    resolver = get_current_content_resolver(); -    g_signal_connect(resolver, "resolved", G_CALLBACK(on_new_content_resolved), project); -    g_object_unref(G_OBJECT(resolver)); -  } @@ -228,30 +255,8 @@ static void g_study_project_init(GStudyProject *project)  static void g_study_project_dispose(GStudyProject *project)  { -    GContentExplorer *explorer;             /* Explorateur de contenus     */ -    GContentResolver *resolver;             /* Resolveur de contenus       */      size_t i;                               /* Boucle de parcours          */ -    explorer = get_current_content_explorer(); -    g_signal_handlers_disconnect_by_func(explorer, G_CALLBACK(on_new_content_explored), project); -    g_object_unref(G_OBJECT(explorer)); - -    resolver = get_current_content_resolver(); -    g_signal_handlers_disconnect_by_func(resolver, G_CALLBACK(on_new_content_resolved), project); -    g_object_unref(G_OBJECT(resolver)); - -    g_mutex_lock(&project->ld_mutex); - -    while (project->ld_count > 0) -        g_study_project_destroy_content_loading(project, project->ld_params); - -    if (project->ld_params != NULL) -        free(project->ld_params); - -    g_mutex_unlock(&project->ld_mutex); - -    g_mutex_clear(&project->ld_mutex); -      g_mutex_lock(&project->mutex);      for (i = 0; i < project->count; i++) @@ -513,36 +518,297 @@ const char *g_study_project_get_filename(const GStudyProject *project)  /******************************************************************************  *                                                                             *  *  Paramètres  : project = projet dont le contenu est à compléter.            * +*                xdoc    = structure XML en cours d'édition.                  * +*                context = contexte à utiliser pour les recherches.           *  *                                                                             * -*  Description : Prépare le suivi d'une nouvelle phase d'intégration.         * +*  Description : Assure l'intégration de contenus listés dans du XML.         *  *                                                                             * -*  Retour      : Nouvelle structure de suivi prête à être complétée.          * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static loading_params *g_study_project_prepare_content_loading(GStudyProject *project) +static void g_study_project_recover_binary_contents(GStudyProject *project, xmlDoc *xdoc, xmlXPathContext *context)  { -    loading_params *result;             /* Trouvaille à retourner      */ +    GLoadingHandler *handler;               /* Encadrement du chargement   */ -    assert(!g_mutex_trylock(&project->ld_mutex)); +    handler = g_loading_handler_new_recovering(project, xdoc, context); -    project->ld_params = (loading_params *)realloc(project->ld_params, -                                                   ++project->ld_count * sizeof(loading_params)); +    if (handler != NULL) +        g_work_queue_schedule_work(get_work_queue(), G_DELAYED_WORK(handler), LOADING_WORK_GROUP); -    result = &project->ld_params[project->ld_count - 1]; +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : project = projet dont le contenu est à compléter.            * +*                content = contenu binaire à mémoriser pour le projet.        * +*                                                                             * +*  Description : Assure l'intégration de contenus binaires dans un projet.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_study_project_discover_binary_content(GStudyProject *project, GBinContent *content) +{ +    GLoadingHandler *handler;               /* Encadrement du chargement   */ + +    handler = g_loading_handler_new_discovering(project, content); + +    g_work_queue_schedule_work(get_work_queue(), G_DELAYED_WORK(handler), LOADING_WORK_GROUP); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : content = contenu chargé et analysé.                         * +*                success = bilan d'une analyse menée.                         * +*                project = projet avide des résultats des opérations.         * +*                                                                             * +*  Description : Réceptionne la recette d'une analyse de contenu.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void on_loaded_content_analyzed(GLoadedContent *content, gboolean success, GStudyProject *project) +{ +    const char *desc;                       /* Description du contenu      */ + +    desc = g_loaded_content_describe(content, true); + +    if (success) +    { +        g_study_project_attach_content(project, content); +        log_variadic_message(LMT_INFO, _("Content from '%s' has been analyzed successfully!"), desc); +    } + +    else +        log_variadic_message(LMT_ERROR, _("Failed to load '%s'"), desc); + +    g_object_ref(G_OBJECT(content)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : project = project à manipuler.                               * +*                content = contenu chargé à associer au projet actuel.        * +*                                                                             * +*  Description : Attache un contenu donné à un projet donné.                  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_study_project_attach_content(GStudyProject *project, GLoadedContent *content) +{ +    g_mutex_lock(&project->mutex); + +    project->contents = (GLoadedContent **)realloc(project->contents, +                                                   ++project->count * sizeof(GLoadedContent *)); + +    project->contents[project->count - 1] = content; +    g_object_ref(G_OBJECT(content)); + +    g_mutex_unlock(&project->mutex); + +    g_signal_emit_by_name(project, "content-added", content); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : project = project à manipuler.                               * +*                content = contenu chargé à dissocier du projet actuel.       * +*                                                                             * +*  Description : Détache un contenu donné d'un projet donné.                  * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_study_project_detach_content(GStudyProject *project, GLoadedContent *content) +{ +    size_t i;                               /* Boucle de parcours          */ + +    g_mutex_lock(&project->mutex); + +    for (i = 0; i < project->count; i++) +        if (project->contents[i] == content) break; + +    if ((i + 1) < project->count) +        memmove(&project->contents[i], &project->contents[i + 1], +                (project->count - i - 1) * sizeof(GLoadedContent *)); + +    project->contents = (GLoadedContent **)realloc(project->contents, +                                                   --project->count * sizeof(GLoadedContent *)); + +    g_mutex_unlock(&project->mutex); + +    g_signal_emit_by_name(project, "content-removed", content); + +    g_object_unref(G_OBJECT(content)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : project = projet dont le contenu est à afficher.             * +*                                                                             * +*  Description : Met en place un projet à l'écran.                            * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_study_project_display(const GStudyProject *project) +{ +#if 0 +    size_t i;                               /* Boucle de parcours #1       */ +    loaded_binary *handled;                 /* Binaire prise en compte     */ +    size_t j;                               /* Boucle de parcours #2       */ + +    for (i = 0; i < project->binaries_count; i++) +    { +        handled = project->binaries[i]; + +        for (j = 0; j < handled->count; j++) +            g_panel_item_dock(handled->items[j]); + +    } +#endif +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : project = projet dont le contenu est à cacher.               * +*                                                                             * +*  Description : Supprime de l'écran un projet en place.                      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_study_project_hide(const GStudyProject *project) +{ +#if 0 +    size_t i;                               /* Boucle de parcours #1       */ +    loaded_binary *handled;                 /* Binaire prise en compte     */ +    size_t j;                               /* Boucle de parcours #2       */ + +    for (i = 0; i < project->binaries_count; i++) +    { +        handled = project->binaries[i]; + +        for (j = 0; j < handled->count; j++) +            g_panel_item_undock(handled->items[j]); + +    } +#endif +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : project = projet dont le contenu est à afficher.             * +*                count = nombre de contenus pris en compte. [OUT]             * +*                                                                             * +*  Description : Fournit l'ensemble des contenus associés à un projet.        * +*                                                                             * +*  Retour      : Liste à libérer de la mémoire.                               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GLoadedContent **g_study_project_get_contents(GStudyProject *project, size_t *count) +{ +    GLoadedContent **result;                /* Tableau à retourner         */ +    size_t i;                               /* Boucle de parcours          */ + +    g_mutex_lock(&project->mutex); + +    *count = project->count; +    result = (GLoadedContent **)calloc(*count, sizeof(GLoadedContent *)); + +    for (i = 0; i < *count; i++) +    { +        result[i] = project->contents[i]; +        g_object_ref(G_OBJECT(result[i])); +    } + +    g_mutex_unlock(&project->mutex);      return result;  } + + +/* ---------------------------------------------------------------------------------- */ +/*                          CHARGEMENTS DE CONTENUS BINAIRES                          */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour les tâches de chargement de contenus binaires. */ +G_DEFINE_TYPE(GLoadingHandler, g_loading_handler, G_TYPE_DELAYED_WORK); + +  /******************************************************************************  *                                                                             * -*  Paramètres  : project = projet dont le contenu est à compléter.            * -*                params  = paramètres de chargemeent à supprimer.             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des tâches de chargement de contenus.   * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_loading_handler_class_init(GLoadingHandlerClass *klass) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ +    GDelayedWorkClass *work;                /* Version en classe parente   */ + +    object = G_OBJECT_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_loading_handler_dispose; +    object->finalize = (GObjectFinalizeFunc)g_loading_handler_finalize; + +    work = G_DELAYED_WORK_CLASS(klass); + +    work->run = (run_task_fc)g_loading_handler_process; + +} + + +/******************************************************************************  *                                                                             * -*  Description : Efface le suivi d'une phase d'intégration obsolète.          * +*  Paramètres  : handler = instance à initialiser.                            * +*                                                                             * +*  Description : Initialise une tâche de chargement de contenus binaires.     *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -550,92 +816,142 @@ static loading_params *g_study_project_prepare_content_loading(GStudyProject *pr  *                                                                             *  ******************************************************************************/ -static void g_study_project_destroy_content_loading(GStudyProject *project, loading_params *params) +static void g_loading_handler_init(GLoadingHandler *handler)  {      GContentExplorer *explorer;             /* Explorateur de contenus     */      GContentResolver *resolver;             /* Resolveur de contenus       */ -    size_t i;                               /* Boucle de parcours          */ -    size_t index;                           /* Indice des paramètres       */ -    assert(!g_mutex_trylock(&project->ld_mutex)); +    g_cond_init(&handler->wait_cond); +    g_mutex_init(&handler->mutex); + +    explorer = get_current_content_explorer(); +    g_signal_connect(explorer, "explored", G_CALLBACK(on_new_content_explored), handler); +    g_object_unref(G_OBJECT(explorer)); + +    resolver = get_current_content_resolver(); +    g_signal_connect(resolver, "resolved", G_CALLBACK(on_new_content_resolved), handler); +    g_object_unref(G_OBJECT(resolver)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : handler = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_loading_handler_dispose(GLoadingHandler *handler) +{ +    GContentExplorer *explorer;             /* Explorateur de contenus     */ +    GContentResolver *resolver;             /* Resolveur de contenus       */ +    size_t i;                               /* Boucle de parcours          */      /* Supression des groupes de travail */      explorer = get_current_content_explorer();      resolver = get_current_content_resolver(); -    for (i = 0; i < params->exp_count; i++) +    g_signal_handlers_disconnect_by_func(explorer, G_CALLBACK(on_new_content_explored), handler); +    g_signal_handlers_disconnect_by_func(resolver, G_CALLBACK(on_new_content_resolved), handler); + +    g_mutex_lock(&handler->mutex); + +    for (i = 0; i < handler->exp_count; i++)      { -        g_content_resolver_delete_group(resolver, *params->exp_wids[i]); -        g_content_explorer_delete_group(explorer, *params->exp_wids[i]); +        g_content_resolver_delete_group(resolver, *handler->exp_wids[i]); +        g_content_explorer_delete_group(explorer, *handler->exp_wids[i]);      } -    free(params->exp_wids); +    g_mutex_unlock(&handler->mutex);      g_object_unref(G_OBJECT(explorer));      g_object_unref(G_OBJECT(resolver)); -    /* Fermture de l'éventuel fichier XML de chargement */ +    /* Nettoyage plus général */ -    if (params->xdoc != NULL) -        close_xml_file(params->xdoc, params->context); +    g_mutex_clear(&handler->mutex); +    g_cond_clear(&handler->wait_cond); -    /* Réorganisation de la liste */ +    g_object_unref(G_OBJECT(handler->project)); -    index = params - project->ld_params; +    G_OBJECT_CLASS(g_loading_handler_parent_class)->dispose(G_OBJECT(handler)); -    if ((index + 1) < project->ld_count) -        memmove(&project->ld_params[index], &project->ld_params[index + 1], -                (project->ld_count - index - 1) * sizeof(loading_params)); +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : handler = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_loading_handler_finalize(GLoadingHandler *handler) +{ +    free(handler->exp_wids); -    project->ld_params = (loading_params *)realloc(project->ld_params, -                                                   --project->ld_count * sizeof(loading_params)); +    /* Fermture de l'éventuel fichier XML de chargement */ + +    if (handler->xdoc != NULL) +        close_xml_file(handler->xdoc, handler->context); + +    G_OBJECT_CLASS(g_loading_handler_parent_class)->finalize(G_OBJECT(handler));  }  /******************************************************************************  *                                                                             * -*  Paramètres  : project = projet dont le contenu est à consulter.            * -*                wid     = identifiant du groupe d'exploration recherché.     * -*                ptr     = pointeur vers la valeur d'origine externe.         * +*  Paramètres  : project = projet dont le contenu est à compléter.            * +*                content = contenu binaire à mémoriser pour le projet.        *  *                                                                             * -*  Description : Retrouve les infos de chargements liées à une exploration.   * +*  Description : Crée une tâche de chargement de contenu bianire.             *  *                                                                             * -*  Retour      : Informations trouvées ou NULL en cas d'échec.                * +*  Retour      : Tâche créée.                                                 *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static loading_params *g_study_project_find_exploration(GStudyProject *project, wgroup_id_t wid, const wgroup_id_t **ptr) +static GLoadingHandler *g_loading_handler_new_discovering(GStudyProject *project, GBinContent *content)  { -    loading_params *result;             /* Trouvaille à retourner      */ -    const wgroup_id_t *value;           /* Raccourci de confort        */ -    size_t i;                           /* Boucle de parcours #1       */ -    size_t k;                           /* Boucle de parcours #2       */ +    GLoadingHandler *result;                /* Tâche à retourner           */ +    GContentExplorer *explorer;             /* Explorateur de contenus     */ -    assert(!g_mutex_trylock(&project->ld_mutex)); +    result = g_object_new(G_TYPE_LOADING_HANDLER, NULL); -    result = NULL; +    result->project = project; +    g_object_ref(G_OBJECT(result->project)); -    value = NULL; +    result->xdoc = NULL; +    result->context = NULL; -    for (i = 0; i < project->ld_count && result == NULL; i++) -        for (k = 0; k < project->ld_params[i].exp_count && result == NULL; k++) -        { -            value = project->ld_params[i].exp_wids[k]; +    result->exp_wids = (const wgroup_id_t **)malloc(sizeof(wgroup_id_t *)); +    result->exp_count = 1; -            if (*value == wid) -                result = &project->ld_params[i]; +    result->resolved = 0; -        } +    explorer = get_current_content_explorer(); -    if (ptr != NULL) -    { -        assert(result == NULL || value != NULL); -        *ptr = (result == NULL ? NULL : value); -    } +    g_mutex_lock(&result->mutex); + +    result->exp_wids[0] = g_content_explorer_create_group(explorer, content); + +    g_mutex_unlock(&result->mutex); + +    g_object_unref(G_OBJECT(explorer));      return result; @@ -648,17 +964,17 @@ static loading_params *g_study_project_find_exploration(GStudyProject *project,  *                xdoc    = structure XML en cours d'édition.                  *  *                context = contexte à utiliser pour les recherches.           *  *                                                                             * -*  Description : Assure l'intégration de contenus listés dans du XML.         * +*  Description : Crée une tâche de chargement de contenu bianire.             *  *                                                                             * -*  Retour      : -                                                            * +*  Retour      : Tâche créée.                                                 *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static void g_study_project_recover_binary_contents(GStudyProject *project, xmlDoc *xdoc, xmlXPathContext *context) +static GLoadingHandler *g_loading_handler_new_recovering(GStudyProject *project, xmlDoc *xdoc, xmlXPathContext *context)  { -    loading_params *params;                 /* Informations de chargement  */ +    GLoadingHandler *result;                /* Tâche à retourner           */      xmlXPathObjectPtr xobject;              /* Cible d'une recherche       */      size_t count;                           /* Nombre de contenus premiers */      GContentExplorer *explorer;             /* Explorateur de contenus     */ @@ -673,21 +989,24 @@ static void g_study_project_recover_binary_contents(GStudyProject *project, xmlD      if (count > 0)      { -        explorer = get_current_content_explorer(); +        result = g_object_new(G_TYPE_LOADING_HANDLER, NULL); -        g_mutex_lock(&project->ld_mutex); +        result->project = project; +        g_object_ref(G_OBJECT(result->project)); -        params = g_study_project_prepare_content_loading(project); +        result->xdoc = xdoc; +        result->context = context; -        params->exp_wids = (const wgroup_id_t **)malloc(count * sizeof(wgroup_id_t *)); +        result->exp_wids = (const wgroup_id_t **)malloc(count * sizeof(wgroup_id_t *)); -        params->resolved = 0; +        result->resolved = 0; -        params->xdoc = xdoc; -        params->context = context; +        explorer = get_current_content_explorer();          explored = 0; +        g_mutex_lock(&result->mutex); +          for (i = 0; i < XPATH_OBJ_NODES_COUNT(xobject); i++)          {              asprintf(&access, "/ChrysalideProject/RootContents/Content[position()=%zu]", i + 1); @@ -702,32 +1021,37 @@ static void g_study_project_recover_binary_contents(GStudyProject *project, xmlD                  continue;              } -            params->exp_wids[explored++] = g_content_explorer_create_group(explorer, content); +            result->exp_wids[explored++] = g_content_explorer_create_group(explorer, content);              g_object_unref(G_OBJECT(content));          } -        params->exp_count = explored; +        result->exp_count = explored; -        g_mutex_unlock(&project->ld_mutex); +        g_mutex_unlock(&result->mutex);          g_object_unref(G_OBJECT(explorer));      } +    else +        result = NULL; +      if(xobject != NULL)          xmlXPathFreeObject(xobject); +    return result; +  }  /******************************************************************************  *                                                                             * -*  Paramètres  : project = projet dont le contenu est à compléter.            * -*                content = contenu binaire à mémoriser pour le projet.        * +*  Paramètres  : handler = opération de chargement à menuer.                  * +*                status  = barre de statut à tenir informée.                  *  *                                                                             * -*  Description : Assure l'intégration de contenus binaires dans un projet.    * +*  Description : Assure le chargement de contenus binaires en différé.        *  *                                                                             *  *  Retour      : -                                                            *  *                                                                             * @@ -735,30 +1059,59 @@ static void g_study_project_recover_binary_contents(GStudyProject *project, xmlD  *                                                                             *  ******************************************************************************/ -void g_study_project_discover_binary_content(GStudyProject *project, GBinContent *content) +static void g_loading_handler_process(GLoadingHandler *handler, GtkStatusStack *status)  { -    loading_params *params;                 /* Informations de chargement  */ -    GContentExplorer *explorer;             /* Explorateur de contenus     */ +    g_mutex_lock(&handler->mutex); -    explorer = get_current_content_explorer(); +    while (handler->resolved < handler->exp_count) +        g_cond_wait(&handler->wait_cond, &handler->mutex); + +    g_mutex_unlock(&handler->mutex); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : handler = gestionnaire dont contenu est à consulter.         * +*                wid     = identifiant du groupe d'exploration recherché.     * +*                ptr     = pointeur vers la valeur d'origine externe.         * +*                                                                             * +*  Description : Détermine si un encadrement est adapté pour un identifiant.  * +*                                                                             * +*  Retour      : Bilan d'adéquation.                                          * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    g_mutex_lock(&project->ld_mutex); +static bool g_loading_handler_check(GLoadingHandler *handler, wgroup_id_t wid, const wgroup_id_t **ptr) +{ +    bool result;                        /* Bilan à retourner           */ +    const wgroup_id_t *value;           /* Raccourci de confort        */ +    size_t i;                           /* Boucle de parcours          */ -    params = g_study_project_prepare_content_loading(project); +    assert(!g_mutex_trylock(&handler->mutex)); -    params->exp_wids = (const wgroup_id_t **)malloc(sizeof(wgroup_id_t *)); -    params->exp_count = 1; +    result = false; + +    value = NULL; -    params->resolved = 0; +    for (i = 0; i < handler->exp_count && !result; i++) +    { +        value = handler->exp_wids[i]; -    params->xdoc = NULL; -    params->context = NULL; +        result = (*value == wid); -    params->exp_wids[0] = g_content_explorer_create_group(explorer, content); +    } -    g_mutex_unlock(&project->ld_mutex); +    if (ptr != NULL) +    { +        assert(!result || value != NULL); +        *ptr = (result ? value : NULL); +    } -    g_object_unref(G_OBJECT(explorer)); +    return result;  } @@ -767,7 +1120,7 @@ void g_study_project_discover_binary_content(GStudyProject *project, GBinContent  *                                                                             *  *  Paramètres  : explorer = gestionnaire d'explorations à consulter.          *  *                wid      = groupe d'exploration concerné.                    * -*                project  = projet avide des résultats des opérations.        * +*                handler  = gestionnaire avide des résultats des opérations.  *  *                                                                             *  *  Description : Note la fin d'une phase d'exploration de contenu.            *  *                                                                             * @@ -777,21 +1130,17 @@ void g_study_project_discover_binary_content(GStudyProject *project, GBinContent  *                                                                             *  ******************************************************************************/ -static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid, GStudyProject *project) +static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid, GLoadingHandler *handler)  {      const wgroup_id_t *wid_ptr;             /* Référence vers l'origine    */ -    loading_params *params;                 /* Informations de chargement  */      GBinContent **available;                /* Contenus binaires présents  */      size_t count;                           /* Quantité de ces contenus    */      GContentResolver *resolver;             /* Resolveur de contenus       */      size_t i;                               /* Boucle de parcours          */ -    g_mutex_lock(&project->ld_mutex); - -    params = g_study_project_find_exploration(project, wid, &wid_ptr); +    g_mutex_lock(&handler->mutex); -    /* S'il s'agit bien d'une exploration nouvelle */ -    if (params != NULL) +    if (g_loading_handler_check(handler, wid, &wid_ptr))      {          available = g_content_explorer_get_all(explorer, wid, &count);          assert(count > 0); @@ -809,7 +1158,7 @@ static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid,      } -    g_mutex_unlock(&project->ld_mutex); +    g_mutex_unlock(&handler->mutex);  } @@ -818,7 +1167,7 @@ static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid,  *                                                                             *  *  Paramètres  : resolver = gestionnaire de résolutions à consulter.          *  *                wid      = groupe d'exploration concerné.                    * -*                project  = projet avide des résultats des opérations.        * +*                handler  = gestionnaire avide des résultats des opérations.  *  *                                                                             *  *  Description : Note la fin d'une phase de resolution de contenu.            *  *                                                                             * @@ -828,9 +1177,8 @@ static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid,  *                                                                             *  ******************************************************************************/ -static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid, GStudyProject *project) +static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid, GLoadingHandler *handler)  { -    loading_params *params;                 /* Informations de chargement  */      GLoadedContent **available;             /* Contenus chargés valables   */      size_t count;                           /* Quantité de ces contenus    */      size_t i;                               /* Boucle de parcours          */ @@ -841,19 +1189,16 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid,      xmlXPathObjectPtr xobject;              /* Cible d'une recherche       */      bool status;                            /* Bilan d'une restauration    */ -    g_mutex_lock(&project->ld_mutex); +    g_mutex_lock(&handler->mutex); -    params = g_study_project_find_exploration(project, wid, NULL); - -    /* S'il s'agit bien d'une exploration nouvelle */ -    if (params != NULL) +    if (g_loading_handler_check(handler, wid, NULL))      {          available = g_content_resolver_get_all(resolver, wid, &count);          /* Rechargement à partir d'XML ? */ -        if (params->xdoc != NULL) +        if (handler->xdoc != NULL)          { -            assert(params->context != NULL); +            assert(handler->context != NULL);              for (i = 0; i < count; i++)              { @@ -866,12 +1211,12 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid,                  asprintf(&access, "/ChrysalideProject/LoadedContents/Content[@hash='%s' and @format='%s']",                           hash, format); -                xobject = get_node_xpath_object(params->context, access); +                xobject = get_node_xpath_object(handler->context, access);                  if (XPATH_OBJ_NODES_COUNT(xobject) > 0)                  { -                    status = g_loaded_content_restore(available[i], params->xdoc, params->context, access); +                    status = g_loaded_content_restore(available[i], handler->xdoc, handler->context, access);                      if (!status)                          log_variadic_message(LMT_ERROR, @@ -888,7 +1233,8 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid,                           */                          g_object_ref(G_OBJECT(available[i])); -                        g_signal_connect(available[i], "analyzed", G_CALLBACK(on_loaded_content_analyzed), project); +                        g_signal_connect(available[i], "analyzed", +                                         G_CALLBACK(on_loaded_content_analyzed), handler->project);                          g_loaded_content_analyze(available[i]); @@ -921,7 +1267,8 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid,                   */                  g_object_ref(G_OBJECT(available[i])); -                g_signal_connect(available[i], "analyzed", G_CALLBACK(on_loaded_content_analyzed), project); +                g_signal_connect(available[i], "analyzed", +                                 G_CALLBACK(on_loaded_content_analyzed), handler->project);                  g_loaded_content_analyze(available[i]); @@ -936,212 +1283,14 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid,              free(available);          /* Si c'était la dernière résolution... */ -        if (++params->resolved == params->exp_count) -            g_study_project_destroy_content_loading(project, params); -    } +        handler->resolved++; -    g_mutex_unlock(&project->ld_mutex); +        g_cond_broadcast(&handler->wait_cond); -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : content = contenu chargé et analysé.                         * -*                success = bilan d'une analyse menée.                         * -*                project = projet avide des résultats des opérations.         * -*                                                                             * -*  Description : Réceptionne la recette d'une analyse de contenu.             * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static void on_loaded_content_analyzed(GLoadedContent *content, gboolean success, GStudyProject *project) -{ -    const char *desc;                       /* Description du contenu      */ - -    desc = g_loaded_content_describe(content, true); - -    if (success) -    { -        g_study_project_attach_content(project, content); -        log_variadic_message(LMT_INFO, _("Content from '%s' has been analyzed successfully!"), desc);      } -    else -        log_variadic_message(LMT_ERROR, _("Failed to load '%s'"), desc); - -    g_object_ref(G_OBJECT(content)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : project = project à manipuler.                               * -*                content = contenu chargé à associer au projet actuel.        * -*                                                                             * -*  Description : Attache un contenu donné à un projet donné.                  * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_study_project_attach_content(GStudyProject *project, GLoadedContent *content) -{ -    g_mutex_lock(&project->mutex); - -    project->contents = (GLoadedContent **)realloc(project->contents, -                                                   ++project->count * sizeof(GLoadedContent *)); - -    project->contents[project->count - 1] = content; -    g_object_ref(G_OBJECT(content)); - -    g_mutex_unlock(&project->mutex); - -    g_signal_emit_by_name(project, "content-added", content); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : project = project à manipuler.                               * -*                content = contenu chargé à dissocier du projet actuel.       * -*                                                                             * -*  Description : Détache un contenu donné d'un projet donné.                  * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_study_project_detach_content(GStudyProject *project, GLoadedContent *content) -{ -    size_t i;                               /* Boucle de parcours          */ - -    g_mutex_lock(&project->mutex); - -    for (i = 0; i < project->count; i++) -        if (project->contents[i] == content) break; - -    if ((i + 1) < project->count) -        memmove(&project->contents[i], &project->contents[i + 1], -                (project->count - i - 1) * sizeof(GLoadedContent *)); - -    project->contents = (GLoadedContent **)realloc(project->contents, -                                                   --project->count * sizeof(GLoadedContent *)); - -    g_mutex_unlock(&project->mutex); - -    g_signal_emit_by_name(project, "content-removed", content); - -    g_object_unref(G_OBJECT(content)); - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : project = projet dont le contenu est à afficher.             * -*                                                                             * -*  Description : Met en place un projet à l'écran.                            * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_study_project_display(const GStudyProject *project) -{ -#if 0 -    size_t i;                               /* Boucle de parcours #1       */ -    loaded_binary *handled;                 /* Binaire prise en compte     */ -    size_t j;                               /* Boucle de parcours #2       */ - -    for (i = 0; i < project->binaries_count; i++) -    { -        handled = project->binaries[i]; - -        for (j = 0; j < handled->count; j++) -            g_panel_item_dock(handled->items[j]); - -    } -#endif -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : project = projet dont le contenu est à cacher.               * -*                                                                             * -*  Description : Supprime de l'écran un projet en place.                      * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -void g_study_project_hide(const GStudyProject *project) -{ -#if 0 -    size_t i;                               /* Boucle de parcours #1       */ -    loaded_binary *handled;                 /* Binaire prise en compte     */ -    size_t j;                               /* Boucle de parcours #2       */ - -    for (i = 0; i < project->binaries_count; i++) -    { -        handled = project->binaries[i]; - -        for (j = 0; j < handled->count; j++) -            g_panel_item_undock(handled->items[j]); - -    } -#endif -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : project = projet dont le contenu est à afficher.             * -*                count = nombre de contenus pris en compte. [OUT]             * -*                                                                             * -*  Description : Fournit l'ensemble des contenus associés à un projet.        * -*                                                                             * -*  Retour      : Liste à libérer de la mémoire.                               * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GLoadedContent **g_study_project_get_contents(GStudyProject *project, size_t *count) -{ -    GLoadedContent **result;                /* Tableau à retourner         */ -    size_t i;                               /* Boucle de parcours          */ - -    g_mutex_lock(&project->mutex); - -    *count = project->count; -    result = (GLoadedContent **)calloc(*count, sizeof(GLoadedContent *)); - -    for (i = 0; i < *count; i++) -    { -        result[i] = project->contents[i]; -        g_object_ref(G_OBJECT(result[i])); -    } - -    g_mutex_unlock(&project->mutex); - -    return result; +    g_mutex_unlock(&handler->mutex);  } | 
