From 682159e73cfbf8ec61d2f2aba765be1016a30ded Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 12 Sep 2019 23:44:24 +0200
Subject: Extended the Python API for update databases.

---
 plugins/pychrysalide/analysis/binary.c            | 109 +++++++++++
 plugins/pychrysalide/analysis/db/collection.c     |  63 +++++-
 plugins/pychrysalide/analysis/db/constants.c      |  39 ++++
 plugins/pychrysalide/analysis/db/item.c           |   3 +
 plugins/pychrysalide/analysis/db/items/bookmark.c | 223 +++++++++++++++++++++-
 plugins/pychrysalide/analysis/db/items/bookmark.h |  17 ++
 plugins/pychrysalide/analysis/db/items/module.c   |   1 +
 src/analysis/binary.c                             |  19 +-
 src/analysis/binary.h                             |   2 +-
 src/analysis/db/collection.c                      |   2 +-
 src/analysis/db/collection.h                      |  17 +-
 src/analysis/db/items/bookmark.c                  |   2 +-
 src/analysis/db/items/comment.c                   |   2 +-
 src/analysis/db/items/move.c                      |   2 +-
 src/analysis/db/items/switcher.c                  |   2 +-
 src/gui/dialogs/storage.c                         |   2 +-
 src/gui/panels/bookmarks.c                        |   2 +-
 src/gui/panels/history.c                          |   6 +-
 18 files changed, 483 insertions(+), 30 deletions(-)

diff --git a/plugins/pychrysalide/analysis/binary.c b/plugins/pychrysalide/analysis/binary.c
index 9d57952..01160a5 100644
--- a/plugins/pychrysalide/analysis/binary.c
+++ b/plugins/pychrysalide/analysis/binary.c
@@ -25,6 +25,7 @@
 #include "binary.h"
 
 
+#include <malloc.h>
 #include <pygobject.h>
 
 
@@ -48,12 +49,18 @@ static PyObject *py_loaded_binary_new(PyTypeObject *, PyObject *, PyObject *);
 /* Fournit un client assurant la liaison avec un serveur. */
 static PyObject *py_loaded_binary_get_client(PyObject *, PyObject *);
 
+/* Trouve une collection assurant une fonctionnalité donnée. */
+static PyObject *py_loaded_binary_find_collection(PyObject *, PyObject *);
+
 /* Demande l'intégration d'une modification dans une collection. */
 static PyObject *py_loaded_binary_add_to_collection(PyObject *, PyObject *);
 
 /* Fournit le nom associé à l'élément binaire. */
 static PyObject *py_loaded_binary_get_name(PyObject *, void *);
 
+/* Fournit l'ensemble des collections utilisées par un binaire. */
+static PyObject *py_loaded_binary_get_collections(PyObject *, void *);
+
 /* Fournit le format de fichier reconnu dans le contenu binaire. */
 static PyObject *py_loaded_binary_get_format(PyObject *, void *);
 
@@ -158,6 +165,59 @@ static PyObject *py_loaded_binary_get_client(PyObject *self, PyObject *args)
 *  Paramètres  : self = objet représentant un binaire chargé.                 *
 *                args = arguments fournis pour l'opération.                   *
 *                                                                             *
