From e5d10374c2aa3cedd679f34fb61457bd0b1c1d53 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 22 Sep 2018 09:26:29 +0200
Subject: Provided a way to load known flat formats.

---
 plugins/pychrysalide/analysis/loading.c |  45 ++++++++++++
 src/analysis/loading.c                  | 117 +++++++++++++++++++++++++++++++-
 src/analysis/loading.h                  |   8 ++-
 src/analysis/project.c                  |  12 +++-
 4 files changed, 178 insertions(+), 4 deletions(-)

diff --git a/plugins/pychrysalide/analysis/loading.c b/plugins/pychrysalide/analysis/loading.c
index 44930cd..f785a53 100644
--- a/plugins/pychrysalide/analysis/loading.c
+++ b/plugins/pychrysalide/analysis/loading.c
@@ -44,6 +44,9 @@
 /* Ajoute un nouveau contenu découvert au crédit d'un groupe. */
 static PyObject *py_content_explorer_populate_group(PyObject *, PyObject *);
 
+/* Note un contenu chargé pour future intégration guidée. */
+static PyObject *py_content_explorer_note_detected(PyObject *, PyObject *);
+
 
 
 /* ------------------- RESOLUTION DE CONTENUS BINAIRES EN CHARGES ------------------- */
@@ -96,6 +99,43 @@ static PyObject *py_content_explorer_populate_group(PyObject *self, PyObject *ar
 
 }
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un binaire.                       *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Note un contenu chargé pour future intégration guidée.       *
+*                                                                             *
+*  Retour      : None.                                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_content_explorer_note_detected(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    unsigned long long wid;                 /* Identifiant de groupe       */
+    PyObject *loaded_obj;                   /* Contenu chargé en Python    */
+    int ret;                                /* Bilan de lecture des args.  */
+    GContentExplorer *explorer;             /* Explorateur à manipuler     */
+    GLoadedContent *loaded;                 /* Contenu chargé au final     */
+
+    ret = PyArg_ParseTuple(args, "KO!", &wid, get_python_loaded_content_type(), &loaded_obj);
+    if (!ret) Py_RETURN_NONE;
+
+    explorer = G_CONTENT_EXPLORER(pygobject_get(self));
+    loaded = G_LOADED_CONTENT(pygobject_get(loaded_obj));
+
+    g_content_explorer_note_detected(explorer, wid, loaded);
+
+    result = Py_None;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
 
 /******************************************************************************
 *                                                                             *
@@ -117,6 +157,11 @@ PyTypeObject *get_python_content_explorer_type(void)
             METH_VARARGS,
             "populate_group($self, wid, content, /)\n--\n\nPush a new binary content into the list to explore."
         },
+        {
+            "note_detected", py_content_explorer_note_detected,
+            METH_VARARGS,
+            "note_detected($self, wid, loaded, /)\n--\n\nMark a loaded content as one final candidate."
+        },
         { NULL }
     };
 
diff --git a/src/analysis/loading.c b/src/analysis/loading.c
index 3a53657..0afc60f 100644
--- a/src/analysis/loading.c
+++ b/src/analysis/loading.c
@@ -113,6 +113,9 @@ typedef struct _exploring_group
     GBinContent **contents;                 /* Contenus reconnus dispos.   */
     size_t count;                           /* Taille de cette liste       */
 
+    GLoadedContent **loaded;                /* Contenus reconnus à intégrer*/
+    size_t noted;                           /* Taille de cette liste       */
+
 } exploring_group;
 
 /* Exploration de contenus binaires (instance) */
