bitmap.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #ifndef BITMAP_H_
  2. #define BITMAP_H_
  3. #include <stdint.h>
  4. #include <string.h>
  5. typedef uint8_t bm_base_type_t;
  6. /* Define a large bit map. */
  7. #define DEFINE_BITMAP(name, nr_bits) bm_base_type_t name[(nr_bits) / 8]
  8. /* Efficiently convert a bit number to the corresponding bit map.
  9. * Resolves at compile-time, if bitnr is a compile-time constant.
  10. * Uses an efficient table lookup otherwise.
  11. */
  12. extern const uint8_t _bit_to_mask8[8];
  13. #define BITMASK8(bitnr) ( \
  14. (uint8_t)(__builtin_constant_p(bitnr) ? \
  15. (1u << (bitnr)) : \
  16. _bit_to_mask8[(bitnr)]) \
  17. )
  18. /* Get a bit from a large bit map.
  19. * Return: The return value is either 0 or non-zero depending on whether
  20. * the bit is 0 or 1.
  21. */
  22. static inline uint8_t bm_get_bit(const bm_base_type_t *bm, uint8_t bit_number)
  23. {
  24. uint8_t byte_number = bit_number >> 3;
  25. bit_number = bit_number & 7u;
  26. return (uint8_t)(bm[byte_number] & BITMASK8(bit_number));
  27. }
  28. /* Get a bit from a large bit map.
  29. * Return: The return value is either 0 or 1 depending on whether
  30. * the bit is 0 or 1.
  31. */
  32. static inline uint8_t bm_get_bool(const bm_base_type_t *bm, uint8_t bit_number)
  33. {
  34. return !!bm_get_bit(bm, bit_number);
  35. }
  36. /* Set a bit in a large bit map. */
  37. static inline void bm_set_bit(bm_base_type_t *bm, uint8_t bit_number)
  38. {
  39. uint8_t byte_number = bit_number >> 3;
  40. bit_number = bit_number & 7u;
  41. bm[byte_number] = (bm_base_type_t)(bm[byte_number] | BITMASK8(bit_number));
  42. }
  43. /* Clear a bit in a large bit map. */
  44. static inline void bm_clear_bit(bm_base_type_t *bm, uint8_t bit_number)
  45. {
  46. uint8_t byte_number = bit_number >> 3;
  47. bit_number = bit_number & 7u;
  48. bm[byte_number] = (bm_base_type_t)(bm[byte_number] & ~BITMASK8(bit_number));
  49. }
  50. /* Write a bit in a large bit map. */
  51. static inline void bm_write_bit(bm_base_type_t *bm,
  52. uint8_t bit_number, uint8_t bit_value)
  53. {
  54. if (bit_value)
  55. bm_set_bit(bm, bit_number);
  56. else
  57. bm_clear_bit(bm, bit_number);
  58. }
  59. /* Initialize all bits in the bit map. */
  60. #define bm_init(bm, all_set) _bm_init(bm, sizeof(bm), all_set)
  61. static inline void _bm_init(bm_base_type_t *bm, uint8_t bm_size,
  62. uint8_t all_set)
  63. {
  64. memset(bm, all_set ? 0xFF : 0, bm_size);
  65. }
  66. #endif /* BITMAP_H_ */