summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/glibext/linegen.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-05-11 21:33:36 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-05-11 21:33:36 (GMT)
commitd2861533cc53fbcc217048bafebf34b1f70ba3aa (patch)
tree28c847a8093761fcaa0916be54445328d843096d /plugins/pychrysalide/glibext/linegen.c
parent6c9e1b5f7ee0915036d47b83f1e34b87b44b1723 (diff)
Updated the API for buffer caches.
Diffstat (limited to 'plugins/pychrysalide/glibext/linegen.c')
-rw-r--r--plugins/pychrysalide/glibext/linegen.c734
1 files changed, 600 insertions, 134 deletions
diff --git a/plugins/pychrysalide/glibext/linegen.c b/plugins/pychrysalide/glibext/linegen.c
index 3ca7fcc..4d6d60d 100644
--- a/plugins/pychrysalide/glibext/linegen.c
+++ b/plugins/pychrysalide/glibext/linegen.c
@@ -28,26 +28,49 @@
#include <pygobject.h>
-#include <common/cpp.h>
-#include <glibext/linegen.h>
+#include <glibext/linegen-int.h>
+#include "bufferline.h"
+#include "constants.h"
+#include "linecursor.h"
#include "../access.h"
#include "../helpers.h"
#include "../analysis/content.h"
-#include "../arch/vmpa.h"
-#include "../glibext/bufferline.h"
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
+/* Procède à l'initialisation de l'interface de génération. */
+static void py_line_generator_interface_init(GLineGeneratorIface *, gpointer *);
+
/* Indique le nombre de ligne prêtes à être générées. */
-static PyObject *py_line_generator_count_lines(PyObject *, PyObject *);
+static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *);
/* Retrouve l'emplacement correspondant à une position donnée. */
-//static PyObject *py_line_generator_compute_addr(PyObject *, PyObject *);
+static void py_line_generator_compute_cursor_wrapper(const GLineGenerator *, gint, size_t, size_t, GLineCursor **);
/* Détermine si le conteneur s'inscrit dans une plage donnée. */
-//static PyObject *py_line_generator_contains_addr(PyObject *, PyObject *);
+static int py_line_generator_contain_cursor_wrapper(const GLineGenerator *, size_t, size_t, const GLineCursor *);
+
+/* 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 *);
+
+
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
+
+/* Retrouve l'emplacement correspondant à une position donnée. */
+static PyObject *py_line_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 *);
/* Renseigne sur les propriétés liées à un générateur. */
static PyObject *py_line_generator_get_flags(PyObject *, PyObject *);
@@ -55,12 +78,61 @@ static PyObject *py_line_generator_get_flags(PyObject *, PyObject *);
/* 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 *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
-* Paramètres : self = classe représentant un générateur à manipuler. *
-* args = arguments fournis à l'appel. *
+* 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_line_generator_interface_init(GLineGeneratorIface *iface, gpointer *unused)
+{
+
+#define LINE_GENERATOR_DOC \
+ "LineGenerator 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" \
+ " ...\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->contains = py_line_generator_contain_cursor_wrapper;
+ iface->get_flags = py_line_generator_get_flags_wrapper;
+ iface->print = py_line_generator_print_wrapper;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à consulter. *
* *
* Description : Indique le nombre de ligne prêtes à être générées. *
* *
@@ -70,17 +142,46 @@ static PyObject *py_line_generator_print(PyObject *, PyObject *);
* *
******************************************************************************/
-static PyObject *py_line_generator_count_lines(PyObject *self, PyObject *args)
+static size_t py_line_generator_count_lines_wrapper(const GLineGenerator *generator)
{
- PyObject *result; /* Décompte à retourner */
- GLineGenerator *generator; /* Version native */
- size_t count; /* Nombre de lignes présentes */
+ size_t result; /* Décompte à retourner */
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *pyret; /* Bilan de consultation */
+ int ret; /* Bilan d'une conversion */
- generator = G_LINE_GENERATOR(pygobject_get(self));
+#define LINE_GENERATOR_COUNT_LINES_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _count_lines, "$self, /", \
+ METH_NOARGS, \
+ "Abstract method used to count the number of lines produced" \
+ " by the current generator." \
+)
- count = g_line_generator_count_lines(generator);
+ result = 0;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(generator));
+
+ if (has_python_method(pyobj, "_count_lines"))
+ {
+ pyret = run_python_method(pyobj, "_count_lines", NULL);
+
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ result = PyLong_AsSize_t(pyret);
+
+ Py_DECREF(pyret);
+
+ }
+
+ }
- result = Py_BuildValue("k", count);
+ PyGILState_Release(gstate);
return result;
@@ -89,40 +190,358 @@ static PyObject *py_line_generator_count_lines(PyObject *self, PyObject *args)
/******************************************************************************
* *
+* 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. *
+* *
+* Retour : Emplacement constitué. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_line_generator_compute_cursor_wrapper(const GLineGenerator *generator, gint x, size_t index, size_t repeat, GLineCursor **cursor)
+{
+ 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 \
+( \
+ _compute_cursor, "$self, x, index, repeat, /", \
+ METH_VARARGS, \
+ "Abstract method used to create 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." \
+)
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(generator));
+
+ if (has_python_method(pyobj, "_compute_cursor"))
+ {
+ 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, "_compute_cursor", args);
+
+ if (pyret != NULL)
+ {
+ ret = convert_to_line_cursor(pyret, cursor);
+
+ if (ret != 1)
+ *cursor = NULL;
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ PyGILState_Release(gstate);
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
+* cursor = emplacement à analyser. *
+* *
+* Description : Détermine si le conteneur s'inscrit dans une plage donnée. *
+* *
+* Retour : Bilan de la détermination, utilisable en comparaisons. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static int py_line_generator_contain_cursor_wrapper(const GLineGenerator *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_CONTAIN_CURSOR_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _contain_cursor, "$self, index, repeat, cursor, /", \
+ METH_VARARGS, \
+ "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 active position. The cursor is a" \
+ " pychrysalide.glibext.LineCursor instance.\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." \
+)
+
+ result = 0;
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(generator));
+
+ if (has_python_method(pyobj, "_contain_cursor"))
+ {
+ 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, "_contain_cursor", args);
+
+ if (pyret != NULL)
+ {
+ ret = PyLong_Check(pyret);
+
+ if (ret)
+ result = PyLong_AsLong(pyret);
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
+* *
+* Description : Renseigne sur les propriétés liées à un générateur. *
+* *
+* Retour : Propriétés particulières associées. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static BufferLineFlags py_line_generator_get_flags_wrapper(const GLineGenerator *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_GET_FLAGS_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _get_flags, "$self, index, repeat, /", \
+ METH_VARARGS, \
+ "Abstract method used to provide flags for a given rendering" \
+ " line.\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 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, "_get_flags"))
+ {
+ 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, "_get_flags", args);
+
+ if (pyret != NULL)
+ {
+ ret = convert_to_buffer_line_flags(pyret, &result);
+
+ if (ret != 1)
+ result = BLF_NONE;
+
+ Py_DECREF(pyret);
+
+ }
+
+ Py_DECREF(args);
+
+ }
+
+ PyGILState_Release(gstate);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : generator = générateur à utiliser pour l'impression. *
+* line = ligne de rendu à compléter. *
+* 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. *
+* *
+* Description : Imprime dans une ligne de rendu le contenu représenté. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void py_line_generator_print_wrapper(GLineGenerator *generator, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content)
+{
+ PyGILState_STATE gstate; /* Sauvegarde d'environnement */
+ PyObject *pyobj; /* Objet Python concerné */
+ PyObject *args; /* Arguments pour l'appel */
+ PyObject *pyret; /* Bilan de consultation */
+
+#define LINE_GENERATOR_PRINT_WRAPPER PYTHON_WRAPPER_DEF \
+( \
+ _print, "$self, line, index, repeat, content, /", \
+ METH_VARARGS, \
+ "Abstract method used to generate content into a rendering" \
+ " line, which is a provided pychrysalide.glibext.BufferLine" \
+ " instance.\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" \
+ "\n" \
+ "If set, the content is a pychrysalide.analysis.BinContent" \
+ " instance providing access to the processed binary data." \
+)
+
+ gstate = PyGILState_Ensure();
+
+ pyobj = pygobject_new(G_OBJECT(generator));
+
+ if (has_python_method(pyobj, "_print"))
+ {
+ 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)));
+
+ pyret = run_python_method(pyobj, "_print", args);
+
+ Py_DECREF(args);
+
+ Py_XDECREF(pyret);
+
+ }
+
+ PyGILState_Release(gstate);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CONNEXION AVEC L'API DE PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
* 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. *
* *
-* Retour : - *
+* Retour : Emplacement constitué. *
* *
* Remarques : - *
* *
******************************************************************************/
-#if 0
-static PyObject *py_line_generator_compute_addr(PyObject *self, PyObject *args)
+
+static PyObject *py_line_generator_compute_cursor(PyObject *self, PyObject *args)
{
- PyObject *result; /* Localisation à retourner */
- GLineGenerator *generator; /* Version native */
- gint x; /* Position géographique */
+ 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. */
- vmpa2t addr; /* Adresse visée par l'opérat° */
+ GLineGenerator *generator; /* Version native */
+ GLineCursor *cursor; /* Curseur nouveau obtenu */
+
+#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." \
+)
+
+ ret = PyArg_ParseTuple(args, "inn", &x, &index, &repeat);
+ if (!ret) return NULL;
generator = G_LINE_GENERATOR(pygobject_get(self));
- ret = PyArg_ParseTuple(args, "ikk", &x, &index, &repeat);
- if (!ret) return NULL;
+ cursor = g_line_generator_compute_cursor(generator, x, index, repeat);
- g_line_generator_compute_addr(generator, x, &addr, index, repeat);
-
- result = build_from_internal_vmpa(&addr);
+ if (cursor != NULL)
+ {
+ result = pygobject_new(G_OBJECT(cursor));
+ g_object_unref(G_OBJECT(cursor));
+ }
+ else
+ {
+ result = Py_None;
+ Py_INCREF(result);
+ }
return result;
}
-#endif
/******************************************************************************
@@ -137,30 +556,46 @@ static PyObject *py_line_generator_compute_addr(PyObject *self, PyObject *args)
* Remarques : - *
* *
******************************************************************************/
-#if 0
-static PyObject *py_line_generator_contains_addr(PyObject *self, PyObject *args)
+
+static PyObject *py_line_generator_contain_cursor(PyObject *self, PyObject *args)
{
- GLineGenerator *generator; /* Version native */
- PyObject *py_vmpa; /* Localisation version Python */
+ PyObject *result; /* Propriétés à retourner */
size_t index; /* Indice dans le tampon */
size_t repeat; /* Utilisations successives */
+ GLineCursor *cursor; /* Curseur à venir situer */
int ret; /* Bilan de lecture des args. */
- vmpa2t *addr; /* Adresse visée par l'opérat° */
+ GLineGenerator *generator; /* Version native */
+ int status; /* Bilan d'une analyse */
+
+#define LINE_GENERATOR_CONTAIN_CURSOR_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" \
+ "\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" \
+ "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, "nnO&", &index, &repeat, convert_to_line_cursor, &cursor);
+ if (!ret) return NULL;
generator = G_LINE_GENERATOR(pygobject_get(self));
- ret = PyArg_ParseTuple(args, "O!kk", get_python_vmpa_type(), &py_vmpa, &index, &repeat);
- if (!ret) return NULL;
-
- addr = get_internal_vmpa(py_vmpa);
- if (addr == NULL) return NULL;
+ status = g_line_generator_contains_cursor(generator, index, repeat, cursor);
- g_line_generator_contains_addr(generator, addr, index, repeat);
+ result = PyLong_FromLong(status);
- Py_RETURN_NONE;
+ return result;
}
-#endif
/******************************************************************************
@@ -179,20 +614,34 @@ static PyObject *py_line_generator_contains_addr(PyObject *self, PyObject *args)
static PyObject *py_line_generator_get_flags(PyObject *self, PyObject *args)
{
PyObject *result; /* Propriétés à retourner */
- GLineGenerator *generator; /* Version native */
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 */
- generator = G_LINE_GENERATOR(pygobject_get(self));
-
- ret = PyArg_ParseTuple(args, "kk", &index, &repeat);
+#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." \
+)
+
+ ret = PyArg_ParseTuple(args, "nn", &index, &repeat);
if (!ret) return NULL;
+ generator = G_LINE_GENERATOR(pygobject_get(self));
+
flags = g_line_generator_get_flags(generator, index, repeat);
- result = Py_BuildValue("I", flags);
+ result = cast_with_constants_group_from_type(get_python_buffer_line_type(), "BufferLineFlags", flags);
return result;
@@ -214,19 +663,33 @@ static PyObject *py_line_generator_get_flags(PyObject *self, PyObject *args)
static PyObject *py_line_generator_print(PyObject *self, PyObject *args)
{
- GLineGenerator *generator; /* Version native */
GBufferLine *line; /* Ligne de rendu à compléter */
size_t index; /* Indice dans le tampon */
size_t repeat; /* Utilisations successives */
GBinContent *content; /* Contenu binaire associé */
+ GLineGenerator *generator; /* Version native */
int ret; /* Bilan de lecture des args. */
- generator = G_LINE_GENERATOR(pygobject_get(self));
-
- ret = PyArg_ParseTuple(args, "O&kkO&", convert_to_buffer_line, &line, &index,
+#define LINE_GENERATOR_PRINT_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" \
+ "\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" \
+ "\n" \
+ "If set, the content is a pychrysalide.analysis.BinContent" \
+ " instance providing access to the processed binary data." \
+)
+
+ ret = PyArg_ParseTuple(args, "O&nnO&", convert_to_buffer_line, &line, &index,
&repeat, convert_to_binary_content, &content);
if (!ret) return NULL;
+ generator = G_LINE_GENERATOR(pygobject_get(self));
+
g_line_generator_print(generator, line, index, repeat, content);
Py_RETURN_NONE;
@@ -234,78 +697,45 @@ static PyObject *py_line_generator_print(PyObject *self, PyObject *args)
}
-
-
-
-
-
-
-
-
-
-
-
-#if 0
-
/******************************************************************************
* *
-* Paramètres : - *
+* Paramètres : self = classe représentant un générateur à manipuler. *
+* closure = non utilisé ici. *
* *
-* Description : Fournit un accès à une définition de type à diffuser. *
+* Description : Indique le nombre de ligne prêtes à être générées. *
* *
-* Retour : - *
+* Retour : Nombre de lignes devant apparaître au final. *
* *
* Remarques : - *
* *
******************************************************************************/
-static void python_line_generator_interface_init(GLineGeneratorIface *iface, PyTypeObject *type)
+static PyObject *py_line_generator_get_lines_count(PyObject *self, void *closure)
{
- GLineGeneratorIface *parent; /* Défintion parente */
- size_t i; /* Boucle de parcours */
- PyObject *method; /* Méthode à associer */
-
- static const char *meth_names[] = {
- "count_lines",
- "compute_addr",
- "contains_addr",
- "get_flags",
- "print"
- };
-
- parent = g_type_interface_peek_parent(iface);
-
- for (i = 0; i < ARRAY_SIZE(meth_names); i++)
- {
- method = NULL;
-
- if (type != NULL)
- method = PyObject_GetAttrString((PyObject *)type, meth_names[i]);
-
- if (method != NULL && PyObject_TypeCheck(method, &PyCFunction_Type) == 0)
- /*iface->iface_method = _wrap_TestInterface__proxy_do_iface_method*/;
+ PyObject *result; /* Décompte à retourner */
+ GLineGenerator *generator; /* Version native */
+ size_t count; /* Nombre de lignes présentes */
- else
- {
- PyErr_Clear();
+#define LINE_GENERATOR_LINES_COUNT_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ lines_count, py_line_generator, \
+ "Quantity of lines produced by the generator.\n" \
+ "\n" \
+ "This number may vary between calls, if a width has changed" \
+ " for instance." \
+)
- if (parent != NULL)
- /*iface->iface_method = parent->iface_method*/;
+ generator = G_LINE_GENERATOR(pygobject_get(self));
- }
+ count = g_line_generator_count_lines(generator);
- Py_XDECREF(method);
+ result = PyLong_FromSize_t(count);
- }
+ return result;
}
-#endif
-
-
-
-
/******************************************************************************
* *
* Paramètres : - *
@@ -321,37 +751,20 @@ static void python_line_generator_interface_init(GLineGeneratorIface *iface, PyT
PyTypeObject *get_python_line_generator_type(void)
{
static PyMethodDef py_line_generator_methods[] = {
- {
- "count_lines", py_line_generator_count_lines,
- METH_NOARGS,
- "count_lines($self, /)\n--\n\nCount the number of lines which can be displayed."
- },
-#if 0
- {
- "compute_addr", py_line_generator_compute_addr,
- METH_VARARGS,
- "compute_addr($self, x, index, repeat, /)\n--\n\nReturn the position at a given location."
- },
- {
- "contains_addr", py_line_generator_contains_addr,
- METH_VARARGS,
- "contains_addr($self, addr, index, repeat, /)\n--\n\nTell if the generator contains an address."
- },
-#endif
- {
- "get_flags", py_line_generator_get_flags,
- METH_VARARGS,
- "get_flags($self, index, repeat, /)\n--\n\nGet the flags of a position from the generator."
- },
- {
- "print", py_line_generator_print,
- METH_VARARGS,
- "print($self, line, index, repeat, content, /)\n--\n\nProduce output into a line from content."
- },
+ 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,
{ NULL }
};
static PyGetSetDef py_line_generator_getseters[] = {
+ LINE_GENERATOR_LINES_COUNT_ATTRIB,
{ NULL }
};
@@ -360,11 +773,11 @@ PyTypeObject *get_python_line_generator_type(void)
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "pychrysalide.glibext.LineGenerator",
- //.tp_basicsize = sizeof(PyGObject),
+ .tp_basicsize = sizeof(PyObject),
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- .tp_doc = "PyChrysalide line content generator",
+ .tp_doc = LINE_GENERATOR_DOC,
.tp_methods = py_line_generator_methods,
.tp_getset = py_line_generator_getseters,
@@ -394,6 +807,14 @@ bool ensure_python_line_generator_is_registered(void)
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_finalize = NULL,
+ .interface_data = NULL,
+
+ };
+
type = get_python_line_generator_type();
if (!PyType_HasFeature(type, Py_TPFLAGS_READY))
@@ -402,7 +823,7 @@ bool ensure_python_line_generator_is_registered(void)
dict = PyModule_GetDict(module);
- if (!register_interface_for_pygobject(dict, G_TYPE_LINE_GENERATOR, type))
+ if (!register_interface_for_pygobject_2(dict, G_TYPE_LINE_GENERATOR, type, &info))
return false;
}
@@ -410,3 +831,48 @@ bool ensure_python_line_generator_is_registered(void)
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 générateur de lignes. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_line_generator(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_line_generator_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 line generator");
+ break;
+
+ case 1:
+ *((GLineGenerator **)dst) = G_LINE_GENERATOR(pygobject_get(arg));
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}