+*  Description : Trouve une collection assurant une fonctionnalité donnée.    *
+*                                                                             *
+*  Retour      : Collection trouvée ou None.                                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_loaded_binary_find_collection(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    unsigned int feature;                   /* Fonctionnalité recherchée   */
+    int ret;                                /* Bilan de lecture des args.  */
+    GLoadedBinary *binary;                  /* Binaire en cours d'analyse  */
+    GDbCollection *found;                   /* Collection trouvée          */
+
+#define LOADED_BINARY_FIND_COLLECTION_METHOD PYTHON_METHOD_DEF                      \
+(                                                                                   \
+    find_collection, "$self, feature, /",                                           \
+    METH_VARARGS, py_loaded_binary,                                                 \
+    "Provide the collection managing a given database feature."                     \
+    "\n"                                                                            \
+    "The feature is a value of type pychrysalide.analysis.db.DbItem.DbItemFlags."   \
+)
+
+    ret = PyArg_ParseTuple(args, "I", &feature);
+    if (!ret) return NULL;
+
+    binary = G_LOADED_BINARY(pygobject_get(self));
+
+    found = g_loaded_binary_find_collection(binary, feature);
+
+    if (found != NULL)
+    {
+        result = pygobject_new(G_OBJECT(found));
+        g_object_unref(G_OBJECT(found));
+    }
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = objet représentant un binaire chargé.                 *
+*                args = arguments fournis pour l'opération.                   *
+*                                                                             *
 *  Description : Demande l'intégration d'une modification dans une collection.*
 *                                                                             *
 *  Retour      : Bilan partiel de l'opération demandée.                       *
@@ -241,6 +301,53 @@ static PyObject *py_loaded_binary_get_name(PyObject *self, void *closure)
 *  Paramètres  : self    = objet Python concerné par l'appel.                 *
 *                closure = non utilisé ici.                                   *
 *                                                                             *
+*  Description : Fournit l'ensemble des collections utilisées par un binaire. *
+*                                                                             *
+*  Retour      : Liste de collections en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_loaded_binary_get_collections(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Trouvailles à retourner     */
+    GLoadedBinary *binary;                  /* Version native              */
+    size_t count;                           /* Quantité de collections     */
+    GDbCollection **collections;            /* Ensemble de collections     */
+    size_t i;                               /* Boucle de parcours          */
+
+#define LOADED_BINARY_COLLECTIONS_ATTRIB PYTHON_GET_DEF_FULL            \
+(                                                                       \
+    collections, py_loaded_binary,                                      \
+    "List of all collections of database items linked to the binary."   \
+)
+
+    binary = G_LOADED_BINARY(pygobject_get(self));
+
+    collections = g_loaded_binary_get_collections(binary, &count);
+
+    result = PyTuple_New(count);
+
+    for (i = 0; i < count; i++)
+    {
+        PyTuple_SetItem(result, i, pygobject_new(G_OBJECT(collections[i])));
+        g_object_unref(G_OBJECT(collections[i]));
+    }
+
+    if (collections != NULL)
+        free(collections);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
 *  Description : Fournit le format de fichier reconnu dans le contenu binaire.*
 *                                                                             *
 *  Retour      : Instance du format reconnu.                                  *
@@ -359,6 +466,7 @@ PyTypeObject *get_python_loaded_binary_type(void)
 {
     static PyMethodDef py_loaded_binary_methods[] = {
         LOADED_BINARY_GET_CLIENT_METHOD,
+        LOADED_BINARY_FIND_COLLECTION_METHOD,
         LOADED_BINARY_ADD_TO_COLLECTION_METHOD,
         { NULL }
     };
@@ -368,6 +476,7 @@ PyTypeObject *get_python_loaded_binary_type(void)
             "name", py_loaded_binary_get_name, NULL,
             "Name of the loaded binary.", NULL
         },
+        LOADED_BINARY_COLLECTIONS_ATTRIB,
         {
             "format", py_loaded_binary_get_format, NULL,
             "File format recognized in the binary content.", NULL
diff --git a/plugins/pychrysalide/analysis/db/collection.c b/plugins/pychrysalide/analysis/db/collection.c
index b7e3e0b..e62c17e 100644
--- a/plugins/pychrysalide/analysis/db/collection.c
+++ b/plugins/pychrysalide/analysis/db/collection.c
@@ -37,6 +37,66 @@
 
 
 
+/* Renvoie la liste des éléments rassemblés. */
+static PyObject *py_db_collection_get_items(PyObject *, void *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Renvoie la liste des éléments rassemblés.                    *
+*                                                                             *
+*  Retour      : Liste d'éléments à parcourir.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_collection_get_items(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Trouvailles à retourner     */
+    GDbCollection *collec;                  /* Version native              */
+    size_t counter;                         /* Décompte des éléments       */
+    GList *items;                           /* Eléments déjà en place      */
+    GList *iter;                            /* Boucle de parcours          */
+    int ret;                                /* Bilan d'une extension       */
+
+#define DB_COLLECTION_ITEMS_ATTRIB PYTHON_GET_DEF_FULL      \
+(                                                           \
+    items, py_db_collection,                                \
+    "List of all items contained in the collection."        \
+    "\n"                                                    \
+    "These items can currently be applied or not."          \
+)
+
+    collec = G_DB_COLLECTION(pygobject_get(self));
+
+    counter = 0;
+    result = PyTuple_New(counter);
+
+    g_db_collection_rlock(collec);
+
+    items = g_db_collection_get_items(G_DB_COLLECTION(collec));
+
+    for (iter = g_list_first(items); iter != NULL; iter = g_list_next(iter))
+    {
+        ret = _PyTuple_Resize(&result, ++counter);
+        if (ret == -1) break;
+
+        PyTuple_SetItem(result, counter - 1, pygobject_new(G_OBJECT(iter->data)));
+
+    }
+
+    g_db_collection_runlock(collec);
+
+    return result;
+
+}
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : -                                                            *
@@ -56,9 +116,8 @@ PyTypeObject *get_python_db_collection_type(void)
     };
 
     static PyGetSetDef py_db_collection_getseters[] = {
-
+        DB_COLLECTION_ITEMS_ATTRIB,
         { NULL }
-
     };
 
     static PyTypeObject py_db_collection_type = {
diff --git a/plugins/pychrysalide/analysis/db/constants.c b/plugins/pychrysalide/analysis/db/constants.c
index 0c03cfc..9c628f9 100644
--- a/plugins/pychrysalide/analysis/db/constants.c
+++ b/plugins/pychrysalide/analysis/db/constants.c
@@ -37,6 +37,45 @@
 *                                                                             *
 *  Paramètres  : type = type dont le dictionnaire est à compléter.            *
 *                                                                             *
+*  Description : Définit les constantes relatives au protocole.               *
+*                                                                             *
+*  Retour      : true en cas de succès de l'opération, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_db_protocol_constants(PyTypeObject *type)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *values;                       /* Groupe de valeurs à établir */
+
+    values = PyDict_New();
+
+    result = add_const_to_group(values, "BOOKMARKS", DBF_BOOKMARKS);
+    if (result) result = add_const_to_group(values, "COMMENTS", DBF_COMMENTS);
+    if (result) result = add_const_to_group(values, "MOVES", DBF_MOVES);
+    if (result) result = add_const_to_group(values, "DISPLAY_SWITCHERS", DBF_DISPLAY_SWITCHERS);
+
+    if (!result)
+    {
+        Py_DECREF(values);
+        goto exit;
+    }
+
+    result = attach_constants_group(type, false, "DBFeatures", values, "Features provided by database items.");
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type dont le dictionnaire est à compléter.            *
+*                                                                             *
 *  Description : Définit les constantes pour les éléments de base de données. *
 *                                                                             *
 *  Retour      : true en cas de succès de l'opération, false sinon.           *
diff --git a/plugins/pychrysalide/analysis/db/item.c b/plugins/pychrysalide/analysis/db/item.c
index 9505838..0923268 100644
--- a/plugins/pychrysalide/analysis/db/item.c
+++ b/plugins/pychrysalide/analysis/db/item.c
@@ -286,6 +286,9 @@ bool ensure_python_db_item_is_registered(void)
         if (!register_class_for_pygobject(dict, G_TYPE_DB_ITEM, type, &PyGObject_Type))
             return false;
 
+        if (!define_db_protocol_constants(type))
+            return false;
+
         if (!define_db_item_constants(type))
             return false;
 
diff --git a/plugins/pychrysalide/analysis/db/items/bookmark.c b/plugins/pychrysalide/analysis/db/items/bookmark.c
index 783efa6..468f38c 100644
--- a/plugins/pychrysalide/analysis/db/items/bookmark.c
+++ b/plugins/pychrysalide/analysis/db/items/bookmark.c
@@ -33,6 +33,7 @@
 #include <plugins/dt.h>
 
 
+#include "../collection.h"
 #include "../item.h"
 #include "../../../access.h"
 #include "../../../helpers.h"
@@ -40,6 +41,9 @@
 
 
 
+/* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */
+
+
 /* Crée un nouvel objet Python de type 'DbBookmark'. */
 static PyObject *py_db_bookmark_new(PyTypeObject *, PyObject *, PyObject *);
 
@@ -54,6 +58,19 @@ static PyObject *py_db_bookmark_get_comment(PyObject *, void *);
 
 
 
+/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
+
+
+/* Crée un nouvel objet Python de type 'BookmarkCollection'. */
+static PyObject *py_bookmark_collection_new(PyTypeObject *, PyObject *, PyObject *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                       ELABORATION D'UN ELEMENT DE COLLECTION                       */
+/* ---------------------------------------------------------------------------------- */
+
+
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : type = type de l'objet à instancier.                         *
@@ -144,7 +161,7 @@ static int py_db_bookmark_init(PyObject *self, PyObject *args, PyObject *kwds)
     "\n"                                                                        \
     "Instances can be created using the following constructor:\n"               \
     "\n"                                                                        \
-    "    DbBookmark(addr, comment=None)"                                        \
+    "    DbBookmark(addr, comment=None)\n"                                      \
     "\n"                                                                        \
     "Where addr is a location of type pychrysalide.arch.vmpa and"               \
     " comment is a string or None.\n"                                           \
@@ -400,3 +417,207 @@ int convert_to_db_bookmark(PyObject *arg, void *dst)
     return result;
 
 }
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        DEFINITION DE LA COLLECTION ASSOCIEE                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type de l'objet à instancier.                         *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Crée un nouvel objet Python de type 'BookmarkCollection'.    *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_bookmark_collection_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Objet à retourner           */
+    PyTypeObject *base;                     /* Type de base à dériver      */
+    bool first_time;                        /* Evite les multiples passages*/
+    GType gtype;                            /* Nouveau type de processeur  */
+    bool status;                            /* Bilan d'un enregistrement   */
+
+#define BOOKMARK_COLLECTION_DOC                                         \
+    "BookmarkCollection remembers all bookmark definitions.\n"          \
+    "\n"                                                                \
+    "Instances can be created using the following constructor:\n"       \
+    "\n"                                                                \
+    "    DbBookmark()\n"                                                \
+    "\n"                                                                \
+    "There should be no need for creating such instances manually."
+
+    /* Validations diverses */
+
+    base = get_python_db_bookmark_type();
+
+    if (type == base)
+        goto simple_way;
+
+    /* Mise en place d'un type dédié */
+
+    first_time = (g_type_from_name(type->tp_name) == 0);
+
+    gtype = build_dynamic_type(G_TYPE_DB_BOOKMARK, type->tp_name, NULL, NULL, NULL);
+
+    if (first_time)
+    {
+        status = register_class_for_dynamic_pygobject(gtype, type, base);
+
+        if (!status)
+        {
+            result = NULL;
+            goto exit;
+        }
+
+    }
+
+    /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
+
+ simple_way:
+
+    result = PyType_GenericNew(type, args, kwds);
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_bookmark_collection_type(void)
+{
+    static PyMethodDef py_bookmark_collection_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_bookmark_collection_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_bookmark_collection_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.db.items.BookmarkCollection",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = BOOKMARK_COLLECTION_DOC,
+
+        .tp_methods     = py_bookmark_collection_methods,
+        .tp_getset      = py_bookmark_collection_getseters,
+
+        .tp_new         = py_bookmark_collection_new,
+
+    };
+
+    return &py_bookmark_collection_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....BookmarkCollection'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_bookmark_collection_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'DbBookmark'    */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_bookmark_collection_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.db.items");
+
+        dict = PyModule_GetDict(module);
+
+        if (!ensure_python_db_item_is_registered())
+            return false;
+
+        if (!register_class_for_pygobject(dict, G_TYPE_BM_COLLECTION, type, get_python_db_collection_type()))
+            return false;
+
+    }
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : arg = argument quelconque à tenter de convertir.             *
+*                dst = destination des valeurs récupérées en cas de succès.   *
+*                                                                             *
+*  Description : Tente de convertir en collection de signets.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_bookmark_collection(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_bookmark_collection_type());
+
+    switch (result)
+    {
+        case -1:
+            /* L'exception est déjà fixée par Python */
+            result = 0;
+            break;
+
+        case 0:
+            PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to bookmark collection");
+            break;
+
+        case 1:
+            *((GBookmarkCollection **)dst) = G_BM_COLLECTION(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/db/items/bookmark.h b/plugins/pychrysalide/analysis/db/items/bookmark.h
index bcf1c11..504795f 100644
--- a/plugins/pychrysalide/analysis/db/items/bookmark.h
+++ b/plugins/pychrysalide/analysis/db/items/bookmark.h
@@ -31,6 +31,9 @@
 
 
 
+/* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */
+
+
 /* Fournit un accès à une définition de type à diffuser. */
 PyTypeObject *get_python_db_bookmark_type(void);
 
@@ -42,4 +45,18 @@ int convert_to_db_bookmark(PyObject *, void *);
 
 
 
+/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_bookmark_collection_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.db.items.BookmarkCollection'. */
+bool ensure_python_bookmark_collection_is_registered(void);
+
+/* Tente de convertir en collection de signets. */
+int convert_to_bookmark_collection(PyObject *, void *);
+
+
+
 #endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_DB_ITEMS_BOOKMARK_H */
diff --git a/plugins/pychrysalide/analysis/db/items/module.c b/plugins/pychrysalide/analysis/db/items/module.c
index fcf636f..04349b5 100644
--- a/plugins/pychrysalide/analysis/db/items/module.c
+++ b/plugins/pychrysalide/analysis/db/items/module.c
@@ -89,6 +89,7 @@ bool populate_analysis_db_items_module(void)
 
     result = true;
 
+    if (result) result = ensure_python_bookmark_collection_is_registered();
     if (result) result = ensure_python_db_bookmark_is_registered();
     if (result) result = ensure_python_db_comment_is_registered();
 
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index ac7556c..822510c 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -995,7 +995,7 @@ GHubClient *g_loaded_binary_get_client(const GLoadedBinary *binary, bool interna
 *                                                                             *
 ******************************************************************************/
 
-GDbCollection **g_loaded_binary_get_all_collections(const GLoadedBinary *binary, size_t *count)
+GDbCollection **g_loaded_binary_get_collections(const GLoadedBinary *binary, size_t *count)
 {
     GDbCollection **result;                 /* Liste à retourner           */
     GList *c;                               /* Boucle de parcours #1       */
@@ -1003,14 +1003,21 @@ GDbCollection **g_loaded_binary_get_all_collections(const GLoadedBinary *binary,
 
     *count = g_list_length(binary->collections);
 
-    result = malloc(*count * sizeof(GDbCollection *));
+    if (*count == 0)
+        result = NULL;
 
-    for (c = g_list_first(binary->collections), i = 0; c != NULL; c = g_list_next(c), i++)
+    else
     {
-        assert(i < *count);
+        result = malloc(*count * sizeof(GDbCollection *));
 
-        result[i] = G_DB_COLLECTION(c->data);
-        g_object_ref(G_OBJECT(result[i]));
+        for (c = g_list_first(binary->collections), i = 0; c != NULL; c = g_list_next(c), i++)
+        {
+            assert(i < *count);
+
+            result[i] = G_DB_COLLECTION(c->data);
+            g_object_ref(G_OBJECT(result[i]));
+
+        }
 
     }
 
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index 36966c9..dd3dfc6 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -120,7 +120,7 @@ bool g_loaded_binary_save_cache(const GLoadedBinary *);
 GHubClient *g_loaded_binary_get_client(const GLoadedBinary *, bool);
 
 /* Fournit l'ensemble des collections utilisées par un binaire. */
-GDbCollection **g_loaded_binary_get_all_collections(const GLoadedBinary *, size_t *);
+GDbCollection **g_loaded_binary_get_collections(const GLoadedBinary *, size_t *);
 
 /* Trouve une collection assurant une fonctionnalité donnée. */
 GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *, DBFeatures);
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c
index 3ac70fa..33145a6 100644
--- a/src/analysis/db/collection.c
+++ b/src/analysis/db/collection.c
@@ -564,7 +564,7 @@ void g_db_collection_lock_unlock(GDbCollection *collec, bool write, bool lock)
 *                                                                             *
 ******************************************************************************/
 
-GList *g_db_collection_list_items(const GDbCollection *collec)
+GList *g_db_collection_get_items(const GDbCollection *collec)
 {
     /**
      * Un verrou doit être posé !
diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h
index cbcf42c..60e5c26 100644
--- a/src/analysis/db/collection.h
+++ b/src/analysis/db/collection.h
@@ -37,15 +37,12 @@
 
 
 
-#define G_TYPE_DB_COLLECTION               g_db_collection_get_type()
-#define G_DB_COLLECTION(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_collection_get_type(), GDbCollection))
-#define G_IS_DB_COLLECTION(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_db_collection_get_type()))
-#define G_DB_COLLECTION_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DB_COLLECTION, GDbCollectionClass))
-#define G_IS_DB_COLLECTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DB_COLLECTION))
-#define G_DB_COLLECTION_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DB_COLLECTION, GDbCollectionClass))
-
-
-
+#define G_TYPE_DB_COLLECTION            g_db_collection_get_type()
+#define G_DB_COLLECTION(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_DB_COLLECTION, GDbCollection))
+#define G_IS_DB_COLLECTION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_DB_COLLECTION))
+#define G_DB_COLLECTION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DB_COLLECTION, GDbCollectionClass))
+#define G_IS_DB_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DB_COLLECTION))
+#define G_DB_COLLECTION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DB_COLLECTION, GDbCollectionClass))
 
 
 /* Collection générique d'éléments (instance) */
@@ -96,7 +93,7 @@ void g_db_collection_lock_unlock(GDbCollection *, bool, bool);
 #define g_db_collection_runlock(col) g_db_collection_lock_unlock(col, false, false);
 
 /* Renvoie la liste des éléments rassemblés. */
-GList *g_db_collection_list_items(const GDbCollection *);
+GList *g_db_collection_get_items(const GDbCollection *);
 
 /* Détermine si un élément est déjà présent ou non. */
 GDbItem *g_db_collection_has_key(GDbCollection *, ...);
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
index 5715737..20f98ea 100644
--- a/src/analysis/db/items/bookmark.c
+++ b/src/analysis/db/items/bookmark.c
@@ -916,7 +916,7 @@ static GDbItem *g_bookmark_collection_has_key(GBookmarkCollection *collec, va_li
 
     ref = va_arg(ap, vmpa2t *);
 
-    items = g_db_collection_list_items(G_DB_COLLECTION(collec));
+    items = g_db_collection_get_items(G_DB_COLLECTION(collec));
 
     for (iter = g_list_first(items); iter != NULL && result == NULL; iter = g_list_next(iter))
     {
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
index 22ae46f..a987464 100644
--- a/src/analysis/db/items/comment.c
+++ b/src/analysis/db/items/comment.c
@@ -1735,7 +1735,7 @@ static GDbItem *g_comment_collection_has_key(GCommentCollection *collec, va_list
 
     ref = va_arg(ap, vmpa2t *);
 
-    items = g_db_collection_list_items(G_DB_COLLECTION(collec));
+    items = g_db_collection_get_items(G_DB_COLLECTION(collec));
 
     for (iter = g_list_first(items); iter != NULL && result == NULL; iter = g_list_next(iter))
     {
diff --git a/src/analysis/db/items/move.c b/src/analysis/db/items/move.c
index c213786..a5d2773 100644
--- a/src/analysis/db/items/move.c
+++ b/src/analysis/db/items/move.c
@@ -835,7 +835,7 @@ static GDbItem *g_move_collection_has_key(GMoveCollection *collec, va_list ap)
 
     ref = va_arg(ap, const GLineCursor *);
 
-    items = g_db_collection_list_items(G_DB_COLLECTION(collec));
+    items = g_db_collection_get_items(G_DB_COLLECTION(collec));
 
     for (iter = g_list_first(items); iter != NULL && result == NULL; iter = g_list_next(iter))
     {
diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c
index 49486f4..043effd 100644
--- a/src/analysis/db/items/switcher.c
+++ b/src/analysis/db/items/switcher.c
@@ -998,7 +998,7 @@ static GDbItem *g_switcher_collection_has_key(GSwitcherCollection *collec, va_li
 
     ref = va_arg(ap, vmpa2t *);
 
-    items = g_db_collection_list_items(G_DB_COLLECTION(collec));
+    items = g_db_collection_get_items(G_DB_COLLECTION(collec));
 
     for (iter = g_list_first(items); iter != NULL && result == NULL; iter = g_list_next(iter))
     {
diff --git a/src/gui/dialogs/storage.c b/src/gui/dialogs/storage.c
index 4aed524..b66f0ab 100644
--- a/src/gui/dialogs/storage.c
+++ b/src/gui/dialogs/storage.c
@@ -107,7 +107,7 @@ GtkWidget *create_storage_dialog(GLoadedBinary *binary, GtkWindow *parent, GtkBu
 
     store = GTK_LIST_STORE(gtk_builder_get_object(builder, "store"));
 
-    collections = g_loaded_binary_get_all_collections(binary, &count);
+    collections = g_loaded_binary_get_collections(binary, &count);
 
     for (i = 0; i < count; i++)
     {
diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c
index 112afe9..5fbc2fc 100644
--- a/src/gui/panels/bookmarks.c
+++ b/src/gui/panels/bookmarks.c
@@ -473,7 +473,7 @@ static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary
 
     g_db_collection_rlock(collec);
 
-    items = g_db_collection_list_items(collec);
+    items = g_db_collection_get_items(collec);
 
     for (b = g_list_first(items); b != NULL; b = g_list_next(b))
     {
diff --git a/src/gui/panels/history.c b/src/gui/panels/history.c
index cfea509..3bdf77e 100644
--- a/src/gui/panels/history.c
+++ b/src/gui/panels/history.c
@@ -292,7 +292,7 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo
 
     if (panel->binary != NULL)
     {
-        collections = g_loaded_binary_get_all_collections(panel->binary, &count);
+        collections = g_loaded_binary_get_collections(panel->binary, &count);
 
         for (k = 0; k < count; k++)
         {
@@ -324,13 +324,13 @@ static void change_history_panel_current_content(GHistoryPanel *panel, GLoadedCo
 
     /* Actualisation de l'affichage */
 
-    collections = g_loaded_binary_get_all_collections(binary, &count);
+    collections = g_loaded_binary_get_collections(binary, &count);
 
     for (k = 0; k < count; k++)
     {
         g_db_collection_rlock(collections[k]);
 
-        items = g_db_collection_list_items(collections[k]);
+        items = g_db_collection_get_items(collections[k]);
 
         for (i = g_list_first(items); i != NULL; i = g_list_next(i))
         {
-- 
cgit v0.11.2-87-g4458