diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-06-19 20:23:30 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-06-19 20:27:43 (GMT) |
commit | 72b1c890ed19ebd7780e634d4874d12a619f259e (patch) | |
tree | 0d2e2f5e76ba9102a6671bdb2f7ab6b2e14c8d9c /plugins/pychrysalide | |
parent | ceeba88cafc4c7d2c625e53fb175b763e480f6ba (diff) |
Extended the bitfield operations and their Python bindings.
Diffstat (limited to 'plugins/pychrysalide')
-rw-r--r-- | plugins/pychrysalide/common/bits.c | 152 |
1 files changed, 151 insertions, 1 deletions
diff --git a/plugins/pychrysalide/common/bits.c b/plugins/pychrysalide/common/bits.c index 33f81c3..065f32e 100644 --- a/plugins/pychrysalide/common/bits.c +++ b/plugins/pychrysalide/common/bits.c @@ -52,6 +52,12 @@ static PyObject *py_bitfield_nb_and(PyObject *, PyObject *); /* Effectue une opération de type 'or' avec le type 'bitfield'. */ static PyObject *py_bitfield_nb_or(PyObject *, PyObject *); +/* Indique la taille de la séquence correspondant à un champ. */ +static Py_ssize_t py_bitfield_sequence_length(PyObject *); + +/* Fournit un élément de la séquence correspondant à un champ. */ +static PyObject *py_bitfield_sequence_item(PyObject *, Py_ssize_t); + /* Effectue une comparaison avec un objet Python 'bitfield'. */ static PyObject *py_bitfield_richcompare(PyObject *, PyObject *, int); @@ -76,6 +82,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 *); +/* Indique la taille d'un champ de bits donné. */ +static PyObject *py_bitfield_get_size(PyObject *, void *); + +/* Détermine le nombre de bits à 1 dans un champ. */ +static PyObject *py_bitfield_popcount(PyObject *, void *); + /****************************************************************************** @@ -228,6 +240,70 @@ static PyObject *py_bitfield_nb_or(PyObject *o1, PyObject *o2) /****************************************************************************** * * +* Paramètres : self = champ de bits à consulter. * +* * +* Description : Indique la taille de la séquence correspondant à un champ. * +* * +* Retour : Taille du champ de bits. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static Py_ssize_t py_bitfield_sequence_length(PyObject *self) +{ + Py_ssize_t result; /* Taille à retourner */ + py_bitfield_t *bf; /* Instance à manipuler */ + + bf = (py_bitfield_t *)self; + + result = get_bit_field_size(bf->native); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = champ de bits à consulter. * +* i = indice de l'élément à retourner. * +* * +* Description : Fournit un élément de la séquence correspondant à un champ. * +* * +* Retour : Valeur booléenne. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_bitfield_sequence_item(PyObject *self, Py_ssize_t i) +{ + PyObject *result; /* Elément à retourner */ + py_bitfield_t *bf; /* Instance à manipuler */ + bool state; /* Etat du bit ciblé */ + + bf = (py_bitfield_t *)self; + + if (i < 0 || i >= (Py_ssize_t)get_bit_field_size(bf->native)) + result = NULL; + + else + { + state = test_in_bit_field(bf->native, i); + + result = state ? Py_True : Py_False; + Py_INCREF(result); + + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : a = premier object Python à consulter. * * b = second object Python à consulter. * * op = type de comparaison menée. * @@ -502,6 +578,66 @@ static PyObject *py_bitfield_test_all(PyObject *self, PyObject *args) /****************************************************************************** * * +* Paramètres : self = classe représentant une instruction. * +* closure = adresse non utilisée ici. * +* * +* Description : Indique la taille d'un champ de bits donné. * +* * +* Retour : Taille du champ de bits. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_bitfield_get_size(PyObject *self, void *closure) +{ + PyObject *result; /* Conversion à retourner */ + py_bitfield_t *bf; /* Instance à manipuler */ + size_t size; /* Taille du champs de bits */ + + bf = (py_bitfield_t *)self; + + size = get_bit_field_size(bf->native); + + result = PyLong_FromSize_t(size); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = classe représentant une instruction. * +* closure = adresse non utilisée ici. * +* * +* Description : Détermine le nombre de bits à 1 dans un champ. * +* * +* Retour : Valeur positive ou nulle. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_bitfield_popcount(PyObject *self, void *closure) +{ + PyObject *result; /* Conversion à retourner */ + py_bitfield_t *bf; /* Instance à manipuler */ + size_t count; /* Quantité de bits à 1 */ + + bf = (py_bitfield_t *)self; + + count = popcount_for_bit_field(bf->native); + + result = PyLong_FromSize_t(count); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : - * * * * Description : Fournit un accès à une définition de type à diffuser. * @@ -517,10 +653,15 @@ PyTypeObject *get_python_bitfield_type(void) static PyNumberMethods py_bitfield_nb_proto = { .nb_and = py_bitfield_nb_and, - .nb_or = py_bitfield_nb_or + .nb_or = py_bitfield_nb_or }; + static PySequenceMethods py_bitfield_sequence_proto = { + .sq_length = py_bitfield_sequence_length, + .sq_item = py_bitfield_sequence_item + }; + static PyMethodDef py_bitfield_methods[] = { { "dup", py_bitfield_dup, @@ -566,6 +707,14 @@ PyTypeObject *get_python_bitfield_type(void) }; static PyGetSetDef py_bitfield_getseters[] = { + { + "size", py_bitfield_get_size, NULL, + "Provide the size of the bitfield.", NULL + }, + { + "popcount", py_bitfield_popcount, NULL, + "Get the number of bits set to 1 in the bitfield.", NULL + }, { NULL } }; @@ -577,6 +726,7 @@ PyTypeObject *get_python_bitfield_type(void) .tp_basicsize = sizeof(py_bitfield_t), .tp_as_number = &py_bitfield_nb_proto, + .tp_as_sequence = &py_bitfield_sequence_proto, .tp_flags = Py_TPFLAGS_DEFAULT, |