From a59fb1b3fb67a348c40bc3668445d64213e9e674 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 7 Mar 2025 10:29:32 +0100
Subject: Prepare a new way to store objects.

---
 plugins/pychrysalide/analysis/storage/serialize.c | 501 -------------
 plugins/pychrysalide/analysis/storage/serialize.h |  45 --
 plugins/pychrysalide/analysis/storage/storage.c   | 687 -----------------
 plugins/pychrysalide/analysis/storage/storage.h   |  48 --
 plugins/pychrysalide/analysis/storage/tpmem.c     | 508 -------------
 plugins/pychrysalide/analysis/storage/tpmem.h     |  45 --
 plugins/pychrysalide/glibext/serialize.c          | 501 +++++++++++++
 plugins/pychrysalide/glibext/serialize.h          |  45 ++
 plugins/pychrysalide/glibext/storage.c            | 687 +++++++++++++++++
 plugins/pychrysalide/glibext/storage.h            |  48 ++
 plugins/pychrysalide/glibext/tpmem.c              | 508 +++++++++++++
 plugins/pychrysalide/glibext/tpmem.h              |  45 ++
 src/analysis/storage/Makefile.am                  |   7 +-
 src/analysis/storage/serialize-int.h              |  58 --
 src/analysis/storage/serialize.c                  | 111 ---
 src/analysis/storage/serialize.h                  |  64 --
 src/analysis/storage/storage-int.h                |  66 --
 src/analysis/storage/storage.c                    | 867 ----------------------
 src/analysis/storage/storage.h                    |  89 ---
 src/analysis/storage/tpmem.c                      | 429 -----------
 src/analysis/storage/tpmem.h                      |  70 --
 src/glibext/serialize-int.h                       |  58 ++
 src/glibext/serialize.c                           | 111 +++
 src/glibext/serialize.h                           |  64 ++
 src/glibext/storage-int.h                         |  66 ++
 src/glibext/storage.c                             | 867 ++++++++++++++++++++++
 src/glibext/storage.h                             |  89 +++
 src/glibext/tpmem.c                               | 429 +++++++++++
 src/glibext/tpmem.h                               |  70 ++
 tests/analysis/storage/storage.py                 |  81 --
 tests/glibext/storage.py                          |  81 ++
 31 files changed, 3670 insertions(+), 3675 deletions(-)
 delete mode 100644 plugins/pychrysalide/analysis/storage/serialize.c
 delete mode 100644 plugins/pychrysalide/analysis/storage/serialize.h
 delete mode 100644 plugins/pychrysalide/analysis/storage/storage.c
 delete mode 100644 plugins/pychrysalide/analysis/storage/storage.h
 delete mode 100644 plugins/pychrysalide/analysis/storage/tpmem.c
 delete mode 100644 plugins/pychrysalide/analysis/storage/tpmem.h
 create mode 100644 plugins/pychrysalide/glibext/serialize.c
 create mode 100644 plugins/pychrysalide/glibext/serialize.h
 create mode 100644 plugins/pychrysalide/glibext/storage.c
 create mode 100644 plugins/pychrysalide/glibext/storage.h
 create mode 100644 plugins/pychrysalide/glibext/tpmem.c
 create mode 100644 plugins/pychrysalide/glibext/tpmem.h
 delete mode 100644 src/analysis/storage/serialize-int.h
 delete mode 100644 src/analysis/storage/serialize.c
 delete mode 100644 src/analysis/storage/serialize.h
 delete mode 100644 src/analysis/storage/storage-int.h
 delete mode 100644 src/analysis/storage/storage.c
 delete mode 100644 src/analysis/storage/storage.h
 delete mode 100644 src/analysis/storage/tpmem.c
 delete mode 100644 src/analysis/storage/tpmem.h
 create mode 100644 src/glibext/serialize-int.h
 create mode 100644 src/glibext/serialize.c
 create mode 100644 src/glibext/serialize.h
 create mode 100644 src/glibext/storage-int.h
 create mode 100644 src/glibext/storage.c
 create mode 100644 src/glibext/storage.h
 create mode 100644 src/glibext/tpmem.c
 create mode 100644 src/glibext/tpmem.h
 delete mode 100644 tests/analysis/storage/storage.py
 create mode 100644 tests/glibext/storage.py

