1 /* Copyright (c) 2003-2004, Roger Dingledine
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
12 * \brief Implements a variable-sized (but non-resizeable) bit-array.
17 #include "lib/cc/torint.h"
18 #include "lib/malloc/malloc.h"
21 #define BITARRAY_SHIFT 5
23 #define BITARRAY_SHIFT 6
25 #error "int is neither 4 nor 8 bytes. I can't deal with that."
26 #endif /* SIZEOF_INT == 4 || ... */
27 #define BITARRAY_MASK ((1u<<BITARRAY_SHIFT)-1)
29 /** A random-access array of one-bit-wide elements. */
30 typedef unsigned int bitarray_t
;
31 /** Create a new bit array that can hold <b>n_bits</b> bits. */
32 static inline bitarray_t
*
33 bitarray_init_zero(unsigned int n_bits
)
35 /* round up to the next int. */
36 size_t sz
= (n_bits
+BITARRAY_MASK
) >> BITARRAY_SHIFT
;
37 return tor_calloc(sz
, sizeof(unsigned int));
39 /** Expand <b>ba</b> from holding <b>n_bits_old</b> to <b>n_bits_new</b>,
40 * clearing all new bits. Returns a possibly changed pointer to the
42 static inline bitarray_t
*
43 bitarray_expand(bitarray_t
*ba
,
44 unsigned int n_bits_old
, unsigned int n_bits_new
)
46 size_t sz_old
= (n_bits_old
+BITARRAY_MASK
) >> BITARRAY_SHIFT
;
47 size_t sz_new
= (n_bits_new
+BITARRAY_MASK
) >> BITARRAY_SHIFT
;
51 ptr
= tor_reallocarray(ba
, sz_new
, sizeof(unsigned int));
52 /* This memset does nothing to the older excess bytes. But they were
53 * already set to 0 by bitarry_init_zero. */
54 memset(ptr
+sz_old
*sizeof(unsigned int), 0,
55 (sz_new
-sz_old
)*sizeof(unsigned int));
56 return (bitarray_t
*) ptr
;
58 /** Free the bit array <b>ba</b>. */
60 bitarray_free_(bitarray_t
*ba
)
64 #define bitarray_free(ba) FREE_AND_NULL(bitarray_t, bitarray_free_, (ba))
66 /** Set the <b>bit</b>th bit in <b>b</b> to 1. */
68 bitarray_set(bitarray_t
*b
, int bit
)
70 b
[bit
>> BITARRAY_SHIFT
] |= (1u << (bit
& BITARRAY_MASK
));
72 /** Set the <b>bit</b>th bit in <b>b</b> to 0. */
74 bitarray_clear(bitarray_t
*b
, int bit
)
76 b
[bit
>> BITARRAY_SHIFT
] &= ~ (1u << (bit
& BITARRAY_MASK
));
78 /** Return true iff <b>bit</b>th bit in <b>b</b> is nonzero. NOTE: does
79 * not necessarily return 1 on true. */
80 static inline unsigned int
81 bitarray_is_set(bitarray_t
*b
, int bit
)
83 return b
[bit
>> BITARRAY_SHIFT
] & (1u << (bit
& BITARRAY_MASK
));
86 #endif /* !defined(TOR_BITARRAY_H) */