summaryrefslogtreecommitdiff
path: root/src/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 /src/common
parent430aad874900f525c67a5aa5de9e6012a64ff603 (diff)
Provide functions to test bit fields against bit fields.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/bits.c128
-rw-r--r--src/common/bits.h6
2 files changed, 134 insertions, 0 deletions
diff --git a/src/common/bits.c b/src/common/bits.c
index a450bb2..d3b45bb 100644
--- a/src/common/bits.c
+++ b/src/common/bits.c
@@ -51,6 +51,9 @@ static bitfield_t *_create_bit_field(size_t);
/* Détermine si un ensemble de bits est homogène dans un champ. */
static bool test_state_in_bit_field(const bitfield_t *, size_t, size_t, bool);
+/* Teste l'état de bits selon un masque de bits. */
+static bool test_state_within_bit_field(const bitfield_t *, size_t, const bitfield_t *, bool);
+
/******************************************************************************
@@ -556,6 +559,131 @@ bool test_all_in_bit_field(const bitfield_t *field, size_t first, size_t count)
/******************************************************************************
* *
+* Paramètres : field = champ de bits à modifier. *
+* first = indice du premier bit à traiter. *
+* mask = second champ de bits à tester logiquement. *
+* state = état global à retrouver idéalement. *
+* *
+* Description : Teste l'état de bits selon un masque de bits. *
+* *
+* Retour : true si les bits visés sont tous à l'état indiqué. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool test_state_within_bit_field(const bitfield_t *field, size_t first, const bitfield_t *mask, bool state)
+{
+ bool result; /* Bilan à retourner */
+ size_t start; /* Mot de départ dans le champ */
+ size_t offset; /* Décalage des mots à testter */
+ size_t remaining; /* Taille du dernier tronçon */
+ unsigned long finalcut; /* Limitation du mot final */
+ size_t i; /* Boucle de parcours */
+ size_t windex; /* Indice du mot courant */
+ unsigned long word; /* Mot reconstituté à tester */
+ unsigned long bitmask; /* Masque à appliquer */
+ unsigned long test; /* Valeur résultante du test */
+
+ result = true;
+
+ assert((first + mask->length) <= field->length);
+
+ start = first / (sizeof(unsigned long) * 8);
+ offset = first % (sizeof(unsigned long) * 8);
+
+ remaining = mask->length % (sizeof(unsigned long) * 8);
+
+ if (remaining == 0)
+ finalcut = ~0lu;
+ else
+ finalcut = (1lu << remaining) - 1;
+
+ for (i = 0; i < mask->requested && result; i++)
+ {
+ windex = start + i;
+
+ if (offset == 0)
+ word = field->bits[windex];
+
+ else
+ {
+ word = field->bits[windex] >> offset;
+ if ((windex + 1) < field->requested)
+ word |= field->bits[start + i + 1] << (sizeof(unsigned long) * 8 - offset);
+ }
+
+ bitmask = mask->bits[i];
+
+ test = word ^ bitmask;
+
+ if ((i + 1) == mask->requested)
+ {
+ bitmask &= finalcut;
+ test &= finalcut;
+ }
+
+ result = (state ? test == 0 : test == bitmask);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = champ de bits à modifier. *
+* first = indice du premier bit à traiter. *
+* mask = second champ de bits à tester logiquement. *
+* *
+* Description : Teste l'état à 0 de bits selon un masque de bits. *
+* *
+* Retour : true si les bits visés sont à l'état bas. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool test_zeros_within_bit_field(const bitfield_t *field, size_t first, const bitfield_t *mask)
+{
+ bool result; /* Valeur retrouvée à renvoyer */
+
+ result = test_state_within_bit_field(field, first, mask, false);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : field = champ de bits à modifier. *
+* first = indice du premier bit à traiter. *
+* mask = second champ de bits à tester logiquement. *
+* *
+* Description : Teste l'état à 1 de bits selon un masque de bits. *
+* *
+* Retour : true si les bits visés sont à l'état haut. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool test_ones_within_bit_field(const bitfield_t *field, size_t first, const bitfield_t *mask)
+{
+ bool result; /* Valeur retrouvée à renvoyer */
+
+ result = test_state_within_bit_field(field, first, mask, true);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : field = champ de bits à consulter. *
* *
* Description : Détermine le nombre de bits à 1 dans un champ. *
diff --git a/src/common/bits.h b/src/common/bits.h
index 96ea06a..fb231d5 100644
--- a/src/common/bits.h
+++ b/src/common/bits.h
@@ -78,6 +78,12 @@ bool test_none_in_bit_field(const bitfield_t *, size_t, size_t);
/* Détermine si un ensemble de bits est à 1 dans un champ. */
bool test_all_in_bit_field(const bitfield_t *, size_t, size_t);
+/* Teste l'état à 0 de bits selon un masque de bits. */
+bool test_zeros_within_bit_field(const bitfield_t *, size_t, const bitfield_t *);
+
+/* Teste l'état à 1 de bits selon un masque de bits. */
+bool test_ones_within_bit_field(const bitfield_t *, size_t, const bitfield_t *);
+
/* Détermine le nombre de bits à 1 dans un champ. */
size_t popcount_for_bit_field(const bitfield_t *);