1e5b75505Sopenharmony_ci/* 2e5b75505Sopenharmony_ci * Bitfield 3e5b75505Sopenharmony_ci * Copyright (c) 2013, Jouni Malinen <j@w1.fi> 4e5b75505Sopenharmony_ci * 5e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license. 6e5b75505Sopenharmony_ci * See README for more details. 7e5b75505Sopenharmony_ci */ 8e5b75505Sopenharmony_ci 9e5b75505Sopenharmony_ci#include "includes.h" 10e5b75505Sopenharmony_ci 11e5b75505Sopenharmony_ci#include "common.h" 12e5b75505Sopenharmony_ci#include "bitfield.h" 13e5b75505Sopenharmony_ci 14e5b75505Sopenharmony_ci 15e5b75505Sopenharmony_cistruct bitfield { 16e5b75505Sopenharmony_ci u8 *bits; 17e5b75505Sopenharmony_ci size_t max_bits; 18e5b75505Sopenharmony_ci}; 19e5b75505Sopenharmony_ci 20e5b75505Sopenharmony_ci 21e5b75505Sopenharmony_cistruct bitfield * bitfield_alloc(size_t max_bits) 22e5b75505Sopenharmony_ci{ 23e5b75505Sopenharmony_ci struct bitfield *bf; 24e5b75505Sopenharmony_ci 25e5b75505Sopenharmony_ci bf = os_zalloc(sizeof(*bf) + (max_bits + 7) / 8); 26e5b75505Sopenharmony_ci if (bf == NULL) 27e5b75505Sopenharmony_ci return NULL; 28e5b75505Sopenharmony_ci bf->bits = (u8 *) (bf + 1); 29e5b75505Sopenharmony_ci bf->max_bits = max_bits; 30e5b75505Sopenharmony_ci return bf; 31e5b75505Sopenharmony_ci} 32e5b75505Sopenharmony_ci 33e5b75505Sopenharmony_ci 34e5b75505Sopenharmony_civoid bitfield_free(struct bitfield *bf) 35e5b75505Sopenharmony_ci{ 36e5b75505Sopenharmony_ci os_free(bf); 37e5b75505Sopenharmony_ci} 38e5b75505Sopenharmony_ci 39e5b75505Sopenharmony_ci 40e5b75505Sopenharmony_civoid bitfield_set(struct bitfield *bf, size_t bit) 41e5b75505Sopenharmony_ci{ 42e5b75505Sopenharmony_ci if (bit >= bf->max_bits) 43e5b75505Sopenharmony_ci return; 44e5b75505Sopenharmony_ci bf->bits[bit / 8] |= BIT(bit % 8); 45e5b75505Sopenharmony_ci} 46e5b75505Sopenharmony_ci 47e5b75505Sopenharmony_ci 48e5b75505Sopenharmony_civoid bitfield_clear(struct bitfield *bf, size_t bit) 49e5b75505Sopenharmony_ci{ 50e5b75505Sopenharmony_ci if (bit >= bf->max_bits) 51e5b75505Sopenharmony_ci return; 52e5b75505Sopenharmony_ci bf->bits[bit / 8] &= ~BIT(bit % 8); 53e5b75505Sopenharmony_ci} 54e5b75505Sopenharmony_ci 55e5b75505Sopenharmony_ci 56e5b75505Sopenharmony_ciint bitfield_is_set(struct bitfield *bf, size_t bit) 57e5b75505Sopenharmony_ci{ 58e5b75505Sopenharmony_ci if (bit >= bf->max_bits) 59e5b75505Sopenharmony_ci return 0; 60e5b75505Sopenharmony_ci return !!(bf->bits[bit / 8] & BIT(bit % 8)); 61e5b75505Sopenharmony_ci} 62e5b75505Sopenharmony_ci 63e5b75505Sopenharmony_ci 64e5b75505Sopenharmony_cistatic int first_zero(u8 val) 65e5b75505Sopenharmony_ci{ 66e5b75505Sopenharmony_ci int i; 67e5b75505Sopenharmony_ci for (i = 0; i < 8; i++) { 68e5b75505Sopenharmony_ci if (!(val & 0x01)) 69e5b75505Sopenharmony_ci return i; 70e5b75505Sopenharmony_ci val >>= 1; 71e5b75505Sopenharmony_ci } 72e5b75505Sopenharmony_ci return -1; 73e5b75505Sopenharmony_ci} 74e5b75505Sopenharmony_ci 75e5b75505Sopenharmony_ci 76e5b75505Sopenharmony_ciint bitfield_get_first_zero(struct bitfield *bf) 77e5b75505Sopenharmony_ci{ 78e5b75505Sopenharmony_ci size_t i; 79e5b75505Sopenharmony_ci for (i = 0; i < (bf->max_bits + 7) / 8; i++) { 80e5b75505Sopenharmony_ci if (bf->bits[i] != 0xff) 81e5b75505Sopenharmony_ci break; 82e5b75505Sopenharmony_ci } 83e5b75505Sopenharmony_ci if (i == (bf->max_bits + 7) / 8) 84e5b75505Sopenharmony_ci return -1; 85e5b75505Sopenharmony_ci i = i * 8 + first_zero(bf->bits[i]); 86e5b75505Sopenharmony_ci if (i >= bf->max_bits) 87e5b75505Sopenharmony_ci return -1; 88e5b75505Sopenharmony_ci return i; 89e5b75505Sopenharmony_ci} 90