1 #ifndef EL__UTIL_BITFIELD_H
2 #define EL__UTIL_BITFIELD_H
6 #include "util/memory.h"
8 /* Bitfield operations: */
10 /** A vector of bits. The size is fixed at initialization time. */
12 unsigned int bitsize
; /**< Number of bits in the bitfield. */
13 unsigned char bits
[1]; /**< Strawberry bitfields forever. */
16 /** @relates bitfield */
17 #define foreach_bitfield_set(bit, bitfield) \
18 for ((bit) = 0; (bit) < (bitfield)->bitsize; (bit)++) \
19 if (test_bitfield_bit(bitfield, bit))
21 /** @relates bitfield */
22 #define foreachback_bitfield_set(bit, bitfield) \
23 for ((bit) = (bitfield)->bitsize; (bit) > 0;) \
24 if (test_bitfield_bit(bitfield, --bit))
26 /** @relates bitfield */
27 #define foreach_bitfield_cleared(bit, bitfield) \
28 for ((bit) = 0; (bit) < (bitfield)->bitsize; (bit)++) \
29 if (!test_bitfield_bit(bitfield, bit))
31 /* By shifting when getting the bit offset it is ensured that only one bit is
32 * set in the resulting value. Idea from libbt by Kevin Smathers. */
33 #define get_bitfield_bit_offset(bit) ((size_t) (0x80 >> ((bit) % 8)))
34 #define get_bitfield_byte_offset(bit) ((size_t) ((bit) / 8))
35 /* +7 to round up to nearest byte. */
36 #define get_bitfield_byte_size(bits) ((size_t) (((bits) + 7) / 8))
38 /** Allocate a bitfield containing @a bits number of bits.
39 * @relates bitfield */
40 static inline struct bitfield
*
41 init_bitfield(size_t bits
)
43 size_t size
= get_bitfield_byte_size(bits
);
44 struct bitfield
*bitfield
;
46 bitfield
= mem_calloc(1, offsetof(struct bitfield
, bits
) + size
);
47 if (bitfield
) bitfield
->bitsize
= bits
;
52 /** Update @a bitfield with the @a bytesize bytes from the bit string
54 * @relates bitfield */
56 copy_bitfield(struct bitfield
*bitfield
,
57 const unsigned char *bits
, unsigned int bytesize
)
59 /* Only for exact size? */
60 if (bytesize
<= get_bitfield_byte_size(bitfield
->bitsize
))
61 memcpy(bitfield
->bits
, bits
, bytesize
);
64 /** Test whether @a bit is set in the @a bitfield.
65 * @relates bitfield */
67 test_bitfield_bit(struct bitfield
*bitfield
, unsigned int bit
)
69 size_t byte_offset
, bit_offset
;
71 if (bit
>= bitfield
->bitsize
)
74 byte_offset
= get_bitfield_byte_offset(bit
);
75 bit_offset
= get_bitfield_bit_offset(bit
);
77 return !!(bitfield
->bits
[byte_offset
] & bit_offset
);
80 /** Set @a bit in the @a bitfield.
81 * @relates bitfield */
83 set_bitfield_bit(struct bitfield
*bitfield
, unsigned int bit
)
85 size_t byte_offset
, bit_offset
;
87 if (bit
>= bitfield
->bitsize
)
90 byte_offset
= get_bitfield_byte_offset(bit
);
91 bit_offset
= get_bitfield_bit_offset(bit
);
93 bitfield
->bits
[byte_offset
] |= bit_offset
;
96 /** Unset @a bit in the @a bitfield.
97 * @relates bitfield */
99 clear_bitfield_bit(struct bitfield
*bitfield
, unsigned int bit
)
101 size_t byte_offset
, bit_offset
;
103 if (bit
>= bitfield
->bitsize
)
106 byte_offset
= get_bitfield_byte_offset(bit
);
107 bit_offset
= get_bitfield_bit_offset(bit
);
109 bitfield
->bits
[byte_offset
] &= ~bit_offset
;
112 /** Count the set bits in @a bitfield.
113 * @relates bitfield */
114 static inline unsigned int
115 get_bitfield_set_count(struct bitfield
*bitfield
)
117 unsigned int bit
, count
= 0;
119 foreach_bitfield_set (bit
, bitfield
)
125 /** Count the unset bits in @a bitfield.
126 * @relates bitfield */
127 static inline unsigned int
128 get_bitfield_cleared_count(struct bitfield
*bitfield
)
130 unsigned int bit
, count
= 0;
132 foreach_bitfield_cleared (bit
, bitfield
)
138 /** Check whether all bits of @a bitfield are set.
139 * @relates bitfield */
140 static inline unsigned int
141 bitfield_is_set(struct bitfield
*bitfield
)
145 foreach_bitfield_cleared (bit
, bitfield
)
151 /** Check whether all bits of @a bitfield are unset.
152 * @relates bitfield */
153 static inline unsigned int
154 bitfield_is_cleared(struct bitfield
*bitfield
)
158 foreach_bitfield_set (bit
, bitfield
)