summaryrefslogtreecommitdiff
path: root/plugins/pychrysalide/common
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2022-12-07 02:52:51 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2022-12-07 02:52:51 (GMT)
commit6dea5e4fed979cb57f3dbc0c9144f1ff1854b800 (patch)
tree7d36f810bc15e8ceb5a994396a0734dfb91015e4 /plugins/pychrysalide/common
parent430aad874900f525c67a5aa5de9e6012a64ff603 (diff)
Provide functions to test bit fields against bit fields.
Diffstat (limited to 'plugins/pychrysalide/common')
-rw-r--r--plugins/pychrysalide/common/bits.c153
-rw-r--r--plugins/pychrysalide/common/bits.h3
2 files changed, 156 insertions, 0 deletions
diff --git a/plugins/pychrysalide/common/bits.c b/plugins/pychrysalide/common/bits.c
index 73fd55b..e73ce7a 100644
--- a/plugins/pychrysalide/common/bits.c
+++ b/plugins/pychrysalide/common/bits.c
@@ -86,6 +86,12 @@ static PyObject *py_bitfield_test_none(PyObject *, PyObject *);
/* Détermine si un ensemble de bits est à 1 dans un champ. */
static PyObject *py_bitfield_test_all(PyObject *, PyObject *);
+/* Teste l'état à 0 de bits selon un masque de bits. */
+static PyObject *py_bitfield_test_zeros_with(PyObject *, PyObject *);
+
+/* Teste l'état à 1 de bits selon un masque de bits. */
+static PyObject *py_bitfield_test_ones_with(PyObject *, PyObject *);
+
/* Indique la taille d'un champ de bits donné. */
static PyObject *py_bitfield_get_size(PyObject *, void *);
@@ -695,6 +701,106 @@ static PyObject *py_bitfield_test_all(PyObject *self, PyObject *args)
/******************************************************************************
* *
+* Paramètres : self = champ de bits à consulter. *
+* args = arguments fournis pour la conduite de l'opération. *
+* *
+* Description : Teste l'état à 0 de bits selon un masque de bits. *
+* *
+* Retour : true si les bits visés sont à l'état bas. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_bitfield_test_zeros_with(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à faire remonter */
+ unsigned long first; /* Indice du premier bit testé */
+ bitfield_t *mask; /* Champ de bits natif */
+ int ret; /* Bilan de lecture des args. */
+ py_bitfield_t *bf; /* Instance à manipuler */
+ bool status; /* Bilan d'analyse */
+
+#define BITFIELD_TEST_ZEROS_WITH_METHOD PYTHON_METHOD_DEF \
+( \
+ test_zeros_with, "$self, first, mask, /", \
+ METH_VARARGS, py_bitfield, \
+ "Test a range of bits against another bit field.\n" \
+ "\n" \
+ "The area to process starts at bit *first* and the" \
+ " test relies on bits set within the *mask* object.\n" \
+ "\n" \
+ "The result is a boolean value: True if all tested" \
+ " bits are unset, False otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "kO&", &first, convert_to_bitfield, &mask);
+ if (!ret) return NULL;
+
+ bf = (py_bitfield_t *)self;
+
+ status = test_zeros_within_bit_field(bf->native, first, mask);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : self = champ de bits à consulter. *
+* args = arguments fournis pour la conduite de l'opération. *
+* *
+* Description : Teste l'état à 1 de bits selon un masque de bits. *
+* *
+* Retour : true si les bits visés sont à l'état haut. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_bitfield_test_ones_with(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Bilan à faire remonter */
+ unsigned long first; /* Indice du premier bit testé */
+ bitfield_t *mask; /* Champ de bits natif */
+ int ret; /* Bilan de lecture des args. */
+ py_bitfield_t *bf; /* Instance à manipuler */
+ bool status; /* Bilan d'analyse */
+
+#define BITFIELD_TEST_ONES_WITH_METHOD PYTHON_METHOD_DEF \
+( \
+ test_ones_with, "$self, first, mask, /", \
+ METH_VARARGS, py_bitfield, \
+ "Test a range of bits against another bit field.\n" \
+ "\n" \
+ "The area to process starts at bit *first* and the" \
+ " test relies on bits set within the *mask* object.\n" \
+ "\n" \
+ "The result is a boolean value: True if all tested" \
+ " bits are set, False otherwise." \
+)
+
+ ret = PyArg_ParseTuple(args, "kO&", &first, convert_to_bitfield, &mask);
+ if (!ret) return NULL;
+
+ bf = (py_bitfield_t *)self;
+
+ status = test_ones_within_bit_field(bf->native, first, mask);
+
+ result = status ? Py_True : Py_False;
+ Py_INCREF(result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : self = classe représentant une instruction. *
* closure = adresse non utilisée ici. *
* *
@@ -798,6 +904,8 @@ PyTypeObject *get_python_bitfield_type(void)
BITFIELD_TEST_METHOD,
BITFIELD_TEST_NONE_METHOD,
BITFIELD_TEST_ALL_METHOD,
+ BITFIELD_TEST_ZEROS_WITH_METHOD,
+ BITFIELD_TEST_ONES_WITH_METHOD,
{ NULL }
};
@@ -876,6 +984,51 @@ bool ensure_python_bitfield_is_registered(void)
/******************************************************************************
* *
+* 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 champ de bits. *
+* *
+* Retour : Bilan de l'opération, voire indications supplémentaires. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int convert_to_bitfield(PyObject *arg, void *dst)
+{
+ int result; /* Bilan à retourner */
+
+ result = PyObject_IsInstance(arg, (PyObject *)get_python_bitfield_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 bit field");
+ break;
+
+ case 1:
+ *((bitfield_t **)dst) = ((py_bitfield_t *)arg)->native;
+ break;
+
+ default:
+ assert(false);
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : field = structure interne à copier en objet Python. *
* *
* Description : Convertit une structure de type 'bitfield_t' en objet Python.*
diff --git a/plugins/pychrysalide/common/bits.h b/plugins/pychrysalide/common/bits.h
index 6ddaaa5..804c3b5 100644
--- a/plugins/pychrysalide/common/bits.h
+++ b/plugins/pychrysalide/common/bits.h
@@ -40,6 +40,9 @@ PyTypeObject *get_python_bitfield_type(void);
/* Prend en charge l'objet 'pychrysalide.common.BitField'. */
bool ensure_python_bitfield_is_registered(void);
+/* Tente de convertir en champ de bits. */
+int convert_to_bitfield(PyObject *, void *);
+
/* Convertit une structure de type 'bitfield_t' en objet Python. */
PyObject *build_from_internal_bitfield(const bitfield_t *);