13c260e60Schristos /* 23c260e60Schristos * Bitfield 33c260e60Schristos * Copyright (c) 2013, Jouni Malinen <j@w1.fi> 43c260e60Schristos * 53c260e60Schristos * This software may be distributed under the terms of the BSD license. 63c260e60Schristos * See README for more details. 73c260e60Schristos */ 83c260e60Schristos 93c260e60Schristos #include "includes.h" 103c260e60Schristos 113c260e60Schristos #include "common.h" 123c260e60Schristos #include "bitfield.h" 133c260e60Schristos 143c260e60Schristos 153c260e60Schristos struct bitfield { 163c260e60Schristos u8 *bits; 173c260e60Schristos size_t max_bits; 183c260e60Schristos }; 193c260e60Schristos 203c260e60Schristos bitfield_alloc(size_t max_bits)213c260e60Schristosstruct bitfield * bitfield_alloc(size_t max_bits) 223c260e60Schristos { 233c260e60Schristos struct bitfield *bf; 243c260e60Schristos 253c260e60Schristos bf = os_zalloc(sizeof(*bf) + (max_bits + 7) / 8); 263c260e60Schristos if (bf == NULL) 273c260e60Schristos return NULL; 283c260e60Schristos bf->bits = (u8 *) (bf + 1); 293c260e60Schristos bf->max_bits = max_bits; 303c260e60Schristos return bf; 313c260e60Schristos } 323c260e60Schristos 333c260e60Schristos bitfield_free(struct bitfield * bf)343c260e60Schristosvoid bitfield_free(struct bitfield *bf) 353c260e60Schristos { 363c260e60Schristos os_free(bf); 373c260e60Schristos } 383c260e60Schristos 393c260e60Schristos bitfield_set(struct bitfield * bf,size_t bit)403c260e60Schristosvoid bitfield_set(struct bitfield *bf, size_t bit) 413c260e60Schristos { 423c260e60Schristos if (bit >= bf->max_bits) 433c260e60Schristos return; 443c260e60Schristos bf->bits[bit / 8] |= BIT(bit % 8); 453c260e60Schristos } 463c260e60Schristos 473c260e60Schristos bitfield_clear(struct bitfield * bf,size_t bit)483c260e60Schristosvoid bitfield_clear(struct bitfield *bf, size_t bit) 493c260e60Schristos { 503c260e60Schristos if (bit >= bf->max_bits) 513c260e60Schristos return; 523c260e60Schristos bf->bits[bit / 8] &= ~BIT(bit % 8); 533c260e60Schristos } 543c260e60Schristos 553c260e60Schristos bitfield_is_set(struct bitfield * bf,size_t bit)563c260e60Schristosint bitfield_is_set(struct bitfield *bf, size_t bit) 573c260e60Schristos { 583c260e60Schristos if (bit >= bf->max_bits) 593c260e60Schristos return 0; 603c260e60Schristos return !!(bf->bits[bit / 8] & BIT(bit % 8)); 613c260e60Schristos } 623c260e60Schristos 633c260e60Schristos first_zero(u8 val)643c260e60Schristosstatic int first_zero(u8 val) 653c260e60Schristos { 663c260e60Schristos int i; 673c260e60Schristos for (i = 0; i < 8; i++) { 683c260e60Schristos if (!(val & 0x01)) 693c260e60Schristos return i; 703c260e60Schristos val >>= 1; 713c260e60Schristos } 723c260e60Schristos return -1; 733c260e60Schristos } 743c260e60Schristos 753c260e60Schristos bitfield_get_first_zero(struct bitfield * bf)763c260e60Schristosint bitfield_get_first_zero(struct bitfield *bf) 773c260e60Schristos { 783c260e60Schristos size_t i; 79*bb610346Schristos for (i = 0; i < (bf->max_bits + 7) / 8; i++) { 803c260e60Schristos if (bf->bits[i] != 0xff) 813c260e60Schristos break; 823c260e60Schristos } 83*bb610346Schristos if (i == (bf->max_bits + 7) / 8) 843c260e60Schristos return -1; 853c260e60Schristos i = i * 8 + first_zero(bf->bits[i]); 863c260e60Schristos if (i >= bf->max_bits) 873c260e60Schristos return -1; 883c260e60Schristos return i; 893c260e60Schristos } 90