huangcm
2024-12-18 9d29be7f7249789d6ffd0440067187a9f040c2cd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
 * 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;
}