@@ -729,6 +732,9 @@ wgroup_id_t g_content_explorer_create_group(GContentExplorer *explorer, GBinCont
     group->contents = NULL;
     group->count = 0;
 
+    group->loaded = NULL;
+    group->noted = 0;
+
     /* Alimentation du contenu initial */
 
     work = g_exploring_work_new(content);
@@ -779,6 +785,15 @@ void g_content_explorer_delete_group(GContentExplorer *explorer, wgroup_id_t wid
     for (i = 0; i < group->count; i++)
         g_object_unref(G_OBJECT(group->contents[i]));
 
+    if (group->contents != NULL)
+        free(group->contents);
+
+    for (i = 0; i < group->noted; i++)
+        g_object_unref(G_OBJECT(group->loaded[i]));
+
+    if (group->loaded != NULL)
+        free(group->loaded);
+
     /* Réorganisation de la liste */
 
     index = group - explorer->groups;
@@ -850,6 +865,39 @@ void g_content_explorer_populate_group(GContentExplorer *explorer, wgroup_id_t w
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : explorer = gestionnaire d'explorations à consulter.          *
+*                wid      = identifiant du groupe recherché.                  *
+*                loaded   = contenu chargé et pouvant être représenté.        *
+*                                                                             *
+*  Description : Note un contenu chargé pour future intégration guidée.       *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_content_explorer_note_detected(GContentExplorer *explorer, wgroup_id_t wid, GLoadedContent *loaded)
+{
+    exploring_group *group;                 /* Groupe d'opération concerné */
+
+    g_mutex_lock(&explorer->mutex);
+
+    group = g_content_explorer_find_group(explorer, wid);
+    assert(group != NULL);
+
+    group->loaded = (GLoadedContent **)realloc(group->loaded, ++group->noted * sizeof(GLoadedContent *));
+
+    group->loaded[group->noted - 1] = loaded;
+    g_object_ref(G_OBJECT(loaded));
+
+    g_mutex_unlock(&explorer->mutex);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : explorer = gestionnaire d'explorations à consulter.          *
 *                wid      = identifiant du groupe à parcourir.                *
 *                count    = nombre de contenus binaires retournés. [OUT]      *
 *                                                                             *
@@ -889,7 +937,54 @@ GBinContent **g_content_explorer_get_all(GContentExplorer *explorer, wgroup_id_t
     {
         result[1 + i] = group->contents[i];
 
-        g_object_ref(G_OBJECT(result[i + 1]));
+        g_object_ref(G_OBJECT(result[1 + i]));
+
+    }
+
+    g_mutex_unlock(&explorer->mutex);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : explorer = gestionnaire d'explorations à consulter.          *
+*                wid      = identifiant du groupe à parcourir.                *
+*                noted    = nombre de contenus chargés retournés. [OUT]       *
+*                                                                             *
+*  Description : Fournit la liste de tous les contenus préalablement détectés.*
+*                                                                             *
+*  Retour      : Liste de contenus chargés enregistrés.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GLoadedContent **g_content_explorer_get_detected(GContentExplorer *explorer, wgroup_id_t wid, size_t *noted)
+{
+    GLoadedContent **result;                /* Trouvailles à retourner      */
+    exploring_group *group;                 /* Groupe d'opération concerné */
+    size_t i;                               /* Boucle de parcours          */
+
+    g_mutex_lock(&explorer->mutex);
+
+    group = g_content_explorer_find_group(explorer, wid);
+    assert(group != NULL);
+
+    /* Allocation de la liste finale */
+
+    *noted = group->noted;
+    result = (GLoadedContent **)malloc(*noted * sizeof(GLoadedContent *));
+
+    /* On parcourt les éventuels contenus encapsulés découverts */
+
+    for (i = 0; i < group->noted; i++)
+    {
+        result[i] = group->loaded[i];
+
+        g_object_ref(G_OBJECT(result[i]));
 
     }
 
@@ -1305,6 +1400,8 @@ static void g_content_resolver_ack(GContentResolver *resolver, GResolvingWork *w
 *                wid      = identifiant du groupe de tâches réservé.          *
 *                contents = contenus à analyser.                              *
 *                count    = nombre de ces contenus.                           *
+*                detected = contenus préalablement détectés.                  *
+*                noted    = nombre de contenus chargés.                       *
 *                                                                             *
 *  Description : Initie une nouvelle vague de résolution de contenus.         *
 *                                                                             *
@@ -1314,7 +1411,7 @@ static void g_content_resolver_ack(GContentResolver *resolver, GResolvingWork *w
 *                                                                             *
 ******************************************************************************/
 
-void g_content_resolver_create_group(GContentResolver *resolver, wgroup_id_t wid, GBinContent **contents, size_t count)
+void g_content_resolver_create_group(GContentResolver *resolver, wgroup_id_t wid, GBinContent **contents, size_t count, GLoadedContent **detected, size_t noted)
 {
     resolving_group *group;                 /* Groupe ciblé par l'opération*/
     GWorkQueue *queue;                      /* Gestionnaire de différés    */
@@ -1336,6 +1433,21 @@ void g_content_resolver_create_group(GContentResolver *resolver, wgroup_id_t wid
     group->loaded = NULL;
     group->count = 0;
 
+    /* Insertion des résultats préalables */
+
+    if (noted > 0)
+    {
+        group->count = noted;
+        group->loaded = (GLoadedContent **)realloc(group->loaded, group->count * sizeof(GLoadedContent *));
+
+        for (i = 0; i < noted; i++)
+        {
+            group->loaded[i] = detected[i];
+            g_object_ref(G_OBJECT(detected[i]));
+        }
+
+    }
+
     /* Alimentation du contenu initial */
 
     queue = get_work_queue();
@@ -1423,6 +1535,7 @@ void g_content_resolver_add_detected(GContentResolver *resolver, wgroup_id_t wid
     g_mutex_lock(&resolver->mutex);
 
     group = g_content_resolver_find_group(resolver, wid);
+    assert(group != NULL);
 
     group->loaded = (GLoadedContent **)realloc(group->loaded, ++group->count * sizeof(GLoadedContent *));
 
diff --git a/src/analysis/loading.h b/src/analysis/loading.h
index c7ede58..e2f7801 100644
--- a/src/analysis/loading.h
+++ b/src/analysis/loading.h
@@ -67,9 +67,15 @@ void g_content_explorer_delete_group(GContentExplorer *, wgroup_id_t);
 /* Ajoute un nouveau contenu découvert au crédit d'un groupe. */
 void g_content_explorer_populate_group(GContentExplorer *, wgroup_id_t, GBinContent *);
 
+/* Note un contenu chargé pour future intégration guidée. */
+void g_content_explorer_note_detected(GContentExplorer *, wgroup_id_t, GLoadedContent *);
+
 /* Fournit la liste de tous les contenus disponibles. */
 GBinContent **g_content_explorer_get_all(GContentExplorer *, wgroup_id_t, size_t *);
 
+/* Fournit la liste de tous les contenus préalablement détectés. */
+GLoadedContent **g_content_explorer_get_detected(GContentExplorer *, wgroup_id_t, size_t *);
+
 
 
 /* ------------------- RESOLUTION DE CONTENUS BINAIRES EN CHARGES ------------------- */
@@ -97,7 +103,7 @@ GType g_content_resolver_get_type(void);
 GContentResolver *g_content_resolver_new(void);
 
 /* Initie une nouvelle vague de résolution de contenus. */
-void g_content_resolver_create_group(GContentResolver *, wgroup_id_t, GBinContent **, size_t);
+void g_content_resolver_create_group(GContentResolver *, wgroup_id_t, GBinContent **, size_t, GLoadedContent **, size_t);
 
 /* Termine une vague de résolution de contenu. */
 void g_content_resolver_delete_group(GContentResolver *, wgroup_id_t);
diff --git a/src/analysis/project.c b/src/analysis/project.c
index 66faa16..4a15ea0 100644
--- a/src/analysis/project.c
+++ b/src/analysis/project.c
@@ -1172,6 +1172,8 @@ static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid,
 {
     GBinContent **available;                /* Contenus binaires présents  */
     size_t count;                           /* Quantité de ces contenus    */
+    GLoadedContent **detected;              /* Contenus chargés présents   */
+    size_t noted;                           /* Quantité de ces contenus    */
     GContentResolver *resolver;             /* Resolveur de contenus       */
     size_t i;                               /* Boucle de parcours          */
 
@@ -1180,9 +1182,11 @@ static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid,
         available = g_content_explorer_get_all(explorer, wid, &count);
         assert(count > 0);
 
+        detected = g_content_explorer_get_detected(explorer, wid, &noted);
+
         resolver = get_current_content_resolver();
 
-        g_content_resolver_create_group(resolver, wid, available, count);
+        g_content_resolver_create_group(resolver, wid, available, count, detected, noted);
 
         g_object_unref(G_OBJECT(resolver));
 
@@ -1191,6 +1195,12 @@ static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid,
 
         free(available);
 
+        for (i = 0; i < noted; i++)
+           g_object_unref(G_OBJECT(detected[i]));
+
+        if (detected != NULL)
+            free(detected);
+
     }
 
 }
-- 
cgit v0.11.2-87-g4458