summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-06-30 21:55:41 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-06-30 21:55:41 (GMT)
commit90184484440afd7bc4b85587f450c1b9ccd6e8de (patch)
tree13982cad9a1234b8f2a807b01e7b276e7f8205d4
parentd3d57aa61bb44fd0bdad460c8c173743ca808733 (diff)
Updated the Python API for bitfields.
-rw-r--r--plugins/pychrysalide/common/bits.c238
-rw-r--r--plugins/pychrysalide/common/bits.h4
-rw-r--r--plugins/pychrysalide/common/packed.c4
-rw-r--r--tests/common/bitfield.py60
4 files changed, 180 insertions, 126 deletions
diff --git a/plugins/pychrysalide/common/bits.c b/plugins/pychrysalide/common/bits.c
index 236bcd6..73fd55b 100644
--- a/plugins/pychrysalide/common/bits.c
+++ b/plugins/pychrysalide/common/bits.c
@@ -47,9 +47,6 @@ static void py_bitfield_dealloc(py_bitfield_t *);
/* Initialise un objet Python de type 'bitfield_t'. */
static int py_bitfield_init(py_bitfield_t *, PyObject *, PyObject *);
-/* Crée une copie d'un champ de bits classique. */
-static PyObject *py_bitfield_dup(PyObject *, PyObject *);
-
/* Effectue une opération de type 'and' avec le type 'bitfield'. */
static PyObject *py_bitfield_nb_and(PyObject *, PyObject *);
@@ -65,6 +62,9 @@ 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);
+/* Crée une copie d'un champ de bits classique. */
+static PyObject *py_bitfield_dup(PyObject *, PyObject *);
+
/* Bascule à 0 un champ de bits dans son intégralité. */
static PyObject *py_bitfield_reset_all(PyObject *, PyObject *);
@@ -90,7 +90,7 @@ static PyObject *py_bitfield_test_all(PyObject *, PyObject *);
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 *);
+static PyObject *py_bitfield_get_popcount(PyObject *, void *);
@@ -136,6 +136,17 @@ static int py_bitfield_init(py_bitfield_t *self, PyObject *args, PyObject *kwds)
int state; /* Initialisation par défaut */
int ret; /* Bilan de lecture des args. */
+#define BITFIELD_DOC \
+ "The BitField object describes a group of bits and provides" \
+ " operations on it.\n" \
+ "\n" \
+ "Instances can be created using the following constructor:\n" \
+ "\n" \
+ " BitField(length, state)" \
+ "\n" \
+ "Where *length* is the size of the bitfield and *state*" \
+ " defines the initial state of each bits." \
+
result = -1;
ret = PyArg_ParseTuple(args, "kp", &length, &state);
@@ -154,33 +165,6 @@ static int py_bitfield_init(py_bitfield_t *self, PyObject *args, PyObject *kwds)
/******************************************************************************
* *
-* Paramètres : self = champ de bits à dupliquer. *
-* args = non utilisé ici. *
-* *
-* Description : Crée une copie d'un champ de bits classique. *
-* *
-* Retour : Champ de bits mis en place. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static PyObject *py_bitfield_dup(PyObject *self, PyObject *args)
-{
- PyObject *result; /* Instance à retourner */
- py_bitfield_t *bf; /* Instance à manipuler */
-
- bf = (py_bitfield_t *)self;
-
- result = build_from_internal_bitfield(bf->native);;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
* Paramètres : o1 = premier élément concerné par l'opération. *
* o2 = second élément concerné par l'opération. *
* *
@@ -378,6 +362,43 @@ static PyObject *py_bitfield_richcompare(PyObject *a, PyObject *b, int op)
/******************************************************************************
* *
+* Paramètres : self = champ de bits à dupliquer. *
+* args = non utilisé ici. *
+* *
+* Description : Crée une copie d'un champ de bits classique. *
+* *
+* Retour : Champ de bits mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static PyObject *py_bitfield_dup(PyObject *self, PyObject *args)
+{
+ PyObject *result; /* Instance à retourner */
+ py_bitfield_t *bf; /* Instance à manipuler */
+
+#define BITFIELD_DUP_METHOD PYTHON_METHOD_DEF \
+( \
+ dup, "$self, /", \
+ METH_NOARGS, py_bitfield, \
+ "Duplicate a bitfield.\n" \
+ "\n" \
+ "The result is a new pychrysalide.common.BitField with the same" \
+ " content." \
+)
+
+ bf = (py_bitfield_t *)self;
+
+ result = build_from_internal_bitfield(bf->native);;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : self = champ de bits à modifier. *
* args = non utilisé ici. *
* *
@@ -393,6 +414,13 @@ static PyObject *py_bitfield_reset_all(PyObject *self, PyObject *args)
{
py_bitfield_t *bf; /* Instance à manipuler */
+#define BITFIELD_RESET_ALL_METHOD PYTHON_METHOD_DEF \
+( \
+ reset_all, "$self, /", \
+ METH_NOARGS, py_bitfield, \
+ "Switch to 0 all bits in a bitfield." \
+)
+
bf = (py_bitfield_t *)self;
reset_all_in_bit_field(bf->native);
@@ -419,6 +447,13 @@ static PyObject *py_bitfield_set_all(PyObject *self, PyObject *args)
{
py_bitfield_t *bf; /* Instance à manipuler */
+#define BITFIELD_SET_ALL_METHOD PYTHON_METHOD_DEF \
+( \
+ set_all, "$self, /", \
+ METH_NOARGS, py_bitfield, \
+ "Switch to 1 all bits in a bitfield." \
+)
+
bf = (py_bitfield_t *)self;
set_all_in_bit_field(bf->native);
@@ -448,6 +483,16 @@ static PyObject *py_bitfield_reset(PyObject *self, PyObject *args)
int ret; /* Bilan de lecture des args. */
py_bitfield_t *bf; /* Instance à manipuler */
+#define BITFIELD_RESET_METHOD PYTHON_METHOD_DEF \
+( \
+ reset, "$self, first, count, /", \
+ METH_VARARGS, py_bitfield, \
+ "Switch to 0 a part of bits in a bitfield.\n" \
+ "\n" \
+ "The area to process starts at bit *first* and has a" \
+ " size of *count* bits." \
+)
+
ret = PyArg_ParseTuple(args, "kk", &first, &count);
if (!ret) return NULL;
@@ -480,6 +525,16 @@ static PyObject *py_bitfield_set(PyObject *self, PyObject *args)
int ret; /* Bilan de lecture des args. */
py_bitfield_t *bf; /* Instance à manipuler */
+#define BITFIELD_SET_METHOD PYTHON_METHOD_DEF \
+( \
+ set, "$self, first, count, /", \
+ METH_VARARGS, py_bitfield, \
+ "Switch to 1 a part of bits in a bitfield.\n" \
+ "\n" \
+ "The area to process starts at bit *first* and has a" \
+ " size of *count* bits." \
+)
+
ret = PyArg_ParseTuple(args, "kk", &first, &count);
if (!ret) return NULL;
@@ -513,6 +568,16 @@ static PyObject *py_bitfield_test(PyObject *self, PyObject *args)
py_bitfield_t *bf; /* Instance à manipuler */
bool status; /* Bilan d'analyse */
+#define BITFIELD_TEST_METHOD PYTHON_METHOD_DEF \
+( \
+ test, "$self, n, /", \
+ METH_VARARGS, py_bitfield, \
+ "Test if a given bit is set in a bitfield.\n" \
+ "\n" \
+ "The result is a boolean value: True if the tested" \
+ " *n* bit is set, False otherwise." \
+)
+
ret = PyArg_ParseTuple(args, "k", &n);
if (!ret) return NULL;
@@ -521,7 +586,6 @@ static PyObject *py_bitfield_test(PyObject *self, PyObject *args)
status = test_in_bit_field(bf->native, n);
result = status ? Py_True : Py_False;
-
Py_INCREF(result);
return result;
@@ -551,6 +615,19 @@ static PyObject *py_bitfield_test_none(PyObject *self, PyObject *args)
py_bitfield_t *bf; /* Instance à manipuler */
bool status; /* Bilan d'analyse */
+#define BITFIELD_TEST_NONE_METHOD PYTHON_METHOD_DEF \
+( \
+ test_none, "$self, first, count, /", \
+ METH_VARARGS, py_bitfield, \
+ "Test a range of bits against 0.\n" \
+ "\n" \
+ "The area to process starts at bit *first* and has a" \
+ " size of *count* bits." \
+ "\n" \
+ "The result is a boolean value: True if all tested" \
+ " bits are unset, False otherwise." \
+)
+
ret = PyArg_ParseTuple(args, "kk", &first, &count);
if (!ret) return NULL;
@@ -559,7 +636,6 @@ static PyObject *py_bitfield_test_none(PyObject *self, PyObject *args)
status = test_none_in_bit_field(bf->native, first, count);
result = status ? Py_True : Py_False;
-
Py_INCREF(result);
return result;
@@ -589,6 +665,19 @@ static PyObject *py_bitfield_test_all(PyObject *self, PyObject *args)
py_bitfield_t *bf; /* Instance à manipuler */
bool status; /* Bilan d'analyse */
+#define BITFIELD_TEST_ALL_METHOD PYTHON_METHOD_DEF \
+( \
+ test_all, "$self, first, count, /", \
+ METH_VARARGS, py_bitfield, \
+ "Test a range of bits against 1.\n" \
+ "\n" \
+ "The area to process starts at bit *first* and has a" \
+ " size of *count* bits." \
+ "\n" \
+ "The result is a boolean value: True if all tested" \
+ " bits are set, False otherwise." \
+)
+
ret = PyArg_ParseTuple(args, "kk", &first, &count);
if (!ret) return NULL;
@@ -597,7 +686,6 @@ static PyObject *py_bitfield_test_all(PyObject *self, PyObject *args)
status = test_all_in_bit_field(bf->native, first, count);
result = status ? Py_True : Py_False;
-
Py_INCREF(result);
return result;
@@ -624,6 +712,12 @@ static PyObject *py_bitfield_get_size(PyObject *self, void *closure)
py_bitfield_t *bf; /* Instance à manipuler */
size_t size; /* Taille du champs de bits */
+#define BITFIELD_SIZE_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ size, py_bitfield, \
+ "Provide the size of the bitfield." \
+)
+
bf = (py_bitfield_t *)self;
size = get_bit_field_size(bf->native);
@@ -648,12 +742,18 @@ static PyObject *py_bitfield_get_size(PyObject *self, void *closure)
* *
******************************************************************************/
-static PyObject *py_bitfield_popcount(PyObject *self, void *closure)
+static PyObject *py_bitfield_get_popcount(PyObject *self, void *closure)
{
PyObject *result; /* Conversion à retourner */
py_bitfield_t *bf; /* Instance à manipuler */
size_t count; /* Quantité de bits à 1 */
+#define BITFIELD_POPCOUNT_ATTRIB PYTHON_GET_DEF_FULL \
+( \
+ popcount, py_bitfield, \
+ "Get the number of bits set to 1 in the bitfield." \
+)
+
bf = (py_bitfield_t *)self;
count = popcount_for_bit_field(bf->native);
@@ -680,10 +780,8 @@ static PyObject *py_bitfield_popcount(PyObject *self, void *closure)
PyTypeObject *get_python_bitfield_type(void)
{
static PyNumberMethods py_bitfield_nb_proto = {
-
.nb_and = py_bitfield_nb_and,
.nb_or = py_bitfield_nb_or
-
};
static PySequenceMethods py_bitfield_sequence_proto = {
@@ -692,58 +790,20 @@ PyTypeObject *get_python_bitfield_type(void)
};
static PyMethodDef py_bitfield_methods[] = {
- {
- "dup", py_bitfield_dup,
- METH_NOARGS,
- "dup(self, /)\n--\n\nDuplicate a bitfield."
- },
- {
- "reset_all", py_bitfield_reset_all,
- METH_NOARGS,
- "reset_all(self, /)\n--\n\nSwitch to 0 all bits in a bitfield."
- },
- {
- "set_all", py_bitfield_set_all,
- METH_NOARGS,
- "set_all(self, /)\n--\n\nSwitch to 1 all bits in a bitfield."
- },
- {
- "reset", py_bitfield_reset,
- METH_VARARGS,
- "reset(self, first, count, /)\n--\n\nSwitch to 0 a part of bits in a bitfield."
- },
- {
- "set", py_bitfield_set,
- METH_VARARGS,
- "set(self, first, count, /)\n--\n\nSwitch to 1 a part of bits in a bitfield."
- },
- {
- "test", py_bitfield_test,
- METH_VARARGS,
- "test(self, n, /)\n--\n\nTest if a given bit is set in a bitfield."
- },
- {
- "test_none", py_bitfield_test_none,
- METH_VARARGS,
- "test_none(self, first, count, /)\n--\n\nTest a range of bits to 0."
- },
- {
- "test_all", py_bitfield_test_all,
- METH_VARARGS,
- "test_all(self, first, count, /)\n--\n\nTest a range of bits to 1."
- },
+ BITFIELD_DUP_METHOD,
+ BITFIELD_RESET_ALL_METHOD,
+ BITFIELD_SET_ALL_METHOD,
+ BITFIELD_RESET_METHOD,
+ BITFIELD_SET_METHOD,
+ BITFIELD_TEST_METHOD,
+ BITFIELD_TEST_NONE_METHOD,
+ BITFIELD_TEST_ALL_METHOD,
{ NULL }
};
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
- },
+ BITFIELD_SIZE_ATTRIB,
+ BITFIELD_POPCOUNT_ATTRIB,
{ NULL }
};
@@ -751,7 +811,7 @@ PyTypeObject *get_python_bitfield_type(void)
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "pychrysalide.common.bitfield",
+ .tp_name = "pychrysalide.common.BitField",
.tp_basicsize = sizeof(py_bitfield_t),
.tp_dealloc = (destructor)py_bitfield_dealloc,
@@ -761,7 +821,7 @@ PyTypeObject *get_python_bitfield_type(void)
.tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_doc = "Python object for bitfield_t.",
+ .tp_doc = BITFIELD_DOC,
.tp_richcompare = py_bitfield_richcompare,
@@ -782,7 +842,7 @@ PyTypeObject *get_python_bitfield_type(void)
* *
* Paramètres : module = module dont la définition est à compléter. *
* *
-* Description : Prend en charge l'objet 'pychrysalide.common.bitfield'. *
+* Description : Prend en charge l'objet 'pychrysalide.common.BitField'. *
* *
* Retour : Bilan de l'opération. *
* *
@@ -818,7 +878,7 @@ bool ensure_python_bitfield_is_registered(void)
* *
* Paramètres : field = structure interne à copier en objet Python. *
* *
-* Description : Convertit une structure de type 'bitfield' en objet Python. *
+* Description : Convertit une structure de type 'bitfield_t' en objet Python.*
* *
* Retour : Object Python résultant de la conversion opérée. *
* *
diff --git a/plugins/pychrysalide/common/bits.h b/plugins/pychrysalide/common/bits.h
index 4a3b90b..6ddaaa5 100644
--- a/plugins/pychrysalide/common/bits.h
+++ b/plugins/pychrysalide/common/bits.h
@@ -37,10 +37,10 @@
/* Fournit un accès à une définition de type à diffuser. */
PyTypeObject *get_python_bitfield_type(void);
-/* Prend en charge l'objet 'pychrysalide.common.bitfield'. */
+/* Prend en charge l'objet 'pychrysalide.common.BitField'. */
bool ensure_python_bitfield_is_registered(void);
-/* Convertit une structure de type 'bitfield' en objet Python. */
+/* Convertit une structure de type 'bitfield_t' en objet Python. */
PyObject *build_from_internal_bitfield(const bitfield_t *);
diff --git a/plugins/pychrysalide/common/packed.c b/plugins/pychrysalide/common/packed.c
index c7fa296..405e241 100644
--- a/plugins/pychrysalide/common/packed.c
+++ b/plugins/pychrysalide/common/packed.c
@@ -112,8 +112,8 @@ static int py_packed_buffer_init(py_packed_buffer_t *self, PyObject *args, PyObj
int result; /* Bilan à retourner */
#define PACKED_BUFFER_DOC \
- "The PackedBuffer is mainly used as helper for the storage of GLib" \
- " objects over the network or into files.\n" \
+ "The PackedBuffer object is mainly used as helper for the storage" \
+ " of GLib objects over the network or into files.\n" \
"\n" \
"The same kind of features as the Python *struct* module are" \
" provided to store and retrieve data.\n" \
diff --git a/tests/common/bitfield.py b/tests/common/bitfield.py
index 717181c..e014111 100644
--- a/tests/common/bitfield.py
+++ b/tests/common/bitfield.py
@@ -1,21 +1,15 @@
-#!/usr/bin/python3-dbg
-# -*- coding: utf-8 -*-
-
-
-# Tests pour valider la manipulation des champs de bits.
-
from chrysacase import ChrysalideTestCase
-from pychrysalide.common import bitfield
+from pychrysalide.common import BitField
-class TestBitfields(ChrysalideTestCase):
- """TestCase for common.bitfield*"""
+class TestBitFields(ChrysalideTestCase):
+ """TestCase for common.BitField*"""
- def testDuplicateBitfield(self):
+ def testDuplicateBitField(self):
"""Check duplicated bitfield value."""
- bf = bitfield(10, 0)
+ bf = BitField(10, 0)
bf2 = bf.dup()
@@ -26,40 +20,40 @@ class TestBitfields(ChrysalideTestCase):
self.assertEqual(bf.popcount, bf2.popcount)
- def testBitfieldValues(self):
+ def testBitFieldValues(self):
"""Evaluate bitfields basic values."""
- bf_a = bitfield(75, 1)
+ bf_a = BitField(75, 1)
- bf_b = bitfield(75, 0)
+ bf_b = BitField(75, 0)
self.assertNotEqual(bf_a, bf_b)
- bf_a = bitfield(75, 1)
+ bf_a = BitField(75, 1)
- bf_b = bitfield(75, 0)
+ bf_b = BitField(75, 0)
bf_b.set_all()
self.assertEqual(bf_a, bf_b)
self.assertEqual(bf_a.popcount, bf_b.popcount)
- bf_a = bitfield(75, 1)
+ bf_a = BitField(75, 1)
bf_a.reset_all()
- bf_b = bitfield(75, 0)
+ bf_b = BitField(75, 0)
self.assertEqual(bf_a, bf_b)
self.assertEqual(bf_a.popcount, bf_b.popcount)
- def testBitfieldLogicalOperations(self):
+ def testBitFieldLogicalOperations(self):
"""Perform logical operations on bitfields."""
- bf_a = bitfield(75, 1)
+ bf_a = BitField(75, 1)
- bf_b = bitfield(75, 0)
+ bf_b = BitField(75, 0)
self.assertEqual(bf_a.size, bf_b.size)
@@ -76,14 +70,14 @@ class TestBitfields(ChrysalideTestCase):
self.assertEqual(bf_f.popcount, bf_a.popcount)
- def testBitfieldSwitch(self):
+ def testBitFieldSwitch(self):
"""Switch various bits in bitfields."""
- bf_1 = bitfield(75, 1)
+ bf_1 = BitField(75, 1)
- bf_0 = bitfield(75, 0)
+ bf_0 = BitField(75, 0)
- bf_t = bitfield(75, 0)
+ bf_t = BitField(75, 0)
for i in range(75):
bf_t.set(i, 1)
@@ -100,10 +94,10 @@ class TestBitfields(ChrysalideTestCase):
self.assertEqual(bf_t.popcount, bf_0.popcount)
- def testBitfieldBits(self):
+ def testBitFieldBits(self):
"""Test bits in bitfields."""
- bf = bitfield(54, 1)
+ bf = BitField(54, 1)
self.assertTrue(bf.test(0))
@@ -113,7 +107,7 @@ class TestBitfields(ChrysalideTestCase):
self.assertFalse(bf.test_none(0, 54))
- bf = bitfield(54, 0)
+ bf = BitField(54, 0)
self.assertFalse(bf.test(0))
@@ -124,23 +118,23 @@ class TestBitfields(ChrysalideTestCase):
self.assertTrue(bf.test_none(0, 54))
- def testPopCountForBitfield(self):
+ def testPopCountForBitField(self):
"""Count bits set to 1 in bitfield."""
- bf = bitfield(65, 1)
+ bf = BitField(65, 1)
self.assertEqual(bf.size, 65)
self.assertEqual(bf.popcount, 65)
- def testBitfieldComparison(self):
+ def testBitFieldComparison(self):
"""Check bitfield comparison."""
- bf_a = bitfield(9, 0)
+ bf_a = BitField(9, 0)
bf_a.set(0, 1)
bf_a.set(5, 1)
- bf_b = bitfield(9, 1)
+ bf_b = BitField(9, 1)
self.assertNotEqual(bf_a, bf_b)