diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/bits.c | 128 | ||||
-rw-r--r-- | src/common/bits.h | 6 |
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 *); |