1 1.1 christos /* 2 1.1 christos * bitset.h -- Dynamic bitset. 3 1.1 christos * 4 1.1 christos * Copyright (c) 2001-2020, NLnet Labs. All rights reserved. 5 1.1 christos * 6 1.1 christos * See LICENSE for the license. 7 1.1 christos * 8 1.1 christos */ 9 1.1 christos #include "config.h" 10 1.1 christos #include "bitset.h" 11 1.1 christos 12 1.1 christos #include <assert.h> 13 1.1 christos #include <limits.h> 14 1.1 christos #include <string.h> 15 1.1 christos 16 1.1 christos size_t nsd_bitset_size(size_t bits) 17 1.1 christos { 18 1.1 christos if(bits == 0) 19 1.1 christos bits++; 20 1.1 christos 21 1.1 christos return (bits / CHAR_BIT) + ((bits % CHAR_BIT) != 0) + sizeof(size_t); 22 1.1 christos } 23 1.1 christos 24 1.1 christos void nsd_bitset_zero(struct nsd_bitset *bset) 25 1.1 christos { 26 1.1 christos size_t sz; 27 1.1 christos 28 1.1 christos assert(bset != NULL); 29 1.1 christos 30 1.1 christos sz = nsd_bitset_size(bset->size) - sizeof(bset->size); 31 1.1 christos assert(sz > 0); 32 1.1 christos memset(bset->bits, 0, sz); 33 1.1 christos } 34 1.1 christos 35 1.1 christos void nsd_bitset_init(struct nsd_bitset *bset, size_t bits) 36 1.1 christos { 37 1.1 christos assert(bset != NULL); 38 1.1 christos if (bits == 0) 39 1.1 christos bits++; 40 1.1 christos 41 1.1 christos bset->size = bits; 42 1.1 christos nsd_bitset_zero(bset); 43 1.1 christos } 44 1.1 christos 45 1.1 christos int nsd_bitset_isset(struct nsd_bitset *bset, size_t bit) 46 1.1 christos { 47 1.1 christos assert(bset != NULL); 48 1.1 christos if(bit >= bset->size) 49 1.1 christos return 0; 50 1.1 christos 51 1.1 christos return (bset->bits[ (bit / CHAR_BIT) ] & (1 << (bit % CHAR_BIT))) != 0; 52 1.1 christos } 53 1.1 christos 54 1.1 christos void nsd_bitset_set(struct nsd_bitset *bset, size_t bit) 55 1.1 christos { 56 1.1 christos assert(bset != NULL); 57 1.1 christos assert(bset->size > bit); 58 1.1 christos bset->bits[ (bit / CHAR_BIT) ] |= (1 << (bit % CHAR_BIT)); 59 1.1 christos } 60 1.1 christos 61 1.1 christos void nsd_bitset_unset(struct nsd_bitset *bset, size_t bit) 62 1.1 christos { 63 1.1 christos assert(bset != NULL); 64 1.1 christos assert(bset->size > bit); 65 1.1 christos bset->bits[ (bit / CHAR_BIT) ] &= ~(1 << (bit % CHAR_BIT)); 66 1.1 christos } 67 1.1 christos 68 1.1 christos void nsd_bitset_or( 69 1.1 christos struct nsd_bitset *destset, 70 1.1 christos struct nsd_bitset *srcset1, 71 1.1 christos struct nsd_bitset *srcset2) 72 1.1 christos { 73 1.1 christos size_t i, n, size, bytes; 74 1.1 christos unsigned char bits; 75 1.1 christos unsigned int mask; 76 1.1 christos 77 1.1 christos assert(destset != NULL); 78 1.1 christos assert(srcset1 != NULL); 79 1.1 christos assert(srcset2 != NULL); 80 1.1 christos 81 1.1 christos size = destset->size; 82 1.1 christos bytes = (size / CHAR_BIT) + ((size % CHAR_BIT) != 0); 83 1.1 christos 84 1.1 christos for(i = 0; i < bytes; i++) { 85 1.1 christos bits = 0; 86 1.1 christos 87 1.1 christos n = (srcset1->size / CHAR_BIT); 88 1.1 christos if (n > i) { 89 1.1 christos bits |= srcset1->bits[i]; 90 1.1 christos } else { 91 1.1 christos n += ((srcset1->size % CHAR_BIT) != 0); 92 1.1 christos mask = (1 << ((srcset1->size % CHAR_BIT) + 1)) - 1; 93 1.1 christos if (n > i) { 94 1.1 christos bits |= (srcset1->bits[i] & mask); 95 1.1 christos } 96 1.1 christos } 97 1.1 christos n = (srcset2->size / CHAR_BIT); 98 1.1 christos if (n > i) { 99 1.1 christos bits |= srcset2->bits[i]; 100 1.1 christos } else { 101 1.1 christos n += ((srcset2->size % CHAR_BIT) != 0); 102 1.1 christos mask = (1 << ((srcset2->size % CHAR_BIT) + 1)) - 1; 103 1.1 christos if (n > i) { 104 1.1 christos bits |= (srcset2->bits[i] & mask); 105 1.1 christos } 106 1.1 christos } 107 1.1 christos destset->bits[i] = bits; 108 1.1 christos } 109 1.1 christos } 110