From 472d566943f527e18eb95f31dbe70c50043396aa Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 25 Nov 2019 08:18:21 +0100
Subject: Updated the Python bindings documentation for binary contents.

---
 plugins/pychrysalide/analysis/Makefile.am |   1 +
 plugins/pychrysalide/analysis/constants.c |  72 +++++++++
 plugins/pychrysalide/analysis/constants.h |  38 +++++
 plugins/pychrysalide/analysis/content.c   | 255 +++++++++++++++++-------------
 4 files changed, 254 insertions(+), 112 deletions(-)
 create mode 100644 plugins/pychrysalide/analysis/constants.c
 create mode 100644 plugins/pychrysalide/analysis/constants.h

diff --git a/plugins/pychrysalide/analysis/Makefile.am b/plugins/pychrysalide/analysis/Makefile.am
index 65f2150..bb7bec6 100644
--- a/plugins/pychrysalide/analysis/Makefile.am
+++ b/plugins/pychrysalide/analysis/Makefile.am
@@ -5,6 +5,7 @@ libpychrysaanalysis_la_SOURCES =		\
 	binary.h binary.c					\
 	block.h block.c						\
 	cattribs.h cattribs.c				\
+	constants.h constants.c				\
 	content.h content.c					\
 	loaded.h loaded.c					\
 	loading.h loading.c					\
