diff options
Diffstat (limited to 'src/common/bits.c')
-rw-r--r-- | src/common/bits.c | 194 |
1 files changed, 185 insertions, 9 deletions
diff --git a/src/common/bits.c b/src/common/bits.c index 1bd90f4..d451100 100644 --- a/src/common/bits.c +++ b/src/common/bits.c @@ -37,6 +37,7 @@ struct _bitfield_t { size_t length; /* Nombre de bits représentés */ + size_t requested; /* Nombre de mots alloués */ void *tail; /* Limite du tableau de bits */ @@ -46,7 +47,7 @@ struct _bitfield_t /* Crée un champ de bits initialisé à zéro. */ -static bitfield_t *_create_bit_field(size_t, size_t); +static bitfield_t *_create_bit_field(size_t, bool, size_t); /* Crée une copie de champ de bits initialisé à zéro. */ static bitfield_t *_create_bit_field_from(const bitfield_t *, size_t); @@ -64,6 +65,7 @@ static bitfield_t *_dup_bit_field(const bitfield_t *, size_t); /****************************************************************************** * * * Paramètres : length = nom de bits du champ à représenter. * +* state = état initial de chaque des bits. * * extra = espace mémoire supplémentaire à ajouter au final. * * * * Description : Crée un champ de bits initialisé à zéro. * @@ -74,7 +76,7 @@ static bitfield_t *_dup_bit_field(const bitfield_t *, size_t); * * ******************************************************************************/ -static bitfield_t *_create_bit_field(size_t length, size_t extra) +static bitfield_t *_create_bit_field(size_t length, bool state, size_t extra) { bitfield_t *result; /* Création à retourner */ size_t requested; /* Nombre de mots à allouer */ @@ -88,10 +90,14 @@ static bitfield_t *_create_bit_field(size_t length, size_t extra) result = (bitfield_t *)malloc(base + extra); result->length = length; + result->requested = requested; result->tail = ((char *)result) + base; - memset(result->bits, 0, requested * sizeof(unsigned long)); + if (state) + set_all_in_bit_field(result); + else + reset_all_in_bit_field(result); return result; @@ -101,6 +107,7 @@ static bitfield_t *_create_bit_field(size_t length, size_t extra) /****************************************************************************** * * * Paramètres : length = nom de bits du champ à représenter. * +* state = état initial de chaque des bits. * * * * Description : Crée un champ de bits initialisé à zéro. * * * @@ -110,9 +117,9 @@ static bitfield_t *_create_bit_field(size_t length, size_t extra) * * ******************************************************************************/ -bitfield_t *create_bit_field(size_t length) +bitfield_t *create_bit_field(size_t length, bool state) { - return _create_bit_field(length, 0); + return _create_bit_field(length, state, 0); } @@ -132,7 +139,7 @@ bitfield_t *create_bit_field(size_t length) static bitfield_t *_create_bit_field_from(const bitfield_t *field, size_t extra) { - return _create_bit_field(field->length, extra); + return _create_bit_field(field->length, false, extra); } @@ -177,6 +184,28 @@ void delete_bit_field(bitfield_t *field) /****************************************************************************** * * +* Paramètres : dest = champ de bits à modifier. * +* src = champ de bits à utiliser pour l'opération. * +* * +* Description : Copie un champ de bits dans un autre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void copy_bit_field(bitfield_t *dest, const bitfield_t *src) +{ + assert(dest->length == src->length); + + memcpy(dest->bits, src->bits, dest->requested * sizeof(unsigned long)); + +} + + +/****************************************************************************** +* * * Paramètres : field = champ de bits à dupliquer. * * extra = espace mémoire supplémentaire à ajouter au final. * * * @@ -193,7 +222,7 @@ static bitfield_t *_dup_bit_field(const bitfield_t *field, size_t extra) bitfield_t *result; /* Copie à retourner */ size_t requested; /* Nombre de mots à allouer */ - result = _create_bit_field(field->length, extra); + result = _create_bit_field(field->length, false, extra); requested = field->length / sizeof(unsigned long); if (field->length % sizeof(unsigned long) != 0) requested++; @@ -227,6 +256,44 @@ bitfield_t *dup_bit_field(const bitfield_t *field) /****************************************************************************** * * * Paramètres : field = champ de bits à modifier. * +* * +* Description : Bascule à 0 un champ de bits dans son intégralité. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void reset_all_in_bit_field(bitfield_t *field) +{ + memset(field->bits, 0u, field->requested * sizeof(unsigned long)); + +} + + +/****************************************************************************** +* * +* Paramètres : field = champ de bits à modifier. * +* * +* Description : Bascule à 1 un champ de bits dans son intégralité. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_all_in_bit_field(bitfield_t *field) +{ + memset(field->bits, ~0u, field->requested * sizeof(unsigned long)); + +} + + +/****************************************************************************** +* * +* Paramètres : field = champ de bits à modifier. * * first = indice du premier bit à traiter. * * count = nombre de bits à marquer. * * * @@ -263,6 +330,56 @@ void set_in_bit_field(bitfield_t *field, size_t first, size_t count) /****************************************************************************** * * +* Paramètres : dest = champ de bits à modifier. * +* src = champ de bits à utiliser pour l'opération. * +* * +* Description : Réalise une opération ET logique entre deux champs de bits. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void and_bit_field(bitfield_t *dest, const bitfield_t *src) +{ + size_t i; /* Boucle de parcours */ + + assert(dest->length == src->length); + + for (i = 0; i < dest->requested; i++) + dest->bits[i] &= src->bits[i]; + +} + + +/****************************************************************************** +* * +* Paramètres : dest = champ de bits à modifier. * +* src = champ de bits à utiliser pour l'opération. * +* * +* Description : Réalise une opération OU logique entre deux champs de bits. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void or_bit_field(bitfield_t *dest, const bitfield_t *src) +{ + size_t i; /* Boucle de parcours */ + + assert(dest->length == src->length); + + for (i = 0; i < dest->requested; i++) + dest->bits[i] |= src->bits[i]; + +} + + +/****************************************************************************** +* * * Paramètres : field = champ de bits à modifier. * * first = indice du premier bit à traiter. * * count = nombre de bits à marquer. * @@ -303,6 +420,64 @@ bool test_in_bit_field(bitfield_t *field, size_t first, size_t count) } +/****************************************************************************** +* * +* Paramètres : a = premier champ de bits à comparer. * +* b = second champ de bits à comparer. * +* * +* Description : Indique si deux champs de bits sont identiques ou non. * +* * +* Retour : true si les champs de bits sont égaux ou false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool is_bit_field_equal_to(const bitfield_t *a, const bitfield_t *b) +{ + bool result; /* Résultat à retourner */ + size_t i; /* Boucle de parcours */ + size_t remaining; /* Nombre de bits restants */ + + if (a->length != b->length) + return false; + + result = true; + + for (i = 0; i < (a->requested - 1) && result; i++) + result = (a->bits[i] == b->bits[i]); + + if (result) + { + remaining = a->length % sizeof(unsigned long); + + if (remaining == 0) + result = (a->bits[i] == b->bits[i]); + + else + { + remaining = (1 << (remaining + 1)) - 1; + + result = ((a->bits[i] & remaining) == (b->bits[i] & remaining)); + + } + + } + + return result; + +} + + + + +unsigned long gfw(const bitfield_t *field) +{ + return field->bits[0]; + +} + + /* ---------------------------------------------------------------------------------- */ /* CHAMPS LIES À UNE ZONE MEMOIRE */ @@ -312,6 +487,7 @@ bool test_in_bit_field(bitfield_t *field, size_t first, size_t count) /****************************************************************************** * * * Paramètres : range = espace mémoire à couvrir. * +* state = état initial de chaque des bits. * * * * Description : Crée un champ de bits couvrant une zone mémoire. * * * @@ -321,11 +497,11 @@ bool test_in_bit_field(bitfield_t *field, size_t first, size_t count) * * ******************************************************************************/ -memfield_t *create_mem_field(const mrange_t *range) +memfield_t *create_mem_field(const mrange_t *range, bool state) { bitfield_t *result; /* Création à retourner */ - result = _create_bit_field(get_mrange_length(range), sizeof(vmpa2t)); + result = _create_bit_field(get_mrange_length(range), state, sizeof(vmpa2t)); copy_vmpa((vmpa2t *)result->tail, get_mrange_addr(range)); |