/*
* Bitfield
* Copyright (c) 2013, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "includes.h"
#include "common.h"
#include "bitfield.h"
struct bitfield {
u8 *bits;
size_t max_bits;
};
struct bitfield * bitfield_alloc(size_t max_bits)
{
struct bitfield *bf;
bf = os_zalloc(sizeof(*bf) + (max_bits + 7) / 8);
if (bf == NULL)
return NULL;
bf->bits = (u8 *) (bf + 1);
bf->max_bits = max_bits;
return bf;
}
void bitfield_free(struct bitfield *bf)
{
os_free(bf);
}
void bitfield_set(struct bitfield *bf, size_t bit)
{
if (bit >= bf->max_bits)
return;
bf->bits[bit / 8] |= BIT(bit % 8);
}
void bitfield_clear(struct bitfield *bf, size_t bit)
{
if (bit >= bf->max_bits)
return;
bf->bits[bit / 8] &= ~BIT(bit % 8);
}
int bitfield_is_set(struct bitfield *bf, size_t bit)
{
if (bit >= bf->max_bits)
return 0;
return !!(bf->bits[bit / 8] & BIT(bit % 8));
}
static int first_zero(u8 val)
{
int i;
for (i = 0; i < 8; i++) {
if (!(val & 0x01))
return i;
val >>= 1;
}
return -1;
}
int bitfield_get_first_zero(struct bitfield *bf)
{
size_t i;
for (i = 0; i < (bf->max_bits + 7) / 8; i++) {
if (bf->bits[i] != 0xff)
break;
}
if (i == (bf->max_bits + 7) / 8)
return -1;
i = i * 8 + first_zero(bf->bits[i]);
if (i >= bf->max_bits)
return -1;
return i;
}