diff options
Diffstat (limited to 'plugins/pychrysalide/glibext/buffercache.c')
-rw-r--r-- | plugins/pychrysalide/glibext/buffercache.c | 947 |
1 files changed, 918 insertions, 29 deletions
diff --git a/plugins/pychrysalide/glibext/buffercache.c b/plugins/pychrysalide/glibext/buffercache.c index 9ce06c1..fec5844 100644 --- a/plugins/pychrysalide/glibext/buffercache.c +++ b/plugins/pychrysalide/glibext/buffercache.c @@ -28,63 +28,897 @@ #include <pygobject.h> -#include <glibext/gbuffercache.h> +#include <glibext/gbuffercache-int.h> +#include <plugins/dt.h> +#include "constants.h" +#include "bufferline.h" +#include "linegen.h" #include "../access.h" #include "../helpers.h" -#include "../arch/vmpa.h" +#include "../analysis/content.h" -#if 0 -/* Retrouve une ligne au sein d'un tampon avec une adresse. */ -static PyObject *py_code_buffer_find_line_by_addr(PyObject *, PyObject *); +/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */ +/* Accompagne la création d'une instance dérivée en Python. */ +static PyObject *py_buffer_cache_new(PyTypeObject *, PyObject *, PyObject *); + +/* Initialise une instance sur la base du dérivé de GObject. */ +static int py_buffer_cache_init(PyObject *, PyObject *, PyObject *); + + + +/* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */ + + +/* Insère un générateur dans des lignes à une position donnée. */ +static PyObject *py_buffer_cache_insert_at(PyObject *, PyObject *); + +/* Retire une ligne du tampon. */ +static PyObject *py_buffer_cache_delete_at(PyObject *, PyObject *); + +/* Retire un type de générateur de lignes. */ +static PyObject *py_buffer_cache_delete_type_at(PyObject *, PyObject *); + +/* Ajoute en fin de tampon un générateur de lignes. */ +static PyObject *py_buffer_cache_append(PyObject *, PyObject *); + +/* Etend un tampon avec un générateur de lignes unique. */ +static PyObject *py_buffer_cache_extend_with(PyObject *, PyObject *); + +/* Réduit le tampon à une quantité de lignes précise. */ +static PyObject *py_buffer_cache_truncate(PyObject *, PyObject *); + +/* Détermine l'ensemble des propriétés attachées à une ligne. */ +static PyObject *py_buffer_cache_get_line_flags(PyObject *, PyObject *); + +/* Retrouve une ligne au sein d'un tampon avec un indice. */ +static PyObject *py_buffer_cache_find_line_by_index(PyObject *, PyObject *); + +/* Avance autant que possible vers une ligne idéale. */ +static PyObject *py_buffer_cache_look_for_flag(PyObject *, PyObject *); + +/* Indique l'éventuel contenu binaire associé au cache. */ +static PyObject *py_buffer_cache_get_content(PyObject *, void *); + +/* Fournit la hauteur d'impression d'une ligne visualisée. */ +static PyObject *py_buffer_cache_get_line_height(PyObject *, void *); + +/* Fournit la taille réservée pour la marge gauche. */ +static PyObject *py_buffer_cache_get_left_margin(PyObject *, void *); + +/* Fournit la position de départ pour l'impression de texte. */ +static PyObject *py_buffer_cache_get_text_position(PyObject *, void *); + +/* Compte le nombre de lignes rassemblées dans un tampon. */ +static PyObject *py_buffer_cache_get_lines_count(PyObject *, void *); + + + +/* ---------------------------------------------------------------------------------- */ +/* 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_buffer_cache_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_buffer_cache_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_BUFFER_CACHE, type->tp_name, NULL, NULL, NULL); + + if (first_time) + { + status = register_class_for_dynamic_pygobject(gtype, type, base); + + if (!status) + { + result = NULL; + goto exit; + } + + } + + /* On crée, et on laisse ensuite la main à PyGObject_Type.tp_init() */ + + simple_way: + + result = PyType_GenericNew(type, args, kwds); + + exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : 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_buffer_cache_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + GBinContent *content; /* Instance GLib du contenu */ + int ret; /* Bilan de lecture des args. */ + GBufferCache *cache; /* Version GLib du tampon */ + +#define BUFFER_CACHE_DOC \ + "The BufferCache object manages a group of lines intended to get" \ + " printed onto the screen or into a file.\n" \ + "\n" \ + "These lines are cached and rebuilt when needed.\n" \ + "\n" \ + "Instances can be created using the following constructor:\n" \ + "\n" \ + " BufferCache(content=None)" \ + "\n" \ + "Where content is a pychrysalide.analysis.BinContent instance, if" \ + " defined. This content is provided to lines as argument when the" \ + " lines get printed, so it may not be always useful and thus can be" \ + " discarded when creating a new buffer cache." \ + + /* Récupération des paramètres */ + + content = NULL; + + ret = PyArg_ParseTuple(args, "|O&", convert_to_binary_content_or_none, &content); + if (!ret) return -1; + + /* Initialisation d'un objet GLib */ + + ret = forward_pygobjet_init(self); + if (ret == -1) return -1; + + /* Eléments de base */ + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + if (content != NULL) + { + cache->content = content; + g_object_ref(G_OBJECT(content)); + } + + return 0; + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* TAMPON POUR CODE DESASSEMBLE */ +/* ---------------------------------------------------------------------------------- */ + /****************************************************************************** * * * Paramètres : self = classe représentant un tampon de code. * * args = arguments fournis à l'appel. * * * -* Description : Retrouve une ligne au sein d'un tampon avec une adresse. * +* Description : Insère un générateur dans des lignes à une position donnée. * * * -* Retour : Instance de la ligne trouvée. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static PyObject *py_code_buffer_find_line_by_addr(PyObject *self, PyObject *args) +static PyObject *py_buffer_cache_insert_at(PyObject *self, PyObject *args) { PyObject *result; /* Trouvailles à retourner */ - PyObject *py_vmpa; /* Localisation version Python */ + size_t index; /* Indice de ligne à supprimer */ + GLineGenerator *generator; /* Générateur à associer */ + BufferLineFlags flags; /* Particularités nominales */ + int before; /* Insertion avant ? */ + int after; /* Insertion après ? */ int ret; /* Bilan de lecture des args. */ - vmpa2t *addr; /* Adresse visée par l'opérat° */ - GBuffercache *buffer; /* Version native */ - GBufferLine *line; /* Ligne trouvée */ + GBufferCache *cache; /* Tampon natif à consulter */ + +#define BUFFER_CACHE_INSERT_AT_METHOD PYTHON_METHOD_DEF \ +( \ + insert_at, "$self, index, generator, /, flags=" \ + "pychrysalide.glibext.BufferLine.BufferLineFlags.NONE," \ + " before=False, after=False", \ + METH_VARARGS, py_buffer_cache, \ + "Add an extra content generator to a given line.\n" \ + "\n" \ + "The new content generator for the line at, before or after" \ + " the provided index is a pychrysalide.glibext.LineGenerator" \ + " instance. Nominal properties can be set for this line as" \ + " extra pychrysalide.glibext.BufferLine.BufferLineFlags" \ + " values.\n" \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) - ret = PyArg_ParseTuple(args, "O", &py_vmpa); + flags = BLF_NONE; + before = 0; + after = 0; + + ret = PyArg_ParseTuple(args, "nO&|O&pp", &index, convert_to_line_generator, &generator, + convert_to_buffer_line_flags, &flags, &before, &after); if (!ret) return NULL; - ret = PyObject_IsInstance(py_vmpa, (PyObject *)get_python_vmpa_type()); + cache = G_BUFFER_CACHE(pygobject_get(self)); + + g_buffer_cache_insert_at(cache, index, generator, flags, before, after); + + result = Py_None; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un tampon de code. * +* args = arguments fournis à l'appel. * +* * +* Description : Retire une ligne du tampon. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_delete_at(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + size_t index; /* Indice de ligne à supprimer */ + int ret; /* Bilan de lecture des args. */ + GBufferCache *cache; /* Tampon natif à consulter */ + +#define BUFFER_CACHE_DELETE_AT_METHOD PYTHON_METHOD_DEF \ +( \ + delete_at, "$self, index, /", \ + METH_VARARGS, py_buffer_cache, \ + "Delete the line at the *index* position from a buffer cache.\n" \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + ret = PyArg_ParseTuple(args, "n", &index); if (!ret) return NULL; - addr = get_internal_vmpa(py_vmpa); - if (addr == NULL) return NULL; + cache = G_BUFFER_CACHE(pygobject_get(self)); + + g_buffer_cache_delete_at(cache, index); + + result = Py_None; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un tampon de code. * +* args = arguments fournis à l'appel. * +* * +* Description : Retire un type de générateur de lignes. * +* * +* Retour : Générateur éventuellement trouvé ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_delete_type_at(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + size_t index; /* Indice de ligne à supprimer */ + PyObject *py_gtype; /* Version Python d'un GType */ + int before; /* Insertion avant ? */ + int after; /* Insertion après ? */ + int ret; /* Bilan de lecture des args. */ + GType gtype; /* Type de générateur visé */ + GBufferCache *cache; /* Tampon natif à consulter */ + GLineGenerator *generator; /* Générateur retiré ou NULL */ + +#define BUFFER_CACHE_DELETE_TYPE_AT_METHOD PYTHON_METHOD_DEF \ +( \ + delete_type_at, "$self, index, gtype, /, before=False, after=False", \ + METH_VARARGS, py_buffer_cache, \ + "Delete the first generator of a given type found inside a line of a" \ + " buffer cache.\n" \ + "\n" \ + "The target type has to be a gobject.GType, usually provided by the" \ + " *__gtype__* attribute of a generator interface. The generator is" \ + " deleted from the line at, before or after the provided index.\n" \ + "\n" \ + "The function returns the deleted generator as a" \ + " pychrysalide.glibext.LineGenerator instance, or None if none found.\n"\ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + before = 0; + after = 0; + + ret = PyArg_ParseTuple(args, "nO|pp", &index, &py_gtype, &before, &after); + if (!ret) return NULL; - buffer = G_CODE_BUFFER(pygobject_get(self)); + gtype = pyg_type_from_object(py_gtype); + if (gtype == 0) return NULL; - line = g_code_buffer_find_line_by_addr(buffer, addr, 0, NULL); - if (line == NULL) Py_RETURN_NONE; + cache = G_BUFFER_CACHE(pygobject_get(self)); - result = pygobject_new(G_OBJECT(line)); + generator = g_buffer_cache_delete_type_at(cache, index, gtype, before, after); + + if (generator != NULL) + { + result = pygobject_new(G_OBJECT(generator)); + g_object_unref(G_OBJECT(generator)); + } + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un tampon de code. * +* args = arguments fournis à l'appel. * +* * +* Description : Ajoute en fin de tampon un générateur de lignes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_append(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + GLineGenerator *generator; /* Générateur à associer */ + BufferLineFlags flags; /* Particularités nominales */ + int ret; /* Bilan de lecture des args. */ + GBufferCache *cache; /* Tampon natif à consulter */ + +#define BUFFER_CACHE_APPEND_METHOD PYTHON_METHOD_DEF \ +( \ + append, "$self, generator, /, flags=" \ + "pychrysalide.glibext.BufferLine.BufferLineFlags.NONE", \ + METH_VARARGS, py_buffer_cache, \ + "Append a new line at the end of a buffer cache.\n" \ + "\n" \ + "The content generator for this new line is a" \ + " pychrysalide.glibext.LineGenerator instance. Nominal" \ + " properties can be set for the line as extra" \ + " pychrysalide.glibext.BufferLine.BufferLineFlags values.\n" \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + flags = BLF_NONE; + + ret = PyArg_ParseTuple(args, "O&|O&", convert_to_line_generator, &generator, + convert_to_buffer_line_flags, &flags); + if (!ret) return NULL; + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + g_buffer_cache_append(cache, generator, flags); + + result = Py_None; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un tampon de code. * +* args = arguments fournis à l'appel. * +* * +* Description : Etend un tampon avec un générateur de lignes unique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_extend_with(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + size_t count; /* Quantité de lignes à créer */ + GLineGenerator *generator; /* Générateur à associer */ + int ret; /* Bilan de lecture des args. */ + GBufferCache *cache; /* Tampon natif à consulter */ + +#define BUFFER_CACHE_EXTEND_WITH_METHOD PYTHON_METHOD_DEF \ +( \ + extend_with, "$self, count, generator, /", \ + METH_VARARGS, py_buffer_cache, \ + "Extend the buffer cache so it will contain *count* lines.\n" \ + "\n" \ + "The *count* number should be greater than the current line" \ + " quantity, otherwise the call makes no sense. The generator" \ + " is a pychrysalide.glibext.LineGenerator instance used to" \ + " produce the extra new lines on demand." \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + ret = PyArg_ParseTuple(args, "nO&", &count, convert_to_line_generator, &generator); + if (!ret) return NULL; + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + g_buffer_cache_extend_with(cache, count, generator); + + result = Py_None; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un tampon de code. * +* args = arguments fournis à l'appel. * +* * +* Description : Réduit le tampon à une quantité de lignes précise. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_truncate(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + size_t max; /* Nombre de lignes au maximum */ + int ret; /* Bilan de lecture des args. */ + GBufferCache *cache; /* Tampon natif à consulter */ + +#define BUFFER_CACHE_TRUNCATE_METHOD PYTHON_METHOD_DEF \ +( \ + truncate, "$self, max, /", \ + METH_VARARGS, py_buffer_cache, \ + "Shrink the buffer cache so it will contain at most *max* lines.\n" \ + "\n" \ + "The *max* number should be lesser than the current line quantity," \ + " otherwise no effect will happen." \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + ret = PyArg_ParseTuple(args, "n", &max); + if (!ret) return NULL; + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + g_buffer_cache_truncate(cache, max); + + result = Py_None; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un tampon de code. * +* args = arguments fournis à l'appel. * +* * +* Description : Détermine l'ensemble des propriétés attachées à une ligne. * +* * +* Retour : Somme de toutes les propriétés enregistrées. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_get_line_flags(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + size_t index; /* Indice de la ligne visée */ + int ret; /* Bilan de lecture des args. */ + GBufferCache *cache; /* Tampon natif à consulter */ + BufferLineFlags flags; /* Fanions conservés */ + +#define BUFFER_CACHE_GET_LINE_FLAGS_METHOD PYTHON_METHOD_DEF \ +( \ + get_line_flags, "$self, index, /", \ + METH_VARARGS, py_buffer_cache, \ + "Provide the optional flags assigned to a given buffer line. The" \ + " line is located using the *index* argument.\n" \ + "\n" \ + "The result is a pychrysalide.glibext.BufferLine.BufferLineFlags" \ + " value.\n" \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + ret = PyArg_ParseTuple(args, "n", &index); + if (!ret) return NULL; + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + flags = g_buffer_cache_get_line_flags(cache, index); + + result = cast_with_constants_group_from_type(get_python_buffer_line_type(), "BufferLineFlags", flags); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un tampon de code. * +* args = arguments fournis à l'appel. * +* * +* Description : Retrouve une ligne au sein d'un tampon avec un indice. * +* * +* Retour : Line retrouvée ou None en cas d'échec. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_find_line_by_index(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + size_t index; /* Indice de la ligne visée */ + int ret; /* Bilan de lecture des args. */ + GBufferCache *cache; /* Tampon natif à consulter */ + GBufferLine *line; /* Ligne trouvée ? */ + +#define BUFFER_CACHE_FIND_LINE_BY_INDEX_METHOD PYTHON_METHOD_DEF \ +( \ + find_line_by_index, "$self, index, /", \ + METH_VARARGS, py_buffer_cache, \ + "Retrieve the line contained in a buffer cache at a given index.\n" \ + "\n" \ + "The result is a pychrysalide.glibext.BufferLine instance or" \ + " None.\n" \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + ret = PyArg_ParseTuple(args, "n", &index); + if (!ret) return NULL; + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + line = g_buffer_cache_find_line_by_index(cache, index); + + if (line != NULL) + { + result = pygobject_new(G_OBJECT(line)); + g_object_unref(G_OBJECT(line)); + } + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant un tampon de code. * +* args = arguments fournis à l'appel. * +* * +* Description : Avance autant que possible vers une ligne idéale. * +* * +* Retour : Indice de la ligne recherchée, si elle existe. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_look_for_flag(PyObject *self, PyObject *args) +{ + PyObject *result; /* Trouvailles à retourner */ + size_t index; /* Indice de la ligne visée */ + BufferLineFlags flag; /* Particularité à retrouver */ + int ret; /* Bilan de lecture des args. */ + GBufferCache *cache; /* Tampon natif à consulter */ + size_t found; /* Indice de la ligne trouvée */ + +#define BUFFER_CACHE_LOOK_FOR_FLAG_METHOD PYTHON_METHOD_DEF \ +( \ + look_for_flag, "$self, index, flag, /", \ + METH_VARARGS, py_buffer_cache, \ + "Iterate the buffer cache lines from a starting index until a" \ + " line with flags matching the provided flag is met.\n" \ + "\n" \ + "The *flag* argument has to be a" \ + " pychrysalide.glibext.BufferLine.BufferLineFlags value.\n" \ + "\n" \ + "The result is an index equal or greater than the starting index" \ + " or, if no match is found, the number of lines in the buffer" \ + " cache.\n" \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + ret = PyArg_ParseTuple(args, "nO&", &index, convert_to_buffer_line_flags, &flag); + if (!ret) return NULL; + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + found = g_buffer_cache_look_for_flag(cache, index, flag); + + result = PyLong_FromSize_t(found); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Indique l'éventuel contenu binaire associé au cache. * +* * +* Retour : Eventuel contenu renseigné ou None. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_get_content(PyObject *self, void *closure) +{ + PyObject *result; /* Contenu binaire à retourner */ + GBufferCache *cache; /* Tampon natif à consulter */ + GBinContent *content; /* Contenu éventuel à renvoyer */ + +#define BUFFER_CACHE_CONTENT_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + content, py_buffer_cache, \ + "Binary content linked to the buffer cache, as a" \ + " pychrysalide.analysis.BinContent instance, or None." \ +) + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + content = g_buffer_cache_get_content(cache); + + if (content != NULL) + { + result = pygobject_new(G_OBJECT(content)); + g_object_unref(G_OBJECT(content)); + } + + else + { + result = Py_None; + Py_INCREF(result); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la hauteur d'impression d'une ligne visualisée. * +* * +* Retour : Hauteur de ligne en pixels. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_get_line_height(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GBufferCache *cache; /* Tampon natif à consulter */ + gint height; /* Valeur obtenue du cache */ + +#define BUFFER_CACHE_LINE_HEIGHT_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + line_height, py_buffer_cache, \ + "Height of a line printed from the buffer cache." \ +) + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + height = g_buffer_cache_get_line_height(cache); + + result = PyLong_FromLong(height); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la taille réservée pour la marge gauche. * +* * +* Retour : Largeur en pixels. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_get_left_margin(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GBufferCache *cache; /* Tampon natif à consulter */ + gint width; /* Valeur obtenue du cache */ + +#define BUFFER_CACHE_LEFT_MARGIN_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + left_margin, py_buffer_cache, \ + "Width of the left margin inside of a buffer cache output." \ +) + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + width = g_buffer_cache_get_left_margin(cache); + + result = PyLong_FromLong(width); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Fournit la position de départ pour l'impression de texte. * +* * +* Retour : Position en pixels. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_get_text_position(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GBufferCache *cache; /* Tampon natif à consulter */ + gint pos; /* Valeur obtenue du cache */ + +#define BUFFER_CACHE_TEXT_POSITION_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + text_position, py_buffer_cache, \ + "Starting position of the text on the left of a buffer cache output." \ +) + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + pos = g_buffer_cache_get_text_position(cache); + + result = PyLong_FromLong(pos); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = objet Python concerné par l'appel. * +* closure = non utilisé ici. * +* * +* Description : Compte le nombre de lignes rassemblées dans un tampon. * +* * +* Retour : Nombre de lignes constituant le tampon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_buffer_cache_get_lines_count(PyObject *self, void *closure) +{ + PyObject *result; /* Valeur à retourner */ + GBufferCache *cache; /* Tampon natif à consulter */ + size_t count; /* Décompte de première main */ + +#define BUFFER_CACHE_LINES_COUNT_ATTRIB PYTHON_GET_DEF_FULL \ +( \ + lines_count, py_buffer_cache, \ + "Count the number of lines contained in a buffer cache.\n" \ + "\n" \ + "An access lock has to be held for the cache; see the" \ + " pychrysalide.glibext.BufferCache.lock() function." \ +) + + cache = G_BUFFER_CACHE(pygobject_get(self)); + + count = g_buffer_cache_count_lines(cache); + + result = PyLong_FromSize_t(count); return result; } -#endif /****************************************************************************** @@ -102,17 +936,24 @@ static PyObject *py_code_buffer_find_line_by_addr(PyObject *self, PyObject *args PyTypeObject *get_python_buffer_cache_type(void) { static PyMethodDef py_buffer_cache_methods[] = { -#if 0 - { - "find_line_by_addr", py_buffer_cache_find_line_by_addr, - METH_VARARGS, - "find_line_by_addr($self, addr, /)\n--\n\nFind a buffer line with a given address." - }, -#endif + BUFFER_CACHE_INSERT_AT_METHOD, + BUFFER_CACHE_DELETE_AT_METHOD, + BUFFER_CACHE_DELETE_TYPE_AT_METHOD, + BUFFER_CACHE_APPEND_METHOD, + BUFFER_CACHE_EXTEND_WITH_METHOD, + BUFFER_CACHE_TRUNCATE_METHOD, + BUFFER_CACHE_GET_LINE_FLAGS_METHOD, + BUFFER_CACHE_FIND_LINE_BY_INDEX_METHOD, + BUFFER_CACHE_LOOK_FOR_FLAG_METHOD, { NULL } }; static PyGetSetDef py_buffer_cache_getseters[] = { + BUFFER_CACHE_CONTENT_ATTRIB, + BUFFER_CACHE_LINE_HEIGHT_ATTRIB, + BUFFER_CACHE_LEFT_MARGIN_ATTRIB, + BUFFER_CACHE_TEXT_POSITION_ATTRIB, + BUFFER_CACHE_LINES_COUNT_ATTRIB, { NULL } }; @@ -125,11 +966,14 @@ PyTypeObject *get_python_buffer_cache_type(void) .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "PyChrysalide code buffer", + .tp_doc = BUFFER_CACHE_DOC, .tp_methods = py_buffer_cache_methods, .tp_getset = py_buffer_cache_getseters, + .tp_init = py_buffer_cache_init, + .tp_new = py_buffer_cache_new + }; return &py_buffer_cache_type; @@ -171,3 +1015,48 @@ bool ensure_python_buffer_cache_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 tampon de lignes. * +* * +* Retour : Bilan de l'opération, voire indications supplémentaires. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int convert_to_buffer_cache(PyObject *arg, void *dst) +{ + int result; /* Bilan à retourner */ + + result = PyObject_IsInstance(arg, (PyObject *)get_python_buffer_cache_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: + *((GBufferCache **)dst) = G_BUFFER_CACHE(pygobject_get(arg)); + break; + + default: + assert(false); + break; + + } + + return result; + +} |