#ifndef TOR_BITARRAY_H
#define TOR_BITARRAY_H
#include "orconfig.h"
#include <string.h>
#include "lib/cc/torint.h"
#include "lib/malloc/malloc.h"
#if SIZEOF_INT == 4
#define BITARRAY_SHIFT 5
#elif SIZEOF_INT == 8
#define BITARRAY_SHIFT 6
#else
#error "int is neither 4 nor 8 bytes. I can't deal with that."
#endif
#define BITARRAY_MASK ((1u<<BITARRAY_SHIFT)-1)
typedef unsigned int bitarray_t;
static inline bitarray_t *
bitarray_init_zero(unsigned int n_bits)
{
size_t sz = (n_bits+BITARRAY_MASK) >> BITARRAY_SHIFT;
return tor_calloc(sz, sizeof(unsigned int));
}
static inline bitarray_t *
bitarray_expand(bitarray_t *ba,
unsigned int n_bits_old, unsigned int n_bits_new)
{
size_t sz_old = (n_bits_old+BITARRAY_MASK) >> BITARRAY_SHIFT;
size_t sz_new = (n_bits_new+BITARRAY_MASK) >> BITARRAY_SHIFT;
char *ptr;
if (sz_new <= sz_old)
return ba;
ptr = tor_reallocarray(ba, sz_new, sizeof(unsigned int));
memset(ptr+sz_old*sizeof(unsigned int), 0,
(sz_new-sz_old)*sizeof(unsigned int));
return (bitarray_t*) ptr;
}
static inline void
bitarray_free_(bitarray_t *ba)
{
tor_free(ba);
}
#define bitarray_free(ba) FREE_AND_NULL(bitarray_t, bitarray_free_, (ba))
static inline void
bitarray_set(bitarray_t *b, int bit)
{
b[bit >> BITARRAY_SHIFT] |= (1u << (bit & BITARRAY_MASK));
}
static inline void
bitarray_clear(bitarray_t *b, int bit)
{
b[bit >> BITARRAY_SHIFT] &= ~ (1u << (bit & BITARRAY_MASK));
}
static inline unsigned int
bitarray_is_set(bitarray_t *b, int bit)
{
return b[bit >> BITARRAY_SHIFT] & (1u << (bit & BITARRAY_MASK));
}
#endif