summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/glibext
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide/glibext')
-rw-r--r--plugins/pychrysalide/glibext/Makefile.am21
-rw-r--r--plugins/pychrysalide/glibext/bufferline.c109
-rw-r--r--plugins/pychrysalide/glibext/constants-ui.c131
-rw-r--r--plugins/pychrysalide/glibext/constants-ui.h41
-rw-r--r--plugins/pychrysalide/glibext/constants.c100
-rw-r--r--plugins/pychrysalide/glibext/constants.h6
-rw-r--r--plugins/pychrysalide/glibext/generator.c (renamed from plugins/pychrysalide/glibext/linegen.c)584
-rw-r--r--plugins/pychrysalide/glibext/generator.h (renamed from plugins/pychrysalide/glibext/linegen.h)18
-rw-r--r--plugins/pychrysalide/glibext/module-ui.c62
-rw-r--r--plugins/pychrysalide/glibext/module-ui.h38
-rw-r--r--plugins/pychrysalide/glibext/module.c4
-rw-r--r--plugins/pychrysalide/glibext/objhole.c102
-rw-r--r--plugins/pychrysalide/glibext/secstorage.c9
-rw-r--r--plugins/pychrysalide/glibext/serialize.c478
-rw-r--r--plugins/pychrysalide/glibext/serialize.h45
-rw-r--r--plugins/pychrysalide/glibext/storage.c572
-rw-r--r--plugins/pychrysalide/glibext/storage.h48
-rw-r--r--plugins/pychrysalide/glibext/tpmem.c508
-rw-r--r--plugins/pychrysalide/glibext/tpmem.h45
19 files changed, 2470 insertions, 451 deletions
diff --git a/plugins/pychrysalide/glibext/Makefile.am b/plugins/pychrysalide/glibext/Makefile.am
index af1d9f2..6d3d746 100644
--- a/plugins/pychrysalide/glibext/Makefile.am
+++ b/plugins/pychrysalide/glibext/Makefile.am
@@ -1,14 +1,11 @@
-noinst_LTLIBRARIES = libpychrysaglibext.la
+noinst_LTLIBRARIES = libpychrysaglibext.la libpychrysaglibextui.la
# libpychrysaglibext_la_SOURCES = \
# binarycursor.h binarycursor.c \
# buffercache.h buffercache.c \
-# bufferline.h bufferline.c \
# configuration.h configuration.c \
-# linecursor.h linecursor.c \
-# linegen.h linegen.c \
-# module.h module.c
+# linecursor.h linecursor.c
# if BUILD_GTK_SUPPORT
@@ -27,7 +24,9 @@ libpychrysaglibext_la_SOURCES = \
objhole.h objhole.c \
portion.h portion.c \
secstorage.h secstorage.c \
+ serialize.h serialize.c \
singleton.h singleton.c \
+ storage.h storage.c \
strbuilder.h strbuilder.c \
work.h work.c \
workqueue.h workqueue.c
@@ -36,6 +35,16 @@ libpychrysaglibext_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS)
-I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+libpychrysaglibextui_la_SOURCES = \
+ bufferline.h bufferline.c \
+ constants-ui.h constants-ui.c \
+ generator.h generator.c \
+ module-ui.h module-ui.c
+
+libpychrysaglibextui_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBPYTHON_INTERPRETER_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+ -I$(top_srcdir)/src -DNO_IMPORT_PYGOBJECT
+
+
devdir = $(includedir)/chrysalide/$(subdir)
-dev_HEADERS = $(libpychrysaglibext_la_SOURCES:%c=)
+dev_HEADERS = $(libpychrysaglibext_la_SOURCES:%c=) $(libpychrysaglibextui_la_SOURCES:%c=)
diff --git a/plugins/pychrysalide/glibext/bufferline.c b/plugins/pychrysalide/glibext/bufferline.c
index 09404bc..c5b3664 100644
--- a/plugins/pychrysalide/glibext/bufferline.c
+++ b/plugins/pychrysalide/glibext/bufferline.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* bufferline.c - équivalent Python du fichier "glibext/bufferline.h"
*
- * Copyright (C) 2018-2019 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -26,25 +26,38 @@
#include <assert.h>
-#include <malloc.h>
+//#include <malloc.h>
#include <pygobject.h>
-#include <i18n.h>
-#include <glibext/bufferline.h>
-#include <plugins/dt.h>
+#include <glibext/bufferline-int.h>
-#include "constants.h"
+//#include "constants.h"
#include "../access.h"
#include "../helpers.h"
-#include "../arch/vmpa.h"
+//#include "../arch/vmpa.h"
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+CREATE_DYN_CONSTRUCTOR(buffer_line, G_TYPE_BUFFER_LINE);
+
+/* Initialise une instance sur la base du dérivé de GObject. */
+static int py_buffer_line_init(PyObject *, PyObject *, PyObject *);
+
+
+
+/* ------------------ LIAISON DE FONCTIONNALITES AVEC L'API PYTHON ------------------ */
+
+
/* Accompagne la création d'une instance dérivée en Python. */
static PyObject *py_buffer_line_new(PyTypeObject *, PyObject *, PyObject *);
+#if 0
+
/* Ajoute du texte à formater dans une ligne donnée. */
static PyObject *py_buffer_line_append_text(PyObject *, PyObject *);
@@ -54,29 +67,34 @@ static PyObject *py_buffer_line_get_text(PyObject *, PyObject *);
/* Renseigne sur les propriétés particulières liées à une ligne. */
static PyObject *py_buffer_line_get_flags(PyObject *, void *);
+#endif
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* 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. *
+* Paramètres : self = objet à initialiser (théoriquement). *
+* args = arguments fournis à l'appel. *
+* kwds = arguments de type key=val fournis. *
* *
-* Description : Accompagne la création d'une instance dérivée en Python. *
+* Description : Initialise une instance sur la base du dérivé de GObject. *
* *
-* Retour : Nouvel objet Python mis en place ou NULL en cas d'échec. *
+* Retour : 0. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_buffer_line_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+static int py_buffer_line_init(PyObject *self, 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 */
+ unsigned char col_count; /* Qté de colonnes attendues */
+ int ret; /* Bilan de lecture des args. */
+ GBufferLine *line; /* Ligne en version native */
#define BUFFER_LINE_DOC \
"The BufferLine object is used to display processed data: disassembled" \
@@ -84,51 +102,40 @@ static PyObject *py_buffer_line_new(PyTypeObject *type, PyObject *args, PyObject
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " BufferLine()" \
+ " BufferLine(col_count)" \
+ "\n" \
+ " Where *col_count* is a integer value providing the expected number of"\
+ " rendering columns." \
"\n" \
"Such objets aim to be created from the Chrysalide core only, and" \
" then get populated on demand. Thus, these lines can be viewed as" \
" cached lines and their properties have to be set through the" \
" pychrysalide.glibext.BufferCache instance which contains them."
- /* Validations diverses */
-
- base = get_python_buffer_line_type();
+ /* Récupération des paramètres */
- if (type == base)
- goto simple_way;
+ ret = PyArg_ParseTuple(args, "B", &col_count);
+ if (!ret) return -1;
- /* Mise en place d'un type dédié */
+ /* Initialisation d'un objet GLib */
- first_time = (g_type_from_name(type->tp_name) == 0);
+ ret = forward_pygobjet_init(self);
+ if (ret == -1) return -1;
- gtype = build_dynamic_type(G_TYPE_BUFFER_LINE, type->tp_name, NULL, NULL, NULL);
-
- if (first_time)
- {
- status = register_class_for_dynamic_pygobject(gtype, type);
+ /* Eléments de base */
- if (!status)
- {
- result = NULL;
- goto exit;
- }
-
- }
-
- /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */
-
- simple_way:
-
- result = PyType_GenericNew(type, args, kwds);
+ line = G_BUFFER_LINE(pygobject_get(self));
- exit:
+ if (!g_buffer_line_create(line, col_count))
+ return -1;
- return result;
+ return 0;
}
+#if 0
+
/******************************************************************************
* *
* Paramètres : self = classe représentant une ligne de tampon. *
@@ -256,6 +263,7 @@ static PyObject *py_buffer_line_get_flags(PyObject *self, void *closure)
return result;
}
+#endif
/******************************************************************************
@@ -273,20 +281,24 @@ static PyObject *py_buffer_line_get_flags(PyObject *self, void *closure)
PyTypeObject *get_python_buffer_line_type(void)
{
static PyMethodDef py_buffer_line_methods[] = {
+ /*
BUFFER_LINE_APPEND_TEXT_METHOD,
{
"get_text", py_buffer_line_get_text,
METH_VARARGS,
"get_text($self, first_col, last_col, markup, /)\n--\n\nProvide the text of a buffer line."
},
+ */
{ NULL }
};
static PyGetSetDef py_buffer_line_getseters[] = {
+ /*
{
"flags", py_buffer_line_get_flags, NULL,
"Current flags of the buffer line.", NULL
},
+ */
{ NULL }
};
@@ -304,7 +316,8 @@ PyTypeObject *get_python_buffer_line_type(void)
.tp_methods = py_buffer_line_methods,
.tp_getset = py_buffer_line_getseters,
- .tp_new = py_buffer_line_new
+ .tp_init = py_buffer_line_init,
+ .tp_new = py_buffer_line_new,
};
@@ -342,11 +355,13 @@ bool ensure_python_buffer_line_is_registered(void)
if (!register_class_for_pygobject(dict, G_TYPE_BUFFER_LINE, type))
return false;
+ /*
if (!define_line_segment_constants(type))
return false;
if (!define_buffer_line_constants(type))
return false;
+ */
}
diff --git a/plugins/pychrysalide/glibext/constants-ui.c b/plugins/pychrysalide/glibext/constants-ui.c
new file mode 100644
index 0000000..4101600
--- /dev/null
+++ b/plugins/pychrysalide/glibext/constants-ui.c
@@ -0,0 +1,131 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants-ui.c - ajout des constantes pour les extensions graphique à la GLib
+ *
+ * Copyright (C) 2025 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 "constants-ui.h"
+
+
+#include <glibext/bufferline.h>
+
+
+#include "../helpers.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type dont le dictionnaire est à compléter. *
+* *
+* Description : Définit les constantes relatives aux lignes de tampon. *
+* *
+* Retour : true en cas de succès de l'opération, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_buffer_line_constants(PyTypeObject *type)
+{
+ bool result; /* Bilan à retourner */
+ PyObject *values; /* Groupe de valeurs à établir */
+
+ values = PyDict_New();
+
+ result = add_const_to_group(values, "NONE", BLF_NONE);
+ if (result) result = add_const_to_group(values, "HAS_CODE", BLF_HAS_CODE);
+ if (result) result = add_const_to_group(values, "IS_LABEL", BLF_IS_LABEL);
+ if (result) result = add_const_to_group(values, "ENTRYPOINT", BLF_ENTRYPOINT);
+ if (result) result = add_const_to_group(values, "BOOKMARK", BLF_BOOKMARK);
+ if (result) result = add_const_to_group(values, "WIDTH_MANAGER", BLF_WIDTH_MANAGER);
+ if (result) result = add_const_to_group(values, "ALL", BLF_ALL);
+
+ if (!result)
+ {
+ Py_DECREF(values);
+ goto exit;
+ }
+
+ result = attach_constants_group_to_type(type, true, "BufferLineFlags", values,
+ "Optional flags linked to a rendering line.");
+
+ exit:
+
+ 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 constante BufferLineFlags. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_buffer_line_flags(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+ unsigned long value; /* Valeur transcrite */
+
+ result = PyObject_IsInstance(arg, (PyObject *)&PyLong_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 BufferLineFlags");
+ break;
+
+ case 1:
+ value = PyLong_AsUnsignedLong(arg);
+
+ if ((value & BLF_ALL) != value)
+ {
+ PyErr_SetString(PyExc_TypeError, "invalid value for BufferLineFlags");
+ result = 0;
+ }
+
+ else
+ *((BufferLineFlags *)dst) = value;
+
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/glibext/constants-ui.h b/plugins/pychrysalide/glibext/constants-ui.h
new file mode 100644
index 0000000..6c7bc6e
--- /dev/null
+++ b/plugins/pychrysalide/glibext/constants-ui.h
@@ -0,0 +1,41 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants-ui.h - prototypes pour l'ajout des constantes pour les extensions graphique à la GLib
+ *
+ * Copyright (C) 2025 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_GLIBEXT_CONSTANTS_UI_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_CONSTANTS_UI_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+/* Définit les constantes relatives aux lignes de tampon. */
+bool define_buffer_line_constants(PyTypeObject *);
+
+/* Tente de convertir en constante BufferLineFlags. */
+int convert_to_buffer_line_flags(PyObject *, void *);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_CONSTANTS_UI_H */
diff --git a/plugins/pychrysalide/glibext/constants.c b/plugins/pychrysalide/glibext/constants.c
index 90ce8cd..f733cf6 100644
--- a/plugins/pychrysalide/glibext/constants.c
+++ b/plugins/pychrysalide/glibext/constants.c
@@ -29,7 +29,6 @@
/*
#include <i18n.h>
-#include <glibext/bufferline.h>
#include <glibext/comparison.h>
#include <glibext/configuration.h>
#include <glibext/linesegment.h>
@@ -159,105 +158,6 @@ int convert_to_portion_access_rights(PyObject *arg, void *dst)
* *
* Paramètres : type = type dont le dictionnaire est à compléter. *
* *
-* Description : Définit les constantes relatives aux lignes de tampon. *
-* *
-* Retour : true en cas de succès de l'opération, false sinon. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool define_buffer_line_constants(PyTypeObject *type)
-{
- bool result; /* Bilan à retourner */
- PyObject *values; /* Groupe de valeurs à établir */
-
- values = PyDict_New();
-
- result = add_const_to_group(values, "NONE", BLF_NONE);
- if (result) result = add_const_to_group(values, "HAS_CODE", BLF_HAS_CODE);
- if (result) result = add_const_to_group(values, "IS_LABEL", BLF_IS_LABEL);
- if (result) result = add_const_to_group(values, "ENTRYPOINT", BLF_ENTRYPOINT);
- if (result) result = add_const_to_group(values, "BOOKMARK", BLF_BOOKMARK);
- if (result) result = add_const_to_group(values, "WIDTH_MANAGER", BLF_WIDTH_MANAGER);
- if (result) result = add_const_to_group(values, "ALL", BLF_ALL);
-
- if (!result)
- {
- Py_DECREF(values);
- goto exit;
- }
-
- result = attach_constants_group_to_type(type, true, "BufferLineFlags", values,
- "Optional flags linked to a rendering line.");
-
- exit:
-
- 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 constante BufferLineFlags. *
-* *
-* Retour : Bilan de l'opération, voire indications supplémentaires. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-int convert_to_buffer_line_flags(PyObject *arg, void *dst)
-{
- int result; /* Bilan à retourner */
- unsigned long value; /* Valeur transcrite */
-
- result = PyObject_IsInstance(arg, (PyObject *)&PyLong_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 BufferLineFlags");
- break;
-
- case 1:
- value = PyLong_AsUnsignedLong(arg);
-
- if ((value & BLF_ALL) != value)
- {
- PyErr_SetString(PyExc_TypeError, "invalid value for BufferLineFlags");
- result = 0;
- }
-
- else
- *((BufferLineFlags *)dst) = value;
-
- break;
-
- default:
- assert(false);
- break;
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : type = type dont le dictionnaire est à compléter. *
-* *
* Description : Définit les constantes relatives aux modes de comparaison. *
* *
* Retour : true en cas de succès de l'opération, false sinon. *
diff --git a/plugins/pychrysalide/glibext/constants.h b/plugins/pychrysalide/glibext/constants.h
index a950125..c695aa9 100644
--- a/plugins/pychrysalide/glibext/constants.h
+++ b/plugins/pychrysalide/glibext/constants.h
@@ -39,12 +39,6 @@ int convert_to_portion_access_rights(PyObject *, void *);
#if 0
-/* Définit les constantes relatives aux lignes de tampon. */
-bool define_buffer_line_constants(PyTypeObject *);
-
-/* Tente de convertir en constante BufferLineFlags. */
-int convert_to_buffer_line_flags(PyObject *, void *);
-
/* Définit les constantes relatives aux modes de comparaison. */
bool define_comparable_item_constants(PyTypeObject *);
diff --git a/plugins/pychrysalide/glibext/linegen.c b/plugins/pychrysalide/glibext/generator.c
index d7e96fd..3a9a8ab 100644
--- a/plugins/pychrysalide/glibext/linegen.c
+++ b/plugins/pychrysalide/glibext/generator.c
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * linegen.c - équivalent Python du fichier "glibext/linegen.h"
+ * generator.c - équivalent Python du fichier "glibext/generator.h"
*
- * Copyright (C) 2018-2019 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -22,21 +22,21 @@
*/
-#include "linegen.h"
+#include "generator.h"
#include <pygobject.h>
-#include <glibext/linegen-int.h>
+#include <glibext/generator-int.h>
#include "bufferline.h"
-#include "constants.h"
-#include "linecursor.h"
+#include "constants-ui.h"
+//#include "linecursor.h"
#include "../access.h"
#include "../helpers.h"
-#include "../analysis/content.h"
+//#include "../analysis/content.h"
@@ -44,42 +44,55 @@
/* Procède à l'initialisation de l'interface de génération. */
-static void py_line_generator_interface_init(GLineGeneratorIface *, gpointer *);
+static void py_token_generator_interface_init(GTokenGeneratorInterface *, gpointer *);
/* Indique le nombre de ligne prêtes à être générées. */
-static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *);
+static size_t py_token_generator_count_lines_wrapper(const GTokenGenerator *);
+
+/* Renseigne sur les propriétés liées à un générateur. */
+static BufferLineFlags py_token_generator_get_flags_wrapper(const GTokenGenerator *, size_t, size_t);
+
+/*Description : Etablit dans une ligne de rendu le contenu représenté. */
+static void py_token_generator_populate_line_wrappper(const GTokenGenerator *, size_t, size_t, GBufferLine *, void *);
+
+
+#if 0
+
/* Retrouve l'emplacement correspondant à une position donnée. */
-static void py_line_generator_compute_cursor_wrapper(const GLineGenerator *, gint, size_t, size_t, GLineCursor **);
+static void py_token_generator_compute_cursor_wrapper(const GTokenGenerator *, gint, size_t, size_t, GLineCursor **);
/* Détermine si le conteneur s'inscrit dans une plage donnée. */
-static int py_line_generator_contain_cursor_wrapper(const GLineGenerator *, size_t, size_t, const GLineCursor *);
+static int py_token_generator_contain_cursor_wrapper(const GTokenGenerator *, size_t, size_t, const GLineCursor *);
+
+
+#endif
-/* Renseigne sur les propriétés liées à un générateur. */
-static BufferLineFlags py_line_generator_get_flags_wrapper(const GLineGenerator *, size_t, size_t);
-/* Imprime dans une ligne de rendu le contenu représenté. */
-static void py_line_generator_print_wrapper(GLineGenerator *, GBufferLine *, size_t, size_t, const GBinContent *);
+/* ------------------ LIAISON DE FONCTIONNALITES AVEC L'API PYTHON ------------------ */
-/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+/* Renseigne sur les propriétés liées à un générateur. */
+static PyObject *py_token_generator_get_flags(PyObject *, PyObject *);
+
+/* Etablit dans une ligne de rendu le contenu représenté. */
+static PyObject *py_token_generator_populate_line(PyObject *self, PyObject *args);
+
+#if 0
/* Retrouve l'emplacement correspondant à une position donnée. */
-static PyObject *py_line_generator_compute_cursor(PyObject *, PyObject *);
+static PyObject *py_token_generator_compute_cursor(PyObject *, PyObject *);
/* Détermine si le conteneur s'inscrit dans une plage donnée. */
-static PyObject *py_line_generator_contain_cursor(PyObject *, PyObject *);
+static PyObject *py_token_generator_contain_cursor(PyObject *, PyObject *);
-/* Renseigne sur les propriétés liées à un générateur. */
-static PyObject *py_line_generator_get_flags(PyObject *, PyObject *);
+#endif
-/* Imprime dans une ligne de rendu le contenu représenté. */
-static PyObject *py_line_generator_print(PyObject *, PyObject *);
/* Indique le nombre de ligne prêtes à être générées. */
-static PyObject *py_line_generator_get_lines_count(PyObject *, void *);
+static PyObject *py_token_generator_get_lines_count(PyObject *, void *);
@@ -101,31 +114,33 @@ static PyObject *py_line_generator_get_lines_count(PyObject *, void *);
* *
******************************************************************************/
-static void py_line_generator_interface_init(GLineGeneratorIface *iface, gpointer *unused)
+static void py_token_generator_interface_init(GTokenGeneratorInterface *iface, gpointer *unused)
{
-#define LINE_GENERATOR_DOC \
- "LineGenerator gives an interface to all objects which aim to produce" \
+#define TOKEN_GENERATOR_DOC \
+ "TokenGenerator gives an interface to all objects which aim to produce" \
" content for rendering lines. Such lines can be exported to graphical" \
" interfaces or text files.\n" \
"\n" \
"A typical class declaration for a new implementation looks like:\n" \
"\n" \
- " class NewImplem(GObject.Object, LineGenerator):\n" \
+ " class NewImplem(GObject.Object, TokenGenerator):\n" \
" ...\n" \
"\n" \
"The following methods have to be defined for new implementations:\n" \
- "* pychrysalide.glibext.LineGenerator._count_lines();\n" \
- "* pychrysalide.glibext.LineGenerator._compute_cursor();\n" \
- "* pychrysalide.glibext.LineGenerator._contain_cursor();\n" \
- "* pychrysalide.glibext.LineGenerator._get_flags();\n" \
- "* pychrysalide.glibext.LineGenerator._print();\n" \
-
- iface->count = py_line_generator_count_lines_wrapper;
- iface->compute = py_line_generator_compute_cursor_wrapper;
- iface->contain = py_line_generator_contain_cursor_wrapper;
- iface->get_flags = py_line_generator_get_flags_wrapper;
- iface->print = py_line_generator_print_wrapper;
+ "* pychrysalide.glibext.TokenGenerator._count_lines();\n" \
+ "* pychrysalide.glibext.TokenGenerator._get_flags();\n" \
+ "* pychrysalide.glibext.TokenGenerator._populate_line();\n" \
+ "* pychrysalide.glibext.TokenGenerator._compute_cursor();\n" \
+ "* pychrysalide.glibext.TokenGenerator._contain_cursor().\n"
+
+ iface->count = py_token_generator_count_lines_wrapper;
+ iface->get_flags = py_token_generator_get_flags_wrapper;
+ iface->populate = py_token_generator_populate_line_wrappper;
+#if 0
+ iface->compute = py_token_generator_compute_cursor_wrapper;
+ iface->contain = py_token_generator_contain_cursor_wrapper;
+#endif
}
@@ -142,7 +157,7 @@ static void py_line_generator_interface_init(GLineGeneratorIface *iface, gpointe
* *
******************************************************************************/
-static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *generator)
+static size_t py_token_generator_count_lines_wrapper(const GTokenGenerator *generator)
{
size_t result; /* Décompte à retourner */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
@@ -150,7 +165,7 @@ static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *genera
PyObject *pyret; /* Bilan de consultation */
int ret; /* Bilan d'une conversion */
-#define LINE_GENERATOR_COUNT_LINES_WRAPPER PYTHON_WRAPPER_DEF \
+#define TOKEN_GENERATOR_COUNT_LINES_WRAPPER PYTHON_WRAPPER_DEF \
( \
_count_lines, "$self, /", \
METH_NOARGS, \
@@ -193,61 +208,61 @@ static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *genera
/******************************************************************************
* *
* Paramètres : generator = générateur à consulter. *
-* x = position géographique sur la ligne concernée. *
* index = indice de cette même ligne dans le tampon global.*
* repeat = indice d'utilisations successives du générateur. *
* *
-* Description : Retrouve l'emplacement correspondant à une position donnée. *
+* Description : Renseigne sur les propriétés liées à un générateur. *
* *
-* Retour : Emplacement constitué. *
+* Retour : Propriétés particulières associées. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void py_line_generator_compute_cursor_wrapper(const GLineGenerator *generator, gint x, size_t index, size_t repeat, GLineCursor **cursor)
+static BufferLineFlags py_token_generator_get_flags_wrapper(const GTokenGenerator *generator, size_t index, size_t repeat)
{
+ BufferLineFlags result; /* Fanions à retourner */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyret; /* Bilan de consultation */
int ret; /* Bilan d'une conversion */
-#define LINE_GENERATOR_COMPUTE_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \
+#define TOKEN_GENERATOR_GET_FLAGS_WRAPPER PYTHON_WRAPPER_DEF \
( \
- _compute_cursor, "$self, x, index, repeat, /", \
+ _get_flags, "$self, index, repeat, /", \
METH_VARARGS, \
- "Abstract method used to create a new cursor for a given" \
- " location inside displayed lines.\n" \
+ "Abstract method used to provide flags for a given rendering" \
+ " line.\n" \
"\n" \
- "The position on the horizontal axis, the line index and the" \
- " number of repetitions (only relevant if the generator" \
- " produces several lines) give indications about the active" \
- " position.\n" \
+ "The line index and the number of repetitions (only relevant" \
+ " if the generator produces several lines) give indications" \
+ " about the active position.\n" \
"\n" \
- "The result has to be a pychrysalide.glibext.LineCursor" \
- " instance." \
+ "The result has to be a" \
+ " pychrysalide.glibext.BufferLine.BufferLineFlags value.\n" \
)
+ result = BLF_NONE;
+
gstate = PyGILState_Ensure();
pyobj = pygobject_new(G_OBJECT(generator));
- if (has_python_method(pyobj, "_compute_cursor"))
+ if (has_python_method(pyobj, "_get_flags"))
{
- args = PyTuple_New(3);
- PyTuple_SetItem(args, 0, PyLong_FromSize_t(x));
- PyTuple_SetItem(args, 1, PyLong_FromSize_t(index));
- PyTuple_SetItem(args, 2, PyLong_FromSize_t(repeat));
+ args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, PyLong_FromSize_t(index));
+ PyTuple_SetItem(args, 1, PyLong_FromSize_t(repeat));
- pyret = run_python_method(pyobj, "_compute_cursor", args);
+ pyret = run_python_method(pyobj, "_get_flags", args);
if (pyret != NULL)
{
- ret = convert_to_line_cursor(pyret, cursor);
+ ret = convert_to_buffer_line_flags(pyret, &result);
if (ret != 1)
- *cursor = NULL;
+ result = BLF_NONE;
Py_DECREF(pyret);
@@ -261,75 +276,66 @@ static void py_line_generator_compute_cursor_wrapper(const GLineGenerator *gener
PyGILState_Release(gstate);
+ return result;
+
}
/******************************************************************************
* *
-* Paramètres : generator = générateur à consulter. *
+* Paramètres : generator = générateur à utiliser pour l'impression. *
* index = indice de cette même ligne dans le tampon global.*
* repeat = indice d'utilisations successives du générateur. *
-* cursor = emplacement à analyser. *
+* line = ligne de rendu à compléter. *
+* data = éventuelle donnée complémentaire fournie. *
* *
-* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* Description : Etablit dans une ligne de rendu le contenu représenté. *
* *
-* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static int py_line_generator_contain_cursor_wrapper(const GLineGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor)
+static void py_token_generator_populate_line_wrappper(const GTokenGenerator *generator, size_t index, size_t repeat, GBufferLine *line, void *data)
{
- int result; /* Bilan d'analyse à retourner */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyret; /* Bilan de consultation */
- int ret; /* Bilan d'une conversion */
-#define LINE_GENERATOR_CONTAIN_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \
+#define TOKEN_GENERATOR_POPULATE_LINE_WRAPPER PYTHON_WRAPPER_DEF \
( \
- _contain_cursor, "$self, index, repeat, cursor, /", \
+ _populate_line, "$self, index, repeat, line, /", \
METH_VARARGS, \
- "Abstract method used to check the position of a cursor in" \
- " relation to rendering lines.\n" \
+ "Abstract method used to generate content into a rendering" \
+ " line.\n" \
"\n" \
- "The line index and the number of repetitions (only relevant" \
+ "This rendering output is pointed by the *line* argument, which"\
+ " is a provided pychrysalide.glibext.BufferLine instance. The" \
+ " line *index* and the number of repetitions (only relevant" \
" if the generator produces several lines) give indications" \
- " about the active position. The cursor is a" \
- " pychrysalide.glibext.LineCursor instance.\n" \
+ " about the current rendering position.\n" \
"\n" \
- "The result has to be an integer less than, equal to, or" \
- " greater than zero if the cursor is, respectively, before," \
- " inside or after the area covered by the generator." \
+ "If set, the content is a pychrysalide.analysis.BinContent" \
+ " instance providing access to the processed binary data." \
)
- result = 0;
-
gstate = PyGILState_Ensure();
pyobj = pygobject_new(G_OBJECT(generator));
- if (has_python_method(pyobj, "_contain_cursor"))
+ if (has_python_method(pyobj, "_populate_line"))
{
args = PyTuple_New(3);
PyTuple_SetItem(args, 0, PyLong_FromSize_t(index));
PyTuple_SetItem(args, 1, PyLong_FromSize_t(repeat));
- PyTuple_SetItem(args, 2, pygobject_new(G_OBJECT(cursor)));
+ PyTuple_SetItem(args, 2, pygobject_new(G_OBJECT(line)));
+ //PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(content)));
- pyret = run_python_method(pyobj, "_contain_cursor", args);
-
- if (pyret != NULL)
- {
- ret = PyLong_Check(pyret);
+ pyret = run_python_method(pyobj, "_populate_line", args);
- if (ret)
- result = PyLong_AsLong(pyret);
-
- Py_DECREF(pyret);
-
- }
+ Py_XDECREF(pyret);
Py_DECREF(args);
@@ -339,69 +345,70 @@ static int py_line_generator_contain_cursor_wrapper(const GLineGenerator *genera
PyGILState_Release(gstate);
- return result;
-
}
+#if 0
+
+
/******************************************************************************
* *
* Paramètres : generator = générateur à consulter. *
+* x = position géographique sur la ligne concernée. *
* index = indice de cette même ligne dans le tampon global.*
* repeat = indice d'utilisations successives du générateur. *
* *
-* Description : Renseigne sur les propriétés liées à un générateur. *
+* Description : Retrouve l'emplacement correspondant à une position donnée. *
* *
-* Retour : Propriétés particulières associées. *
+* Retour : Emplacement constitué. *
* *
* Remarques : - *
* *
******************************************************************************/
-static BufferLineFlags py_line_generator_get_flags_wrapper(const GLineGenerator *generator, size_t index, size_t repeat)
+static void py_token_generator_compute_cursor_wrapper(const GTokenGenerator *generator, gint x, size_t index, size_t repeat, GLineCursor **cursor)
{
- BufferLineFlags result; /* Fanions à retourner */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyret; /* Bilan de consultation */
int ret; /* Bilan d'une conversion */
-#define LINE_GENERATOR_GET_FLAGS_WRAPPER PYTHON_WRAPPER_DEF \
+#define TOKEN_GENERATOR_COMPUTE_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \
( \
- _get_flags, "$self, index, repeat, /", \
+ _compute_cursor, "$self, x, index, repeat, /", \
METH_VARARGS, \
- "Abstract method used to provide flags for a given rendering" \
- " line.\n" \
+ "Abstract method used to create a new cursor for a given" \
+ " location inside displayed lines.\n" \
"\n" \
- "The line index and the number of repetitions (only relevant" \
- " if the generator produces several lines) give indications" \
- " about the active position.\n" \
+ "The position on the horizontal axis, the line index and the" \
+ " number of repetitions (only relevant if the generator" \
+ " produces several lines) give indications about the active" \
+ " position.\n" \
"\n" \
- "The result has to be a" \
- " pychrysalide.glibext.BufferLine.BufferLineFlags value.\n" \
+ "The result has to be a pychrysalide.glibext.LineCursor" \
+ " instance." \
)
- result = BLF_NONE;
-
gstate = PyGILState_Ensure();
pyobj = pygobject_new(G_OBJECT(generator));
- if (has_python_method(pyobj, "_get_flags"))
+ if (has_python_method(pyobj, "_compute_cursor"))
{
- args = PyTuple_New(2);
- PyTuple_SetItem(args, 0, PyLong_FromSize_t(index));
- PyTuple_SetItem(args, 1, PyLong_FromSize_t(repeat));
+ args = PyTuple_New(3);
+ PyTuple_SetItem(args, 0, PyLong_FromSize_t(x));
+ PyTuple_SetItem(args, 1, PyLong_FromSize_t(index));
+ PyTuple_SetItem(args, 2, PyLong_FromSize_t(repeat));
- pyret = run_python_method(pyobj, "_get_flags", args);
+ pyret = run_python_method(pyobj, "_compute_cursor", args);
if (pyret != NULL)
{
- ret = convert_to_buffer_line_flags(pyret, &result);
+ ret = convert_to_line_cursor(pyret, cursor);
if (ret != 1)
- result = BLF_NONE;
+ *cursor = NULL;
Py_DECREF(pyret);
@@ -415,65 +422,75 @@ static BufferLineFlags py_line_generator_get_flags_wrapper(const GLineGenerator
PyGILState_Release(gstate);
- return result;
-
}
/******************************************************************************
* *
-* Paramètres : generator = générateur à utiliser pour l'impression. *
-* line = ligne de rendu à compléter. *
+* Paramètres : generator = générateur à consulter. *
* index = indice de cette même ligne dans le tampon global.*
* repeat = indice d'utilisations successives du générateur. *
-* content = éventuel contenu binaire brut à imprimer. *
+* cursor = emplacement à analyser. *
* *
-* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
* *
-* Retour : - *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void py_line_generator_print_wrapper(GLineGenerator *generator, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content)
+static int py_token_generator_contain_cursor_wrapper(const GTokenGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor)
{
+ int result; /* Bilan d'analyse à retourner */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *args; /* Arguments pour l'appel */
PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Bilan d'une conversion */
-#define LINE_GENERATOR_PRINT_WRAPPER PYTHON_WRAPPER_DEF \
+#define TOKEN_GENERATOR_CONTAIN_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \
( \
- _print, "$self, line, index, repeat, content, /", \
+ _contain_cursor, "$self, index, repeat, cursor, /", \
METH_VARARGS, \
- "Abstract method used to generate content into a rendering" \
- " line, which is a provided pychrysalide.glibext.BufferLine" \
- " instance.\n" \
+ "Abstract method used to check the position of a cursor in" \
+ " relation to rendering lines.\n" \
"\n" \
"The line index and the number of repetitions (only relevant" \
" if the generator produces several lines) give indications" \
- " about the current rendering position.\n" \
+ " about the active position. The cursor is a" \
+ " pychrysalide.glibext.LineCursor instance.\n" \
"\n" \
- "If set, the content is a pychrysalide.analysis.BinContent" \
- " instance providing access to the processed binary data." \
+ "The result has to be an integer less than, equal to, or" \
+ " greater than zero if the cursor is, respectively, before," \
+ " inside or after the area covered by the generator." \
)
+ result = 0;
+
gstate = PyGILState_Ensure();
pyobj = pygobject_new(G_OBJECT(generator));
- if (has_python_method(pyobj, "_print"))
+ if (has_python_method(pyobj, "_contain_cursor"))
{
- args = PyTuple_New(4);
- PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(line)));
- PyTuple_SetItem(args, 1, PyLong_FromSize_t(index));
- PyTuple_SetItem(args, 2, PyLong_FromSize_t(repeat));
- PyTuple_SetItem(args, 3, pygobject_new(G_OBJECT(content)));
+ args = PyTuple_New(3);
+ PyTuple_SetItem(args, 0, PyLong_FromSize_t(index));
+ PyTuple_SetItem(args, 1, PyLong_FromSize_t(repeat));
+ PyTuple_SetItem(args, 2, pygobject_new(G_OBJECT(cursor)));
- pyret = run_python_method(pyobj, "_print", args);
+ pyret = run_python_method(pyobj, "_contain_cursor", args);
- Py_XDECREF(pyret);
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ result = PyLong_AsLong(pyret);
+
+ Py_DECREF(pyret);
+
+ }
Py_DECREF(args);
@@ -483,12 +500,16 @@ static void py_line_generator_print_wrapper(GLineGenerator *generator, GBufferLi
PyGILState_Release(gstate);
+ return result;
+
}
+#endif
+
/* ---------------------------------------------------------------------------------- */
-/* CONNEXION AVEC L'API DE PYTHON */
+/* LIAISON DE FONCTIONNALITES AVEC L'API PYTHON */
/* ---------------------------------------------------------------------------------- */
@@ -497,57 +518,45 @@ static void py_line_generator_print_wrapper(GLineGenerator *generator, GBufferLi
* Paramètres : self = classe représentant un générateur à manipuler. *
* args = arguments fournis à l'appel. *
* *
-* Description : Retrouve l'emplacement correspondant à une position donnée. *
+* Description : Renseigne sur les propriétés liées à un générateur. *
* *
-* Retour : Emplacement constitué. *
+* Retour : Propriétés particulières associées. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_line_generator_compute_cursor(PyObject *self, PyObject *args)
+static PyObject *py_token_generator_get_flags(PyObject *self, PyObject *args)
{
PyObject *result; /* Propriétés à retourner */
- int x; /* Position horizontale */
size_t index; /* Indice dans le tampon */
size_t repeat; /* Utilisations successives */
int ret; /* Bilan de lecture des args. */
- GLineGenerator *generator; /* Version native */
- GLineCursor *cursor; /* Curseur nouveau obtenu */
+ GTokenGenerator *generator; /* Version native */
+ BufferLineFlags flags; /* Propriétés courantes */
-#define LINE_GENERATOR_COMPUTE_CURSOR_METHOD PYTHON_METHOD_DEF \
-( \
- compute_cursor, "$self, x, index, repeat, /", \
- METH_VARARGS, py_line_generator, \
- "Create a a new cursor for a given location inside displayed" \
- " lines.\n" \
- "\n" \
- "The position on the horizontal axis, the line index and the" \
- " number of repetitions (only relevant if the generator" \
- " produces several lines) give indications about the active" \
- " position.\n" \
- "\n" \
- "The result has to be a pychrysalide.glibext.LineCursor" \
- " instance." \
+#define TOKEN_GENERATOR_GET_FLAGS_METHOD PYTHON_METHOD_DEF \
+( \
+ get_flags, "$self, index, repeat, /", \
+ METH_VARARGS, py_token_generator, \
+ "Get the flags of a given position from the generator.\n" \
+ "\n" \
+ "The line index and the number of repetitions (only relevant" \
+ " if the generator produces several lines) give indications" \
+ " about the active position.\n" \
+ "\n" \
+ "The result is a pychrysalide.glibext.BufferLine.BufferLineFlags" \
+ " value." \
)
- ret = PyArg_ParseTuple(args, "inn", &x, &index, &repeat);
+ ret = PyArg_ParseTuple(args, "nn", &index, &repeat);
if (!ret) return NULL;
- generator = G_LINE_GENERATOR(pygobject_get(self));
+ generator = G_TOKEN_GENERATOR(pygobject_get(self));
- cursor = g_line_generator_compute_cursor(generator, x, index, repeat);
+ flags = g_token_generator_get_flags(generator, index, repeat);
- if (cursor != NULL)
- {
- result = pygobject_new(G_OBJECT(cursor));
- g_object_unref(G_OBJECT(cursor));
- }
- else
- {
- result = Py_None;
- Py_INCREF(result);
- }
+ result = cast_with_constants_group_from_type(get_python_buffer_line_type(), "BufferLineFlags", flags);
return result;
@@ -559,99 +568,108 @@ static PyObject *py_line_generator_compute_cursor(PyObject *self, PyObject *args
* Paramètres : self = classe représentant un générateur à manipuler. *
* args = arguments fournis à l'appel. *
* *
-* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* Description : Etablit dans une ligne de rendu le contenu représenté. *
* *
-* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_line_generator_contain_cursor(PyObject *self, PyObject *args)
+static PyObject *py_token_generator_populate_line(PyObject *self, PyObject *args)
{
- PyObject *result; /* Propriétés à retourner */
+ GBufferLine *line; /* Ligne de rendu à compléter */
size_t index; /* Indice dans le tampon */
size_t repeat; /* Utilisations successives */
- GLineCursor *cursor; /* Curseur à venir situer */
+ GTokenGenerator *generator; /* Version native */
int ret; /* Bilan de lecture des args. */
- GLineGenerator *generator; /* Version native */
- int status; /* Bilan d'une analyse */
-#define LINE_GENERATOR_CONTAIN_CURSOR_METHOD PYTHON_METHOD_DEF \
+#define TOKEN_GENERATOR_POPULATE_LINE_METHOD PYTHON_METHOD_DEF \
( \
- contain_cursor, "$self, index, repeat, cursor, /", \
- METH_VARARGS, py_line_generator, \
- "Check the position of a cursor in relation to rendering" \
- " lines.\n" \
+ populate_line, "$self, index, repeat, line, /", \
+ METH_VARARGS, py_token_generator, \
+ "Produce output into a rendering line with optional content.\n" \
"\n" \
- "The line index and the number of repetitions (only relevant" \
- " if the generator produces several lines) give indications" \
- " about the active position. The cursor is a" \
- " pychrysalide.glibext.LineCursor instance.\n" \
+ "The provided *line* is a pychrysalide.glibext.BufferLine" \
+ " instance. The *index* and the number of repetitions (only" \
+ " relevant if the generator produces several lines) give" \
+ " indications about the current rendering position.\n" \
"\n" \
- "The result has to be an integer less than, equal to, or" \
- " greater than zero if the cursor is, respectively, before," \
- " inside or after the area covered by the generator." \
+ "If set, the content is a pychrysalide.analysis.BinContent" \
+ " instance providing access to the processed binary data." \
)
- ret = PyArg_ParseTuple(args, "nnO&", &index, &repeat, convert_to_line_cursor, &cursor);
+ ret = PyArg_ParseTuple(args, "nnO&", &index, &repeat, convert_to_buffer_line, &line);
if (!ret) return NULL;
- generator = G_LINE_GENERATOR(pygobject_get(self));
+ generator = G_TOKEN_GENERATOR(pygobject_get(self));
- status = g_line_generator_contain_cursor(generator, index, repeat, cursor);
+ g_token_generator_populate_line(generator, index, repeat, line, NULL);
- result = PyLong_FromLong(status);
-
- return result;
+ Py_RETURN_NONE;
}
+
+#if 0
+
/******************************************************************************
* *
* Paramètres : self = classe représentant un générateur à manipuler. *
* args = arguments fournis à l'appel. *
* *
-* Description : Renseigne sur les propriétés liées à un générateur. *
+* Description : Retrouve l'emplacement correspondant à une position donnée. *
* *
-* Retour : Propriétés particulières associées. *
+* Retour : Emplacement constitué. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_line_generator_get_flags(PyObject *self, PyObject *args)
+static PyObject *py_token_generator_compute_cursor(PyObject *self, PyObject *args)
{
PyObject *result; /* Propriétés à retourner */
+ int x; /* Position horizontale */
size_t index; /* Indice dans le tampon */
size_t repeat; /* Utilisations successives */
int ret; /* Bilan de lecture des args. */
- GLineGenerator *generator; /* Version native */
- BufferLineFlags flags; /* Propriétés courantes */
+ GTokenGenerator *generator; /* Version native */
+ GLineCursor *cursor; /* Curseur nouveau obtenu */
-#define LINE_GENERATOR_GET_FLAGS_METHOD PYTHON_METHOD_DEF \
-( \
- get_flags, "$self, index, repeat, /", \
- METH_VARARGS, py_line_generator, \
- "Get the flags of a given position from the generator.\n" \
- "\n" \
- "The line index and the number of repetitions (only relevant" \
- " if the generator produces several lines) give indications" \
- " about the active position.\n" \
- "\n" \
- "The result is a pychrysalide.glibext.BufferLine.BufferLineFlags" \
- " value." \
+#define TOKEN_GENERATOR_COMPUTE_CURSOR_METHOD PYTHON_METHOD_DEF \
+( \
+ compute_cursor, "$self, x, index, repeat, /", \
+ METH_VARARGS, py_token_generator, \
+ "Create a a new cursor for a given location inside displayed" \
+ " lines.\n" \
+ "\n" \
+ "The position on the horizontal axis, the line index and the" \
+ " number of repetitions (only relevant if the generator" \
+ " produces several lines) give indications about the active" \
+ " position.\n" \
+ "\n" \
+ "The result has to be a pychrysalide.glibext.LineCursor" \
+ " instance." \
)
- ret = PyArg_ParseTuple(args, "nn", &index, &repeat);
+ ret = PyArg_ParseTuple(args, "inn", &x, &index, &repeat);
if (!ret) return NULL;
- generator = G_LINE_GENERATOR(pygobject_get(self));
+ generator = G_TOKEN_GENERATOR(pygobject_get(self));
- flags = g_line_generator_get_flags(generator, index, repeat);
+ cursor = g_token_generator_compute_cursor(generator, x, index, repeat);
- result = cast_with_constants_group_from_type(get_python_buffer_line_type(), "BufferLineFlags", flags);
+ if (cursor != NULL)
+ {
+ result = pygobject_new(G_OBJECT(cursor));
+ g_object_unref(G_OBJECT(cursor));
+ }
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
return result;
@@ -663,50 +681,56 @@ static PyObject *py_line_generator_get_flags(PyObject *self, PyObject *args)
* Paramètres : self = classe représentant un générateur à manipuler. *
* args = arguments fournis à l'appel. *
* *
-* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
* *
-* Retour : - *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
* *
* Remarques : - *
* *
******************************************************************************/
-static PyObject *py_line_generator_print(PyObject *self, PyObject *args)
+static PyObject *py_token_generator_contain_cursor(PyObject *self, PyObject *args)
{
- GBufferLine *line; /* Ligne de rendu à compléter */
+ PyObject *result; /* Propriétés à retourner */
size_t index; /* Indice dans le tampon */
size_t repeat; /* Utilisations successives */
- GBinContent *content; /* Contenu binaire associé */
- GLineGenerator *generator; /* Version native */
+ GLineCursor *cursor; /* Curseur à venir situer */
int ret; /* Bilan de lecture des args. */
+ GTokenGenerator *generator; /* Version native */
+ int status; /* Bilan d'une analyse */
-#define LINE_GENERATOR_PRINT_METHOD PYTHON_METHOD_DEF \
+#define TOKEN_GENERATOR_CONTAIN_CURSOR_METHOD PYTHON_METHOD_DEF \
( \
- print, "$self, line, index, repeat, content, /", \
- METH_VARARGS, py_line_generator, \
- "Produce output into a rendering line with optional content.\n" \
+ contain_cursor, "$self, index, repeat, cursor, /", \
+ METH_VARARGS, py_token_generator, \
+ "Check the position of a cursor in relation to rendering" \
+ " lines.\n" \
"\n" \
- "The provided line is a pychrysalide.glibext.BufferLine" \
- " instance. The index and the number of repetitions (only" \
- " relevant if the generator produces several lines) give" \
- " indications about the current rendering position.\n" \
+ "The line index and the number of repetitions (only relevant" \
+ " if the generator produces several lines) give indications" \
+ " about the active position. The cursor is a" \
+ " pychrysalide.glibext.LineCursor instance.\n" \
"\n" \
- "If set, the content is a pychrysalide.analysis.BinContent" \
- " instance providing access to the processed binary data." \
+ "The result has to be an integer less than, equal to, or" \
+ " greater than zero if the cursor is, respectively, before," \
+ " inside or after the area covered by the generator." \
)
- ret = PyArg_ParseTuple(args, "O&nnO&", convert_to_buffer_line, &line, &index,
- &repeat, convert_to_binary_content, &content);
+ ret = PyArg_ParseTuple(args, "nnO&", &index, &repeat, convert_to_line_cursor, &cursor);
if (!ret) return NULL;
- generator = G_LINE_GENERATOR(pygobject_get(self));
+ generator = G_TOKEN_GENERATOR(pygobject_get(self));
- g_line_generator_print(generator, line, index, repeat, content);
+ status = g_token_generator_contain_cursor(generator, index, repeat, cursor);
- Py_RETURN_NONE;
+ result = PyLong_FromLong(status);
+
+ return result;
}
+#endif
+
/******************************************************************************
* *
@@ -721,24 +745,24 @@ static PyObject *py_line_generator_print(PyObject *self, PyObject *args)
* *
******************************************************************************/
-static PyObject *py_line_generator_get_lines_count(PyObject *self, void *closure)
+static PyObject *py_token_generator_get_lines_count(PyObject *self, void *closure)
{
PyObject *result; /* Décompte à retourner */
- GLineGenerator *generator; /* Version native */
+ GTokenGenerator *generator; /* Version native */
size_t count; /* Nombre de lignes présentes */
-#define LINE_GENERATOR_LINES_COUNT_ATTRIB PYTHON_GET_DEF_FULL \
+#define TOKEN_GENERATOR_LINES_COUNT_ATTRIB PYTHON_GET_DEF_FULL \
( \
- lines_count, py_line_generator, \
+ lines_count, py_token_generator, \
"Quantity of lines produced by the generator.\n" \
"\n" \
"This number may vary between calls, if a width has changed" \
" for instance." \
)
- generator = G_LINE_GENERATOR(pygobject_get(self));
+ generator = G_TOKEN_GENERATOR(pygobject_get(self));
- count = g_line_generator_count_lines(generator);
+ count = g_token_generator_count_lines(generator);
result = PyLong_FromSize_t(count);
@@ -759,43 +783,47 @@ static PyObject *py_line_generator_get_lines_count(PyObject *self, void *closure
* *
******************************************************************************/
-PyTypeObject *get_python_line_generator_type(void)
+PyTypeObject *get_python_token_generator_type(void)
{
- static PyMethodDef py_line_generator_methods[] = {
- LINE_GENERATOR_COUNT_LINES_WRAPPER,
- LINE_GENERATOR_COMPUTE_CURSOR_WRAPPER,
- LINE_GENERATOR_CONTAIN_CURSOR_WRAPPER,
- LINE_GENERATOR_GET_FLAGS_WRAPPER,
- LINE_GENERATOR_PRINT_WRAPPER,
- LINE_GENERATOR_COMPUTE_CURSOR_METHOD,
- LINE_GENERATOR_CONTAIN_CURSOR_METHOD,
- LINE_GENERATOR_GET_FLAGS_METHOD,
- LINE_GENERATOR_PRINT_METHOD,
+ static PyMethodDef py_token_generator_methods[] = {
+ TOKEN_GENERATOR_COUNT_LINES_WRAPPER,
+ TOKEN_GENERATOR_GET_FLAGS_WRAPPER,
+ TOKEN_GENERATOR_POPULATE_LINE_WRAPPER,
+ /*
+ TOKEN_GENERATOR_COMPUTE_CURSOR_WRAPPER,
+ TOKEN_GENERATOR_CONTAIN_CURSOR_WRAPPER,
+ */
+ TOKEN_GENERATOR_GET_FLAGS_METHOD,
+ TOKEN_GENERATOR_POPULATE_LINE_METHOD,
+ /*
+ TOKEN_GENERATOR_COMPUTE_CURSOR_METHOD,
+ TOKEN_GENERATOR_CONTAIN_CURSOR_METHOD,
+ */
{ NULL }
};
- static PyGetSetDef py_line_generator_getseters[] = {
- LINE_GENERATOR_LINES_COUNT_ATTRIB,
+ static PyGetSetDef py_token_generator_getseters[] = {
+ TOKEN_GENERATOR_LINES_COUNT_ATTRIB,
{ NULL }
};
- static PyTypeObject py_line_generator_type = {
+ static PyTypeObject py_token_generator_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.glibext.LineGenerator",
+ .tp_name = "pychrysalide.glibext.TokenGenerator",
.tp_basicsize = sizeof(PyObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = LINE_GENERATOR_DOC,
+ .tp_doc = TOKEN_GENERATOR_DOC,
- .tp_methods = py_line_generator_methods,
- .tp_getset = py_line_generator_getseters,
+ .tp_methods = py_token_generator_methods,
+ .tp_getset = py_token_generator_getseters,
};
- return &py_line_generator_type;
+ return &py_token_generator_type;
}
@@ -804,7 +832,7 @@ PyTypeObject *get_python_line_generator_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide.glibext.LineGenerator'.*
+* Description : Prend en charge l'objet 'pychrysalide.....TokenGenerator'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -812,21 +840,21 @@ PyTypeObject *get_python_line_generator_type(void)
* *
******************************************************************************/
-bool ensure_python_line_generator_is_registered(void)
+bool ensure_python_token_generator_is_registered(void)
{
- PyTypeObject *type; /* Type Python 'LineGenerator' */
+ PyTypeObject *type; /* Type Python 'TokenGenerator'*/
PyObject *module; /* Module à recompléter */
PyObject *dict; /* Dictionnaire du module */
static GInterfaceInfo info = { /* Paramètres d'inscription */
- .interface_init = (GInterfaceInitFunc)py_line_generator_interface_init,
+ .interface_init = (GInterfaceInitFunc)py_token_generator_interface_init,
.interface_finalize = NULL,
.interface_data = NULL,
};
- type = get_python_line_generator_type();
+ type = get_python_token_generator_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
{
@@ -834,7 +862,7 @@ bool ensure_python_line_generator_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_interface_for_pygobject(dict, G_TYPE_LINE_GENERATOR, type, &info))
+ if (!register_interface_for_pygobject(dict, G_TYPE_TOKEN_GENERATOR, type, &info))
return false;
}
@@ -857,11 +885,11 @@ bool ensure_python_line_generator_is_registered(void)
* *
******************************************************************************/
-int convert_to_line_generator(PyObject *arg, void *dst)
+int convert_to_token_generator(PyObject *arg, void *dst)
{
int result; /* Bilan à retourner */
- result = PyObject_IsInstance(arg, (PyObject *)get_python_line_generator_type());
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_token_generator_type());
switch (result)
{
@@ -871,11 +899,11 @@ int convert_to_line_generator(PyObject *arg, void *dst)
break;
case 0:
- PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to line generator");
+ PyErr_SetString(PyExc_TypeError, "unable to convert the provided argument to token generator");
break;
case 1:
- *((GLineGenerator **)dst) = G_LINE_GENERATOR(pygobject_get(arg));
+ *((GTokenGenerator **)dst) = G_TOKEN_GENERATOR(pygobject_get(arg));
break;
default:
diff --git a/plugins/pychrysalide/glibext/linegen.h b/plugins/pychrysalide/glibext/generator.h
index bfad885..b2672a8 100644
--- a/plugins/pychrysalide/glibext/linegen.h
+++ b/plugins/pychrysalide/glibext/generator.h
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * linegen.h - prototypes pour l'équivalent Python du fichier "glibext/linegen.h"
+ * generator.h - prototypes pour l'équivalent Python du fichier "glibext/generator.h"
*
- * Copyright (C) 2018 Cyrille Bagard
+ * Copyright (C) 2018-2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -22,8 +22,8 @@
*/
-#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_LINEGEN_H
-#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_LINEGEN_H
+#ifndef _PLUGINS_PYCHRYSALIDE_GLIBEXT_GENERATOR_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_GENERATOR_H
#include <Python.h>
@@ -32,14 +32,14 @@
/* Fournit un accès à une définition de type à diffuser. */
-PyTypeObject *get_python_line_generator_type(void);
+PyTypeObject *get_python_token_generator_type(void);
-/* Prend en charge l'objet 'pychrysalide.glibext.LineGenerator'. */
-bool ensure_python_line_generator_is_registered(void);
+/* Prend en charge l'objet 'pychrysalide.glibext.TokenGenerator'. */
+bool ensure_python_token_generator_is_registered(void);
/* Tente de convertir en générateur de lignes. */
-int convert_to_line_generator(PyObject *, void *);
+int convert_to_token_generator(PyObject *, void *);
-#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_LINEGEN_H */
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_GENERATOR_H */
diff --git a/plugins/pychrysalide/glibext/module-ui.c b/plugins/pychrysalide/glibext/module-ui.c
new file mode 100644
index 0000000..8fa6d0e
--- /dev/null
+++ b/plugins/pychrysalide/glibext/module-ui.c
@@ -0,0 +1,62 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire glibext (forme graphique) en tant que module
+ *
+ * Copyright (C) 2025 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 "module-ui.h"
+
+
+#include <assert.h>
+
+
+#include "bufferline.h"
+#include "generator.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Intègre les objets du module 'glibext' (mode UI). *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool populate_glibext_module_ui(void)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ if (result) result = ensure_python_token_generator_is_registered();
+
+ if (result) result = ensure_python_buffer_line_is_registered();
+
+ assert(result);
+
+ return result;
+
+}
diff --git a/plugins/pychrysalide/glibext/module-ui.h b/plugins/pychrysalide/glibext/module-ui.h
new file mode 100644
index 0000000..d91a2fa
--- /dev/null
+++ b/plugins/pychrysalide/glibext/module-ui.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire glibext (forme graphique) en tant que module
+ *
+ * Copyright (C) 2025 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_GLIBEXT_MODULE_UI_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_MODULE_UI_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+/* Intègre les objets du module 'glibext' (mode UI). */
+bool populate_glibext_module_ui(void);
+
+
+
+#endif /* _PLUGINS_PYCHRYSALIDE_GLIBEXT_MODULE_UI_H */
diff --git a/plugins/pychrysalide/glibext/module.c b/plugins/pychrysalide/glibext/module.c
index 6ce0709..bbe357d 100644
--- a/plugins/pychrysalide/glibext/module.c
+++ b/plugins/pychrysalide/glibext/module.c
@@ -44,7 +44,9 @@
#include "objhole.h"
#include "portion.h"
#include "secstorage.h"
+#include "serialize.h"
#include "singleton.h"
+#include "storage.h"
#include "strbuilder.h"
#include "work.h"
#include "workqueue.h"
@@ -116,12 +118,14 @@ bool populate_glibext_module(void)
if (result) result = ensure_python_comparable_object_is_registered();
if (result) result = ensure_python_hashable_object_is_registered();
+ if (result) result = ensure_python_serializable_object_is_registered();
if (result) result = ensure_python_singleton_candidate_is_registered();
if (result) result = ensure_python_string_builder_is_registered();
if (result) result = ensure_python_thick_object_is_registered();
if (result) result = ensure_python_binary_portion_is_registered();
if (result) result = ensure_python_generic_work_is_registered();
+ if (result) result = ensure_python_object_storage_is_registered();
if (result) result = ensure_python_secret_storage_is_registered();
if (result) result = ensure_python_singleton_factory_is_registered();
if (result) result = ensure_python_work_queue_is_registered();
diff --git a/plugins/pychrysalide/glibext/objhole.c b/plugins/pychrysalide/glibext/objhole.c
index 2a3ad6f..6bea5d1 100644
--- a/plugins/pychrysalide/glibext/objhole.c
+++ b/plugins/pychrysalide/glibext/objhole.c
@@ -37,12 +37,25 @@
-CREATE_DYN_CONSTRUCTOR(thick_object, G_TYPE_THICK_OBJECT);
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+CREATE_DYN_CONSTRUCTOR(thick_object, G_TYPE_THICK_OBJECT);
/* Initialise une instance sur la base du dérivé de GObject. */
static int py_thick_object_init(PyObject *, PyObject *, PyObject *);
+
+
+/* ------------------ LIAISON DE FONCTIONNALITES AVEC L'API PYTHON ------------------ */
+
+
+/* Pose un verrou à l'aide du bit dédié de GObject. */
+static PyObject *py_thick_object_lock(PyObject *, PyObject *);
+
+/* Retire un verrou via le bit dédié de GObject. */
+static PyObject *py_thick_object_unlock(PyObject *, PyObject *);
+
/* Indique le nombre de bits accaparés par la GLib. */
static PyObject *py_thick_object_get__GOBJECT_RESERVED_EXTRA_BITS(PyObject *, void *);
@@ -54,6 +67,11 @@ static int py_thick_object_set_extra(PyObject *, PyObject *, void *);
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : self = objet à initialiser (théoriquement). *
@@ -92,6 +110,86 @@ static int py_thick_object_init(PyObject *self, PyObject *args, PyObject *kwds)
}
+
+/* ---------------------------------------------------------------------------------- */
+/* LIAISON DE FONCTIONNALITES AVEC L'API PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : self = instance représentant une extension d'objet. *
+* args = arguments fournis à l'appel, non utilisé ici. *
+* *
+* Description : Pose un verrou à l'aide du bit dédié de GObject. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_thick_object_lock(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Résultat à retourner */
+ GThickObject *obj; /* Version GLib de l'instance */
+
+#define THICK_OBJECT_LOCK_METHOD PYTHON_METHOD_DEF \
+( \
+ lock, "$self", \
+ METH_NOARGS, py_thick_object, \
+ "Lock the object using the internal GLib bit.\n" \
+)
+
+ obj = G_THICK_OBJECT(pygobject_get(self));
+
+ g_thick_object_lock(obj);
+
+ result = Py_None;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = instance représentant une extension d'objet. *
+* args = arguments fournis à l'appel, non utilisé ici. *
+* *
+* Description : Retire un verrou via le bit dédié de GObject. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_thick_object_unlock(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Résultat à retourner */
+ GThickObject *obj; /* Version GLib de l'instance */
+
+#define THICK_OBJECT_UNLOCK_METHOD PYTHON_METHOD_DEF \
+( \
+ unlock, "$self", \
+ METH_NOARGS, py_thick_object, \
+ "Unlock the object using the internal GLib bit.\n" \
+)
+
+ obj = G_THICK_OBJECT(pygobject_get(self));
+
+ g_thick_object_unlock(obj);
+
+ result = Py_None;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
/******************************************************************************
* *
* Paramètres : self = objet Python concerné par l'appel. *
@@ -215,6 +313,8 @@ static int py_thick_object_set_extra(PyObject *self, PyObject *value, void *clos
PyTypeObject *get_python_thick_object_type(void)
{
static PyMethodDef py_thick_object_methods[] = {
+ THICK_OBJECT_LOCK_METHOD,
+ THICK_OBJECT_UNLOCK_METHOD,
{ NULL }
};
diff --git a/plugins/pychrysalide/glibext/secstorage.c b/plugins/pychrysalide/glibext/secstorage.c
index b5adb7c..5935d29 100644
--- a/plugins/pychrysalide/glibext/secstorage.c
+++ b/plugins/pychrysalide/glibext/secstorage.c
@@ -106,14 +106,15 @@ static int py_secret_storage_init(PyObject *self, PyObject *args, PyObject *kwds
"\n" \
"Instances can be created using the following constructor:\n" \
"\n" \
- " SecretStorage(settings)" \
+ " SecretStorage(settings=None)" \
"\n" \
- "The *settings* arguement must point to a GSettings intance;" \
- " the main configuration settings are used by default." \
+ "The *settings* arguement may point to a GSettings instance." \
+ " This optional argument is mainly used for testing purpose;" \
+ " the main configuration settings are used by default."
settings = NULL;
- ret = PyArg_ParseTuple(args, "|O&", convert_to_gsettings, &settings);
+ ret = PyArg_ParseTuple(args, "|O&", convert_to_gsettings_or_none, &settings);
if (!ret) return -1;
/* Initialisation d'un objet GLib */
diff --git a/plugins/pychrysalide/glibext/serialize.c b/plugins/pychrysalide/glibext/serialize.c
new file mode 100644
index 0000000..61f359f
--- /dev/null
+++ b/plugins/pychrysalide/glibext/serialize.c
@@ -0,0 +1,478 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * serialize.c - équivalent Python du fichier "glibext/serialize.h"
+ *
+ * Copyright (C) 2020-2025 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 <glibext/serialize-int.h>
+
+
+#include "storage.h"
+#include "../access.h"
+#include "../helpers.h"
+
+
+
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void py_serializable_object_interface_init(GSerializableObjectInterface *, gpointer *);
+
+/* Charge un objet depuis un flux de données. */
+static bool py_serializable_object_load_wrapper(GSerializableObject *, GObjectStorage *, int);
+
+/* Sauvegarde un objet dans un flux de données. */
+static bool py_serializable_object_store_wrapper(const GSerializableObject *, GObjectStorage *, int);
+
+
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
+
+/* Charge un objet depuis un flux de données. */
+static bool py_serializable_object_load(PyObject *, PyObject *);
+
+/* Sauvegarde un objet dans un flux de données. */
+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(GSerializableObjectInterface *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.glibext.SerializableObject._load();\n" \
+ "* pychrysalide.glibext.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. *
+* fd = flux ouvert en lecture. *
+* *
+* Description : Charge un objet depuis un flux de données. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_serializable_object_load_wrapper(GSerializableObject *object, GObjectStorage *storage, int fd)
+{
+ bool result; /* Bilan à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ 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, fd, /", \
+ METH_VARARGS, \
+ "Abstract method used to load an object definition from a data stream.\n" \
+ "\n" \
+ "The *storage* is a pychrysalide.glibext.ObjectStorage instance" \
+ " provided to store inner objects. The *fd* argument is an integer value" \
+ " provided as a file descriptor which as to be kept open after" \
+ " processing.\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"))
+ {
+ args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(storage)));
+ PyTuple_SetItem(args, 1, PyLong_FromLong(fd));
+
+ 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. *
+* fd = flux ouvert en écriture. *
+* *
+* Description : Sauvegarde un objet dans un flux de données. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool py_serializable_object_store_wrapper(const GSerializableObject *object, GObjectStorage *storage, int fd)
+{
+ bool result; /* Bilan à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ 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, fd, /", \
+ METH_VARARGS, \
+ "Abstract method used to store an object definition into a data stream.\n" \
+ "\n" \
+ "The *storage* is a pychrysalide.glibext.ObjectStorage instance" \
+ " provided to store inner objects. The *fd* argument is an integer value" \
+ " provided as a file descriptor which as to be kept open after" \
+ " processing.\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"))
+ {
+ args = PyTuple_New(2);
+ PyTuple_SetItem(args, 0, pygobject_new(G_OBJECT(storage)));
+ PyTuple_SetItem(args, 1, PyLong_FromLong(fd));
+
+ 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 un flux de données. *
+* *
+* 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 */
+ int fd; /* Flux ouvert (en lecture) */
+ 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, fd, /", \
+ METH_VARARGS, py_serializable_object, \
+ "Load an object definition from a data stream.\n" \
+ "\n" \
+ "The *storage* is a pychrysalide.glibext.ObjectStorage instance" \
+ " provided to store inner objects. The *fd* argument is an integer value" \
+ " used as a file descriptor for writing data\n" \
+ "\n" \
+ "The result is a boolean indicating the status of the operation." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&i", convert_to_object_storage, &storage, &fd);
+ if (!ret) return NULL;
+
+ object = G_SERIALIZABLE_OBJECT(pygobject_get(self));
+
+ status = g_serializable_object_load(object, storage, fd);
+
+ 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 un flux de données. *
+* *
+* 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 */
+ int fd; /* Flux ouvert (en lecture) */
+ 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, fd, /", \
+ METH_VARARGS, py_serializable_object, \
+ "Store an object definition into a data stream.\n" \
+ "\n" \
+ "The *storage* is a pychrysalide.glibext.ObjectStorage instance" \
+ " provided to store inner objects. The *fd* argument is an integer value" \
+ " used as a file descriptor for writing data\n" \
+ "\n" \
+ "The result is a boolean indicating the status of the operation." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&i", convert_to_object_storage, &storage, &fd);
+ if (!ret) return NULL;
+
+ object = G_SERIALIZABLE_OBJECT(pygobject_get(self));
+
+ status = g_serializable_object_store(object, storage, fd);
+
+ 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.glibext.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.glibext");
+
+ 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..90688ba
--- /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 "glibext/serialize.h"
+ *
+ * Copyright (C) 2020-2025 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_GLIBEXT_SERIALIZE_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_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.glibext.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_GLIBEXT_SERIALIZE_H */
diff --git a/plugins/pychrysalide/glibext/storage.c b/plugins/pychrysalide/glibext/storage.c
new file mode 100644
index 0000000..f2962bf
--- /dev/null
+++ b/plugins/pychrysalide/glibext/storage.c
@@ -0,0 +1,572 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * storage.c - équivalent Python du fichier "glibext/storage.c"
+ *
+ * Copyright (C) 2020-2025 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 <assert.h>
+#include <pygobject.h>
+
+
+#include <glibext/storage-int.h>
+
+
+#include "serialize.h"
+#include "../access.h"
+#include "../helpers.h"
+
+
+
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+CREATE_DYN_CONSTRUCTOR(object_storage, G_TYPE_OBJECT_STORAGE);
+
+/* 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 *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* 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 *type; /* Type global de conservation */
+ unsigned char version; /* Version de ce type */
+ const char *uid; /* Identifiant de distinction */
+ 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(type, version uid)" \
+ "\n" \
+ "Where *type* is a short string describing the storage kind," \
+ " *version* provides a version control for this type and *uid* is" \
+ " an arbitrary unique identifier used for creating temporary files."
+
+ /* Récupération des paramètres */
+
+ ret = PyArg_ParseTuple(args, "sbs", &type, &version, &uid);
+ 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));
+
+ if (!g_object_storage_create(storage, type, version, uid))
+ 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 : 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 */
+ const char *filename; /* Fichier de source à traiter */
+ int ret; /* Bilan de lecture des args. */
+ GObjectStorage *storage; /* Mécanismes natifs */
+
+#define OBJECT_STORAGE_LOAD_METHOD PYTHON_METHOD_DEF \
+( \
+ load, "filename, /", \
+ METH_STATIC | METH_VARARGS, py_object_storage, \
+ "Construct a new storage from a filename.\n" \
+ "\n" \
+ "The *filename* argument points to the source file to" \
+ " read.\n" \
+ "\n" \
+ "The result is a new pychrysalide.glibext.ObjectStorage" \
+ " object on success, *None* otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "s", &filename);
+ if (!ret) return NULL;
+
+ storage = g_object_storage_load(filename);
+
+ if (storage == NULL)
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
+ else
+ {
+ result = pygobject_new(G_OBJECT(storage));
+ unref_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 */
+ const char *filename; /* Fichier de destination */
+ 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, filename, /", \
+ METH_VARARGS, py_object_storage, \
+ "Save a storage into a file.\n" \
+ "\n" \
+ "The *filename* argument points to the destination" \
+ " file to write.\n" \
+ "\n" \
+ "The result is *True* on success, *False* otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "s", &filename);
+ if (!ret) return NULL;
+
+ storage = G_OBJECT_STORAGE(pygobject_get(self));
+
+ status = g_object_storage_store(storage, filename);
+
+ 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 */
+ int fd; /* Flux de fonnées courant */
+ const char *name; /* Désignation de groupe */
+ 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, fd, name, /", \
+ METH_VARARGS, py_object_storage, \
+ "Load an object from a reference to serialized data.\n" \
+ "\n" \
+ "The *fd* argument is a file descriptor pointing to the data" \
+ " stream for a current object being restored. A reference to" \
+ " another object belonging to a group pointed by the string *name*" \
+ " should be available at the current read position for this data" \
+ " stream.\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, "is", &fd, &name);
+ if (!ret) return NULL;
+
+ storage = G_OBJECT_STORAGE(pygobject_get(self));
+
+ object = g_object_storage_unpack_object(storage, fd, name);
+
+ 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 : - *
+* *
+* 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,
+ { NULL }
+ };
+
+ static PyGetSetDef py_object_storage_getseters[] = {
+ { NULL }
+ };
+
+ static PyTypeObject py_object_storage_type = {
+
+ PyVarObject_HEAD_INIT(NULL, 0)
+
+ .tp_name = "pychrysalide.glibext.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.glibext.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.glibext");
+
+ 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..681f99a
--- /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 "glibext/storage.h"
+ *
+ * Copyright (C) 2020-2025 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_GLIBEXT_STORAGE_H
+#define _PLUGINS_PYCHRYSALIDE_GLIBEXT_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.glibext.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_GLIBEXT_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 */