diff --git a/plugins/pychrysalide/analysis/storage/serialize.c b/plugins/pychrysalide/analysis/storage/serialize.c
deleted file mode 100644
index 40fcef7..0000000
--- a/plugins/pychrysalide/analysis/storage/serialize.c
+++ /dev/null
@@ -1,501 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * serialize.c - équivalent Python du fichier "analysis/storage/serialize.h"
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "serialize.h"
-
-
-#include <pygobject.h>
-
-
-#include <analysis/storage/serialize-int.h>
-
-
-#include "storage.h"
-#include "../../access.h"
-#include "../../helpers.h"
-#include "../../common/packed.h"
-
-
-
-/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-
-
-/* Procède à l'initialisation de l'interface de génération. */
-static void py_serializable_object_interface_init(GSerializableObjectIface *, gpointer *);
-
-/* Charge un objet depuis une mémoire tampon. */
-static bool py_serializable_object_load_wrapper(GSerializableObject *, GObjectStorage *, packed_buffer_t *);
-
-/* Sauvegarde un objet dans une mémoire tampon. */
-static bool py_serializable_object_store_wrapper(const GSerializableObject *, GObjectStorage *, packed_buffer_t *);
-
-
-
-/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
-
-
-/* Charge un objet depuis une mémoire tampon. */
-static bool py_serializable_object_load(PyObject *, PyObject *);
-
-/* Sauvegarde un objet dans une mémoire tampon. */
-static bool py_serializable_object_store(PyObject *, PyObject *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : iface  = interface GLib à initialiser.                       *
-*                unused = adresse non utilisée ici.                           *
-*                                                                             *
-*  Description : Procède à l'initialisation de l'interface de génération.     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void py_serializable_object_interface_init(GSerializableObjectIface *iface, gpointer *unused)
-{
-
-#define SERIALIZABLE_OBJECT_DOC                                             \
-    "SerializableObject defines an interface used to store and load"        \
-    " objects to and from a data buffer.\n"                                 \
-    "\n"                                                                    \
-    "A typical class declaration for a new implementation looks like:\n"    \
-    "\n"                                                                    \
-    "    class NewImplem(GObject.Object, SerializableObject):\n"            \
-    "        ...\n"                                                         \
-    "\n"                                                                    \
-    "The following methods have to be defined for new implementations:\n"   \
-    "* pychrysalide.analysis.storage.SerializableObject._load();\n"         \
-    "* pychrysalide.analysis.storage.SerializableObject._store();\n"
-
-    iface->load = py_serializable_object_load_wrapper;
-    iface->store = py_serializable_object_store_wrapper;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : object  = instruction d'assemblage à consulter.              *
-*                storage = conservateur de données à manipuler ou NULL.       *
-*                pbuf    = zone tampon à remplir.                             *
-*                                                                             *
-*  Description : Charge un objet depuis une mémoire tampon.                   *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool py_serializable_object_load_wrapper(GSerializableObject *object, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
-    PyObject *storage_obj;                  /* Objet Python à emmployer    */
-    PyObject *args;                         /* Arguments pour l'appel      */
-    PyObject *pyobj;                        /* Objet Python concerné       */
-    PyObject *pyret;                        /* Bilan de consultation       */
-
-#define SERIALIZABLE_OBJECT_LOAD_WRAPPER PYTHON_WRAPPER_DEF                     \
-(                                                                               \
-    _load, "$self, storage, pbuf, /",                                           \
-    METH_VARARGS,                                                               \
-    "Abstract method used to load an object definition from buffered data.\n"   \
-    "\n"                                                                        \
-    "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance"   \
-    " provided to store inner objects, if relevant, or None. The *pbuf*"        \
-    " argument points to a pychrysalide.common.PackedBuffer object containing"  \
-    " the data to process.\n"                                                   \
-    "\n"                                                                        \
-    "The result is a boolean indicating the status of the operation."           \
-)
-
-    result = false;
-
-    gstate = PyGILState_Ensure();
-
-    pyobj = pygobject_new(G_OBJECT(object));
-
-    if (has_python_method(pyobj, "_load"))
-    {
-        if (storage == NULL)
-        {
-            storage_obj = Py_None;
-            Py_INCREF(storage_obj);
-        }
-        else
-            storage_obj = pygobject_new(G_OBJECT(storage));
-
-        args = PyTuple_New(2);
-        PyTuple_SetItem(args, 0, storage_obj);
-        PyTuple_SetItem(args, 1, build_from_internal_packed_buffer(pbuf));
-
-        pyret = run_python_method(pyobj, "_load", args);
-
-        result = (pyret == Py_True ? true : false);
-
-        Py_XDECREF(pyret);
-
-        Py_DECREF(args);
-
-    }
-
-    Py_DECREF(pyobj);
-
-    PyGILState_Release(gstate);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : object  = instruction d'assemblage à consulter.              *
-*                storage = conservateur de données à manipuler ou NULL.       *
-*                pbuf    = zone tampon à remplir.                             *
-*                                                                             *
-*  Description : Sauvegarde un objet dans une mémoire tampon.                 *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool py_serializable_object_store_wrapper(const GSerializableObject *object, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
-    PyObject *storage_obj;                  /* Objet Python à emmployer    */
-    PyObject *args;                         /* Arguments pour l'appel      */
-    PyObject *pyobj;                        /* Objet Python concerné       */
-    PyObject *pyret;                        /* Bilan de consultation       */
-
-#define SERIALIZABLE_OBJECT_STORE_WRAPPER PYTHON_WRAPPER_DEF                    \
-(                                                                               \
-    _store, "$self, storage, pbuf, /",                                          \
-    METH_VARARGS,                                                               \
-    "Abstract method used to store an object definition into buffered data.\n"  \
-    "\n"                                                                        \
-    "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance"   \
-    " provided to store inner objects, if relevant, or None. The *pbuf*"        \
-    " argument points to a pychrysalide.common.PackedBuffer object containing"  \
-    " the data to process.\n"                                                   \
-    "\n"                                                                        \
-    "The result is a boolean indicating the status of the operation."           \
-)
-
-    result = false;
-
-    gstate = PyGILState_Ensure();
-
-    pyobj = pygobject_new(G_OBJECT(object));
-
-    if (has_python_method(pyobj, "_store"))
-    {
-        if (storage == NULL)
-        {
-            storage_obj = Py_None;
-            Py_INCREF(storage_obj);
-        }
-        else
-            storage_obj = pygobject_new(G_OBJECT(storage));
-
-        args = PyTuple_New(2);
-        PyTuple_SetItem(args, 0, storage_obj);
-        PyTuple_SetItem(args, 1, build_from_internal_packed_buffer(pbuf));
-
-        pyret = run_python_method(pyobj, "_store", args);
-
-        result = (pyret == Py_True ? true : false);
-
-        Py_XDECREF(pyret);
-
-        Py_DECREF(args);
-
-    }
-
-    Py_DECREF(pyobj);
-
-    PyGILState_Release(gstate);
-
-    return result;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                           CONNEXION AVEC L'API DE PYTHON                           */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant un générateur à manipuler.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Charge un objet depuis une mémoire tampon.                   *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool py_serializable_object_load(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Bilan à retourner           */
-    GObjectStorage *storage;                /* Conservateur à manipuler    */
-    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
-    int ret;                                /* Bilan de lecture des args.  */
-    GSerializableObject *object;            /* Version native              */
-    bool status;                            /* Bilan de l'opération        */
-
-#define SERIALIZABLE_OBJECT_LOAD_METHOD PYTHON_METHOD_DEF                       \
-(                                                                               \
-    load, "$self, storage, pbuf, /",                                            \
-    METH_VARARGS, py_serializable_object,                                       \
-    "Load an object definition from buffered data.\n"                           \
-    "\n"                                                                        \
-    "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance"   \
-    " provided to store inner objects, if relevant, or None. The *pbuf*"        \
-    " argument points to a pychrysalide.common.PackedBuffer object containing"  \
-    " the data to process.\n"                                                   \
-    "\n"                                                                        \
-    "The result is a boolean indicating the status of the operation."           \
-)
-
-    ret = PyArg_ParseTuple(args, "O&O&", convert_to_object_storage_or_none, &storage,
-                           convert_to_packed_buffer, &pbuf);
-    if (!ret) return NULL;
-
-    object = G_SERIALIZABLE_OBJECT(pygobject_get(self));
-
-    status = g_serializable_object_load(object, storage, pbuf);
-
-    result = status ? Py_True : Py_False;
-    Py_INCREF(result);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant un générateur à manipuler.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Sauvegarde un objet dans une mémoire tampon.                 *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool py_serializable_object_store(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Bilan à retourner           */
-    GObjectStorage *storage;                /* Conservateur à manipuler    */
-    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
-    int ret;                                /* Bilan de lecture des args.  */
-    GSerializableObject *object;            /* Version native              */
-    bool status;                            /* Bilan de l'opération        */
-
-#define SERIALIZABLE_OBJECT_STORE_METHOD PYTHON_METHOD_DEF                      \
-(                                                                               \
-    store, "$self, storage, pbuf, /",                                           \
-    METH_VARARGS, py_serializable_object,                                       \
-    "Store an object definition into buffered data.\n"                          \
-    "\n"                                                                        \
-    "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance"   \
-    " provided to store inner objects, if relevant, or None. The *pbuf*"        \
-    " argument points to a pychrysalide.common.PackedBuffer object containing"  \
-    " the data to process.\n"                                                   \
-    "\n"                                                                        \
-    "The result is a boolean indicating the status of the operation."           \
-)
-
-    ret = PyArg_ParseTuple(args, "O&O&", convert_to_object_storage_or_none, &storage,
-                           convert_to_packed_buffer, &pbuf);
-    if (!ret) return NULL;
-
-    object = G_SERIALIZABLE_OBJECT(pygobject_get(self));
-
-    status = g_serializable_object_store(object, storage, pbuf);
-
-    result = status ? Py_True : Py_False;
-    Py_INCREF(result);
-
-    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_serializable_object_type(void)
-{
-    static PyMethodDef py_serializable_object_methods[] = {
-        SERIALIZABLE_OBJECT_LOAD_WRAPPER,
-        SERIALIZABLE_OBJECT_STORE_WRAPPER,
-        SERIALIZABLE_OBJECT_LOAD_METHOD,
-        SERIALIZABLE_OBJECT_STORE_METHOD,
-        { NULL }
-    };
-
-    static PyGetSetDef py_serializable_object_getseters[] = {
-        { NULL }
-    };
-
-    static PyTypeObject py_serializable_object_type = {
-
-        PyVarObject_HEAD_INIT(NULL, 0)
-
-        .tp_name        = "pychrysalide.analysis.storage.SerializableObject",
-        .tp_basicsize   = sizeof(PyObject),
-
-        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
-
-        .tp_doc         = SERIALIZABLE_OBJECT_DOC,
-
-        .tp_methods     = py_serializable_object_methods,
-        .tp_getset      = py_serializable_object_getseters,
-
-    };
-
-    return &py_serializable_object_type;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
-*                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide....SerializableObject'.*
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool ensure_python_serializable_object_is_registered(void)
-{
-    PyTypeObject *type;                     /* Type 'SerializableObject'   */
-    PyObject *module;                       /* Module à recompléter        */
-    PyObject *dict;                         /* Dictionnaire du module      */
-
-    static GInterfaceInfo info = {          /* Paramètres d'inscription    */
-
-        .interface_init = (GInterfaceInitFunc)py_serializable_object_interface_init,
-        .interface_finalize = NULL,
-        .interface_data = NULL,
-
-    };
-
-    type = get_python_serializable_object_type();
-
-    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
-    {
-        module = get_access_to_python_module("pychrysalide.analysis.storage");
-
-        dict = PyModule_GetDict(module);
-
-        if (!register_interface_for_pygobject(dict, G_TYPE_SERIALIZABLE_OBJECT, type, &info))
-            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 objet adapté à une mise en cache.      *
-*                                                                             *
-*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-int convert_to_serializable_object(PyObject *arg, void *dst)
-{
-    int result;                             /* Bilan à retourner           */
-
-    result = PyObject_IsInstance(arg, (PyObject *)get_python_serializable_object_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 serializable object");
-            break;
-
-        case 1:
-            *((GSerializableObject **)dst) = G_SERIALIZABLE_OBJECT(pygobject_get(arg));
-            break;
-
-        default:
-            assert(false);
-            break;
-
-    }
-
-    return result;
-
-}
diff --git a/plugins/pychrysalide/analysis/storage/serialize.h b/plugins/pychrysalide/analysis/storage/serialize.h
deleted file mode 100644
index 7e831e5..0000000
--- a/plugins/pychrysalide/analysis/storage/serialize.h
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * serialize.h - prototypes pour l'équivalent Python du fichier "analysis/storage/serialize.h"
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_SERIALIZE_H
-#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_SERIALIZE_H
-
-
-#include <Python.h>
-#include <stdbool.h>
-
-
-
-/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_serializable_object_type(void);
-
-/* Prend en charge l'objet 'pychrysalide.analysis.storage.SerializableObject'. */
-bool ensure_python_serializable_object_is_registered(void);
-
-/* Tente de convertir en objet adapté à une mise en cache. */
-int convert_to_serializable_object(PyObject *, void *);
-
-
-
-#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_SERIALIZE_H */
diff --git a/plugins/pychrysalide/analysis/storage/storage.c b/plugins/pychrysalide/analysis/storage/storage.c
deleted file mode 100644
index c54fe0f..0000000
--- a/plugins/pychrysalide/analysis/storage/storage.c
+++ /dev/null
@@ -1,687 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * storage.c - équivalent Python du fichier "analysis/storage/storage.c"
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "storage.h"
-
-
-#include <pygobject.h>
-
-
-#include <analysis/storage/storage-int.h>
-#include <plugins/dt.h>
-
-
-#include "serialize.h"
-#include "../../access.h"
-#include "../../helpers.h"
-#include "../../common/packed.h"
-
-
-
-/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-
-
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_object_storage_new(PyTypeObject *, PyObject *, PyObject *);
-
-/* Initialise une instance sur la base du dérivé de GObject. */
-static int py_object_storage_init(PyObject *, PyObject *, PyObject *);
-
-
-
-/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
-
-
-/* Charge le support d'une conservation d'objets en place. */
-static PyObject *py_object_storage_load(PyObject *, PyObject *);
-
-/* Sauvegarde le support d'une conservation d'objets en place. */
-static PyObject *py_object_storage_store(PyObject *, PyObject *);
-
-/* Charge un objet à partir de données rassemblées. */
-static PyObject *py_object_storage_load_object(PyObject *, PyObject *);
-
-/* Charge un objet interne à partir de données rassemblées. */
-static PyObject *py_object_storage_unpack_object(PyObject *, PyObject *);
-
-/* Sauvegarde un object sous forme de données rassemblées. */
-static PyObject *py_object_storage_store_object(PyObject *, PyObject *);
-
-/* Sauvegarde un object interne sous forme de données. */
-static PyObject *py_object_storage_pack_object(PyObject *, PyObject *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : type = type du nouvel objet à mettre en place.               *
-*                args = éventuelle liste d'arguments.                         *
-*                kwds = éventuel dictionnaire de valeurs mises à disposition. *
-*                                                                             *
-*  Description : Accompagne la création d'une instance dérivée en Python.     *
-*                                                                             *
-*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_object_storage_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   */
-
-    /* Validations diverses */
-
-    base = get_python_object_storage_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_OBJECT_STORAGE, type->tp_name, NULL, NULL, NULL);
-
-    if (first_time)
-    {
-        status = register_class_for_dynamic_pygobject(gtype, type);
-
-        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  : self = objet à initialiser (théoriquement).                  *
-*                args = arguments fournis à l'appel.                          *
-*                kwds = arguments de type key=val fournis.                    *
-*                                                                             *
-*  Description : Initialise une instance sur la base du dérivé de GObject.    *
-*                                                                             *
-*  Retour      : 0.                                                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static int py_object_storage_init(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    const char *hash;                       /* Empreinte de contenu        */
-    int ret;                                /* Bilan de lecture des args.  */
-    GObjectStorage *storage;                /* Mécanismes natifs           */
-
-#define OBJECT_STORAGE_DOC                                              \
-    "The ObjectStorage object manages the generic storage of GLib"      \
-    " objects through serialization.\n"                                 \
-    "\n"                                                                \
-    "Instances can be created using the following constructor:\n"       \
-    "\n"                                                                \
-    "    ObjectStorage(hash)"                                           \
-    "\n"                                                                \
-    "Where *hash* should a string built from the checksum of the"       \
-    " relative binary content linked to the storage.pychrysalide."
-
-    /* Récupération des paramètres */
-
-    ret = PyArg_ParseTuple(args, "s", &hash);
-    if (!ret) return -1;
-
-    /* Initialisation d'un objet GLib */
-
-    ret = forward_pygobjet_init(self);
-    if (ret == -1) return -1;
-
-    /* Eléments de base */
-
-    storage = G_OBJECT_STORAGE(pygobject_get(self));
-
-    storage->hash = strdup(hash);
-
-    return 0;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            TAMPON POUR CODE DESASSEMBLE                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant une mémorisation de types.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Charge le support d'une conservation d'objets en place.      *
-*                                                                             *
-*  Retour      : Gestionnaire de conservations construit ou None si erreur.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_object_storage_load(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Emplacement à retourner     */
-    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
-    int ret;                                /* Bilan de lecture des args.  */
-    GObjectStorage *storage;                /* Mécanismes natifs           */
-
-#define OBJECT_STORAGE_LOAD_METHOD PYTHON_METHOD_DEF                    \
-(                                                                       \
-    load, "pbuf, /",                                                    \
-    METH_STATIC | METH_VARARGS, py_object_storage,                      \
-    "Construct a new storage from a buffer.\n"                          \
-    "\n"                                                                \
-    "The *pbuf* has to be an instance of type"                          \
-    " pychrysalide.common.PackedBuffer.\n"                              \
-    "\n"                                                                \
-    "The result is a new pychrysalide.analysis.storage.ObjectStorage"   \
-    " object on success, *None* otherwise."                             \
-)
-
-    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
-    if (!ret) return NULL;
-
-    storage = g_object_storage_load(pbuf);
-
-    if (storage == NULL)
-    {
-        result = Py_None;
-        Py_INCREF(result);
-    }
-    else
-    {
-        result = pygobject_new(G_OBJECT(storage));
-        g_object_unref(G_OBJECT(storage));
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant une mémorisation de types.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Sauvegarde le support d'une conservation d'objets en place.  *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_object_storage_store(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Emplacement à retourner     */
-    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
-    int ret;                                /* Bilan de lecture des args.  */
-    GObjectStorage *storage;                /* Mécanismes natifs           */
-    bool status;                            /* Bilan de l'opération        */
-
-#define OBJECT_STORAGE_STORE_METHOD PYTHON_METHOD_DEF       \
-(                                                           \
-    store, "$self, pbuf, /",                                \
-    METH_VARARGS, py_object_storage,                        \
-    "Save a storage into a buffer.\n"                       \
-    "\n"                                                    \
-    "The *pbuf* has to be an instance of type"              \
-    " pychrysalide.common.PackedBuffer.\n"                  \
-    "\n"                                                    \
-    "The result is *True* on success, *False* otherwise."   \
-)
-
-    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
-    if (!ret) return NULL;
-
-    storage = G_OBJECT_STORAGE(pygobject_get(self));
-
-    status = g_object_storage_store(storage, pbuf);
-
-    result = status ? Py_True : Py_False;
-    Py_INCREF(result);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant une mémorisation de types.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Charge un objet à partir de données rassemblées.             *
-*                                                                             *
-*  Retour      : Objet restauré en mémoire ou None en cas d'échec.            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_object_storage_load_object(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Bilan à retourner           */
-    const char *name;                       /* Désignation de groupe       */
-    unsigned long long pos;                 /* Emplacement des données     */
-    int ret;                                /* Bilan de lecture des args.  */
-    GObjectStorage *storage;                /* Mécanismes natifs           */
-    GSerializableObject *object;            /* Objet reconstruit ou NULL   */
-
-#define OBJECT_STORAGE_LOAD_OBJECT_METHOD PYTHON_METHOD_DEF             \
-(                                                                       \
-    load_object, "$self, name, pos, /",                                 \
-    METH_VARARGS, py_object_storage,                                    \
-    "Load an object from serialized data.\n"                            \
-    "\n"                                                                \
-    "The *name* is a string label for the group of target objects and"  \
-    " *pos* is an offset into the data stream indicating the start of"  \
-    " the data to unserialize.\n"                                       \
-    "\n"                                                                \
-    "The result is a pychrysalide.analysis.storage.SerializableObject"  \
-    " instancet in case of success, or None in case of failure."        \
-)
-
-    ret = PyArg_ParseTuple(args, "sK", &name, &pos);
-    if (!ret) return NULL;
-
-    storage = G_OBJECT_STORAGE(pygobject_get(self));
-
-    object = g_object_storage_load_object(storage, name, pos);
-
-    if (object != NULL)
-        result = pygobject_new(G_OBJECT(object));
-    else
-    {
-        result = Py_None;
-        Py_INCREF(result);
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant une mémorisation de types.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Charge un objet interne à partir de données rassemblées.     *
-*                                                                             *
-*  Retour      : Objet restauré en mémoire ou None en cas d'échec.            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_object_storage_unpack_object(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Bilan à retourner           */
-    const char *name;                       /* Désignation de groupe       */
-    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
-    int ret;                                /* Bilan de lecture des args.  */
-    GObjectStorage *storage;                /* Mécanismes natifs           */
-    GSerializableObject *object;            /* Objet reconstruit ou NULL   */
-
-#define OBJECT_STORAGE_UNPACK_OBJECT_METHOD PYTHON_METHOD_DEF           \
-(                                                                       \
-    unpack_object, "$self, name, pbuf, /",                              \
-    METH_VARARGS, py_object_storage,                                    \
-    "Load an object from a buffer with a location pointing to data.\n"  \
-    "\n"                                                                \
-    "The *name* is a string label for the group of target objects and"  \
-    " *pbuf* has to be a pychrysalide.common.PackedBuffer instance.\n"  \
-    "\n"                                                                \
-    "The result is a pychrysalide.analysis.storage.SerializableObject"  \
-    " instancet in case of success, or None in case of failure."        \
-)
-
-    ret = PyArg_ParseTuple(args, "sO&", &name, convert_to_packed_buffer, &pbuf);
-    if (!ret) return NULL;
-
-    storage = G_OBJECT_STORAGE(pygobject_get(self));
-
-    object = g_object_storage_unpack_object(storage, name, pbuf);
-
-    if (object != NULL)
-        result = pygobject_new(G_OBJECT(object));
-    else
-    {
-        result = Py_None;
-        Py_INCREF(result);
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant une mémorisation de types.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Sauvegarde un object sous forme de données rassemblées.      *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_object_storage_store_object(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Emplacement à retourner     */
-    const char *name;                       /* Désignation de groupe       */
-    GSerializableObject *object;            /* Objet à traiter             */
-    int ret;                                /* Bilan de lecture des args.  */
-    GObjectStorage *storage;                /* Mécanismes natifs           */
-    off64_t pos;                            /* Emplacement d'enregistrement*/
-    bool status;                            /* Bilan de l'opération        */
-
-#define OBJECT_STORAGE_STORE_OBJECT_METHOD PYTHON_METHOD_DEF        \
-(                                                                   \
-    store_object, "$self, name, object, /",                         \
-    METH_VARARGS, py_object_storage,                                \
-    "Save an object as serialized data.\n"                          \
-    "\n"                                                            \
-    "The *name* is a string label for the group of target objects"  \
-    " and the processed *object* has to be a"                       \
-    " pychrysalide.analysis.storage.SerializableObject instance.\n" \
-    "\n"                                                            \
-    "The result is the position of the data for stored object,"     \
-    " provided as an integer offset, in case of success or None"    \
-    " in case of failure."                                          \
-)
-
-    ret = PyArg_ParseTuple(args, "sO&", &name, convert_to_serializable_object, &object);
-    if (!ret) return NULL;
-
-    storage = G_OBJECT_STORAGE(pygobject_get(self));
-
-    status = g_object_storage_store_object(storage, name, object, &pos);
-
-    if (status)
-        result = PyLong_FromUnsignedLongLong((unsigned long long)pos);
-    else
-    {
-        result = Py_None;
-        Py_INCREF(result);
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant une mémorisation de types.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Sauvegarde un object interne sous forme de données.          *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_object_storage_pack_object(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Emplacement à retourner     */
-    const char *name;                       /* Désignation de groupe       */
-    GSerializableObject *object;            /* Objet à traiter             */
-    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
-    int ret;                                /* Bilan de lecture des args.  */
-    GObjectStorage *storage;                /* Mécanismes natifs           */
-    bool status;                            /* Bilan de l'opération        */
-
-#define OBJECT_STORAGE_PACK_OBJECT_METHOD PYTHON_METHOD_DEF         \
-(                                                                   \
-    pack_object, "$self, name, object, pbuf/",                      \
-    METH_VARARGS, py_object_storage,                                \
-    "Save an object as serialized data and store the location of"   \
-    " the data intro a buffer.\n"                                   \
-    "\n"                                                            \
-    "The *name* is a string label for the group of target objects," \
-    " the processed *object* has to be a"                           \
-    " pychrysalide.analysis.storage.SerializableObject instance"    \
-    " and *pbuf* is expected to be a"                               \
-    " pychrysalide.common.PackedBuffer instance.\n"                 \
-    "\n"                                                            \
-    "The status of the operation is returned as a boolean value:"   \
-    " *True* for success, *False* for failure."                     \
-)
-
-    ret = PyArg_ParseTuple(args, "sO&O&", &name, convert_to_serializable_object, &object,
-                           convert_to_packed_buffer, &pbuf);
-    if (!ret) return NULL;
-
-    storage = G_OBJECT_STORAGE(pygobject_get(self));
-
-    status = g_object_storage_pack_object(storage, name, object, pbuf);
-
-    result = status ? Py_True : Py_False;
-    Py_INCREF(result);
-
-    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_object_storage_type(void)
-{
-    static PyMethodDef py_object_storage_methods[] = {
-        OBJECT_STORAGE_LOAD_METHOD,
-        OBJECT_STORAGE_STORE_METHOD,
-        OBJECT_STORAGE_LOAD_OBJECT_METHOD,
-        OBJECT_STORAGE_UNPACK_OBJECT_METHOD,
-        OBJECT_STORAGE_STORE_OBJECT_METHOD,
-        OBJECT_STORAGE_PACK_OBJECT_METHOD,
-        { NULL }
-    };
-
-    static PyGetSetDef py_object_storage_getseters[] = {
-        { NULL }
-    };
-
-    static PyTypeObject py_object_storage_type = {
-
-        PyVarObject_HEAD_INIT(NULL, 0)
-
-        .tp_name        = "pychrysalide.analysis.storage.ObjectStorage",
-        .tp_basicsize   = sizeof(PyGObject),
-
-        .tp_flags       = Py_TPFLAGS_DEFAULT,
-
-        .tp_doc         = OBJECT_STORAGE_DOC,
-
-        .tp_methods     = py_object_storage_methods,
-        .tp_getset      = py_object_storage_getseters,
-
-        .tp_init        = py_object_storage_init,
-        .tp_new         = py_object_storage_new
-
-    };
-
-    return &py_object_storage_type;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
-*                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide....ObjectStorage'.     *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool ensure_python_object_storage_is_registered(void)
-{
-    PyTypeObject *type;                     /* Type Python 'ObjectStorage' */
-    PyObject *module;                       /* Module à recompléter        */
-    PyObject *dict;                         /* Dictionnaire du module      */
-
-    type = get_python_object_storage_type();
-
-    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
-    {
-        module = get_access_to_python_module("pychrysalide.analysis.storage");
-
-        dict = PyModule_GetDict(module);
-
-        if (!register_class_for_pygobject(dict, G_TYPE_OBJECT_STORAGE, 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 conservateur d'objets.                 *
-*                                                                             *
-*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-int convert_to_object_storage(PyObject *arg, void *dst)
-{
-    int result;                             /* Bilan à retourner           */
-
-    result = PyObject_IsInstance(arg, (PyObject *)get_python_object_storage_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 object storage");
-            break;
-
-        case 1:
-            *((GObjectStorage **)dst) = G_OBJECT_STORAGE(pygobject_get(arg));
-            break;
-
-        default:
-            assert(false);
-            break;
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  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 conservateur d'objets ou NULL.         *
-*                                                                             *
-*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-int convert_to_object_storage_or_none(PyObject *arg, void *dst)
-{
-    int result;                             /* Bilan à retourner           */
-
-    if (arg == Py_None)
-    {
-        *((GTypeMemory **)dst) = NULL;
-        result = 1;
-    }
-
-    else
-        result = convert_to_object_storage(arg, dst);
-
-    return result;
-
-}
diff --git a/plugins/pychrysalide/analysis/storage/storage.h b/plugins/pychrysalide/analysis/storage/storage.h
deleted file mode 100644
index a0a2c18..0000000
--- a/plugins/pychrysalide/analysis/storage/storage.h
+++ /dev/null
@@ -1,48 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * storage.h - prototypes pour l'équivalent Python du fichier "analysis/storage/storage.h"
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_STORAGE_H
-#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_STORAGE_H
-
-
-#include <Python.h>
-#include <stdbool.h>
-
-
-
-/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_object_storage_type(void);
-
-/* Prend en charge l'objet 'pychrysalide.analysis.storage.ObjectStorage'. */
-bool ensure_python_object_storage_is_registered(void);
-
-/* Tente de convertir en conservateur d'objets. */
-int convert_to_object_storage(PyObject *, void *);
-
-/* Tente de convertir en conservateur d'objets ou NULL. */
-int convert_to_object_storage_or_none(PyObject *, void *);
-
-
-
-#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_STORAGE_H */
diff --git a/plugins/pychrysalide/analysis/storage/tpmem.c b/plugins/pychrysalide/analysis/storage/tpmem.c
deleted file mode 100644
index ae07008..0000000
--- a/plugins/pychrysalide/analysis/storage/tpmem.c
+++ /dev/null
@@ -1,508 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * tpmem.c - équivalent Python du fichier "analysis/storage/tpmem.c"
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#include "tpmem.h"
-
-
-#include <pygobject.h>
-
-
-#include <analysis/storage/tpmem.h>
-#include <plugins/dt.h>
-
-
-#include "../../access.h"
-#include "../../helpers.h"
-#include "../../common/packed.h"
-
-
-
-/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
-
-
-/* Accompagne la création d'une instance dérivée en Python. */
-static PyObject *py_type_memory_new(PyTypeObject *, PyObject *, PyObject *);
-
-/* Initialise une instance sur la base du dérivé de GObject. */
-static int py_type_memory_init(PyObject *, PyObject *, PyObject *);
-
-
-
-/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
-
-
-/* Apprend tous les types mémorisés dans un tampon. */
-static PyObject *py_type_memory_load_types(PyObject *, PyObject *);
-
-/* Crée une nouvelle instance d'objet à partir de son type. */
-static PyObject *py_type_memory_create_object(PyObject *, PyObject *);
-
-/* Sauvegarde le type d'un objet instancié. */
-static PyObject *py_type_memory_store_object_gtype(PyObject *, PyObject *);
-
-/* Enregistre tous les types mémorisés dans un tampon. */
-static PyObject *py_type_memory_store_types(PyObject *, PyObject *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : type = type du nouvel objet à mettre en place.               *
-*                args = éventuelle liste d'arguments.                         *
-*                kwds = éventuel dictionnaire de valeurs mises à disposition. *
-*                                                                             *
-*  Description : Accompagne la création d'une instance dérivée en Python.     *
-*                                                                             *
-*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_type_memory_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   */
-
-    /* Validations diverses */
-
-    base = get_python_type_memory_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_TYPE_MEMORY, type->tp_name, NULL, NULL, NULL);
-
-    if (first_time)
-    {
-        status = register_class_for_dynamic_pygobject(gtype, type);
-
-        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  : self = objet à initialiser (théoriquement).                  *
-*                args = arguments fournis à l'appel.                          *
-*                kwds = arguments de type key=val fournis.                    *
-*                                                                             *
-*  Description : Initialise une instance sur la base du dérivé de GObject.    *
-*                                                                             *
-*  Retour      : 0.                                                           *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static int py_type_memory_init(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    int ret;                                /* Bilan de lecture des args.  */
-
-#define TYPE_MEMORY_DOC                                             \
-    "The TypeMemory remembers all the types of objects involved in" \
-    " a serialization process.\n"                                   \
-    "\n"                                                            \
-    "Instances can be created using the following constructor:\n"   \
-    "\n"                                                            \
-    "    TypeMemory()"                                              \
-
-    /* Initialisation d'un objet GLib */
-
-    ret = forward_pygobjet_init(self);
-    if (ret == -1) return -1;
-
-    return 0;
-
-}
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/*                            TAMPON POUR CODE DESASSEMBLE                            */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant une mémorisation de types.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Apprend tous les types mémorisés dans un tampon.             *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_type_memory_load_types(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Bilan à retourner           */
-    packed_buffer_t *pbuf;                  /* Tampon à consulter          */
-    int ret;                                /* Bilan de lecture des args.  */
-    GTypeMemory *tpmem;                     /* Mémorisation native         */
-    bool status;                            /* Bilan de l'opération        */
-
-#define TYPE_MEMORY_LOAD_TYPES_METHOD PYTHON_METHOD_DEF         \
-(                                                               \
-    load_types, "$self, pbuf",                                  \
-    METH_VARARGS, py_type_memory,                               \
-    "Read types from a buffer.\n"                               \
-    "\n"                                                        \
-    "This operation is usually handled internally by the"       \
-    " Chrysalide's core.\n"                                     \
-    "\n"                                                        \
-    "The *pbuf* parameter is a pychrysalide.common.PackedBuffer"\
-    " instance providing buffered data to read."                \
-    "\n"                                                        \
-    "The result is a boolean value indicating the status of"    \
-    " the operation: True for success, False for failure."      \
-)
-
-    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
-    if (!ret) return NULL;
-
-    tpmem = G_TYPE_MEMORY(pygobject_get(self));
-
-    status = g_type_memory_load_types(tpmem, pbuf);
-
-    result = status ? Py_True : Py_False;
-    Py_INCREF(result);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant une mémorisation de types.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Crée une nouvelle instance d'objet à partir de son type.     *
-*                                                                             *
-*  Retour      : Instance issue de l'opération ou NULL.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_type_memory_create_object(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Instance à retourner        */
-    packed_buffer_t *pbuf;                  /* Tampon à consulter          */
-    int ret;                                /* Bilan de lecture des args.  */
-    GTypeMemory *tpmem;                     /* Mémorisation native         */
-    GObject *obj;                           /* Instance retournée          */
-
-#define TYPE_MEMORY_CREATE_OBJECT_METHOD PYTHON_METHOD_DEF          \
-(                                                                   \
-    create_object, "$self, pbuf",                                   \
-    METH_VARARGS, py_type_memory,                                   \
-    "Create a new GLib object from serialized data.\n"              \
-    "\n"                                                            \
-    "The *pbuf* parameter is a pychrysalide.common.PackedBuffer"    \
-    " instance providing buffered data to read."                    \
-    "\n"                                                            \
-    "The result is a Python object linked to a native GLib"         \
-    " object instance."                                             \
-)
-
-    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
-    if (!ret) return NULL;
-
-    tpmem = G_TYPE_MEMORY(pygobject_get(self));
-
-    obj = g_type_memory_create_object(tpmem, pbuf);
-
-    result = pygobject_new(obj);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant une mémorisation de types.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Sauvegarde le type d'un objet instancié.                     *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_type_memory_store_object_gtype(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Bilan à retourner           */
-    GObject *obj;                           /* Instance à traiter          */
-    packed_buffer_t *pbuf;                  /* Tampon à consulter          */
-    int ret;                                /* Bilan de lecture des args.  */
-    GTypeMemory *tpmem;                     /* Mémorisation native         */
-    bool status;                            /* Bilan de l'opération        */
-
-#define TYPE_MEMORY_STORE_OBJECT_GTYPE_METHOD PYTHON_METHOD_DEF     \
-(                                                                   \
-    store_object_gtype, "$self, obj, pbuf",                         \
-    METH_VARARGS, py_type_memory,                                   \
-    "Create a new GLib object from serialized data.\n"              \
-    "\n"                                                            \
-    "The *obj* parameter is the Python version of the GObject"      \
-    " whose type is to process and the *pbuf* parameter is a"       \
-    " pychrysalide.common.PackedBuffer instance providing buffered" \
-    " data to extend."                                              \
-    "\n"                                                            \
-    "The result is a boolean value indicating the status of the"    \
-    " operation: True for success, False for failure."              \
-)
-
-    ret = PyArg_ParseTuple(args, "O!O&", PyGObject_Type, &obj, convert_to_packed_buffer, &pbuf);
-    if (!ret) return NULL;
-
-    tpmem = G_TYPE_MEMORY(pygobject_get(self));
-
-    status = g_type_memory_store_object_gtype(tpmem, obj, pbuf);
-
-    result = status ? Py_True : Py_False;
-    Py_INCREF(result);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : self = classe représentant une mémorisation de types.        *
-*                args = arguments fournis à l'appel.                          *
-*                                                                             *
-*  Description : Enregistre tous les types mémorisés dans un tampon.          *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static PyObject *py_type_memory_store_types(PyObject *self, PyObject *args)
-{
-    PyObject *result;                       /* Bilan à retourner           */
-    packed_buffer_t *pbuf;                  /* Tampon à consulter          */
-    int ret;                                /* Bilan de lecture des args.  */
-    GTypeMemory *tpmem;                     /* Mémorisation native         */
-    bool status;                            /* Bilan de l'opération        */
-
-#define TYPE_MEMORY_STORE_TYPES_METHOD PYTHON_METHOD_DEF        \
-(                                                               \
-    store_types, "$self, pbuf",                                 \
-    METH_VARARGS, py_type_memory,                               \
-    "Write types into a buffer.\n"                              \
-    "\n"                                                        \
-    "This operation is usually handled internally by the"       \
-    " Chrysalide's core.\n"                                     \
-    "\n"                                                        \
-    "The *pbuf* parameter is a pychrysalide.common.PackedBuffer"\
-    " instance providing buffered data to read."                \
-    "\n"                                                        \
-    "The result is a boolean value indicating the status of"    \
-    " the operation: True for success, False for failure."      \
-)
-
-    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
-    if (!ret) return NULL;
-
-    tpmem = G_TYPE_MEMORY(pygobject_get(self));
-
-    status = g_type_memory_store_types(tpmem, pbuf);
-
-    result = status ? Py_True : Py_False;
-    Py_INCREF(result);
-
-    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_type_memory_type(void)
-{
-    static PyMethodDef py_type_memory_methods[] = {
-        TYPE_MEMORY_LOAD_TYPES_METHOD,
-        TYPE_MEMORY_CREATE_OBJECT_METHOD,
-        TYPE_MEMORY_STORE_OBJECT_GTYPE_METHOD,
-        TYPE_MEMORY_STORE_TYPES_METHOD,
-        { NULL }
-    };
-
-    static PyGetSetDef py_type_memory_getseters[] = {
-        { NULL }
-    };
-
-    static PyTypeObject py_type_memory_type = {
-
-        PyVarObject_HEAD_INIT(NULL, 0)
-
-        .tp_name        = "pychrysalide.analysis.storage.TypeMemory",
-        .tp_basicsize   = sizeof(PyGObject),
-
-        .tp_flags       = Py_TPFLAGS_DEFAULT,
-
-        .tp_doc         = TYPE_MEMORY_DOC,
-
-        .tp_methods     = py_type_memory_methods,
-        .tp_getset      = py_type_memory_getseters,
-
-        .tp_init        = py_type_memory_init,
-        .tp_new         = py_type_memory_new
-
-    };
-
-    return &py_type_memory_type;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : module = module dont la définition est à compléter.          *
-*                                                                             *
-*  Description : Prend en charge l'objet 'pychrysalide.analysis...TypeMemory'.*
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool ensure_python_type_memory_is_registered(void)
-{
-    PyTypeObject *type;                     /* Type Python 'BufferCache'   */
-    PyObject *module;                       /* Module à recompléter        */
-    PyObject *dict;                         /* Dictionnaire du module      */
-
-    type = get_python_type_memory_type();
-
-    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
-    {
-        module = get_access_to_python_module("pychrysalide.analysis.storage");
-
-        dict = PyModule_GetDict(module);
-
-        if (!register_class_for_pygobject(dict, G_TYPE_TYPE_MEMORY, 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 mémorisation de types.                 *
-*                                                                             *
-*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-int convert_to_type_memory(PyObject *arg, void *dst)
-{
-    int result;                             /* Bilan à retourner           */
-
-    result = PyObject_IsInstance(arg, (PyObject *)get_python_type_memory_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 buffer cache");
-            break;
-
-        case 1:
-            *((GTypeMemory **)dst) = G_TYPE_MEMORY(pygobject_get(arg));
-            break;
-
-        default:
-            assert(false);
-            break;
-
-    }
-
-    return result;
-
-}
diff --git a/plugins/pychrysalide/analysis/storage/tpmem.h b/plugins/pychrysalide/analysis/storage/tpmem.h
deleted file mode 100644
index 1085632..0000000
--- a/plugins/pychrysalide/analysis/storage/tpmem.h
+++ /dev/null
@@ -1,45 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * tpmem.h - prototypes pour l'équivalent Python du fichier "analysis/storage/tpmem.h"
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-
-#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_TPMEM_H
-#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_TPMEM_H
-
-
-#include <Python.h>
-#include <stdbool.h>
-
-
-
-/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_type_memory_type(void);
-
-/* Prend en charge l'objet 'pychrysalide.analysis.storage.TypeMemory'. */
-bool ensure_python_type_memory_is_registered(void);
-
-/* Tente de convertir en mémorisation de types. */
-int convert_to_type_memory(PyObject *, void *);
-
-
-
-#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_TPMEM_H */
diff --git a/plugins/pychrysalide/glibext/serialize.c b/plugins/pychrysalide/glibext/serialize.c
new file mode 100644
index 0000000..40fcef7
--- /dev/null
+++ b/plugins/pychrysalide/glibext/serialize.c
@@ -0,0 +1,501 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * serialize.c - équivalent Python du fichier "analysis/storage/serialize.h"
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "serialize.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/storage/serialize-int.h>
+
+
+#include "storage.h"
+#include "../../access.h"
+#include "../../helpers.h"
+#include "../../common/packed.h"
+
+
+
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void py_serializable_object_interface_init(GSerializableObjectIface *, gpointer *);
+
+/* Charge un objet depuis une mémoire tampon. */
+static bool py_serializable_object_load_wrapper(GSerializableObject *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un objet dans une mémoire tampon. */
+static bool py_serializable_object_store_wrapper(const GSerializableObject *, GObjectStorage *, packed_buffer_t *);
+
+
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
+
+/* Charge un objet depuis une mémoire tampon. */
+static bool py_serializable_object_load(PyObject *, PyObject *);
+
+/* Sauvegarde un objet dans une mémoire tampon. */
+static bool py_serializable_object_store(PyObject *, PyObject *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface  = interface GLib à initialiser.                       *
+*                unused = adresse non utilisée ici.                           *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de génération.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void py_serializable_object_interface_init(GSerializableObjectIface *iface, gpointer *unused)
+{
+
+#define SERIALIZABLE_OBJECT_DOC                                             \
+    "SerializableObject defines an interface used to store and load"        \
+    " objects to and from a data buffer.\n"                                 \
+    "\n"                                                                    \
+    "A typical class declaration for a new implementation looks like:\n"    \
+    "\n"                                                                    \
+    "    class NewImplem(GObject.Object, SerializableObject):\n"            \
+    "        ...\n"                                                         \
+    "\n"                                                                    \
+    "The following methods have to be defined for new implementations:\n"   \
+    "* pychrysalide.analysis.storage.SerializableObject._load();\n"         \
+    "* pychrysalide.analysis.storage.SerializableObject._store();\n"
+
+    iface->load = py_serializable_object_load_wrapper;
+    iface->store = py_serializable_object_store_wrapper;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : object  = instruction d'assemblage à consulter.              *
+*                storage = conservateur de données à manipuler ou NULL.       *
+*                pbuf    = zone tampon à remplir.                             *
+*                                                                             *
+*  Description : Charge un objet depuis une mémoire tampon.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_serializable_object_load_wrapper(GSerializableObject *object, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *storage_obj;                  /* Objet Python à emmployer    */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyret;                        /* Bilan de consultation       */
+
+#define SERIALIZABLE_OBJECT_LOAD_WRAPPER PYTHON_WRAPPER_DEF                     \
+(                                                                               \
+    _load, "$self, storage, pbuf, /",                                           \
+    METH_VARARGS,                                                               \
+    "Abstract method used to load an object definition from buffered data.\n"   \
+    "\n"                                                                        \
+    "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance"   \
+    " provided to store inner objects, if relevant, or None. The *pbuf*"        \
+    " argument points to a pychrysalide.common.PackedBuffer object containing"  \
+    " the data to process.\n"                                                   \
+    "\n"                                                                        \
+    "The result is a boolean indicating the status of the operation."           \
+)
+
+    result = false;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(object));
+
+    if (has_python_method(pyobj, "_load"))
+    {
+        if (storage == NULL)
+        {
+            storage_obj = Py_None;
+            Py_INCREF(storage_obj);
+        }
+        else
+            storage_obj = pygobject_new(G_OBJECT(storage));
+
+        args = PyTuple_New(2);
+        PyTuple_SetItem(args, 0, storage_obj);
+        PyTuple_SetItem(args, 1, build_from_internal_packed_buffer(pbuf));
+
+        pyret = run_python_method(pyobj, "_load", args);
+
+        result = (pyret == Py_True ? true : false);
+
+        Py_XDECREF(pyret);
+
+        Py_DECREF(args);
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : object  = instruction d'assemblage à consulter.              *
+*                storage = conservateur de données à manipuler ou NULL.       *
+*                pbuf    = zone tampon à remplir.                             *
+*                                                                             *
+*  Description : Sauvegarde un objet dans une mémoire tampon.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_serializable_object_store_wrapper(const GSerializableObject *object, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyGILState_STATE gstate;                /* Sauvegarde d'environnement  */
+    PyObject *storage_obj;                  /* Objet Python à emmployer    */
+    PyObject *args;                         /* Arguments pour l'appel      */
+    PyObject *pyobj;                        /* Objet Python concerné       */
+    PyObject *pyret;                        /* Bilan de consultation       */
+
+#define SERIALIZABLE_OBJECT_STORE_WRAPPER PYTHON_WRAPPER_DEF                    \
+(                                                                               \
+    _store, "$self, storage, pbuf, /",                                          \
+    METH_VARARGS,                                                               \
+    "Abstract method used to store an object definition into buffered data.\n"  \
+    "\n"                                                                        \
+    "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance"   \
+    " provided to store inner objects, if relevant, or None. The *pbuf*"        \
+    " argument points to a pychrysalide.common.PackedBuffer object containing"  \
+    " the data to process.\n"                                                   \
+    "\n"                                                                        \
+    "The result is a boolean indicating the status of the operation."           \
+)
+
+    result = false;
+
+    gstate = PyGILState_Ensure();
+
+    pyobj = pygobject_new(G_OBJECT(object));
+
+    if (has_python_method(pyobj, "_store"))
+    {
+        if (storage == NULL)
+        {
+            storage_obj = Py_None;
+            Py_INCREF(storage_obj);
+        }
+        else
+            storage_obj = pygobject_new(G_OBJECT(storage));
+
+        args = PyTuple_New(2);
+        PyTuple_SetItem(args, 0, storage_obj);
+        PyTuple_SetItem(args, 1, build_from_internal_packed_buffer(pbuf));
+
+        pyret = run_python_method(pyobj, "_store", args);
+
+        result = (pyret == Py_True ? true : false);
+
+        Py_XDECREF(pyret);
+
+        Py_DECREF(args);
+
+    }
+
+    Py_DECREF(pyobj);
+
+    PyGILState_Release(gstate);
+
+    return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           CONNEXION AVEC L'API DE PYTHON                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un générateur à manipuler.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Charge un objet depuis une mémoire tampon.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_serializable_object_load(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    GObjectStorage *storage;                /* Conservateur à manipuler    */
+    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
+    int ret;                                /* Bilan de lecture des args.  */
+    GSerializableObject *object;            /* Version native              */
+    bool status;                            /* Bilan de l'opération        */
+
+#define SERIALIZABLE_OBJECT_LOAD_METHOD PYTHON_METHOD_DEF                       \
+(                                                                               \
+    load, "$self, storage, pbuf, /",                                            \
+    METH_VARARGS, py_serializable_object,                                       \
+    "Load an object definition from buffered data.\n"                           \
+    "\n"                                                                        \
+    "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance"   \
+    " provided to store inner objects, if relevant, or None. The *pbuf*"        \
+    " argument points to a pychrysalide.common.PackedBuffer object containing"  \
+    " the data to process.\n"                                                   \
+    "\n"                                                                        \
+    "The result is a boolean indicating the status of the operation."           \
+)
+
+    ret = PyArg_ParseTuple(args, "O&O&", convert_to_object_storage_or_none, &storage,
+                           convert_to_packed_buffer, &pbuf);
+    if (!ret) return NULL;
+
+    object = G_SERIALIZABLE_OBJECT(pygobject_get(self));
+
+    status = g_serializable_object_load(object, storage, pbuf);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant un générateur à manipuler.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Sauvegarde un objet dans une mémoire tampon.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool py_serializable_object_store(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    GObjectStorage *storage;                /* Conservateur à manipuler    */
+    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
+    int ret;                                /* Bilan de lecture des args.  */
+    GSerializableObject *object;            /* Version native              */
+    bool status;                            /* Bilan de l'opération        */
+
+#define SERIALIZABLE_OBJECT_STORE_METHOD PYTHON_METHOD_DEF                      \
+(                                                                               \
+    store, "$self, storage, pbuf, /",                                           \
+    METH_VARARGS, py_serializable_object,                                       \
+    "Store an object definition into buffered data.\n"                          \
+    "\n"                                                                        \
+    "The *storage* is a pychrysalide.analysis.storage.ObjectStorage instance"   \
+    " provided to store inner objects, if relevant, or None. The *pbuf*"        \
+    " argument points to a pychrysalide.common.PackedBuffer object containing"  \
+    " the data to process.\n"                                                   \
+    "\n"                                                                        \
+    "The result is a boolean indicating the status of the operation."           \
+)
+
+    ret = PyArg_ParseTuple(args, "O&O&", convert_to_object_storage_or_none, &storage,
+                           convert_to_packed_buffer, &pbuf);
+    if (!ret) return NULL;
+
+    object = G_SERIALIZABLE_OBJECT(pygobject_get(self));
+
+    status = g_serializable_object_store(object, storage, pbuf);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    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_serializable_object_type(void)
+{
+    static PyMethodDef py_serializable_object_methods[] = {
+        SERIALIZABLE_OBJECT_LOAD_WRAPPER,
+        SERIALIZABLE_OBJECT_STORE_WRAPPER,
+        SERIALIZABLE_OBJECT_LOAD_METHOD,
+        SERIALIZABLE_OBJECT_STORE_METHOD,
+        { NULL }
+    };
+
+    static PyGetSetDef py_serializable_object_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_serializable_object_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.storage.SerializableObject",
+        .tp_basicsize   = sizeof(PyObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = SERIALIZABLE_OBJECT_DOC,
+
+        .tp_methods     = py_serializable_object_methods,
+        .tp_getset      = py_serializable_object_getseters,
+
+    };
+
+    return &py_serializable_object_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....SerializableObject'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_serializable_object_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type 'SerializableObject'   */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    static GInterfaceInfo info = {          /* Paramètres d'inscription    */
+
+        .interface_init = (GInterfaceInitFunc)py_serializable_object_interface_init,
+        .interface_finalize = NULL,
+        .interface_data = NULL,
+
+    };
+
+    type = get_python_serializable_object_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.storage");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_interface_for_pygobject(dict, G_TYPE_SERIALIZABLE_OBJECT, type, &info))
+            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 objet adapté à une mise en cache.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_serializable_object(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_serializable_object_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 serializable object");
+            break;
+
+        case 1:
+            *((GSerializableObject **)dst) = G_SERIALIZABLE_OBJECT(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/glibext/serialize.h b/plugins/pychrysalide/glibext/serialize.h
new file mode 100644
index 0000000..7e831e5
--- /dev/null
+++ b/plugins/pychrysalide/glibext/serialize.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * serialize.h - prototypes pour l'équivalent Python du fichier "analysis/storage/serialize.h"
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_SERIALIZE_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_SERIALIZE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_serializable_object_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.storage.SerializableObject'. */
+bool ensure_python_serializable_object_is_registered(void);
+
+/* Tente de convertir en objet adapté à une mise en cache. */
+int convert_to_serializable_object(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_SERIALIZE_H */
diff --git a/plugins/pychrysalide/glibext/storage.c b/plugins/pychrysalide/glibext/storage.c
new file mode 100644
index 0000000..c54fe0f
--- /dev/null
+++ b/plugins/pychrysalide/glibext/storage.c
@@ -0,0 +1,687 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * storage.c - équivalent Python du fichier "analysis/storage/storage.c"
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "storage.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/storage/storage-int.h>
+#include <plugins/dt.h>
+
+
+#include "serialize.h"
+#include "../../access.h"
+#include "../../helpers.h"
+#include "../../common/packed.h"
+
+
+
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Accompagne la création d'une instance dérivée en Python. */
+static PyObject *py_object_storage_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_object_storage_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
+
+
+/* Charge le support d'une conservation d'objets en place. */
+static PyObject *py_object_storage_load(PyObject *, PyObject *);
+
+/* Sauvegarde le support d'une conservation d'objets en place. */
+static PyObject *py_object_storage_store(PyObject *, PyObject *);
+
+/* Charge un objet à partir de données rassemblées. */
+static PyObject *py_object_storage_load_object(PyObject *, PyObject *);
+
+/* Charge un objet interne à partir de données rassemblées. */
+static PyObject *py_object_storage_unpack_object(PyObject *, PyObject *);
+
+/* Sauvegarde un object sous forme de données rassemblées. */
+static PyObject *py_object_storage_store_object(PyObject *, PyObject *);
+
+/* Sauvegarde un object interne sous forme de données. */
+static PyObject *py_object_storage_pack_object(PyObject *, PyObject *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type du nouvel objet à mettre en place.               *
+*                args = éventuelle liste d'arguments.                         *
+*                kwds = éventuel dictionnaire de valeurs mises à disposition. *
+*                                                                             *
+*  Description : Accompagne la création d'une instance dérivée en Python.     *
+*                                                                             *
+*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_object_storage_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   */
+
+    /* Validations diverses */
+
+    base = get_python_object_storage_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_OBJECT_STORAGE, type->tp_name, NULL, NULL, NULL);
+
+    if (first_time)
+    {
+        status = register_class_for_dynamic_pygobject(gtype, type);
+
+        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  : self = objet à initialiser (théoriquement).                  *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Initialise une instance sur la base du dérivé de GObject.    *
+*                                                                             *
+*  Retour      : 0.                                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_object_storage_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    const char *hash;                       /* Empreinte de contenu        */
+    int ret;                                /* Bilan de lecture des args.  */
+    GObjectStorage *storage;                /* Mécanismes natifs           */
+
+#define OBJECT_STORAGE_DOC                                              \
+    "The ObjectStorage object manages the generic storage of GLib"      \
+    " objects through serialization.\n"                                 \
+    "\n"                                                                \
+    "Instances can be created using the following constructor:\n"       \
+    "\n"                                                                \
+    "    ObjectStorage(hash)"                                           \
+    "\n"                                                                \
+    "Where *hash* should a string built from the checksum of the"       \
+    " relative binary content linked to the storage.pychrysalide."
+
+    /* Récupération des paramètres */
+
+    ret = PyArg_ParseTuple(args, "s", &hash);
+    if (!ret) return -1;
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
+
+    /* Eléments de base */
+
+    storage = G_OBJECT_STORAGE(pygobject_get(self));
+
+    storage->hash = strdup(hash);
+
+    return 0;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            TAMPON POUR CODE DESASSEMBLE                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant une mémorisation de types.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Charge le support d'une conservation d'objets en place.      *
+*                                                                             *
+*  Retour      : Gestionnaire de conservations construit ou None si erreur.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_object_storage_load(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Emplacement à retourner     */
+    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
+    int ret;                                /* Bilan de lecture des args.  */
+    GObjectStorage *storage;                /* Mécanismes natifs           */
+
+#define OBJECT_STORAGE_LOAD_METHOD PYTHON_METHOD_DEF                    \
+(                                                                       \
+    load, "pbuf, /",                                                    \
+    METH_STATIC | METH_VARARGS, py_object_storage,                      \
+    "Construct a new storage from a buffer.\n"                          \
+    "\n"                                                                \
+    "The *pbuf* has to be an instance of type"                          \
+    " pychrysalide.common.PackedBuffer.\n"                              \
+    "\n"                                                                \
+    "The result is a new pychrysalide.analysis.storage.ObjectStorage"   \
+    " object on success, *None* otherwise."                             \
+)
+
+    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+    if (!ret) return NULL;
+
+    storage = g_object_storage_load(pbuf);
+
+    if (storage == NULL)
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+    else
+    {
+        result = pygobject_new(G_OBJECT(storage));
+        g_object_unref(G_OBJECT(storage));
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant une mémorisation de types.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Sauvegarde le support d'une conservation d'objets en place.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_object_storage_store(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Emplacement à retourner     */
+    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
+    int ret;                                /* Bilan de lecture des args.  */
+    GObjectStorage *storage;                /* Mécanismes natifs           */
+    bool status;                            /* Bilan de l'opération        */
+
+#define OBJECT_STORAGE_STORE_METHOD PYTHON_METHOD_DEF       \
+(                                                           \
+    store, "$self, pbuf, /",                                \
+    METH_VARARGS, py_object_storage,                        \
+    "Save a storage into a buffer.\n"                       \
+    "\n"                                                    \
+    "The *pbuf* has to be an instance of type"              \
+    " pychrysalide.common.PackedBuffer.\n"                  \
+    "\n"                                                    \
+    "The result is *True* on success, *False* otherwise."   \
+)
+
+    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+    if (!ret) return NULL;
+
+    storage = G_OBJECT_STORAGE(pygobject_get(self));
+
+    status = g_object_storage_store(storage, pbuf);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant une mémorisation de types.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Charge un objet à partir de données rassemblées.             *
+*                                                                             *
+*  Retour      : Objet restauré en mémoire ou None en cas d'échec.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_object_storage_load_object(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    const char *name;                       /* Désignation de groupe       */
+    unsigned long long pos;                 /* Emplacement des données     */
+    int ret;                                /* Bilan de lecture des args.  */
+    GObjectStorage *storage;                /* Mécanismes natifs           */
+    GSerializableObject *object;            /* Objet reconstruit ou NULL   */
+
+#define OBJECT_STORAGE_LOAD_OBJECT_METHOD PYTHON_METHOD_DEF             \
+(                                                                       \
+    load_object, "$self, name, pos, /",                                 \
+    METH_VARARGS, py_object_storage,                                    \
+    "Load an object from serialized data.\n"                            \
+    "\n"                                                                \
+    "The *name* is a string label for the group of target objects and"  \
+    " *pos* is an offset into the data stream indicating the start of"  \
+    " the data to unserialize.\n"                                       \
+    "\n"                                                                \
+    "The result is a pychrysalide.analysis.storage.SerializableObject"  \
+    " instancet in case of success, or None in case of failure."        \
+)
+
+    ret = PyArg_ParseTuple(args, "sK", &name, &pos);
+    if (!ret) return NULL;
+
+    storage = G_OBJECT_STORAGE(pygobject_get(self));
+
+    object = g_object_storage_load_object(storage, name, pos);
+
+    if (object != NULL)
+        result = pygobject_new(G_OBJECT(object));
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant une mémorisation de types.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Charge un objet interne à partir de données rassemblées.     *
+*                                                                             *
+*  Retour      : Objet restauré en mémoire ou None en cas d'échec.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_object_storage_unpack_object(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    const char *name;                       /* Désignation de groupe       */
+    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
+    int ret;                                /* Bilan de lecture des args.  */
+    GObjectStorage *storage;                /* Mécanismes natifs           */
+    GSerializableObject *object;            /* Objet reconstruit ou NULL   */
+
+#define OBJECT_STORAGE_UNPACK_OBJECT_METHOD PYTHON_METHOD_DEF           \
+(                                                                       \
+    unpack_object, "$self, name, pbuf, /",                              \
+    METH_VARARGS, py_object_storage,                                    \
+    "Load an object from a buffer with a location pointing to data.\n"  \
+    "\n"                                                                \
+    "The *name* is a string label for the group of target objects and"  \
+    " *pbuf* has to be a pychrysalide.common.PackedBuffer instance.\n"  \
+    "\n"                                                                \
+    "The result is a pychrysalide.analysis.storage.SerializableObject"  \
+    " instancet in case of success, or None in case of failure."        \
+)
+
+    ret = PyArg_ParseTuple(args, "sO&", &name, convert_to_packed_buffer, &pbuf);
+    if (!ret) return NULL;
+
+    storage = G_OBJECT_STORAGE(pygobject_get(self));
+
+    object = g_object_storage_unpack_object(storage, name, pbuf);
+
+    if (object != NULL)
+        result = pygobject_new(G_OBJECT(object));
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant une mémorisation de types.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Sauvegarde un object sous forme de données rassemblées.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_object_storage_store_object(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Emplacement à retourner     */
+    const char *name;                       /* Désignation de groupe       */
+    GSerializableObject *object;            /* Objet à traiter             */
+    int ret;                                /* Bilan de lecture des args.  */
+    GObjectStorage *storage;                /* Mécanismes natifs           */
+    off64_t pos;                            /* Emplacement d'enregistrement*/
+    bool status;                            /* Bilan de l'opération        */
+
+#define OBJECT_STORAGE_STORE_OBJECT_METHOD PYTHON_METHOD_DEF        \
+(                                                                   \
+    store_object, "$self, name, object, /",                         \
+    METH_VARARGS, py_object_storage,                                \
+    "Save an object as serialized data.\n"                          \
+    "\n"                                                            \
+    "The *name* is a string label for the group of target objects"  \
+    " and the processed *object* has to be a"                       \
+    " pychrysalide.analysis.storage.SerializableObject instance.\n" \
+    "\n"                                                            \
+    "The result is the position of the data for stored object,"     \
+    " provided as an integer offset, in case of success or None"    \
+    " in case of failure."                                          \
+)
+
+    ret = PyArg_ParseTuple(args, "sO&", &name, convert_to_serializable_object, &object);
+    if (!ret) return NULL;
+
+    storage = G_OBJECT_STORAGE(pygobject_get(self));
+
+    status = g_object_storage_store_object(storage, name, object, &pos);
+
+    if (status)
+        result = PyLong_FromUnsignedLongLong((unsigned long long)pos);
+    else
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant une mémorisation de types.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Sauvegarde un object interne sous forme de données.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_object_storage_pack_object(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Emplacement à retourner     */
+    const char *name;                       /* Désignation de groupe       */
+    GSerializableObject *object;            /* Objet à traiter             */
+    packed_buffer_t *pbuf;                  /* Tampon de données à employer*/
+    int ret;                                /* Bilan de lecture des args.  */
+    GObjectStorage *storage;                /* Mécanismes natifs           */
+    bool status;                            /* Bilan de l'opération        */
+
+#define OBJECT_STORAGE_PACK_OBJECT_METHOD PYTHON_METHOD_DEF         \
+(                                                                   \
+    pack_object, "$self, name, object, pbuf/",                      \
+    METH_VARARGS, py_object_storage,                                \
+    "Save an object as serialized data and store the location of"   \
+    " the data intro a buffer.\n"                                   \
+    "\n"                                                            \
+    "The *name* is a string label for the group of target objects," \
+    " the processed *object* has to be a"                           \
+    " pychrysalide.analysis.storage.SerializableObject instance"    \
+    " and *pbuf* is expected to be a"                               \
+    " pychrysalide.common.PackedBuffer instance.\n"                 \
+    "\n"                                                            \
+    "The status of the operation is returned as a boolean value:"   \
+    " *True* for success, *False* for failure."                     \
+)
+
+    ret = PyArg_ParseTuple(args, "sO&O&", &name, convert_to_serializable_object, &object,
+                           convert_to_packed_buffer, &pbuf);
+    if (!ret) return NULL;
+
+    storage = G_OBJECT_STORAGE(pygobject_get(self));
+
+    status = g_object_storage_pack_object(storage, name, object, pbuf);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    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_object_storage_type(void)
+{
+    static PyMethodDef py_object_storage_methods[] = {
+        OBJECT_STORAGE_LOAD_METHOD,
+        OBJECT_STORAGE_STORE_METHOD,
+        OBJECT_STORAGE_LOAD_OBJECT_METHOD,
+        OBJECT_STORAGE_UNPACK_OBJECT_METHOD,
+        OBJECT_STORAGE_STORE_OBJECT_METHOD,
+        OBJECT_STORAGE_PACK_OBJECT_METHOD,
+        { NULL }
+    };
+
+    static PyGetSetDef py_object_storage_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_object_storage_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.storage.ObjectStorage",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = OBJECT_STORAGE_DOC,
+
+        .tp_methods     = py_object_storage_methods,
+        .tp_getset      = py_object_storage_getseters,
+
+        .tp_init        = py_object_storage_init,
+        .tp_new         = py_object_storage_new
+
+    };
+
+    return &py_object_storage_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....ObjectStorage'.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_object_storage_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'ObjectStorage' */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_object_storage_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.storage");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_OBJECT_STORAGE, 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 conservateur d'objets.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_object_storage(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_object_storage_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 object storage");
+            break;
+
+        case 1:
+            *((GObjectStorage **)dst) = G_OBJECT_STORAGE(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  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 conservateur d'objets ou NULL.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_object_storage_or_none(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    if (arg == Py_None)
+    {
+        *((GTypeMemory **)dst) = NULL;
+        result = 1;
+    }
+
+    else
+        result = convert_to_object_storage(arg, dst);
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/glibext/storage.h b/plugins/pychrysalide/glibext/storage.h
new file mode 100644
index 0000000..a0a2c18
--- /dev/null
+++ b/plugins/pychrysalide/glibext/storage.h
@@ -0,0 +1,48 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * storage.h - prototypes pour l'équivalent Python du fichier "analysis/storage/storage.h"
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_STORAGE_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_STORAGE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_object_storage_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.storage.ObjectStorage'. */
+bool ensure_python_object_storage_is_registered(void);
+
+/* Tente de convertir en conservateur d'objets. */
+int convert_to_object_storage(PyObject *, void *);
+
+/* Tente de convertir en conservateur d'objets ou NULL. */
+int convert_to_object_storage_or_none(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_STORAGE_H */
diff --git a/plugins/pychrysalide/glibext/tpmem.c b/plugins/pychrysalide/glibext/tpmem.c
new file mode 100644
index 0000000..ae07008
--- /dev/null
+++ b/plugins/pychrysalide/glibext/tpmem.c
@@ -0,0 +1,508 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tpmem.c - équivalent Python du fichier "analysis/storage/tpmem.c"
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "tpmem.h"
+
+
+#include <pygobject.h>
+
+
+#include <analysis/storage/tpmem.h>
+#include <plugins/dt.h>
+
+
+#include "../../access.h"
+#include "../../helpers.h"
+#include "../../common/packed.h"
+
+
+
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Accompagne la création d'une instance dérivée en Python. */
+static PyObject *py_type_memory_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_type_memory_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
+
+
+/* Apprend tous les types mémorisés dans un tampon. */
+static PyObject *py_type_memory_load_types(PyObject *, PyObject *);
+
+/* Crée une nouvelle instance d'objet à partir de son type. */
+static PyObject *py_type_memory_create_object(PyObject *, PyObject *);
+
+/* Sauvegarde le type d'un objet instancié. */
+static PyObject *py_type_memory_store_object_gtype(PyObject *, PyObject *);
+
+/* Enregistre tous les types mémorisés dans un tampon. */
+static PyObject *py_type_memory_store_types(PyObject *, PyObject *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          GLUE POUR CREATION DEPUIS PYTHON                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type du nouvel objet à mettre en place.               *
+*                args = éventuelle liste d'arguments.                         *
+*                kwds = éventuel dictionnaire de valeurs mises à disposition. *
+*                                                                             *
+*  Description : Accompagne la création d'une instance dérivée en Python.     *
+*                                                                             *
+*  Retour      : Nouvel objet Python mis en place ou NULL en cas d'échec.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_type_memory_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   */
+
+    /* Validations diverses */
+
+    base = get_python_type_memory_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_TYPE_MEMORY, type->tp_name, NULL, NULL, NULL);
+
+    if (first_time)
+    {
+        status = register_class_for_dynamic_pygobject(gtype, type);
+
+        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  : self = objet à initialiser (théoriquement).                  *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Initialise une instance sur la base du dérivé de GObject.    *
+*                                                                             *
+*  Retour      : 0.                                                           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_type_memory_init(PyObject *self, PyObject *args, PyObject *kwds)
+{
+    int ret;                                /* Bilan de lecture des args.  */
+
+#define TYPE_MEMORY_DOC                                             \
+    "The TypeMemory remembers all the types of objects involved in" \
+    " a serialization process.\n"                                   \
+    "\n"                                                            \
+    "Instances can be created using the following constructor:\n"   \
+    "\n"                                                            \
+    "    TypeMemory()"                                              \
+
+    /* Initialisation d'un objet GLib */
+
+    ret = forward_pygobjet_init(self);
+    if (ret == -1) return -1;
+
+    return 0;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            TAMPON POUR CODE DESASSEMBLE                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant une mémorisation de types.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Apprend tous les types mémorisés dans un tampon.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_type_memory_load_types(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    packed_buffer_t *pbuf;                  /* Tampon à consulter          */
+    int ret;                                /* Bilan de lecture des args.  */
+    GTypeMemory *tpmem;                     /* Mémorisation native         */
+    bool status;                            /* Bilan de l'opération        */
+
+#define TYPE_MEMORY_LOAD_TYPES_METHOD PYTHON_METHOD_DEF         \
+(                                                               \
+    load_types, "$self, pbuf",                                  \
+    METH_VARARGS, py_type_memory,                               \
+    "Read types from a buffer.\n"                               \
+    "\n"                                                        \
+    "This operation is usually handled internally by the"       \
+    " Chrysalide's core.\n"                                     \
+    "\n"                                                        \
+    "The *pbuf* parameter is a pychrysalide.common.PackedBuffer"\
+    " instance providing buffered data to read."                \
+    "\n"                                                        \
+    "The result is a boolean value indicating the status of"    \
+    " the operation: True for success, False for failure."      \
+)
+
+    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+    if (!ret) return NULL;
+
+    tpmem = G_TYPE_MEMORY(pygobject_get(self));
+
+    status = g_type_memory_load_types(tpmem, pbuf);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant une mémorisation de types.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Crée une nouvelle instance d'objet à partir de son type.     *
+*                                                                             *
+*  Retour      : Instance issue de l'opération ou NULL.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_type_memory_create_object(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    packed_buffer_t *pbuf;                  /* Tampon à consulter          */
+    int ret;                                /* Bilan de lecture des args.  */
+    GTypeMemory *tpmem;                     /* Mémorisation native         */
+    GObject *obj;                           /* Instance retournée          */
+
+#define TYPE_MEMORY_CREATE_OBJECT_METHOD PYTHON_METHOD_DEF          \
+(                                                                   \
+    create_object, "$self, pbuf",                                   \
+    METH_VARARGS, py_type_memory,                                   \
+    "Create a new GLib object from serialized data.\n"              \
+    "\n"                                                            \
+    "The *pbuf* parameter is a pychrysalide.common.PackedBuffer"    \
+    " instance providing buffered data to read."                    \
+    "\n"                                                            \
+    "The result is a Python object linked to a native GLib"         \
+    " object instance."                                             \
+)
+
+    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+    if (!ret) return NULL;
+
+    tpmem = G_TYPE_MEMORY(pygobject_get(self));
+
+    obj = g_type_memory_create_object(tpmem, pbuf);
+
+    result = pygobject_new(obj);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant une mémorisation de types.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Sauvegarde le type d'un objet instancié.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_type_memory_store_object_gtype(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    GObject *obj;                           /* Instance à traiter          */
+    packed_buffer_t *pbuf;                  /* Tampon à consulter          */
+    int ret;                                /* Bilan de lecture des args.  */
+    GTypeMemory *tpmem;                     /* Mémorisation native         */
+    bool status;                            /* Bilan de l'opération        */
+
+#define TYPE_MEMORY_STORE_OBJECT_GTYPE_METHOD PYTHON_METHOD_DEF     \
+(                                                                   \
+    store_object_gtype, "$self, obj, pbuf",                         \
+    METH_VARARGS, py_type_memory,                                   \
+    "Create a new GLib object from serialized data.\n"              \
+    "\n"                                                            \
+    "The *obj* parameter is the Python version of the GObject"      \
+    " whose type is to process and the *pbuf* parameter is a"       \
+    " pychrysalide.common.PackedBuffer instance providing buffered" \
+    " data to extend."                                              \
+    "\n"                                                            \
+    "The result is a boolean value indicating the status of the"    \
+    " operation: True for success, False for failure."              \
+)
+
+    ret = PyArg_ParseTuple(args, "O!O&", PyGObject_Type, &obj, convert_to_packed_buffer, &pbuf);
+    if (!ret) return NULL;
+
+    tpmem = G_TYPE_MEMORY(pygobject_get(self));
+
+    status = g_type_memory_store_object_gtype(tpmem, obj, pbuf);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self = classe représentant une mémorisation de types.        *
+*                args = arguments fournis à l'appel.                          *
+*                                                                             *
+*  Description : Enregistre tous les types mémorisés dans un tampon.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_type_memory_store_types(PyObject *self, PyObject *args)
+{
+    PyObject *result;                       /* Bilan à retourner           */
+    packed_buffer_t *pbuf;                  /* Tampon à consulter          */
+    int ret;                                /* Bilan de lecture des args.  */
+    GTypeMemory *tpmem;                     /* Mémorisation native         */
+    bool status;                            /* Bilan de l'opération        */
+
+#define TYPE_MEMORY_STORE_TYPES_METHOD PYTHON_METHOD_DEF        \
+(                                                               \
+    store_types, "$self, pbuf",                                 \
+    METH_VARARGS, py_type_memory,                               \
+    "Write types into a buffer.\n"                              \
+    "\n"                                                        \
+    "This operation is usually handled internally by the"       \
+    " Chrysalide's core.\n"                                     \
+    "\n"                                                        \
+    "The *pbuf* parameter is a pychrysalide.common.PackedBuffer"\
+    " instance providing buffered data to read."                \
+    "\n"                                                        \
+    "The result is a boolean value indicating the status of"    \
+    " the operation: True for success, False for failure."      \
+)
+
+    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
+    if (!ret) return NULL;
+
+    tpmem = G_TYPE_MEMORY(pygobject_get(self));
+
+    status = g_type_memory_store_types(tpmem, pbuf);
+
+    result = status ? Py_True : Py_False;
+    Py_INCREF(result);
+
+    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_type_memory_type(void)
+{
+    static PyMethodDef py_type_memory_methods[] = {
+        TYPE_MEMORY_LOAD_TYPES_METHOD,
+        TYPE_MEMORY_CREATE_OBJECT_METHOD,
+        TYPE_MEMORY_STORE_OBJECT_GTYPE_METHOD,
+        TYPE_MEMORY_STORE_TYPES_METHOD,
+        { NULL }
+    };
+
+    static PyGetSetDef py_type_memory_getseters[] = {
+        { NULL }
+    };
+
+    static PyTypeObject py_type_memory_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.storage.TypeMemory",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = TYPE_MEMORY_DOC,
+
+        .tp_methods     = py_type_memory_methods,
+        .tp_getset      = py_type_memory_getseters,
+
+        .tp_init        = py_type_memory_init,
+        .tp_new         = py_type_memory_new
+
+    };
+
+    return &py_type_memory_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide.analysis...TypeMemory'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool ensure_python_type_memory_is_registered(void)
+{
+    PyTypeObject *type;                     /* Type Python 'BufferCache'   */
+    PyObject *module;                       /* Module à recompléter        */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    type = get_python_type_memory_type();
+
+    if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
+    {
+        module = get_access_to_python_module("pychrysalide.analysis.storage");
+
+        dict = PyModule_GetDict(module);
+
+        if (!register_class_for_pygobject(dict, G_TYPE_TYPE_MEMORY, 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 mémorisation de types.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération, voire indications supplémentaires.     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int convert_to_type_memory(PyObject *arg, void *dst)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = PyObject_IsInstance(arg, (PyObject *)get_python_type_memory_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 buffer cache");
+            break;
+
+        case 1:
+            *((GTypeMemory **)dst) = G_TYPE_MEMORY(pygobject_get(arg));
+            break;
+
+        default:
+            assert(false);
+            break;
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/glibext/tpmem.h b/plugins/pychrysalide/glibext/tpmem.h
new file mode 100644
index 0000000..1085632
--- /dev/null
+++ b/plugins/pychrysalide/glibext/tpmem.h
@@ -0,0 +1,45 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tpmem.h - prototypes pour l'équivalent Python du fichier "analysis/storage/tpmem.h"
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_TPMEM_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_TPMEM_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_type_memory_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.storage.TypeMemory'. */
+bool ensure_python_type_memory_is_registered(void);
+
+/* Tente de convertir en mémorisation de types. */
+int convert_to_type_memory(PyObject *, void *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_STORAGE_TPMEM_H */
diff --git a/src/analysis/storage/Makefile.am b/src/analysis/storage/Makefile.am
index 3eb287b..dad7411 100644
--- a/src/analysis/storage/Makefile.am
+++ b/src/analysis/storage/Makefile.am
@@ -6,12 +6,7 @@ libanalysisstorage_la_SOURCES =				\
 	cache-int.h								\
 	cache.h cache.c							\
 	container-int.h							\
-	container.h container.c					\
-	serialize-int.h							\
-	serialize.h serialize.c					\
-	storage-int.h							\
-	storage.h storage.c						\
-	tpmem.h tpmem.c
+	container.h container.c
 
 libanalysisstorage_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS)
 
diff --git a/src/analysis/storage/serialize-int.h b/src/analysis/storage/serialize-int.h
deleted file mode 100644
index de8d3e3..0000000
--- a/src/analysis/storage/serialize-int.h
+++ /dev/null
@@ -1,58 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * serialize-int.h - définitions internes propres aux objets entreposables dans un cache
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_STORAGE_SERIALIZE_INT_H
-#define _ANALYSIS_STORAGE_SERIALIZE_INT_H
-
-
-#include "serialize.h"
-
-
-#include "storage.h"
-
-
-
-/* Charge un objet depuis une mémoire tampon. */
-typedef bool (* load_serializable_object_cb) (GSerializableObject *, GObjectStorage *, packed_buffer_t *);
-
-/* Sauvegarde un objet dans une mémoire tampon. */
-typedef bool (* store_serializable_object_cb) (const GSerializableObject *, GObjectStorage *, packed_buffer_t *);
-
-
-/* Intermédiaire pour la mise en cache d'objet (interface) */
-struct _GSerializableObjectIface
-{
-    GTypeInterface base_iface;              /* A laisser en premier        */
-
-    load_serializable_object_cb load;       /* Chargement                  */
-    store_serializable_object_cb store;     /* Enregistrement              */
-
-};
-
-
-/* Redéfinition */
-typedef GSerializableObjectIface GSerializableObjectInterface;
-
-
-
-#endif  /* _ANALYSIS_STORAGE_SERIALIZE_INT_H */
diff --git a/src/analysis/storage/serialize.c b/src/analysis/storage/serialize.c
deleted file mode 100644
index d1b0502..0000000
--- a/src/analysis/storage/serialize.c
+++ /dev/null
@@ -1,111 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * serialize.h - objets entreposables dans un cache
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "serialize.h"
-
-
-#include "serialize-int.h"
-
-
-
-/* Procède à l'initialisation de l'interface de mise en cache. */
-static void g_serializable_object_default_init(GSerializableObjectInterface *);
-
-
-
-/* Détermine le type d'une interface pour la mise en cache d'objet. */
-G_DEFINE_INTERFACE(GSerializableObject, g_serializable_object, G_TYPE_OBJECT)
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : iface = interface GLib à initialiser.                        *
-*                                                                             *
-*  Description : Procède à l'initialisation de l'interface de mise en cache.  *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_serializable_object_default_init(GSerializableObjectInterface *iface)
-{
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : object  = élément GLib à constuire.                          *
-*                storage = conservateur de données à manipuler ou NULL.       *
-*                pbuf    = zone tampon à lire.                                *
-*                                                                             *
-*  Description : Charge un objet depuis une mémoire tampon.                   *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_serializable_object_load(GSerializableObject *object, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-    GSerializableObjectIface *iface;        /* Interface utilisée          */
-
-    iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object);
-
-    result = iface->load(object, storage, pbuf);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : object  = élément GLib à consulter.                          *
-*                storage = conservateur de données à manipuler ou NULL.       *
-*                pbuf    = zone tampon à remplir.                             *
-*                                                                             *
-*  Description : Sauvegarde un objet dans une mémoire tampon.                 *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_serializable_object_store(const GSerializableObject *object, GObjectStorage *storage, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-    GSerializableObjectIface *iface;        /* Interface utilisée          */
-
-    iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object);
-
-    result = iface->store(object, storage, pbuf);
-
-    return result;
-
-}
diff --git a/src/analysis/storage/serialize.h b/src/analysis/storage/serialize.h
deleted file mode 100644
index 93a4496..0000000
--- a/src/analysis/storage/serialize.h
+++ /dev/null
@@ -1,64 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * serialize.h - prototypes pour les objets entreposables dans un cache
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_STORAGE_SERIALIZE_H
-#define _ANALYSIS_STORAGE_SERIALIZE_H
-
-
-#include <glib-object.h>
-
-
-#include "../../common/packed.h"
-
-
-
-#define G_TYPE_SERIALIZABLE_OBJECT             g_serializable_object_get_type()
-#define G_SERIALIZABLE_OBJECT(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SERIALIZABLE_OBJECT, GSerializableObject))
-#define G_SERIALIZABLE_OBJECT_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_SERIALIZABLE_OBJECT, GSerializableObjectIface))
-#define G_IS_SERIALIZABLE_OBJECT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SERIALIZABLE_OBJECT))
-#define G_IS_SERIALIZABLE_OBJECT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_SERIALIZABLE_OBJECT))
-#define G_SERIALIZABLE_OBJECT_GET_IFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_SERIALIZABLE_OBJECT, GSerializableObjectIface))
-
-
-/* Intermédiaire pour la mise en cache d'objet (coquille vide) */
-typedef struct _GSerializableObject GSerializableObject;
-
-/* Intermédiaire pour la mise en cache d'objet (interface) */
-typedef struct _GSerializableObjectIface GSerializableObjectIface;
-
-
-/* Détermine le type d'une interface pour la mise en cache d'objet. */
-GType g_serializable_object_get_type(void) G_GNUC_CONST;
-
-/* storage.h : définition d'une conservation d'objets construits */
-typedef struct _GObjectStorage GObjectStorage;
-
-/* Charge un objet depuis une mémoire tampon. */
-bool g_serializable_object_load(GSerializableObject *, GObjectStorage *, packed_buffer_t *);
-
-/* Sauvegarde un objet dans une mémoire tampon. */
-bool g_serializable_object_store(const GSerializableObject *, GObjectStorage *, packed_buffer_t *);
-
-
-
-#endif  /* _ANALYSIS_STORAGE_SERIALIZE_H */
diff --git a/src/analysis/storage/storage-int.h b/src/analysis/storage/storage-int.h
deleted file mode 100644
index 4883aa8..0000000
--- a/src/analysis/storage/storage-int.h
+++ /dev/null
@@ -1,66 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * storage.h - prototypes internes pour la conservation sur disque d'objets construits
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_STORAGE_STORAGE_INT_H
-#define _ANALYSIS_STORAGE_STORAGE_INT_H
-
-
-#include "storage.h"
-
-
-
-/* Gestion d'enregistrements spécifiques */
-typedef struct _storage_backend_t
-{
-    char *name;                             /* Désignation du groupe       */
-
-    char *filename;                         /* Nom du fichier associé      */
-    int fd;                                 /* Flux d'accès correspondant  */
-
-} storage_backend_t;
-
-/* Définition d'une conservation d'objets construits (instance) */
-struct _GObjectStorage
-{
-    GObject parent;                         /* A laisser en premier        */
-
-    GTypeMemory *tpmem;                     /* Mémorisation de types       */
-
-    char *hash;                             /* Empreinte du contenu        */
-
-    storage_backend_t *backends;            /* Gestionnaires existants     */
-    size_t count;                           /* Quantité de gestionnaires   */
-    GMutex mutex;                           /* Contrôle d'accès à la liste */
-
-};
-
-/* Définition d'une conservation d'objets construits (classe) */
-struct _GObjectStorageClass
-{
-    GObjectClass parent;                    /* A laisser en premier        */
-
-};
-
-
-
-#endif  /* _ANALYSIS_STORAGE_STORAGE_INT_H */
diff --git a/src/analysis/storage/storage.c b/src/analysis/storage/storage.c
deleted file mode 100644
index 610a0f6..0000000
--- a/src/analysis/storage/storage.c
+++ /dev/null
@@ -1,867 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * storage.c - conservation hors mémoire d'objets choisis
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "storage.h"
-
-
-#include <assert.h>
-#include <malloc.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-
-#include "storage-int.h"
-#include "../db/misc/rlestr.h"
-#include "../../common/io.h"
-#include "../../common/leb128.h"
-#include "../../common/pathname.h"
-#include "../../core/logs.h"
-
-
-
-#define STORAGE_MAGIC "CSTR"
-#define STORAGE_NUMBER "\x00\x01"
-
-
-/* Initialise la classe des conservations d'objets en place. */
-static void g_object_storage_class_init(GObjectStorageClass *);
-
-/* Initialise une instance de conservation d'objets en place. */
-static void g_object_storage_init(GObjectStorage *);
-
-/* Supprime toutes les références externes. */
-static void g_object_storage_dispose(GObjectStorage *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_object_storage_finalize(GObjectStorage *);
-
-/* Retrouve l'encadrement pour un nouveau groupe d'objets. */
-static storage_backend_t *g_object_storage_find_backend(GObjectStorage *, const char *);
-
-/* Ajoute le support d'un nouveau groupe d'objets construits. */
-static bool g_object_storage_add_backend(GObjectStorage *, const char *, storage_backend_t **);
-
-/* Extrait d'un tampon des enregistrements spécifiques. */
-static bool g_object_storage_load_backend(GObjectStorage *, packed_buffer_t *);
-
-/* Place dans un tampon les données liées à des enregistrements. */
-static bool pack_storage_backend(const storage_backend_t *, packed_buffer_t *);
-
-
-
-/* Indique le type défini pour une conservation d'objets construits. */
-G_DEFINE_TYPE(GObjectStorage, g_object_storage, G_TYPE_OBJECT);
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des conservations d'objets en place.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_object_storage_class_init(GObjectStorageClass *klass)
-{
-    GObjectClass *object;                   /* Autre version de la classe  */
-
-    object = G_OBJECT_CLASS(klass);
-
-    object->dispose = (GObjectFinalizeFunc/* ! */)g_object_storage_dispose;
-    object->finalize = (GObjectFinalizeFunc)g_object_storage_finalize;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = instance à initialiser.                            *
-*                                                                             *
-*  Description : Initialise une instance de conservation d'objets en place.   *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_object_storage_init(GObjectStorage *storage)
-{
-    storage->tpmem = g_type_memory_new();
-
-    storage->hash = NULL;
-
-    storage->backends = NULL;
-    storage->count = 0;
-    g_mutex_init(&storage->mutex);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = instance d'objet GLib à traiter.                   *
-*                                                                             *
-*  Description : Supprime toutes les références externes.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_object_storage_dispose(GObjectStorage *storage)
-{
-    g_clear_object(&storage->tpmem);
-
-    G_OBJECT_CLASS(g_object_storage_parent_class)->dispose(G_OBJECT(storage));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = instance d'objet GLib à traiter.                   *
-*                                                                             *
-*  Description : Procède à la libération totale de la mémoire.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_object_storage_finalize(GObjectStorage *storage)
-{
-    size_t i;                               /* Boucle de parcours          */
-    storage_backend_t *backend;             /* Gestionnaire à manipuler    */
-    int ret;                                /* Bilan d'un appel            */
-
-    g_mutex_lock(&storage->mutex);
-
-    for (i = 0; i < storage->count; i++)
-    {
-        backend = &storage->backends[i];
-
-        if (backend->fd != -1)
-            close(backend->fd);
-        else
-            assert(false);
-
-        ret = access(backend->filename, W_OK);
-        if (ret == 0)
-        {
-            ret = unlink(backend->filename);
-            if (ret != 0) LOG_ERROR_N("unlink");
-        }
-
-        free(backend->name);
-
-        free(backend->filename);
-
-    }
-
-    if (storage->backends != NULL)
-        free(storage->backends);
-
-    g_mutex_unlock(&storage->mutex);
-
-    g_mutex_clear(&storage->mutex);
-
-    if (storage->hash != NULL)
-        free(storage->hash);
-
-    G_OBJECT_CLASS(g_object_storage_parent_class)->finalize(G_OBJECT(storage));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : loaded = contenu binaire à associer.                         *
-*                                                                             *
-*  Description : Crée le support d'une conservation d'objets en place.        *
-*                                                                             *
-*  Retour      : Mécanismes mis en place.                                     *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GObjectStorage *g_object_storage_new(const char *hash)
-{
-    GObjectStorage *result;                 /* Structure à retourner       */
-
-    result = g_object_new(G_TYPE_OBJECT_STORAGE, NULL);
-
-    result->hash = strdup(hash);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : pbuf = zone tampon à lire.                                   *
-*                                                                             *
-*  Description : Charge le support d'une conservation d'objets en place.      *
-*                                                                             *
-*  Retour      : Gestionnaire de conservations construit ou NULL si erreur.   *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GObjectStorage *g_object_storage_load(packed_buffer_t *pbuf)
-{
-    GObjectStorage *result;                 /* Structure à retourner       */
-    char header[6];                         /* Entête attendue des données */
-    bool status;                            /* Bilan d'une extraction      */
-    rle_string str;                         /* Chaîne à conserver          */
-    uleb128_t count;                        /* Nombre de groupes à charger */
-    uleb128_t i;                            /* Boucle de parcours          */
-
-    result = NULL;
-
-    status = extract_packed_buffer(pbuf, header, 6, false);
-    if (!status) goto quick_exit;
-
-    if (strncmp(header, STORAGE_MAGIC STORAGE_NUMBER, 6) != 0)
-        goto quick_exit;
-
-    setup_empty_rle_string(&str);
-
-    status = unpack_rle_string(&str, pbuf);
-    if (!status) goto quick_exit;
-
-    if (get_rle_string(&str) == NULL)
-    {
-        exit_rle_string(&str);
-        goto quick_exit;
-    }
-
-    result = g_object_new(G_TYPE_OBJECT_STORAGE, NULL);
-
-    result->hash = strdup(get_rle_string(&str));
-
-    exit_rle_string(&str);
-
-    status = g_type_memory_load_types(result->tpmem, pbuf);
-    if (!status) goto exit_while_loading;
-
-    status = unpack_uleb128(&count, pbuf);
-
-    for (i = 0; i < count && status; i++)
-        status = g_object_storage_load_backend(result, pbuf);
-
- exit_while_loading:
-
-    if (!status)
-    {
-        g_object_unref(G_OBJECT(result));
-        result = NULL;
-    }
-
- quick_exit:
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = gestionnaire de conservations à manipuler.         *
-*                pbuf    = zone tampon à remplir. [OUT]                       *
-*                                                                             *
-*  Description : Sauvegarde le support d'une conservation d'objets en place.  *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_object_storage_store(GObjectStorage *storage, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-    rle_string str;                         /* Chaîne à conserver          */
-    size_t i;                               /* Boucle de parcours          */
-
-    result = extend_packed_buffer(pbuf, STORAGE_MAGIC STORAGE_NUMBER, 6, false);
-
-    if (result)
-    {
-        init_static_rle_string(&str, storage->hash);
-
-        result = pack_rle_string(&str, pbuf);
-
-        exit_rle_string(&str);
-
-    }
-
-    g_mutex_lock(&storage->mutex);
-
-    if (result)
-        result = g_type_memory_store_types(storage->tpmem, pbuf);
-
-    if (result)
-        result = pack_uleb128((uleb128_t []){ storage->count }, pbuf);
-
-    for (i = 0; i < storage->count && result; i++)
-        result = pack_storage_backend(&storage->backends[i], pbuf);
-
-    g_mutex_unlock(&storage->mutex);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = gestionnaire de conservations à compléter.         *
-*                name    = désignation d'un nouveau groupe d'objets.          *
-*                                                                             *
-*  Description : Retrouve l'encadrement pour un nouveau groupe d'objets.      *
-*                                                                             *
-*  Retour      : Informations liées à un groupe ou NULL en cas d'échec.       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static storage_backend_t *g_object_storage_find_backend(GObjectStorage *storage, const char *name)
-{
-    storage_backend_t *result;              /* Encadrement à retourner     */
-    size_t i;                               /* Boucle de parcours          */
-
-    assert(!g_mutex_trylock(&storage->mutex));
-
-    for (i = 0; i < storage->count; i++)
-        if (strcmp(storage->backends[i].name, name) == 0)
-            break;
-
-    if (i == storage->count)
-        result = NULL;
-    else
-        result = &storage->backends[i];
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = gestionnaire de conservations à compléter.         *
-*                name    = désignation d'un nouveau groupe d'objets.          *
-*                backend = support mis en place pour les enregistrements.     *
-*                                                                             *
-*  Description : Ajoute le support d'un nouveau groupe d'objets construits.   *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_object_storage_add_backend(GObjectStorage *storage, const char *name, storage_backend_t **backend)
-{
-    bool result;                            /* Bilan à retourner           */
-    char *prefix;                           /* Début de nom de fichier     */
-    char *filename;                         /* Chemin d'accès aux données  */
-    int fd;                                 /* Descripteur de flux ouvert  */
-
-    result = false;
-
-    *backend = NULL;
-
-    assert(!g_mutex_trylock(&storage->mutex));
-
-    if (g_object_storage_find_backend(storage, name) != NULL)
-        goto exit;
-
-    /* Préparatifs */
-
-    asprintf(&prefix, "%s-%s", storage->hash, name);
-
-    fd = make_tmp_file(prefix, "cache", &filename);
-
-    free(prefix);
-
-    if (fd == -1)
-        goto exit;
-
-    /* Inscription en bonne et due forme */
-
-    storage->backends = realloc(storage->backends, ++storage->count * sizeof(storage_backend_t));
-
-    *backend = &storage->backends[storage->count - 1];
-
-    (*backend)->name = strdup(name);
-
-    (*backend)->filename = filename;
-    (*backend)->fd = fd;
-
-    result = true;
-
- exit:
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = gestionnaire de conservations à compléter.         *
-*                pbuf    = zone tampon à lire.                                *
-*                                                                             *
-*  Description : Extrait d'un tampon des enregistrements spécifiques.         *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool g_object_storage_load_backend(GObjectStorage *storage, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-    rle_string str;                         /* Chaîne à conserver          */
-    bool status;                            /* Bilan de lecture de contenu */
-    storage_backend_t *backend;             /* Informations à intégrer     */
-    uleb128_t length;                       /* Taille des données à charger*/
-    off_t moved;                            /* Nouvelle position établie   */
-
-    result = false;
-
-    g_mutex_lock(&storage->mutex);
-
-    /* Récupération du nom et création du support */
-
-    setup_empty_rle_string(&str);
-
-    status = unpack_rle_string(&str, pbuf);
-    if (!status) goto exit;
-
-    if (get_rle_string(&str) == NULL)
-    {
-        exit_rle_string(&str);
-        goto exit;
-    }
-
-    status = g_object_storage_add_backend(storage, get_rle_string(&str), &backend);
-
-    exit_rle_string(&str);
-
-    if (!status) goto exit;
-
-    /* Récupération du contenu */
-
-    status = unpack_uleb128(&length, pbuf);
-    if (!status) goto exit;
-
-    status = safe_write(backend->fd, pbuf->data + pbuf->pos, length);
-    if (!status) goto exit;
-
-    advance_packed_buffer(pbuf, length);
-
-    moved = lseek(backend->fd, 0, SEEK_SET);
-    if (moved == ((off_t)-1))
-    {
-        LOG_ERROR_N("lseek");
-        goto exit;
-    }
-
-    result = true;
-
- exit:
-
-    g_mutex_unlock(&storage->mutex);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : backend = stockage des enregistrements spécifiques.          *
-*                pbuf    = zone tampon à remplir. [OUT]                       *
-*                                                                             *
-*  Description : Place dans un tampon les données liées à des enregistrements.*
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static bool pack_storage_backend(const storage_backend_t *backend, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-    rle_string str;                         /* Chaîne à conserver          */
-    bool status;                            /* Bilan de lecture de contenu */
-    off_t current;                          /* Position courante           */
-    off_t moved;                            /* Nouvelle position établie   */
-    void *data;                             /* Données à transférer        */
-
-    result = false;
-
-    /* Inscription du nom */
-
-    init_static_rle_string(&str, backend->name);
-
-    status = pack_rle_string(&str, pbuf);
-
-    exit_rle_string(&str);
-
-    if (!status) goto exit;
-
-    /* Inscription du contenu */
-
-    current = lseek(backend->fd, 0, SEEK_CUR);
-    if (current == ((off_t)-1))
-    {
-        LOG_ERROR_N("lseek");
-        goto exit;
-    }
-
-    moved = lseek(backend->fd, 0, SEEK_SET);
-    if (moved == ((off_t)-1))
-    {
-        LOG_ERROR_N("lseek");
-        goto exit;
-    }
-
-    data = malloc(current);
-    if (data == NULL)
-    {
-        LOG_ERROR_N("malloc");
-        goto restore;
-    }
-
-    status = safe_read(backend->fd, data, current);
-    if (!status) goto free_mem;
-
-    status = pack_uleb128((uleb128_t []){ current }, pbuf);
-    if (!status) goto free_mem;
-
-    status = extend_packed_buffer(pbuf, data, current, false);
-
- free_mem:
-
-    free(data);
-
- restore:
-
-    moved = lseek(backend->fd, current, SEEK_SET);
-    if (moved == ((off_t)-1))
-    {
-        LOG_ERROR_N("lseek");
-        goto exit;
-    }
-
-    result = status;
-
- exit:
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = gestionnaire à manipuler.                          *
-*                name    = désignation d'un nouveau groupe d'objets.          *
-*                pos     = tête de lecture avant écriture.                    *
-*                                                                             *
-*  Description : Charge un objet à partir de données rassemblées.             *
-*                                                                             *
-*  Retour      : Objet restauré en mémoire ou NULL en cas d'échec.            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GSerializableObject *g_object_storage_load_object(GObjectStorage *storage, const char *name, off64_t pos)
-{
-    GSerializableObject *result;            /* Instance à retourner        */
-    bool status;                            /* Bilan d'une opération       */
-    storage_backend_t *backend;             /* Informations à consulter    */
-    packed_buffer_t pbuf;                   /* Tampon des données à lire   */
-    off64_t new;                            /* Nouvelle position de lecture*/
-
-    result = NULL;
-
-    /* Chargement */
-
-    status = false;
-
-    g_mutex_lock(&storage->mutex);
-
-    backend = g_object_storage_find_backend(storage, name);
-
-    if (backend != NULL)
-    {
-        new = lseek64(backend->fd, pos, SEEK_SET);
-
-        if (new == pos)
-        {
-            init_packed_buffer(&pbuf);
-            status = read_packed_buffer(&pbuf, backend->fd);
-        }
-
-    }
-
-    g_mutex_unlock(&storage->mutex);
-
-    if (!status)
-        goto exit;
-
-    /* Phase de conversion */
-
-    result = G_SERIALIZABLE_OBJECT(g_type_memory_create_object(storage->tpmem, &pbuf));
-
-    if (result)
-    {
-        status = g_serializable_object_load(result, storage, &pbuf);
-
-        if (!status)
-            g_clear_object(&result);
-
-    }
-
-    exit_packed_buffer(&pbuf);
-
- exit:
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = gestionnaire à manipuler.                          *
-*                name    = désignation d'un nouveau groupe d'objets.          *
-*                pbuf    = zone tampon à parcourir.                           *
-*                                                                             *
-*  Description : Charge un objet interne à partir de données rassemblées.     *
-*                                                                             *
-*  Retour      : Objet restauré en mémoire ou NULL en cas d'échec.            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GSerializableObject *g_object_storage_unpack_object(GObjectStorage *storage, const char *name, packed_buffer_t *pbuf)
-{
-    GSerializableObject *result;            /* Instance à retourner        */
-    uint64_t pos;                           /* Localisation des données    */
-    bool status;                            /* Bilan d'une opération       */
-
-    result = NULL;
-
-    status = extract_packed_buffer(pbuf, &pos, sizeof(uint64_t), true);
-
-    if (status)
-        result = g_object_storage_load_object(storage, name, pos);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage  = gestionnaire à manipuler.                         *
-*                name     = désignation d'un nouveau groupe d'objets.         *
-*                pbuf     = zone tampon à parcourir.                          *
-*                expected = type d'objet attendu.                             *
-*                ...      = élément restauré ou NULL en cas d'échec. [OUT]    *
-*                                                                             *
-*  Description : Charge un objet interne à partir de données rassemblées.     *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_object_storage_unpack_object_2(GObjectStorage *storage, const char *name, packed_buffer_t *pbuf, GType expected, ...)
-{
-    bool result;                            /* Bilan d'une opération       */
-    uint64_t pos;                           /* Localisation des données    */
-    GSerializableObject *instance;          /* Objet rechargé à valider    */
-    va_list ap;                             /* Liste d'arguments variables */
-    void **object;                          /* Lieu d'enregistrement final */
-
-    result = extract_packed_buffer(pbuf, &pos, sizeof(uint64_t), true);
-
-    if (result)
-    {
-        if (pos == 0)
-            *object = NULL;
-
-        else
-        {
-            instance = g_object_storage_load_object(storage, name, pos);
-
-            result = G_TYPE_CHECK_INSTANCE_TYPE(instance, expected);
-
-            if (result)
-            {
-                va_start(ap, expected);
-
-                object = va_arg(ap, void **);
-
-                *object = instance;
-
-                va_end(ap);
-
-            }
-
-            else
-                g_clear_object(&instance);
-
-        }
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = gestionnaire à manipuler.                          *
-*                name    = désignation d'un nouveau groupe d'objets.          *
-*                object  = objet sérialisable à traiter.                      *
-*                pos     = tête de lecture avant écriture. [OUT]              *
-*                                                                             *
-*  Description : Sauvegarde un object sous forme de données rassemblées.      *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_object_storage_store_object(GObjectStorage *storage, const char *name, const GSerializableObject *object, off64_t *pos)
-{
-    bool result;                            /* Bilan à retourner           */
-    packed_buffer_t pbuf;                   /* Tampon des données à écrire */
-    storage_backend_t *backend;             /* Informations à consulter    */
-    off64_t tmp;                            /* Conservation éphémère       */
-
-    /* Phase de conversion */
-
-    init_packed_buffer(&pbuf);
-
-    result = g_type_memory_store_object_gtype(storage->tpmem, G_OBJECT(object), &pbuf);
-    if (!result) goto exit;
-
-    result = g_serializable_object_store(object, storage, &pbuf);
-    if (!result) goto exit;
-
-    /* Enregistrement */
-
-    result = false;
-
-    g_mutex_lock(&storage->mutex);
-
-    backend = g_object_storage_find_backend(storage, name);
-
-    if (backend == NULL)
-        g_object_storage_add_backend(storage, name, &backend);
-
-    if (backend != NULL)
-    {
-        if (pos == NULL)
-            pos = &tmp;
-
-        *pos = lseek64(backend->fd, 0, SEEK_CUR);
-
-        if (*pos != (off64_t)-1)
-            result = write_packed_buffer(&pbuf, backend->fd);
-
-    }
-
-    g_mutex_unlock(&storage->mutex);
-
-    /* Sortie propre */
-
- exit:
-
-    exit_packed_buffer(&pbuf);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : storage = gestionnaire à manipuler.                          *
-*                name    = désignation d'un nouveau groupe d'objets.          *
-*                pbuf    = zone tampon à remplir.                             *
-*                                                                             *
-*  Description : Sauvegarde un object interne sous forme de données.          *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_object_storage_pack_object(GObjectStorage *storage, const char *name, const GSerializableObject *object, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-    off64_t pos;                            /* Localisation des données    */
-
-    if (object == NULL)
-        result = extend_packed_buffer(pbuf, (uint64_t []){ 0 }, sizeof(uint64_t), true);
-
-    else
-    {
-        result = g_object_storage_store_object(storage, name, object, &pos);
-
-        if (result)
-            result = extend_packed_buffer(pbuf, (uint64_t []){ pos }, sizeof(uint64_t), true);
-
-    }
-
-    return result;
-
-}
diff --git a/src/analysis/storage/storage.h b/src/analysis/storage/storage.h
deleted file mode 100644
index cc0caad..0000000
--- a/src/analysis/storage/storage.h
+++ /dev/null
@@ -1,89 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * storage.h - prototypes pour la conservation sur disque d'objets construits
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_STORAGE_STORAGE_H
-#define _ANALYSIS_STORAGE_STORAGE_H
-
-
-#include <glib-object.h>
-#include <stdbool.h>
-
-
-#include "serialize.h"
-#include "tpmem.h"
-
-
-
-#define G_TYPE_OBJECT_STORAGE            g_object_storage_get_type()
-#define G_OBJECT_STORAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_OBJECT_STORAGE, GObjectStorage))
-#define G_IS_OBJECT_STORAGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_OBJECT_STORAGE))
-#define G_OBJECT_STORAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_OBJECT_STORAGE, GObjectStorageClass))
-#define G_IS_OBJECT_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_OBJECT_STORAGE))
-#define G_OBJECT_STORAGE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_OBJECT_STORAGE, GObjectStorageClass))
-
-
-/* Définition d'une conservation d'objets construits (instance) */
-typedef struct _GObjectStorage GObjectStorage;
-
-/* Définition d'une conservation d'objets construits (classe) */
-typedef struct _GObjectStorageClass GObjectStorageClass;
-
-
-/* Indique le type défini pour une conservation d'objets construits. */
-GType g_object_storage_get_type(void);
-
-/* Crée le support d'une conservation d'objets en place. */
-GObjectStorage *g_object_storage_new(const char *);
-
-#define get_storage_linked_format(s)                            \
-    ({                                                          \
-        void*__result;                                          \
-        __result = g_object_get_data(G_OBJECT(s), "format");    \
-        g_object_ref(G_OBJECT(__result));                       \
-        __result;                                               \
-    })
-
-/* Charge le support d'une conservation d'objets en place. */
-GObjectStorage *g_object_storage_load(packed_buffer_t *);
-
-/* Sauvegarde le support d'une conservation d'objets en place. */
-bool g_object_storage_store(GObjectStorage *, packed_buffer_t *);
-
-/* Charge un objet à partir de données rassemblées. */
-GSerializableObject *g_object_storage_load_object(GObjectStorage *, const char *, off64_t);
-
-/* Charge un objet interne à partir de données rassemblées. */
-GSerializableObject *g_object_storage_unpack_object(GObjectStorage *, const char *, packed_buffer_t *);
-
-/* Sauvegarde un object sous forme de données rassemblées. */
-bool g_object_storage_store_object(GObjectStorage *, const char *, const GSerializableObject *, off64_t *);
-
-/* Charge un objet interne à partir de données rassemblées. */
-bool g_object_storage_unpack_object_2(GObjectStorage *, const char *, packed_buffer_t *, GType, ...);
-
-/* Sauvegarde un object interne sous forme de données. */
-bool g_object_storage_pack_object(GObjectStorage *, const char *, const GSerializableObject *, packed_buffer_t *);
-
-
-
-#endif  /* _ANALYSIS_STORAGE_STORAGE_H */
diff --git a/src/analysis/storage/tpmem.c b/src/analysis/storage/tpmem.c
deleted file mode 100644
index 0703aeb..0000000
--- a/src/analysis/storage/tpmem.c
+++ /dev/null
@@ -1,429 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * tpmem.c - mémorisation des types d'objets mis en cache
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "tpmem.h"
-
-
-#include <assert.h>
-#include <stdint.h>
-
-
-#include "../db/misc/rlestr.h"
-#include "../../arch/operands/target.h"
-#include "../../core/logs.h"
-
-
-
-/* Conservation d'une référence sur un type */
-typedef struct _gtype_ref_info_t
-{
-    GType gtype;                            /* Type pour la GLib           */
-    gpointer gclass;                        /* Lien vers sa classe         */
-
-    /**
-     * La GLib n'est pas très claire sur la taille de GType :
-     *
-     *    #if     GLIB_SIZEOF_SIZE_T != GLIB_SIZEOF_LONG || !defined __cplusplus
-     *    typedef gsize                           GType;
-     *    #else   // for historic reasons, C++ links against gulong GTypes
-     *    typedef gulong                          GType;
-     *    #endif
-     *
-     * Et :
-     *
-     *    typedef unsigned $glib_size_type_define gsize;
-     *
-     * On prend donc le parti de conserver ces types sous forme de valeurs 64 bits
-     * lors des enregistrements.
-     */
-
-} gtype_ref_info_t;
-
-/* Définition d'une mémoire de types d'objets (instance) */
-struct _GTypeMemory
-{
-    GObject parent;                         /* A laisser en premier        */
-
-    gtype_ref_info_t *gtypes;               /* Types des objets reconnus   */
-    size_t count;                           /* Quantité de ces objets      */
-    GMutex mutex;                           /* Contrôle d'accès à la liste */
-
-};
-
-/* Définition d'une mémoire de types d'objets (classe) */
-struct _GTypeMemoryClass
-{
-    GObjectClass parent;                    /* A laisser en premier        */
-
-};
-
-
-/* Initialise la classe des mémoires de types d'objets. */
-static void g_type_memory_class_init(GTypeMemoryClass *);
-
-/* Initialise une instance de mémoire de types d'objets. */
-static void g_type_memory_init(GTypeMemory *);
-
-/* Supprime toutes les références externes. */
-static void g_type_memory_dispose(GTypeMemory *);
-
-/* Procède à la libération totale de la mémoire. */
-static void g_type_memory_finalize(GTypeMemory *);
-
-
-
-/* Indique le type défini pour une mémoire de types d'objets. */
-G_DEFINE_TYPE(GTypeMemory, g_type_memory, G_TYPE_OBJECT);
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : klass = classe à initialiser.                                *
-*                                                                             *
-*  Description : Initialise la classe des mémoires de types d'objets.         *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_type_memory_class_init(GTypeMemoryClass *klass)
-{
-    GObjectClass *object;                   /* Autre version de la classe  */
-
-    object = G_OBJECT_CLASS(klass);
-
-    object->dispose = (GObjectFinalizeFunc/* ! */)g_type_memory_dispose;
-    object->finalize = (GObjectFinalizeFunc)g_type_memory_finalize;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : tpmem = instance à initialiser.                              *
-*                                                                             *
-*  Description : Initialise une instance de mémoire de types d'objets.        *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_type_memory_init(GTypeMemory *tpmem)
-{
-    tpmem->gtypes = NULL;
-    tpmem->count = 0;
-    g_mutex_init(&tpmem->mutex);
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : tpmem = instance d'objet GLib à traiter.                     *
-*                                                                             *
-*  Description : Supprime toutes les références externes.                     *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_type_memory_dispose(GTypeMemory *tpmem)
-{
-    uint64_t i;                             /* Boucle de parcours          */
-
-    g_mutex_lock(&tpmem->mutex);
-
-    for (i = 0; i < tpmem->count; i++)
-        if (tpmem->gtypes[i].gclass != NULL)
-            g_type_class_unref(tpmem->gtypes[i].gclass);
-
-    g_mutex_unlock(&tpmem->mutex);
-
-    g_mutex_clear(&tpmem->mutex);
-
-    G_OBJECT_CLASS(g_type_memory_parent_class)->dispose(G_OBJECT(tpmem));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : tpmem = instance d'objet GLib à traiter.                     *
-*                                                                             *
-*  Description : Procède à la libération totale de la mémoire.                *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void g_type_memory_finalize(GTypeMemory *tpmem)
-{
-    if (tpmem->gtypes != NULL)
-        free(tpmem->gtypes);
-
-    G_OBJECT_CLASS(g_type_memory_parent_class)->finalize(G_OBJECT(tpmem));
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : -                                                            *
-*                                                                             *
-*  Description : Crée une mémoire pour types d'objets.                        *
-*                                                                             *
-*  Retour      : Instance mise en place.                                      *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GTypeMemory *g_type_memory_new(void)
-{
-    GTypeMemory *result;                    /* Structure à retourner       */
-
-    result = g_object_new(G_TYPE_TYPE_MEMORY, NULL);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : tpmem = mémoire à compléter.                                 *
-*                pbuf  = zone tampon à lire.                                  *
-*                                                                             *
-*  Description : Apprend tous les types mémorisés dans un tampon.             *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_type_memory_load_types(GTypeMemory *tpmem, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à enregistrer         */
-    uleb128_t count;                        /* Nombre d'éléments détectés  */
-    uleb128_t i;                            /* Boucle de parcours          */
-    rle_string str;                         /* Chaîne à charger            */
-
-    result = unpack_uleb128(&count, pbuf);
-
-    if (result)
-    {
-        g_mutex_lock(&tpmem->mutex);
-
-        tpmem->count = count;
-
-        assert(tpmem->gtypes == NULL);
-        tpmem->gtypes = calloc(count, sizeof(gtype_ref_info_t));
-
-        setup_empty_rle_string(&str);
-
-        for (i = 0; i < tpmem->count && result; i++)
-        {
-            result = unpack_rle_string(&str, pbuf);
-            if (!result) break;
-
-            if (get_rle_string(&str) == NULL)
-            {
-                exit_rle_string(&str);
-                break;
-            }
-
-            tpmem->gtypes[i].gtype = g_type_from_name(get_rle_string(&str));
-            result = (tpmem->gtypes[i].gtype != 0);
-
-            if (!result)
-                log_variadic_message(LMT_ERROR, "Unknown type: '%s'", get_rle_string(&str));
-
-            else
-                tpmem->gtypes[i].gclass = g_type_class_ref(tpmem->gtypes[i].gtype);
-
-            exit_rle_string(&str);
-
-        }
-
-    }
-
-    g_mutex_unlock(&tpmem->mutex);
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : tpmem = mémoire à manipuler.                                 *
-*                pbuf  = zone tampon à venir lire.                            *
-*                                                                             *
-*  Description : Crée une nouvelle instance d'objet à partir de son type.     *
-*                                                                             *
-*  Retour      : Instance issue de l'opération ou NULL.                       *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-GObject *g_type_memory_create_object(GTypeMemory *tpmem, packed_buffer_t *pbuf)
-{
-    GObject *result;                        /* Nouvelle instance à renvoyer*/
-    uleb128_t index;                        /* Indice du point d'insertion */
-    bool status;                            /* Bilan d'une récupération    */
-
-    result = NULL;
-
-    status = unpack_uleb128(&index, pbuf);
-
-    if (status)
-    {
-        g_mutex_lock(&tpmem->mutex);
-
-        if (index < tpmem->count)
-            result = g_object_new(tpmem->gtypes[index].gtype, NULL);
-
-        g_mutex_unlock(&tpmem->mutex);
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : tpmem = mémoire à manipuler.                                 *
-*                obj   = instance dont le type est à mémoriser.               *
-*                pbuf  = zone tampon à remplir. [OUT]                         *
-*                                                                             *
-*  Description : Sauvegarde le type d'un objet instancié.                     *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_type_memory_store_object_gtype(GTypeMemory *tpmem, GObject *obj, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à retourner           */
-    GType gtype;                            /* Type à enregistrer          */
-    size_t index;                           /* Indice du point d'insertion */
-
-    gtype = G_TYPE_FROM_INSTANCE(obj);
-
-    /**
-     * Pour quelques explications sur l'esquive suivante, se rapporter aux
-     * commentaires de g_target_operand_unserialize().
-     *
-     * Dans la situation présente, on ne doit pas enregistrer le type dans le tampon,
-     * car l'opérande va relancer l'opération entière (avec un opérande temporaire),
-     * ce qui conduirait à l'enregistrement de deux types successifs dans les données.
-     */
-
-    if (gtype == G_TYPE_TARGET_OPERAND)
-        result = true;
-
-    else
-    {
-        g_mutex_lock(&tpmem->mutex);
-
-        for (index = 0; index < tpmem->count; index++)
-            if (tpmem->gtypes[index].gtype == gtype)
-                break;
-
-        if (index == tpmem->count)
-        {
-            tpmem->gtypes = realloc(tpmem->gtypes, ++tpmem->count * sizeof(gtype_ref_info_t));
-
-            assert(tpmem->count > 0);
-
-            tpmem->gtypes[index].gtype = gtype;
-            tpmem->gtypes[index].gclass = g_type_class_ref(gtype);
-
-        }
-
-        g_mutex_unlock(&tpmem->mutex);
-
-        result = pack_uleb128((uleb128_t []){ index }, pbuf);
-
-    }
-
-    return result;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : tpmem = mémoire à consulter.                                 *
-*                pbuf  = zone tampon à remplir. [OUT]                         *
-*                                                                             *
-*  Description : Enregistre tous les types mémorisés dans un tampon.          *
-*                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-bool g_type_memory_store_types(GTypeMemory *tpmem, packed_buffer_t *pbuf)
-{
-    bool result;                            /* Bilan à enregistrer         */
-    uint64_t i;                             /* Boucle de parcours          */
-    const gchar *name;                      /* Désignation d'un type       */
-    rle_string str;                         /* Chaîne à conserver          */
-
-    g_mutex_lock(&tpmem->mutex);
-
-    result = pack_uleb128((uleb128_t []){ tpmem->count }, pbuf);
-
-    for (i = 0; i < tpmem->count && result; i++)
-    {
-        name = g_type_name(tpmem->gtypes[i].gtype);
-
-        init_static_rle_string(&str, name);
-
-        result = pack_rle_string(&str, pbuf);
-
-        exit_rle_string(&str);
-
-    }
-
-    g_mutex_unlock(&tpmem->mutex);
-
-    return result;
-
-}
diff --git a/src/analysis/storage/tpmem.h b/src/analysis/storage/tpmem.h
deleted file mode 100644
index 34cbde6..0000000
--- a/src/analysis/storage/tpmem.h
+++ /dev/null
@@ -1,70 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * tpmem.h - prototypes pour la mémorisation des types d'objets mis en cache
- *
- * Copyright (C) 2020 Cyrille Bagard
- *
- *  This file is part of Chrysalide.
- *
- *  Chrysalide is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  Chrysalide is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#ifndef _ANALYSIS_STORAGE_TPMEM_H
-#define _ANALYSIS_STORAGE_TPMEM_H
-
-
-#include <glib-object.h>
-
-
-#include "../../common/packed.h"
-
-
-
-#define G_TYPE_TYPE_MEMORY            g_type_memory_get_type()
-#define G_TYPE_MEMORY(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TYPE_MEMORY, GTypeMemory))
-#define G_IS_TYPE_MEMORY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TYPE_MEMORY))
-#define G_TYPE_MEMORY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_TYPE_MEMORY, GTypeMemoryClass))
-#define G_IS_TYPE_MEMORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_TYPE_MEMORY))
-#define G_TYPE_MEMORY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_TYPE_MEMORY, GTypeMemoryClass))
-
-
-/* Définition d'une mémoire de types d'objets (instance) */
-typedef struct _GTypeMemory GTypeMemory;
-
-/* Définition d'une mémoire de types d'objets (classe) */
-typedef struct _GTypeMemoryClass GTypeMemoryClass;
-
-
-/* Indique le type défini pour une mémoire de types d'objets. */
-GType g_type_memory_get_type(void);
-
-/* Crée une mémoire pour types d'objets. */
-GTypeMemory *g_type_memory_new(void);
-
-/* Apprend tous les types mémorisés dans un tampon. */
-bool g_type_memory_load_types(GTypeMemory *, packed_buffer_t *);
-
-/* Crée une nouvelle instance d'objet à partir de son type. */
-GObject *g_type_memory_create_object(GTypeMemory *, packed_buffer_t *);
-
-/* Sauvegarde le type d'un objet instancié. */
-bool g_type_memory_store_object_gtype(GTypeMemory *, GObject *, packed_buffer_t *);
-
-/* Enregistre tous les types mémorisés dans un tampon. */
-bool g_type_memory_store_types(GTypeMemory *, packed_buffer_t *);
-
-
-
-#endif  /* _ANALYSIS_STORAGE_TPMEM_H */
diff --git a/src/glibext/serialize-int.h b/src/glibext/serialize-int.h
new file mode 100644
index 0000000..de8d3e3
--- /dev/null
+++ b/src/glibext/serialize-int.h
@@ -0,0 +1,58 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * serialize-int.h - définitions internes propres aux objets entreposables dans un cache
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_STORAGE_SERIALIZE_INT_H
+#define _ANALYSIS_STORAGE_SERIALIZE_INT_H
+
+
+#include "serialize.h"
+
+
+#include "storage.h"
+
+
+
+/* Charge un objet depuis une mémoire tampon. */
+typedef bool (* load_serializable_object_cb) (GSerializableObject *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un objet dans une mémoire tampon. */
+typedef bool (* store_serializable_object_cb) (const GSerializableObject *, GObjectStorage *, packed_buffer_t *);
+
+
+/* Intermédiaire pour la mise en cache d'objet (interface) */
+struct _GSerializableObjectIface
+{
+    GTypeInterface base_iface;              /* A laisser en premier        */
+
+    load_serializable_object_cb load;       /* Chargement                  */
+    store_serializable_object_cb store;     /* Enregistrement              */
+
+};
+
+
+/* Redéfinition */
+typedef GSerializableObjectIface GSerializableObjectInterface;
+
+
+
+#endif  /* _ANALYSIS_STORAGE_SERIALIZE_INT_H */
diff --git a/src/glibext/serialize.c b/src/glibext/serialize.c
new file mode 100644
index 0000000..d1b0502
--- /dev/null
+++ b/src/glibext/serialize.c
@@ -0,0 +1,111 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * serialize.h - objets entreposables dans un cache
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "serialize.h"
+
+
+#include "serialize-int.h"
+
+
+
+/* Procède à l'initialisation de l'interface de mise en cache. */
+static void g_serializable_object_default_init(GSerializableObjectInterface *);
+
+
+
+/* Détermine le type d'une interface pour la mise en cache d'objet. */
+G_DEFINE_INTERFACE(GSerializableObject, g_serializable_object, G_TYPE_OBJECT)
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : iface = interface GLib à initialiser.                        *
+*                                                                             *
+*  Description : Procède à l'initialisation de l'interface de mise en cache.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_serializable_object_default_init(GSerializableObjectInterface *iface)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : object  = élément GLib à constuire.                          *
+*                storage = conservateur de données à manipuler ou NULL.       *
+*                pbuf    = zone tampon à lire.                                *
+*                                                                             *
+*  Description : Charge un objet depuis une mémoire tampon.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_serializable_object_load(GSerializableObject *object, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+    GSerializableObjectIface *iface;        /* Interface utilisée          */
+
+    iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object);
+
+    result = iface->load(object, storage, pbuf);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : object  = élément GLib à consulter.                          *
+*                storage = conservateur de données à manipuler ou NULL.       *
+*                pbuf    = zone tampon à remplir.                             *
+*                                                                             *
+*  Description : Sauvegarde un objet dans une mémoire tampon.                 *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_serializable_object_store(const GSerializableObject *object, GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+    GSerializableObjectIface *iface;        /* Interface utilisée          */
+
+    iface = G_SERIALIZABLE_OBJECT_GET_IFACE(object);
+
+    result = iface->store(object, storage, pbuf);
+
+    return result;
+
+}
diff --git a/src/glibext/serialize.h b/src/glibext/serialize.h
new file mode 100644
index 0000000..93a4496
--- /dev/null
+++ b/src/glibext/serialize.h
@@ -0,0 +1,64 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * serialize.h - prototypes pour les objets entreposables dans un cache
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Chrysalide.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_STORAGE_SERIALIZE_H
+#define _ANALYSIS_STORAGE_SERIALIZE_H
+
+
+#include <glib-object.h>
+
+
+#include "../../common/packed.h"
+
+
+
+#define G_TYPE_SERIALIZABLE_OBJECT             g_serializable_object_get_type()
+#define G_SERIALIZABLE_OBJECT(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_SERIALIZABLE_OBJECT, GSerializableObject))
+#define G_SERIALIZABLE_OBJECT_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_SERIALIZABLE_OBJECT, GSerializableObjectIface))
+#define G_IS_SERIALIZABLE_OBJECT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_SERIALIZABLE_OBJECT))
+#define G_IS_SERIALIZABLE_OBJECT_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_SERIALIZABLE_OBJECT))
+#define G_SERIALIZABLE_OBJECT_GET_IFACE(inst)  (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_SERIALIZABLE_OBJECT, GSerializableObjectIface))
+
+
+/* Intermédiaire pour la mise en cache d'objet (coquille vide) */
+typedef struct _GSerializableObject GSerializableObject;
+
+/* Intermédiaire pour la mise en cache d'objet (interface) */
+typedef struct _GSerializableObjectIface GSerializableObjectIface;
+
+
+/* Détermine le type d'une interface pour la mise en cache d'objet. */
+GType g_serializable_object_get_type(void) G_GNUC_CONST;
+
+/* storage.h : définition d'une conservation d'objets construits */
+typedef struct _GObjectStorage GObjectStorage;
+
+/* Charge un objet depuis une mémoire tampon. */
+bool g_serializable_object_load(GSerializableObject *, GObjectStorage *, packed_buffer_t *);
+
+/* Sauvegarde un objet dans une mémoire tampon. */
+bool g_serializable_object_store(const GSerializableObject *, GObjectStorage *, packed_buffer_t *);
+
+
+
+#endif  /* _ANALYSIS_STORAGE_SERIALIZE_H */
diff --git a/src/glibext/storage-int.h b/src/glibext/storage-int.h
new file mode 100644
index 0000000..4883aa8
--- /dev/null
+++ b/src/glibext/storage-int.h
@@ -0,0 +1,66 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * storage.h - prototypes internes pour la conservation sur disque d'objets construits
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_STORAGE_STORAGE_INT_H
+#define _ANALYSIS_STORAGE_STORAGE_INT_H
+
+
+#include "storage.h"
+
+
+
+/* Gestion d'enregistrements spécifiques */
+typedef struct _storage_backend_t
+{
+    char *name;                             /* Désignation du groupe       */
+
+    char *filename;                         /* Nom du fichier associé      */
+    int fd;                                 /* Flux d'accès correspondant  */
+
+} storage_backend_t;
+
+/* Définition d'une conservation d'objets construits (instance) */
+struct _GObjectStorage
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    GTypeMemory *tpmem;                     /* Mémorisation de types       */
+
+    char *hash;                             /* Empreinte du contenu        */
+
+    storage_backend_t *backends;            /* Gestionnaires existants     */
+    size_t count;                           /* Quantité de gestionnaires   */
+    GMutex mutex;                           /* Contrôle d'accès à la liste */
+
+};
+
+/* Définition d'une conservation d'objets construits (classe) */
+struct _GObjectStorageClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+
+#endif  /* _ANALYSIS_STORAGE_STORAGE_INT_H */
diff --git a/src/glibext/storage.c b/src/glibext/storage.c
new file mode 100644
index 0000000..610a0f6
--- /dev/null
+++ b/src/glibext/storage.c
@@ -0,0 +1,867 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * storage.c - conservation hors mémoire d'objets choisis
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "storage.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+
+#include "storage-int.h"
+#include "../db/misc/rlestr.h"
+#include "../../common/io.h"
+#include "../../common/leb128.h"
+#include "../../common/pathname.h"
+#include "../../core/logs.h"
+
+
+
+#define STORAGE_MAGIC "CSTR"
+#define STORAGE_NUMBER "\x00\x01"
+
+
+/* Initialise la classe des conservations d'objets en place. */
+static void g_object_storage_class_init(GObjectStorageClass *);
+
+/* Initialise une instance de conservation d'objets en place. */
+static void g_object_storage_init(GObjectStorage *);
+
+/* Supprime toutes les références externes. */
+static void g_object_storage_dispose(GObjectStorage *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_object_storage_finalize(GObjectStorage *);
+
+/* Retrouve l'encadrement pour un nouveau groupe d'objets. */
+static storage_backend_t *g_object_storage_find_backend(GObjectStorage *, const char *);
+
+/* Ajoute le support d'un nouveau groupe d'objets construits. */
+static bool g_object_storage_add_backend(GObjectStorage *, const char *, storage_backend_t **);
+
+/* Extrait d'un tampon des enregistrements spécifiques. */
+static bool g_object_storage_load_backend(GObjectStorage *, packed_buffer_t *);
+
+/* Place dans un tampon les données liées à des enregistrements. */
+static bool pack_storage_backend(const storage_backend_t *, packed_buffer_t *);
+
+
+
+/* Indique le type défini pour une conservation d'objets construits. */
+G_DEFINE_TYPE(GObjectStorage, g_object_storage, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des conservations d'objets en place.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_object_storage_class_init(GObjectStorageClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_object_storage_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_object_storage_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise une instance de conservation d'objets en place.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_object_storage_init(GObjectStorage *storage)
+{
+    storage->tpmem = g_type_memory_new();
+
+    storage->hash = NULL;
+
+    storage->backends = NULL;
+    storage->count = 0;
+    g_mutex_init(&storage->mutex);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_object_storage_dispose(GObjectStorage *storage)
+{
+    g_clear_object(&storage->tpmem);
+
+    G_OBJECT_CLASS(g_object_storage_parent_class)->dispose(G_OBJECT(storage));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_object_storage_finalize(GObjectStorage *storage)
+{
+    size_t i;                               /* Boucle de parcours          */
+    storage_backend_t *backend;             /* Gestionnaire à manipuler    */
+    int ret;                                /* Bilan d'un appel            */
+
+    g_mutex_lock(&storage->mutex);
+
+    for (i = 0; i < storage->count; i++)
+    {
+        backend = &storage->backends[i];
+
+        if (backend->fd != -1)
+            close(backend->fd);
+        else
+            assert(false);
+
+        ret = access(backend->filename, W_OK);
+        if (ret == 0)
+        {
+            ret = unlink(backend->filename);
+            if (ret != 0) LOG_ERROR_N("unlink");
+        }
+
+        free(backend->name);
+
+        free(backend->filename);
+
+    }
+
+    if (storage->backends != NULL)
+        free(storage->backends);
+
+    g_mutex_unlock(&storage->mutex);
+
+    g_mutex_clear(&storage->mutex);
+
+    if (storage->hash != NULL)
+        free(storage->hash);
+
+    G_OBJECT_CLASS(g_object_storage_parent_class)->finalize(G_OBJECT(storage));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : loaded = contenu binaire à associer.                         *
+*                                                                             *
+*  Description : Crée le support d'une conservation d'objets en place.        *
+*                                                                             *
+*  Retour      : Mécanismes mis en place.                                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GObjectStorage *g_object_storage_new(const char *hash)
+{
+    GObjectStorage *result;                 /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_OBJECT_STORAGE, NULL);
+
+    result->hash = strdup(hash);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : pbuf = zone tampon à lire.                                   *
+*                                                                             *
+*  Description : Charge le support d'une conservation d'objets en place.      *
+*                                                                             *
+*  Retour      : Gestionnaire de conservations construit ou NULL si erreur.   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GObjectStorage *g_object_storage_load(packed_buffer_t *pbuf)
+{
+    GObjectStorage *result;                 /* Structure à retourner       */
+    char header[6];                         /* Entête attendue des données */
+    bool status;                            /* Bilan d'une extraction      */
+    rle_string str;                         /* Chaîne à conserver          */
+    uleb128_t count;                        /* Nombre de groupes à charger */
+    uleb128_t i;                            /* Boucle de parcours          */
+
+    result = NULL;
+
+    status = extract_packed_buffer(pbuf, header, 6, false);
+    if (!status) goto quick_exit;
+
+    if (strncmp(header, STORAGE_MAGIC STORAGE_NUMBER, 6) != 0)
+        goto quick_exit;
+
+    setup_empty_rle_string(&str);
+
+    status = unpack_rle_string(&str, pbuf);
+    if (!status) goto quick_exit;
+
+    if (get_rle_string(&str) == NULL)
+    {
+        exit_rle_string(&str);
+        goto quick_exit;
+    }
+
+    result = g_object_new(G_TYPE_OBJECT_STORAGE, NULL);
+
+    result->hash = strdup(get_rle_string(&str));
+
+    exit_rle_string(&str);
+
+    status = g_type_memory_load_types(result->tpmem, pbuf);
+    if (!status) goto exit_while_loading;
+
+    status = unpack_uleb128(&count, pbuf);
+
+    for (i = 0; i < count && status; i++)
+        status = g_object_storage_load_backend(result, pbuf);
+
+ exit_while_loading:
+
+    if (!status)
+    {
+        g_object_unref(G_OBJECT(result));
+        result = NULL;
+    }
+
+ quick_exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = gestionnaire de conservations à manipuler.         *
+*                pbuf    = zone tampon à remplir. [OUT]                       *
+*                                                                             *
+*  Description : Sauvegarde le support d'une conservation d'objets en place.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_object_storage_store(GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+    rle_string str;                         /* Chaîne à conserver          */
+    size_t i;                               /* Boucle de parcours          */
+
+    result = extend_packed_buffer(pbuf, STORAGE_MAGIC STORAGE_NUMBER, 6, false);
+
+    if (result)
+    {
+        init_static_rle_string(&str, storage->hash);
+
+        result = pack_rle_string(&str, pbuf);
+
+        exit_rle_string(&str);
+
+    }
+
+    g_mutex_lock(&storage->mutex);
+
+    if (result)
+        result = g_type_memory_store_types(storage->tpmem, pbuf);
+
+    if (result)
+        result = pack_uleb128((uleb128_t []){ storage->count }, pbuf);
+
+    for (i = 0; i < storage->count && result; i++)
+        result = pack_storage_backend(&storage->backends[i], pbuf);
+
+    g_mutex_unlock(&storage->mutex);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = gestionnaire de conservations à compléter.         *
+*                name    = désignation d'un nouveau groupe d'objets.          *
+*                                                                             *
+*  Description : Retrouve l'encadrement pour un nouveau groupe d'objets.      *
+*                                                                             *
+*  Retour      : Informations liées à un groupe ou NULL en cas d'échec.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static storage_backend_t *g_object_storage_find_backend(GObjectStorage *storage, const char *name)
+{
+    storage_backend_t *result;              /* Encadrement à retourner     */
+    size_t i;                               /* Boucle de parcours          */
+
+    assert(!g_mutex_trylock(&storage->mutex));
+
+    for (i = 0; i < storage->count; i++)
+        if (strcmp(storage->backends[i].name, name) == 0)
+            break;
+
+    if (i == storage->count)
+        result = NULL;
+    else
+        result = &storage->backends[i];
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = gestionnaire de conservations à compléter.         *
+*                name    = désignation d'un nouveau groupe d'objets.          *
+*                backend = support mis en place pour les enregistrements.     *
+*                                                                             *
+*  Description : Ajoute le support d'un nouveau groupe d'objets construits.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_object_storage_add_backend(GObjectStorage *storage, const char *name, storage_backend_t **backend)
+{
+    bool result;                            /* Bilan à retourner           */
+    char *prefix;                           /* Début de nom de fichier     */
+    char *filename;                         /* Chemin d'accès aux données  */
+    int fd;                                 /* Descripteur de flux ouvert  */
+
+    result = false;
+
+    *backend = NULL;
+
+    assert(!g_mutex_trylock(&storage->mutex));
+
+    if (g_object_storage_find_backend(storage, name) != NULL)
+        goto exit;
+
+    /* Préparatifs */
+
+    asprintf(&prefix, "%s-%s", storage->hash, name);
+
+    fd = make_tmp_file(prefix, "cache", &filename);
+
+    free(prefix);
+
+    if (fd == -1)
+        goto exit;
+
+    /* Inscription en bonne et due forme */
+
+    storage->backends = realloc(storage->backends, ++storage->count * sizeof(storage_backend_t));
+
+    *backend = &storage->backends[storage->count - 1];
+
+    (*backend)->name = strdup(name);
+
+    (*backend)->filename = filename;
+    (*backend)->fd = fd;
+
+    result = true;
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = gestionnaire de conservations à compléter.         *
+*                pbuf    = zone tampon à lire.                                *
+*                                                                             *
+*  Description : Extrait d'un tampon des enregistrements spécifiques.         *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_object_storage_load_backend(GObjectStorage *storage, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+    rle_string str;                         /* Chaîne à conserver          */
+    bool status;                            /* Bilan de lecture de contenu */
+    storage_backend_t *backend;             /* Informations à intégrer     */
+    uleb128_t length;                       /* Taille des données à charger*/
+    off_t moved;                            /* Nouvelle position établie   */
+
+    result = false;
+
+    g_mutex_lock(&storage->mutex);
+
+    /* Récupération du nom et création du support */
+
+    setup_empty_rle_string(&str);
+
+    status = unpack_rle_string(&str, pbuf);
+    if (!status) goto exit;
+
+    if (get_rle_string(&str) == NULL)
+    {
+        exit_rle_string(&str);
+        goto exit;
+    }
+
+    status = g_object_storage_add_backend(storage, get_rle_string(&str), &backend);
+
+    exit_rle_string(&str);
+
+    if (!status) goto exit;
+
+    /* Récupération du contenu */
+
+    status = unpack_uleb128(&length, pbuf);
+    if (!status) goto exit;
+
+    status = safe_write(backend->fd, pbuf->data + pbuf->pos, length);
+    if (!status) goto exit;
+
+    advance_packed_buffer(pbuf, length);
+
+    moved = lseek(backend->fd, 0, SEEK_SET);
+    if (moved == ((off_t)-1))
+    {
+        LOG_ERROR_N("lseek");
+        goto exit;
+    }
+
+    result = true;
+
+ exit:
+
+    g_mutex_unlock(&storage->mutex);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : backend = stockage des enregistrements spécifiques.          *
+*                pbuf    = zone tampon à remplir. [OUT]                       *
+*                                                                             *
+*  Description : Place dans un tampon les données liées à des enregistrements.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool pack_storage_backend(const storage_backend_t *backend, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+    rle_string str;                         /* Chaîne à conserver          */
+    bool status;                            /* Bilan de lecture de contenu */
+    off_t current;                          /* Position courante           */
+    off_t moved;                            /* Nouvelle position établie   */
+    void *data;                             /* Données à transférer        */
+
+    result = false;
+
+    /* Inscription du nom */
+
+    init_static_rle_string(&str, backend->name);
+
+    status = pack_rle_string(&str, pbuf);
+
+    exit_rle_string(&str);
+
+    if (!status) goto exit;
+
+    /* Inscription du contenu */
+
+    current = lseek(backend->fd, 0, SEEK_CUR);
+    if (current == ((off_t)-1))
+    {
+        LOG_ERROR_N("lseek");
+        goto exit;
+    }
+
+    moved = lseek(backend->fd, 0, SEEK_SET);
+    if (moved == ((off_t)-1))
+    {
+        LOG_ERROR_N("lseek");
+        goto exit;
+    }
+
+    data = malloc(current);
+    if (data == NULL)
+    {
+        LOG_ERROR_N("malloc");
+        goto restore;
+    }
+
+    status = safe_read(backend->fd, data, current);
+    if (!status) goto free_mem;
+
+    status = pack_uleb128((uleb128_t []){ current }, pbuf);
+    if (!status) goto free_mem;
+
+    status = extend_packed_buffer(pbuf, data, current, false);
+
+ free_mem:
+
+    free(data);
+
+ restore:
+
+    moved = lseek(backend->fd, current, SEEK_SET);
+    if (moved == ((off_t)-1))
+    {
+        LOG_ERROR_N("lseek");
+        goto exit;
+    }
+
+    result = status;
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = gestionnaire à manipuler.                          *
+*                name    = désignation d'un nouveau groupe d'objets.          *
+*                pos     = tête de lecture avant écriture.                    *
+*                                                                             *
+*  Description : Charge un objet à partir de données rassemblées.             *
+*                                                                             *
+*  Retour      : Objet restauré en mémoire ou NULL en cas d'échec.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GSerializableObject *g_object_storage_load_object(GObjectStorage *storage, const char *name, off64_t pos)
+{
+    GSerializableObject *result;            /* Instance à retourner        */
+    bool status;                            /* Bilan d'une opération       */
+    storage_backend_t *backend;             /* Informations à consulter    */
+    packed_buffer_t pbuf;                   /* Tampon des données à lire   */
+    off64_t new;                            /* Nouvelle position de lecture*/
+
+    result = NULL;
+
+    /* Chargement */
+
+    status = false;
+
+    g_mutex_lock(&storage->mutex);
+
+    backend = g_object_storage_find_backend(storage, name);
+
+    if (backend != NULL)
+    {
+        new = lseek64(backend->fd, pos, SEEK_SET);
+
+        if (new == pos)
+        {
+            init_packed_buffer(&pbuf);
+            status = read_packed_buffer(&pbuf, backend->fd);
+        }
+
+    }
+
+    g_mutex_unlock(&storage->mutex);
+
+    if (!status)
+        goto exit;
+
+    /* Phase de conversion */
+
+    result = G_SERIALIZABLE_OBJECT(g_type_memory_create_object(storage->tpmem, &pbuf));
+
+    if (result)
+    {
+        status = g_serializable_object_load(result, storage, &pbuf);
+
+        if (!status)
+            g_clear_object(&result);
+
+    }
+
+    exit_packed_buffer(&pbuf);
+
+ exit:
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = gestionnaire à manipuler.                          *
+*                name    = désignation d'un nouveau groupe d'objets.          *
+*                pbuf    = zone tampon à parcourir.                           *
+*                                                                             *
+*  Description : Charge un objet interne à partir de données rassemblées.     *
+*                                                                             *
+*  Retour      : Objet restauré en mémoire ou NULL en cas d'échec.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GSerializableObject *g_object_storage_unpack_object(GObjectStorage *storage, const char *name, packed_buffer_t *pbuf)
+{
+    GSerializableObject *result;            /* Instance à retourner        */
+    uint64_t pos;                           /* Localisation des données    */
+    bool status;                            /* Bilan d'une opération       */
+
+    result = NULL;
+
+    status = extract_packed_buffer(pbuf, &pos, sizeof(uint64_t), true);
+
+    if (status)
+        result = g_object_storage_load_object(storage, name, pos);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage  = gestionnaire à manipuler.                         *
+*                name     = désignation d'un nouveau groupe d'objets.         *
+*                pbuf     = zone tampon à parcourir.                          *
+*                expected = type d'objet attendu.                             *
+*                ...      = élément restauré ou NULL en cas d'échec. [OUT]    *
+*                                                                             *
+*  Description : Charge un objet interne à partir de données rassemblées.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_object_storage_unpack_object_2(GObjectStorage *storage, const char *name, packed_buffer_t *pbuf, GType expected, ...)
+{
+    bool result;                            /* Bilan d'une opération       */
+    uint64_t pos;                           /* Localisation des données    */
+    GSerializableObject *instance;          /* Objet rechargé à valider    */
+    va_list ap;                             /* Liste d'arguments variables */
+    void **object;                          /* Lieu d'enregistrement final */
+
+    result = extract_packed_buffer(pbuf, &pos, sizeof(uint64_t), true);
+
+    if (result)
+    {
+        if (pos == 0)
+            *object = NULL;
+
+        else
+        {
+            instance = g_object_storage_load_object(storage, name, pos);
+
+            result = G_TYPE_CHECK_INSTANCE_TYPE(instance, expected);
+
+            if (result)
+            {
+                va_start(ap, expected);
+
+                object = va_arg(ap, void **);
+
+                *object = instance;
+
+                va_end(ap);
+
+            }
+
+            else
+                g_clear_object(&instance);
+
+        }
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = gestionnaire à manipuler.                          *
+*                name    = désignation d'un nouveau groupe d'objets.          *
+*                object  = objet sérialisable à traiter.                      *
+*                pos     = tête de lecture avant écriture. [OUT]              *
+*                                                                             *
+*  Description : Sauvegarde un object sous forme de données rassemblées.      *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_object_storage_store_object(GObjectStorage *storage, const char *name, const GSerializableObject *object, off64_t *pos)
+{
+    bool result;                            /* Bilan à retourner           */
+    packed_buffer_t pbuf;                   /* Tampon des données à écrire */
+    storage_backend_t *backend;             /* Informations à consulter    */
+    off64_t tmp;                            /* Conservation éphémère       */
+
+    /* Phase de conversion */
+
+    init_packed_buffer(&pbuf);
+
+    result = g_type_memory_store_object_gtype(storage->tpmem, G_OBJECT(object), &pbuf);
+    if (!result) goto exit;
+
+    result = g_serializable_object_store(object, storage, &pbuf);
+    if (!result) goto exit;
+
+    /* Enregistrement */
+
+    result = false;
+
+    g_mutex_lock(&storage->mutex);
+
+    backend = g_object_storage_find_backend(storage, name);
+
+    if (backend == NULL)
+        g_object_storage_add_backend(storage, name, &backend);
+
+    if (backend != NULL)
+    {
+        if (pos == NULL)
+            pos = &tmp;
+
+        *pos = lseek64(backend->fd, 0, SEEK_CUR);
+
+        if (*pos != (off64_t)-1)
+            result = write_packed_buffer(&pbuf, backend->fd);
+
+    }
+
+    g_mutex_unlock(&storage->mutex);
+
+    /* Sortie propre */
+
+ exit:
+
+    exit_packed_buffer(&pbuf);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : storage = gestionnaire à manipuler.                          *
+*                name    = désignation d'un nouveau groupe d'objets.          *
+*                pbuf    = zone tampon à remplir.                             *
+*                                                                             *
+*  Description : Sauvegarde un object interne sous forme de données.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_object_storage_pack_object(GObjectStorage *storage, const char *name, const GSerializableObject *object, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+    off64_t pos;                            /* Localisation des données    */
+
+    if (object == NULL)
+        result = extend_packed_buffer(pbuf, (uint64_t []){ 0 }, sizeof(uint64_t), true);
+
+    else
+    {
+        result = g_object_storage_store_object(storage, name, object, &pos);
+
+        if (result)
+            result = extend_packed_buffer(pbuf, (uint64_t []){ pos }, sizeof(uint64_t), true);
+
+    }
+
+    return result;
+
+}
diff --git a/src/glibext/storage.h b/src/glibext/storage.h
new file mode 100644
index 0000000..cc0caad
--- /dev/null
+++ b/src/glibext/storage.h
@@ -0,0 +1,89 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * storage.h - prototypes pour la conservation sur disque d'objets construits
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_STORAGE_STORAGE_H
+#define _ANALYSIS_STORAGE_STORAGE_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+#include "serialize.h"
+#include "tpmem.h"
+
+
+
+#define G_TYPE_OBJECT_STORAGE            g_object_storage_get_type()
+#define G_OBJECT_STORAGE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_OBJECT_STORAGE, GObjectStorage))
+#define G_IS_OBJECT_STORAGE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_OBJECT_STORAGE))
+#define G_OBJECT_STORAGE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_OBJECT_STORAGE, GObjectStorageClass))
+#define G_IS_OBJECT_STORAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_OBJECT_STORAGE))
+#define G_OBJECT_STORAGE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_OBJECT_STORAGE, GObjectStorageClass))
+
+
+/* Définition d'une conservation d'objets construits (instance) */
+typedef struct _GObjectStorage GObjectStorage;
+
+/* Définition d'une conservation d'objets construits (classe) */
+typedef struct _GObjectStorageClass GObjectStorageClass;
+
+
+/* Indique le type défini pour une conservation d'objets construits. */
+GType g_object_storage_get_type(void);
+
+/* Crée le support d'une conservation d'objets en place. */
+GObjectStorage *g_object_storage_new(const char *);
+
+#define get_storage_linked_format(s)                            \
+    ({                                                          \
+        void*__result;                                          \
+        __result = g_object_get_data(G_OBJECT(s), "format");    \
+        g_object_ref(G_OBJECT(__result));                       \
+        __result;                                               \
+    })
+
+/* Charge le support d'une conservation d'objets en place. */
+GObjectStorage *g_object_storage_load(packed_buffer_t *);
+
+/* Sauvegarde le support d'une conservation d'objets en place. */
+bool g_object_storage_store(GObjectStorage *, packed_buffer_t *);
+
+/* Charge un objet à partir de données rassemblées. */
+GSerializableObject *g_object_storage_load_object(GObjectStorage *, const char *, off64_t);
+
+/* Charge un objet interne à partir de données rassemblées. */
+GSerializableObject *g_object_storage_unpack_object(GObjectStorage *, const char *, packed_buffer_t *);
+
+/* Sauvegarde un object sous forme de données rassemblées. */
+bool g_object_storage_store_object(GObjectStorage *, const char *, const GSerializableObject *, off64_t *);
+
+/* Charge un objet interne à partir de données rassemblées. */
+bool g_object_storage_unpack_object_2(GObjectStorage *, const char *, packed_buffer_t *, GType, ...);
+
+/* Sauvegarde un object interne sous forme de données. */
+bool g_object_storage_pack_object(GObjectStorage *, const char *, const GSerializableObject *, packed_buffer_t *);
+
+
+
+#endif  /* _ANALYSIS_STORAGE_STORAGE_H */
diff --git a/src/glibext/tpmem.c b/src/glibext/tpmem.c
new file mode 100644
index 0000000..0703aeb
--- /dev/null
+++ b/src/glibext/tpmem.c
@@ -0,0 +1,429 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tpmem.c - mémorisation des types d'objets mis en cache
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "tpmem.h"
+
+
+#include <assert.h>
+#include <stdint.h>
+
+
+#include "../db/misc/rlestr.h"
+#include "../../arch/operands/target.h"
+#include "../../core/logs.h"
+
+
+
+/* Conservation d'une référence sur un type */
+typedef struct _gtype_ref_info_t
+{
+    GType gtype;                            /* Type pour la GLib           */
+    gpointer gclass;                        /* Lien vers sa classe         */
+
+    /**
+     * La GLib n'est pas très claire sur la taille de GType :
+     *
+     *    #if     GLIB_SIZEOF_SIZE_T != GLIB_SIZEOF_LONG || !defined __cplusplus
+     *    typedef gsize                           GType;
+     *    #else   // for historic reasons, C++ links against gulong GTypes
+     *    typedef gulong                          GType;
+     *    #endif
+     *
+     * Et :
+     *
+     *    typedef unsigned $glib_size_type_define gsize;
+     *
+     * On prend donc le parti de conserver ces types sous forme de valeurs 64 bits
+     * lors des enregistrements.
+     */
+
+} gtype_ref_info_t;
+
+/* Définition d'une mémoire de types d'objets (instance) */
+struct _GTypeMemory
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    gtype_ref_info_t *gtypes;               /* Types des objets reconnus   */
+    size_t count;                           /* Quantité de ces objets      */
+    GMutex mutex;                           /* Contrôle d'accès à la liste */
+
+};
+
+/* Définition d'une mémoire de types d'objets (classe) */
+struct _GTypeMemoryClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+};
+
+
+/* Initialise la classe des mémoires de types d'objets. */
+static void g_type_memory_class_init(GTypeMemoryClass *);
+
+/* Initialise une instance de mémoire de types d'objets. */
+static void g_type_memory_init(GTypeMemory *);
+
+/* Supprime toutes les références externes. */
+static void g_type_memory_dispose(GTypeMemory *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_type_memory_finalize(GTypeMemory *);
+
+
+
+/* Indique le type défini pour une mémoire de types d'objets. */
+G_DEFINE_TYPE(GTypeMemory, g_type_memory, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des mémoires de types d'objets.         *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_type_memory_class_init(GTypeMemoryClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_type_memory_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_type_memory_finalize;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tpmem = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance de mémoire de types d'objets.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_type_memory_init(GTypeMemory *tpmem)
+{
+    tpmem->gtypes = NULL;
+    tpmem->count = 0;
+    g_mutex_init(&tpmem->mutex);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tpmem = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_type_memory_dispose(GTypeMemory *tpmem)
+{
+    uint64_t i;                             /* Boucle de parcours          */
+
+    g_mutex_lock(&tpmem->mutex);
+
+    for (i = 0; i < tpmem->count; i++)
+        if (tpmem->gtypes[i].gclass != NULL)
+            g_type_class_unref(tpmem->gtypes[i].gclass);
+
+    g_mutex_unlock(&tpmem->mutex);
+
+    g_mutex_clear(&tpmem->mutex);
+
+    G_OBJECT_CLASS(g_type_memory_parent_class)->dispose(G_OBJECT(tpmem));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tpmem = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_type_memory_finalize(GTypeMemory *tpmem)
+{
+    if (tpmem->gtypes != NULL)
+        free(tpmem->gtypes);
+
+    G_OBJECT_CLASS(g_type_memory_parent_class)->finalize(G_OBJECT(tpmem));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Crée une mémoire pour types d'objets.                        *
+*                                                                             *
+*  Retour      : Instance mise en place.                                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GTypeMemory *g_type_memory_new(void)
+{
+    GTypeMemory *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_TYPE_MEMORY, NULL);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tpmem = mémoire à compléter.                                 *
+*                pbuf  = zone tampon à lire.                                  *
+*                                                                             *
+*  Description : Apprend tous les types mémorisés dans un tampon.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_type_memory_load_types(GTypeMemory *tpmem, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à enregistrer         */
+    uleb128_t count;                        /* Nombre d'éléments détectés  */
+    uleb128_t i;                            /* Boucle de parcours          */
+    rle_string str;                         /* Chaîne à charger            */
+
+    result = unpack_uleb128(&count, pbuf);
+
+    if (result)
+    {
+        g_mutex_lock(&tpmem->mutex);
+
+        tpmem->count = count;
+
+        assert(tpmem->gtypes == NULL);
+        tpmem->gtypes = calloc(count, sizeof(gtype_ref_info_t));
+
+        setup_empty_rle_string(&str);
+
+        for (i = 0; i < tpmem->count && result; i++)
+        {
+            result = unpack_rle_string(&str, pbuf);
+            if (!result) break;
+
+            if (get_rle_string(&str) == NULL)
+            {
+                exit_rle_string(&str);
+                break;
+            }
+
+            tpmem->gtypes[i].gtype = g_type_from_name(get_rle_string(&str));
+            result = (tpmem->gtypes[i].gtype != 0);
+
+            if (!result)
+                log_variadic_message(LMT_ERROR, "Unknown type: '%s'", get_rle_string(&str));
+
+            else
+                tpmem->gtypes[i].gclass = g_type_class_ref(tpmem->gtypes[i].gtype);
+
+            exit_rle_string(&str);
+
+        }
+
+    }
+
+    g_mutex_unlock(&tpmem->mutex);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tpmem = mémoire à manipuler.                                 *
+*                pbuf  = zone tampon à venir lire.                            *
+*                                                                             *
+*  Description : Crée une nouvelle instance d'objet à partir de son type.     *
+*                                                                             *
+*  Retour      : Instance issue de l'opération ou NULL.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GObject *g_type_memory_create_object(GTypeMemory *tpmem, packed_buffer_t *pbuf)
+{
+    GObject *result;                        /* Nouvelle instance à renvoyer*/
+    uleb128_t index;                        /* Indice du point d'insertion */
+    bool status;                            /* Bilan d'une récupération    */
+
+    result = NULL;
+
+    status = unpack_uleb128(&index, pbuf);
+
+    if (status)
+    {
+        g_mutex_lock(&tpmem->mutex);
+
+        if (index < tpmem->count)
+            result = g_object_new(tpmem->gtypes[index].gtype, NULL);
+
+        g_mutex_unlock(&tpmem->mutex);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tpmem = mémoire à manipuler.                                 *
+*                obj   = instance dont le type est à mémoriser.               *
+*                pbuf  = zone tampon à remplir. [OUT]                         *
+*                                                                             *
+*  Description : Sauvegarde le type d'un objet instancié.                     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_type_memory_store_object_gtype(GTypeMemory *tpmem, GObject *obj, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à retourner           */
+    GType gtype;                            /* Type à enregistrer          */
+    size_t index;                           /* Indice du point d'insertion */
+
+    gtype = G_TYPE_FROM_INSTANCE(obj);
+
+    /**
+     * Pour quelques explications sur l'esquive suivante, se rapporter aux
+     * commentaires de g_target_operand_unserialize().
+     *
+     * Dans la situation présente, on ne doit pas enregistrer le type dans le tampon,
+     * car l'opérande va relancer l'opération entière (avec un opérande temporaire),
+     * ce qui conduirait à l'enregistrement de deux types successifs dans les données.
+     */
+
+    if (gtype == G_TYPE_TARGET_OPERAND)
+        result = true;
+
+    else
+    {
+        g_mutex_lock(&tpmem->mutex);
+
+        for (index = 0; index < tpmem->count; index++)
+            if (tpmem->gtypes[index].gtype == gtype)
+                break;
+
+        if (index == tpmem->count)
+        {
+            tpmem->gtypes = realloc(tpmem->gtypes, ++tpmem->count * sizeof(gtype_ref_info_t));
+
+            assert(tpmem->count > 0);
+
+            tpmem->gtypes[index].gtype = gtype;
+            tpmem->gtypes[index].gclass = g_type_class_ref(gtype);
+
+        }
+
+        g_mutex_unlock(&tpmem->mutex);
+
+        result = pack_uleb128((uleb128_t []){ index }, pbuf);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : tpmem = mémoire à consulter.                                 *
+*                pbuf  = zone tampon à remplir. [OUT]                         *
+*                                                                             *
+*  Description : Enregistre tous les types mémorisés dans un tampon.          *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_type_memory_store_types(GTypeMemory *tpmem, packed_buffer_t *pbuf)
+{
+    bool result;                            /* Bilan à enregistrer         */
+    uint64_t i;                             /* Boucle de parcours          */
+    const gchar *name;                      /* Désignation d'un type       */
+    rle_string str;                         /* Chaîne à conserver          */
+
+    g_mutex_lock(&tpmem->mutex);
+
+    result = pack_uleb128((uleb128_t []){ tpmem->count }, pbuf);
+
+    for (i = 0; i < tpmem->count && result; i++)
+    {
+        name = g_type_name(tpmem->gtypes[i].gtype);
+
+        init_static_rle_string(&str, name);
+
+        result = pack_rle_string(&str, pbuf);
+
+        exit_rle_string(&str);
+
+    }
+
+    g_mutex_unlock(&tpmem->mutex);
+
+    return result;
+
+}
diff --git a/src/glibext/tpmem.h b/src/glibext/tpmem.h
new file mode 100644
index 0000000..34cbde6
--- /dev/null
+++ b/src/glibext/tpmem.h
@@ -0,0 +1,70 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tpmem.h - prototypes pour la mémorisation des types d'objets mis en cache
+ *
+ * Copyright (C) 2020 Cyrille Bagard
+ *
+ *  This file is part of Chrysalide.
+ *
+ *  Chrysalide is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  Chrysalide is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ANALYSIS_STORAGE_TPMEM_H
+#define _ANALYSIS_STORAGE_TPMEM_H
+
+
+#include <glib-object.h>
+
+
+#include "../../common/packed.h"
+
+
+
+#define G_TYPE_TYPE_MEMORY            g_type_memory_get_type()
+#define G_TYPE_MEMORY(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_TYPE_MEMORY, GTypeMemory))
+#define G_IS_TYPE_MEMORY(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_TYPE_MEMORY))
+#define G_TYPE_MEMORY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_TYPE_MEMORY, GTypeMemoryClass))
+#define G_IS_TYPE_MEMORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_TYPE_MEMORY))
+#define G_TYPE_MEMORY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_TYPE_MEMORY, GTypeMemoryClass))
+
+
+/* Définition d'une mémoire de types d'objets (instance) */
+typedef struct _GTypeMemory GTypeMemory;
+
+/* Définition d'une mémoire de types d'objets (classe) */
+typedef struct _GTypeMemoryClass GTypeMemoryClass;
+
+
+/* Indique le type défini pour une mémoire de types d'objets. */
+GType g_type_memory_get_type(void);
+
+/* Crée une mémoire pour types d'objets. */
+GTypeMemory *g_type_memory_new(void);
+
+/* Apprend tous les types mémorisés dans un tampon. */
+bool g_type_memory_load_types(GTypeMemory *, packed_buffer_t *);
+
+/* Crée une nouvelle instance d'objet à partir de son type. */
+GObject *g_type_memory_create_object(GTypeMemory *, packed_buffer_t *);
+
+/* Sauvegarde le type d'un objet instancié. */
+bool g_type_memory_store_object_gtype(GTypeMemory *, GObject *, packed_buffer_t *);
+
+/* Enregistre tous les types mémorisés dans un tampon. */
+bool g_type_memory_store_types(GTypeMemory *, packed_buffer_t *);
+
+
+
+#endif  /* _ANALYSIS_STORAGE_TPMEM_H */
diff --git a/tests/analysis/storage/storage.py b/tests/analysis/storage/storage.py
deleted file mode 100644
index 612d500..0000000
--- a/tests/analysis/storage/storage.py
+++ /dev/null
@@ -1,81 +0,0 @@
-
-from chrysacase import ChrysalideTestCase
-from pychrysalide import core
-from pychrysalide.analysis.contents import FileContent
-from pychrysalide.analysis.storage import ObjectStorage
-from pychrysalide.common import PackedBuffer
-import os
-import shutil
-import tempfile
-
-
-class TestObjectStorage(ChrysalideTestCase):
-    """TestCase for analysis.storage."""
-
-    @classmethod
-    def setUpClass(cls):
-
-        super(TestObjectStorage, cls).setUpClass()
-
-        cls._tmp_path = tempfile.mkdtemp()
-
-        config = core.get_main_configuration()
-        param = config.search(core.MainParameterKeys.TMPDIR)
-
-        cls._old_tmpdir = param.value
-        param.value = cls._tmp_path
-
-        cls.log('Using temporary directory "%s"' % cls._tmp_path)
-
-
-    @classmethod
-    def tearDownClass(cls):
-
-        super(TestObjectStorage, cls).tearDownClass()
-
-        config = core.get_main_configuration()
-        param = config.search(core.MainParameterKeys.TMPDIR)
-
-        param.value = cls._old_tmpdir
-
-        # import os
-        # os.system('ls -laihR %s' % cls._tmp_path)
-
-        cls.log('Delete directory "%s"' % cls._tmp_path)
-
-        shutil.rmtree(cls._tmp_path)
-
-
-    def testFileContentStorage(self):
-        """Store and load file binary content."""
-
-        storage = ObjectStorage('my-storage-hash')
-        self.assertIsNotNone(storage)
-
-        filename = os.path.join(self._tmp_path, 'test.bin')
-
-        with open(filename, 'wb') as fd:
-            fd.write(b'ABC')
-
-        cnt = FileContent(filename)
-        self.assertIsNotNone(cnt)
-
-        ret = storage.store_object('contents', cnt)
-        self.assertEqual(ret, 0)
-
-        pbuf = PackedBuffer()
-
-        ret = storage.store(pbuf)
-        self.assertTrue(ret)
-
-        self.assertTrue(pbuf.payload_length > 0)
-
-        pbuf.rewind()
-
-        storage2 = ObjectStorage.load(pbuf)
-        self.assertIsNotNone(storage2)
-
-        cnt2 = storage2.load_object('contents', 0)
-        self.assertIsNotNone(cnt2)
-
-        self.assertEqual(cnt.data, cnt2.data)
diff --git a/tests/glibext/storage.py b/tests/glibext/storage.py
new file mode 100644
index 0000000..612d500
--- /dev/null
+++ b/tests/glibext/storage.py
@@ -0,0 +1,81 @@
+
+from chrysacase import ChrysalideTestCase
+from pychrysalide import core
+from pychrysalide.analysis.contents import FileContent
+from pychrysalide.analysis.storage import ObjectStorage
+from pychrysalide.common import PackedBuffer
+import os
+import shutil
+import tempfile
+
+
+class TestObjectStorage(ChrysalideTestCase):
+    """TestCase for analysis.storage."""
+
+    @classmethod
+    def setUpClass(cls):
+
+        super(TestObjectStorage, cls).setUpClass()
+
+        cls._tmp_path = tempfile.mkdtemp()
+
+        config = core.get_main_configuration()
+        param = config.search(core.MainParameterKeys.TMPDIR)
+
+        cls._old_tmpdir = param.value
+        param.value = cls._tmp_path
+
+        cls.log('Using temporary directory "%s"' % cls._tmp_path)
+
+
+    @classmethod
+    def tearDownClass(cls):
+
+        super(TestObjectStorage, cls).tearDownClass()
+
+        config = core.get_main_configuration()
+        param = config.search(core.MainParameterKeys.TMPDIR)
+
+        param.value = cls._old_tmpdir
+
+        # import os
+        # os.system('ls -laihR %s' % cls._tmp_path)
+
+        cls.log('Delete directory "%s"' % cls._tmp_path)
+
+        shutil.rmtree(cls._tmp_path)
+
+
+    def testFileContentStorage(self):
+        """Store and load file binary content."""
+
+        storage = ObjectStorage('my-storage-hash')
+        self.assertIsNotNone(storage)
+
+        filename = os.path.join(self._tmp_path, 'test.bin')
+
+        with open(filename, 'wb') as fd:
+            fd.write(b'ABC')
+
+        cnt = FileContent(filename)
+        self.assertIsNotNone(cnt)
+
+        ret = storage.store_object('contents', cnt)
+        self.assertEqual(ret, 0)
+
+        pbuf = PackedBuffer()
+
+        ret = storage.store(pbuf)
+        self.assertTrue(ret)
+
+        self.assertTrue(pbuf.payload_length > 0)
+
+        pbuf.rewind()
+
+        storage2 = ObjectStorage.load(pbuf)
+        self.assertIsNotNone(storage2)
+
+        cnt2 = storage2.load_object('contents', 0)
+        self.assertIsNotNone(cnt2)
+
+        self.assertEqual(cnt.data, cnt2.data)
-- 
cgit v0.11.2-87-g4458