diff --git a/plugins/pychrysalide/analysis/constants.c b/plugins/pychrysalide/analysis/constants.c
new file mode 100644
index 0000000..de7e522
--- /dev/null
+++ b/plugins/pychrysalide/analysis/constants.c
@@ -0,0 +1,72 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.c - ajout des constantes liées aux analyses
+ *
+ * Copyright (C) 2018 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.h"
+
+
+#include <common/endianness.h>
+
+
+#include "../helpers.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type dont le dictionnaire est à compléter.            *
+*                                                                             *
+*  Description : Définit les constantes relatives au contenus binaires.       *
+*                                                                             *
+*  Retour      : true en cas de succès de l'opération, false sinon.           *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool define_analysis_content_constants(PyTypeObject *type)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *values;                       /* Groupe de valeurs à établir */
+
+    values = PyDict_New();
+
+    result = add_const_to_group(values, "LITTLE", SRE_LITTLE);
+    if (result) result = add_const_to_group(values, "LITTLE_WORD", SRE_LITTLE_WORD);
+    if (result) result = add_const_to_group(values, "BIG_WORD", SRE_BIG_WORD);
+    if (result) result = add_const_to_group(values, "BIG", SRE_BIG);
+
+    if (!result)
+    {
+        Py_DECREF(values);
+        goto exit;
+    }
+
+    result = attach_constants_group(type, false, "SourceEndian", values,
+                                    "Endianness of handled data.");
+
+ exit:
+
+    return result;
+
+}
diff --git a/plugins/pychrysalide/analysis/constants.h b/plugins/pychrysalide/analysis/constants.h
new file mode 100644
index 0000000..c4da054
--- /dev/null
+++ b/plugins/pychrysalide/analysis/constants.h
@@ -0,0 +1,38 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * constants.h - prototypes pour l'ajout des constantes liées aux analyses
+ *
+ * Copyright (C) 2019 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_CONSTANTS_H
+#define _PLUGINS_PYCHRYSALIDE_ANALYSIS_CONSTANTS_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+/* Définit les constantes relatives aux contenus binaires. */
+bool define_analysis_content_constants(PyTypeObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSALIDE_ANALYSIS_CONSTANTS_H */
diff --git a/plugins/pychrysalide/analysis/content.c b/plugins/pychrysalide/analysis/content.c
index 5f8694a..93292fb 100644
--- a/plugins/pychrysalide/analysis/content.c
+++ b/plugins/pychrysalide/analysis/content.c
@@ -37,12 +37,23 @@
 
 
 #include "cattribs.h"
+#include "constants.h"
 #include "../access.h"
 #include "../helpers.h"
 #include "../arch/vmpa.h"
 
 
 
+#define BINARY_CONTENT_DOC                                              \
+    "The BinContent is an interface which handles access to a given"    \
+    " binary content."                                                  \
+    "\n"                                                                \
+    "All of its implementations are located in the"                     \
+    " pychrysalide.analysis.contents module. The main implemantation"   \
+    " is the pychrysalide.analysis.contents.FileContent class."
+
+
+
 /* Fournit le nom associé au contenu binaire. */
 static PyObject *py_binary_content_describe(PyObject *, PyObject *);
 
@@ -71,16 +82,16 @@ static PyObject *py_binary_content_get_attributes(PyObject *, void *);
 static PyObject *py_binary_content_get_checksum(PyObject *, void *);
 
 /* Détermine le nombre d'octets lisibles. */
-static PyObject *py_binary_content_compute_size(PyObject *, void *);
+static PyObject *py_binary_content_get_size(PyObject *, void *);
 
 /* Détermine la position initiale d'un contenu. */
-static PyObject *py_binary_content_compute_start_pos(PyObject *, void *);
+static PyObject *py_binary_content_get_start_pos(PyObject *, void *);
 
 /* Détermine la position finale d'un contenu. */
-static PyObject *py_binary_content_compute_end_pos(PyObject *, void *);
+static PyObject *py_binary_content_get_end_pos(PyObject *, void *);
 
 /* Renvoie tout le contenu binaire d'un coup. */
-static PyObject *py_binary_content_get_all_bytes(PyObject *, void *);
+static PyObject *py_binary_content_get_data(PyObject *, void *);
 
 
 
@@ -100,17 +111,25 @@ static PyObject *py_binary_content_get_all_bytes(PyObject *, void *);
 static PyObject *py_binary_content_describe(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Instance à retourner        */
-    GBinContent *content;                   /* Version GLib du format      */
     int full;                               /* Description complète ?      */
     int ret;                                /* Bilan de lecture des args.  */
+    GBinContent *content;                   /* Version GLib du format      */
     const char *desc;                       /* Description obtenue         */
 
-    content = G_BIN_CONTENT(pygobject_get(self));
-    assert(content != NULL);
+#define BINARY_CONTENT_DESCRIBE_METHOD PYTHON_METHOD_DEF                \
+(                                                                       \
+    describe, "$self, /, full=False",                                   \
+    METH_VARARGS, py_binary_content,                                    \
+    "Get a (full ?) description of the binary content."                 \
+)
 
-    ret = PyArg_ParseTuple(args, "p", &full);
+    full = 0;
+
+    ret = PyArg_ParseTuple(args, "|p", &full);
     if (!ret) return NULL;
 
+    content = G_BIN_CONTENT(pygobject_get(self));
+
     desc = g_binary_content_describe(content, full);
 
     result = PyUnicode_FromString(desc);
@@ -136,23 +155,25 @@ static PyObject *py_binary_content_describe(PyObject *self, PyObject *args)
 static PyObject *py_binary_content_read_raw(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Instance à retourner        */
-    GBinContent *content;                   /* Version GLib du format      */
-    PyObject *addr_obj;                     /* Objet pour une position     */
-    vmpa2t *addr;                           /* Position interne associée   */
+    vmpa2t addr;                            /* Position interne associée   */
     unsigned long long length;              /* Quantité de données à lire  */
     int ret;                                /* Bilan de lecture des args.  */
+    GBinContent *content;                   /* Version GLib du format      */
     const bin_t *val;                       /* Valeur lue à faire suivre   */
 
-    content = G_BIN_CONTENT(pygobject_get(self));
-    assert(content != NULL);
+#define BINARY_CONTENT_READ_RAW_METHOD PYTHON_METHOD_DEF                \
+(                                                                       \
+    read_raw, "$self, addr, length, /",                                 \
+    METH_VARARGS, py_binary_content,                                    \
+    "Read bytes from a given position."                                 \
+)
 
-    ret = PyArg_ParseTuple(args, "OK", &addr_obj, &length);
+    ret = PyArg_ParseTuple(args, "O&K", convert_any_to_vmpa, &addr, &length);
     if (!ret) return NULL;
 
-    addr = get_internal_vmpa(addr_obj);
-    assert(addr != NULL);
+    content = G_BIN_CONTENT(pygobject_get(self));
 
-    val = g_binary_content_get_raw_access(content, addr, length);
+    val = g_binary_content_get_raw_access(content, &addr, length);
     if (val == NULL)
     {
         PyErr_SetString(PyExc_Exception, _("Invalid read access."));
@@ -182,23 +203,25 @@ static PyObject *py_binary_content_read_raw(PyObject *self, PyObject *args)
 static PyObject *py_binary_content_read_u8(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Instance à retourner        */
-    GBinContent *content;                   /* Version GLib du format      */
+    vmpa2t addr;                            /* Position interne associée   */
     int ret;                                /* Bilan de lecture des args.  */
-    PyObject *addr_obj;                     /* Objet pour une position     */
-    vmpa2t *addr;                           /* Position interne associée   */
+    GBinContent *content;                   /* Version GLib du format      */
     uint8_t val;                            /* Valeur lue à faire suivre   */
     bool status;                            /* Bilan de l'opération        */
 
-    content = G_BIN_CONTENT(pygobject_get(self));
-    assert(content != NULL);
+#define BINARY_CONTENT_READ_U8_METHOD PYTHON_METHOD_DEF                 \
+(                                                                       \
+    read_u8, "$self, addr, /",                                          \
+    METH_VARARGS, py_binary_content,                                    \
+    "Read an unsigned byte from a given position."                      \
+)
 
-    ret = PyArg_ParseTuple(args, "O", &addr_obj);
+    ret = PyArg_ParseTuple(args, "O&", convert_any_to_vmpa, &addr);
     if (!ret) return NULL;
 
-    addr = get_internal_vmpa(addr_obj);
-    assert(addr != NULL);
+    content = G_BIN_CONTENT(pygobject_get(self));
 
-    status = g_binary_content_read_u8(content, addr, &val);
+    status = g_binary_content_read_u8(content, &addr, &val);
     if (!status)
     {
         PyErr_SetString(PyExc_Exception, _("Invalid read access."));
@@ -228,24 +251,29 @@ static PyObject *py_binary_content_read_u8(PyObject *self, PyObject *args)
 static PyObject *py_binary_content_read_u16(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Instance à retourner        */
-    GBinContent *content;                   /* Version GLib du format      */
-    int ret;                                /* Bilan de lecture des args.  */
-    PyObject *addr_obj;                     /* Objet pour une position     */
+    vmpa2t addr;                            /* Position interne associée   */
     unsigned long endianness;               /* Boutisme de la lecture      */
-    vmpa2t *addr;                           /* Position interne associée   */
+    int ret;                                /* Bilan de lecture des args.  */
+    GBinContent *content;                   /* Version GLib du format      */
     uint16_t val;                           /* Valeur lue à faire suivre   */
     bool status;                            /* Bilan de l'opération        */
 
-    content = G_BIN_CONTENT(pygobject_get(self));
-    assert(content != NULL);
+#define BINARY_CONTENT_READ_U16_METHOD PYTHON_METHOD_DEF                \
+(                                                                       \
+    read_u16, "$self, addr, endian, /",                                 \
+    METH_VARARGS, py_binary_content,                                    \
+    "Read two unsigned bytes from a given position."                    \
+    "\n"                                                                \
+    "The endianness of the data can be provided using"                  \
+    " pychrysalide.analysis.BinContent.SourceEndian values."            \
+)
 
-    ret = PyArg_ParseTuple(args, "Ok", &addr_obj, &endianness);
+    ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
     if (!ret) return NULL;
 
-    addr = get_internal_vmpa(addr_obj);
-    assert(addr != NULL);
+    content = G_BIN_CONTENT(pygobject_get(self));
 
-    status = g_binary_content_read_u16(content, addr, endianness, &val);
+    status = g_binary_content_read_u16(content, &addr, endianness, &val);
     if (!status)
     {
         PyErr_SetString(PyExc_Exception, _("Invalid read access."));
@@ -275,24 +303,29 @@ static PyObject *py_binary_content_read_u16(PyObject *self, PyObject *args)
 static PyObject *py_binary_content_read_u32(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Instance à retourner        */
-    GBinContent *content;                   /* Version GLib du format      */
-    int ret;                                /* Bilan de lecture des args.  */
-    PyObject *addr_obj;                     /* Objet pour une position     */
+    vmpa2t addr;                            /* Position interne associée   */
     unsigned long endianness;               /* Boutisme de la lecture      */
-    vmpa2t *addr;                           /* Position interne associée   */
+    int ret;                                /* Bilan de lecture des args.  */
+    GBinContent *content;                   /* Version GLib du format      */
     uint32_t val;                           /* Valeur lue à faire suivre   */
     bool status;                            /* Bilan de l'opération        */
 
-    content = G_BIN_CONTENT(pygobject_get(self));
-    assert(content != NULL);
+#define BINARY_CONTENT_READ_U32_METHOD PYTHON_METHOD_DEF                \
+(                                                                       \
+    read_u32, "$self, addr, endian, /",                                 \
+    METH_VARARGS, py_binary_content,                                    \
+    "Read four unsigned bytes from a given position."                   \
+    "\n"                                                                \
+    "The endianness of the data can be provided using"                  \
+    " pychrysalide.analysis.BinContent.SourceEndian values."            \
+)
 
-    ret = PyArg_ParseTuple(args, "Ok", &addr_obj, &endianness);
+    ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
     if (!ret) return NULL;
 
-    addr = get_internal_vmpa(addr_obj);
-    assert(addr != NULL);
+    content = G_BIN_CONTENT(pygobject_get(self));
 
-    status = g_binary_content_read_u32(content, addr, endianness, &val);
+    status = g_binary_content_read_u32(content, &addr, endianness, &val);
     if (!status)
     {
         PyErr_SetString(PyExc_Exception, _("Invalid read access."));
@@ -321,24 +354,29 @@ static PyObject *py_binary_content_read_u32(PyObject *self, PyObject *args)
 static PyObject *py_binary_content_read_u64(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Instance à retourner        */
-    GBinContent *content;                   /* Version GLib du format      */
-    int ret;                                /* Bilan de lecture des args.  */
-    PyObject *addr_obj;                     /* Objet pour une position     */
+    vmpa2t addr;                            /* Position interne associée   */
     unsigned long endianness;               /* Boutisme de la lecture      */
-    vmpa2t *addr;                           /* Position interne associée   */
+    int ret;                                /* Bilan de lecture des args.  */
+    GBinContent *content;                   /* Version GLib du format      */
     uint64_t val;                           /* Valeur lue à faire suivre   */
     bool status;                            /* Bilan de l'opération        */
 
-    content = G_BIN_CONTENT(pygobject_get(self));
-    assert(content != NULL);
+#define BINARY_CONTENT_READ_U64_METHOD PYTHON_METHOD_DEF                \
+(                                                                       \
+    read_u64, "$self, addr, endian, /",                                 \
+    METH_VARARGS, py_binary_content,                                    \
+    "Read eight unsigned bytes from a given position."                  \
+    "\n"                                                                \
+    "The endianness of the data can be provided using"                  \
+    " pychrysalide.analysis.BinContent.SourceEndian values."            \
+)
 
-    ret = PyArg_ParseTuple(args, "Ok", &addr_obj, &endianness);
+    ret = PyArg_ParseTuple(args, "O&k", convert_any_to_vmpa, &addr, &endianness);
     if (!ret) return NULL;
 
-    addr = get_internal_vmpa(addr_obj);
-    assert(addr != NULL);
+    content = G_BIN_CONTENT(pygobject_get(self));
 
-    status = g_binary_content_read_u64(content, addr, endianness, &val);
+    status = g_binary_content_read_u64(content, &addr, endianness, &val);
     if (!status)
     {
         PyErr_SetString(PyExc_Exception, _("Invalid read access."));
@@ -445,6 +483,12 @@ static PyObject *py_binary_content_get_checksum(PyObject *self, void *closure)
     GBinContent *content;                   /* Version GLib du format      */
     const gchar *checksum;                  /* Empreinte fournie           */
 
+#define BINARY_CONTENT_CHECKSUM_ATTRIB PYTHON_GET_DEF_FULL              \
+(                                                                       \
+    checksum, py_binary_content,                                        \
+    "Compute a SHA256 hash as chechsum of handled data."                \
+)
+
     content = G_BIN_CONTENT(pygobject_get(self));
 
     checksum = g_binary_content_get_checksum(content);
@@ -469,12 +513,18 @@ static PyObject *py_binary_content_get_checksum(PyObject *self, void *closure)
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_binary_content_compute_size(PyObject *self, void *closure)
+static PyObject *py_binary_content_get_size(PyObject *self, void *closure)
 {
     PyObject *result;                       /* Instance à retourner        */
     GBinContent *content;                   /* Version GLib du format      */
     phys_t size;                            /* Quantité d'octets dispos.   */
 
+#define BINARY_CONTENT_SIZE_ATTRIB PYTHON_GET_DEF_FULL                  \
+(                                                                       \
+    size, py_binary_content,                                            \
+    "Compute the quantity of readable bytes."                           \
+)
+
     content = G_BIN_CONTENT(pygobject_get(self));
 
     size = g_binary_content_compute_size(content);
@@ -499,12 +549,18 @@ static PyObject *py_binary_content_compute_size(PyObject *self, void *closure)
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_binary_content_compute_start_pos(PyObject *self, void *closure)
+static PyObject *py_binary_content_get_start_pos(PyObject *self, void *closure)
 {
     PyObject *result;                       /* Instance à retourner        */
     GBinContent *content;                   /* Version GLib du format      */
     vmpa2t pos;                             /* Position à transmettre      */
 
+#define BINARY_CONTENT_START_POS_ATTRIB PYTHON_GET_DEF_FULL             \
+(                                                                       \
+    start_pos, py_binary_content,                                       \
+    "Provide the starting position of the binary content."              \
+)
+
     content = G_BIN_CONTENT(pygobject_get(self));
 
     g_binary_content_compute_start_pos(content, &pos);
@@ -529,12 +585,18 @@ static PyObject *py_binary_content_compute_start_pos(PyObject *self, void *closu
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_binary_content_compute_end_pos(PyObject *self, void *closure)
+static PyObject *py_binary_content_get_end_pos(PyObject *self, void *closure)
 {
     PyObject *result;                       /* Instance à retourner        */
     GBinContent *content;                   /* Version GLib du format      */
     vmpa2t pos;                             /* Position à transmettre      */
 
+#define BINARY_CONTENT_END_POS_ATTRIB PYTHON_GET_DEF_FULL               \
+(                                                                       \
+    end_pos, py_binary_content,                                         \
+    "Provide the ending position of the binary content."                \
+)
+
     content = G_BIN_CONTENT(pygobject_get(self));
 
     g_binary_content_compute_end_pos(content, &pos);
@@ -559,7 +621,7 @@ static PyObject *py_binary_content_compute_end_pos(PyObject *self, void *closure
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_binary_content_get_all_bytes(PyObject *self, void *closure)
+static PyObject *py_binary_content_get_data(PyObject *self, void *closure)
 {
     PyObject *result;                       /* Contenu à retourner         */
     GBinContent *content;                   /* Version GLib du format      */
@@ -567,8 +629,13 @@ static PyObject *py_binary_content_get_all_bytes(PyObject *self, void *closure)
     phys_t length;                          /* Nombre d'octets disponibles */
     const bin_t *val;                       /* Valeur lue à faire suivre   */
 
+#define BINARY_CONTENT_DATA_ATTRIB PYTHON_GET_DEF_FULL                  \
+(                                                                       \
+    data, py_binary_content,                                            \
+    "Provide all the content bytes at once."                            \
+)
+
     content = G_BIN_CONTENT(pygobject_get(self));
-    assert(content != NULL);
 
     init_vmpa(&start, 0, VMPA_NO_VIRTUAL);
 
@@ -599,61 +666,22 @@ static PyObject *py_binary_content_get_all_bytes(PyObject *self, void *closure)
 PyTypeObject *get_python_binary_content_type(void)
 {
     static PyMethodDef py_binary_content_methods[] = {
-        {
-            "describe", py_binary_content_describe,
-            METH_VARARGS,
-            "describe($self, full, /)\n--\n\nGet a (full ?) description of the binary content."
-        },
-        {
-            "read_raw", py_binary_content_read_raw,
-            METH_VARARGS,
-            "read_raw($self, addr, length, /)\n--\n\nRead bytes from a given position."
-        },
-        {
-            "read_u8", py_binary_content_read_u8,
-            METH_VARARGS,
-            "read_u8($self, addr, /)\n--\n\nRead an unsigned byte from a given position."
-        },
-        {
-            "read_u16", py_binary_content_read_u16,
-            METH_VARARGS,
-            "read_u16($self, addr, endianness, /)\n--\n\nRead two unsigned bytes from a given position."
-        },
-        {
-            "read_u32", py_binary_content_read_u32,
-            METH_VARARGS,
-            "read_u32($self, addr, endianness, /)\n--\n\nRead four unsigned bytes from a given position."
-        },
-        {
-            "read_u64", py_binary_content_read_u64,
-            METH_VARARGS,
-            "read_u64($self, addr, endianness, /)\n--\n\nRead eight unsigned bytes from a given position."
-        },
+        BINARY_CONTENT_DESCRIBE_METHOD,
+        BINARY_CONTENT_READ_RAW_METHOD,
+        BINARY_CONTENT_READ_U8_METHOD,
+        BINARY_CONTENT_READ_U16_METHOD,
+        BINARY_CONTENT_READ_U32_METHOD,
+        BINARY_CONTENT_READ_U64_METHOD,
         { NULL }
     };
 
     static PyGetSetDef py_binary_content_getseters[] = {
         BINARY_CONTENT_ATTRIBUTES_ATTRIB,
-        {
-            "checksum", py_binary_content_get_checksum, NULL,
-            "Compute a SHA256 hash as chechsum of handled data.", NULL
-        },
-        {
-            "size", py_binary_content_compute_size, NULL,
-            "Compute the quantity of readable bytes.", NULL
-        },
-        {
-            "start_pos", py_binary_content_compute_start_pos, NULL,
-            "Provide the starting position of the binary content.", NULL
-        },
-        {
-            "end_pos", py_binary_content_compute_end_pos, NULL,
-            "Provide the ending position of the binary content.", NULL
-        },
-        {
-            "data", py_binary_content_get_all_bytes, NULL,
-            "Provide all the content bytes at once.", NULL
-        },
+        BINARY_CONTENT_CHECKSUM_ATTRIB,
+        BINARY_CONTENT_SIZE_ATTRIB,
+        BINARY_CONTENT_START_POS_ATTRIB,
+        BINARY_CONTENT_END_POS_ATTRIB,
+        BINARY_CONTENT_DATA_ATTRIB,
         { NULL }
     };
 
@@ -666,7 +694,7 @@ PyTypeObject *get_python_binary_content_type(void)
 
         .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 
-        .tp_doc         = "PyChrysalide binary content",
+        .tp_doc         = BINARY_CONTENT_DOC,
 
         .tp_methods     = py_binary_content_methods,
         .tp_getset      = py_binary_content_getseters
@@ -707,6 +735,9 @@ bool ensure_python_binary_content_is_registered(void)
         if (!register_interface_for_pygobject(dict, G_TYPE_BIN_CONTENT, type))
             return false;
 
+        if (!define_analysis_content_constants(type))
+            return false;
+
     }
 
     return true;
-- 
cgit v0.11.2-87-g4458