diff options
Diffstat (limited to 'src/common')
| -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 *); | 
