summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/glibext/strbuilder.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/pychrysalide/glibext/strbuilder.c')
-rw-r--r--plugins/pychrysalide/glibext/strbuilder.c199
1 files changed, 166 insertions, 33 deletions
diff --git a/plugins/pychrysalide/glibext/strbuilder.c b/plugins/pychrysalide/glibext/strbuilder.c
index 482f7df..a6de0f0 100644
--- a/plugins/pychrysalide/glibext/strbuilder.c
+++ b/plugins/pychrysalide/glibext/strbuilder.c
@@ -2,7 +2,7 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
* strbuilder.c - équivalent Python du fichier "glibext/strbuilder.c"
*
- * Copyright (C) 2021 Cyrille Bagard
+ * Copyright (C) 2025 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -37,11 +37,22 @@
+/* ------------------------ GLUE POUR CREATION DEPUIS PYTHON ------------------------ */
+
+
/* Procède à l'initialisation de l'interface d'exportation. */
static void py_string_builder_interface_init(GStringBuilderInterface *, gpointer *);
/* Exporte une chaîne de caractères à partir d'un objet. */
-bool py_string_builder_to_string_wrapper(const GStringBuilder *, unsigned int, sized_binary_t *);
+static bool py_string_builder_to_string_wrapper(const GStringBuilder *, unsigned int, sized_binary_t *);
+
+
+
+/* ------------------------- CONNEXION AVEC L'API DE PYTHON ------------------------- */
+
+
+/* Transmet la description d'un objet définie par son parent. */
+static PyObject *py_string_builder_parent_to_string(PyObject *, PyObject *);
/* Exporte une chaîne de caractères à partir d'un objet. */
static PyObject *py_string_builder_to_string(PyObject *, PyObject *);
@@ -51,6 +62,11 @@ static PyObject *py_string_builder_str(PyObject *);
+/* ---------------------------------------------------------------------------------- */
+/* GLUE POUR CREATION DEPUIS PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
/******************************************************************************
* *
* Paramètres : iface = interface GLib à initialiser. *
@@ -98,9 +114,9 @@ static void py_string_builder_interface_init(GStringBuilderInterface *iface, gpo
* *
******************************************************************************/
-bool py_string_builder_to_string_wrapper(const GStringBuilder *builder, unsigned int flags, sized_binary_t *out)
+static bool py_string_builder_to_string_wrapper(const GStringBuilder *builder, unsigned int flags, sized_binary_t *out)
{
- bool result; /* Bilan à retourner */
+ bool result; /* Bilan à retourner */
PyGILState_STATE gstate; /* Sauvegarde d'environnement */
PyObject *pyobj; /* Objet Python concerné */
PyObject *args; /* Arguments pour l'appel */
@@ -119,7 +135,10 @@ bool py_string_builder_to_string_wrapper(const GStringBuilder *builder, unsigned
"The optional *flags* argument define hints for the operation" \
" (for instance the Intel or AT&T flavor for x86 assembly).\n" \
"\n" \
- "The result has to be a string or *None* in case of error." \
+ "The result has to be a string." \
+ "\n" \
+ "A *TypeError* exception is raised if the return value is not" \
+ " a string." \
)
result = false;
@@ -128,38 +147,37 @@ bool py_string_builder_to_string_wrapper(const GStringBuilder *builder, unsigned
pyobj = pygobject_new(G_OBJECT(builder));
- if (has_python_method(pyobj, "_to_string"))
- {
- args = PyTuple_New(1);
- PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(flags));
+ args = PyTuple_New(1);
+ PyTuple_SetItem(args, 0, PyLong_FromUnsignedLong(flags));
- pyret = run_python_method(pyobj, "_to_string", args);
+ pyret = run_python_method(pyobj, "_to_string", args);
- if (pyret != NULL && pyret != Py_None)
+ if (pyret != NULL)
+ {
+ if (PyUnicode_Check(pyret))
{
- if (PyUnicode_Check(pyret))
- {
- utf8 = PyUnicode_AsUTF8AndSize(pyret, &size);
-
- if (utf8 != NULL)
- {
- assert(size >= 0);
+ utf8 = PyUnicode_AsUTF8AndSize(pyret, &size);
- add_to_sized_binary(out, utf8, size);
- result = true;
+ if (utf8 != NULL)
+ {
+ assert(size >= 0);
- }
+ add_to_sized_binary(out, utf8, size);
+ result = true;
}
}
- Py_XDECREF(pyret);
-
- Py_DECREF(args);
+ if (!result)
+ PyErr_SetString(PyExc_TypeError, _("object description has to get provided as an UTF-8 string value"));
}
+ Py_XDECREF(pyret);
+
+ Py_DECREF(args);
+
Py_DECREF(pyobj);
PyGILState_Release(gstate);
@@ -169,6 +187,108 @@ bool py_string_builder_to_string_wrapper(const GStringBuilder *builder, unsigned
}
+
+/* ---------------------------------------------------------------------------------- */
+/* CONNEXION AVEC L'API DE PYTHON */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : self = objet dont l'instance se veut unique. *
+* args = adresse non utilisée ici. *
+* *
+* Description : Transmet la description d'un objet définie par son parent. *
+* *
+* Retour : Présentation de l'élément construite. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_string_builder_parent_to_string(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Valeur à retourner */
+ unsigned int flags; /* Eventuelles indications */
+ int ret; /* Bilan de lecture des args. */
+ GStringBuilder *builder; /* Mécanismes natifs */
+ GStringBuilderInterface *iface; /* Interface utilisée */
+ GStringBuilderInterface *parent_iface; /* Interface parente */
+ sized_binary_t out; /* Description construite */
+ bool status; /* Bilan de l'opération */
+
+#define STRING_BUILDER_PARENT_TO_STRING_METHOD PYTHON_METHOD_DEF \
+( \
+ parent_to_string, "$self, /, flags=0", \
+ METH_VARARGS, py_string_builder, \
+ "Provide a string representation defined by the interface" \
+ " implementation from the object native parent.\n" \
+ "\n" \
+ "The result is a string.\n" \
+ "\n" \
+ "A *TypeError* exception is raised if the object parent does" \
+ " not implement the pychrysalide.glibext.StringBuilder" \
+ " interface." \
+ "\n" \
+ "A *RuntimeError* exception is raised if the direct parent type"\
+ " of the object has not a native implementation. For Python" \
+ " implementations, the super()._to_string() function has to be" \
+ " used instead.\n" \
+ "\n" \
+ "A *BufferError* exception is raised if the description has" \
+ " not been able to get created." \
+)
+
+ if (!check_for_native_parent(self))
+ return NULL;
+
+ flags = 0;
+
+ ret = PyArg_ParseTuple(args, "|I", &flags);
+ if (!ret) return NULL;
+
+ builder = G_STRING_BUILDER(pygobject_get(self));
+
+ iface = G_STRING_BUILDER_GET_IFACE(builder);
+
+ parent_iface = g_type_interface_peek_parent(iface);
+
+ if (parent_iface == NULL)
+ {
+ PyErr_SetString(PyExc_TypeError, _("object parent does not implement the StringBuilder interface"));
+
+ result = NULL;
+
+ }
+ else
+ {
+ init_sized_binary(&out);
+
+ status = parent_iface->to_string(builder, flags, &out);
+
+ if (status)
+ result = PyUnicode_FromStringAndSize(out.data, out.size);
+
+ else
+ {
+ result = NULL;
+
+ if (PyErr_Occurred() == NULL)
+ PyErr_SetString(PyExc_BufferError, _("unable to create a description"));
+
+ }
+
+ exit_sized_binary(&out);
+
+ CLEAN_RESULT_IF_RAISED_EXCEPTION(result);
+
+ }
+
+ return result;
+
+}
+
+
/******************************************************************************
* *
* Paramètres : self = objet manipulé ici. *
@@ -176,7 +296,7 @@ bool py_string_builder_to_string_wrapper(const GStringBuilder *builder, unsigned
* *
* Description : Exporte une chaîne de caractères à partir d'un objet. *
* *
-* Retour : Présentation de l'élément construite ou None. *
+* Retour : Présentation de l'élément construite. *
* *
* Remarques : - *
* *
@@ -198,11 +318,13 @@ static PyObject *py_string_builder_to_string(PyObject *self, PyObject *args)
"Provide a string representation for the object which is used" \
" as the default implementation of the __repr__() method.\n" \
"\n" \
- "\n" \
"The optional *flags* argument define hints for the operation" \
" (for instance the Intel or AT&T flavor for x86 assembly).\n" \
"\n" \
- "The result is a string or *None* in case of error." \
+ "The result is a string.\n" \
+ "\n" \
+ "A *BufferError* exception is raised if the description has" \
+ " not been able to get created." \
)
flags = 0;
@@ -221,12 +343,17 @@ static PyObject *py_string_builder_to_string(PyObject *self, PyObject *args)
else
{
- result = Py_None;
- Py_INCREF(result);
+ result = NULL;
+
+ if (PyErr_Occurred() == NULL)
+ PyErr_SetString(PyExc_BufferError, _("unable to create a description"));
+
}
exit_sized_binary(&out);
+ CLEAN_RESULT_IF_RAISED_EXCEPTION(result);
+
return result;
}
@@ -238,13 +365,13 @@ static PyObject *py_string_builder_to_string(PyObject *self, PyObject *args)
* *
* Description : Fournit une représentation de l'objet exportable. *
* *
-* Retour : Présentation de l'élément construite ou None. *
+* Retour : Présentation de l'élément construite. *
* *
* Remarques : - *
* *
******************************************************************************/
-PyObject *py_string_builder_str(PyObject *self)
+static PyObject *py_string_builder_str(PyObject *self)
{
PyObject *result; /* Emplacement à retourner */
GStringBuilder *builder; /* Mécanismes natifs */
@@ -262,12 +389,17 @@ PyObject *py_string_builder_str(PyObject *self)
else
{
- result = Py_None;
- Py_INCREF(result);
+ result = NULL;
+
+ if (PyErr_Occurred() == NULL)
+ PyErr_SetString(PyExc_BufferError, _("unable to create a description"));
+
}
exit_sized_binary(&out);
+ CLEAN_RESULT_IF_RAISED_EXCEPTION(result);
+
return result;
}
@@ -289,6 +421,7 @@ PyTypeObject *get_python_string_builder_type(void)
{
static PyMethodDef py_string_builder_methods[] = {
STRING_BUILDER_TO_STRING_WRAPPER,
+ STRING_BUILDER_PARENT_TO_STRING_METHOD,
STRING_BUILDER_TO_STRING_METHOD,
{ NULL }
};