#include "deluge.h" Bits * bitnew(int n, uchar *init) { Bits *b; int i; b = emalloc(sizeof b[0]); b->n = n; b->nhave = 0; if(init){ b->p = init; for(i = 0; i < b->n; i++) if(bitget(b, i)) b->nhave++; }else b->p = emallocz((n+7) / 8, 1); return b; } void bitset(Bits *b, int n) { assert(n < b->n); if(!bitget(b, n)){ b->nhave++; b->p[n/8] = b->p[n/8] | ((uchar)1<<(8 - n%8 - 1)); } } void bitunset(Bits *b, int n) { assert(n < b->n); if(bitget(b, n)){ b->nhave--; b->p[n/8] = b->p[n/8] & ~((uchar)1<<(8 - n%8 - 1)); } } int bitget(Bits *b, int n) { assert(n < b->n); return (b->p[n/8] >> (8 - n%8 - 1)) & 1; } int bitlen(Bits *b) { return b->n; } int bitnbytes(Bits *b) { return (b->n+7) / 8; } void bitfree(Bits *b) { if(b) free(b->p); free(b); } int bithaveall(Bits *b) { return b->n == b->nhave; } double bithave(Bits *b) { return (double)b->nhave / (double)b->n; } int bitnhave(Bits *b) { return b->nhave; } static void bitcalcnhave(Bits *b) { int i; b->nhave = 0; for(i = 0; i < b->n; i++) if(bitget(b, i)) b->nhave++; } void bitcopy(Bits *dst, Bits *src, int len) { assert(bitnbytes(dst) == bitnbytes(src)); dst->n = len; memmove(dst->p, src->p, bitnbytes(src)); bitcalcnhave(dst); } void bitclear(Bits *b) { memset(b->p, 0, bitnbytes(b)); b->nhave = 0; } Bits * bitand(Bits *b1, Bits *b2) { Bits *r; int i; assert(bitlen(b1) == bitlen(b2)); r = bitnew(bitlen(b1), nil); for(i = 0; i < bitnbytes(b1); i++) r->p[i] = b1->p[i] & b2->p[i]; bitcalcnhave(r); return r; } void bitinvert(Bits *b) { int i; for(i = 0; i < bitnbytes(b); i++) b->p[i] = ~b->p[i]; b->nhave = b->n - b->nhave; } Bits * bitinvertand(Bits *b1, Bits *b2) { Bits *inv; Bits *r; inv = bitnew(bitlen(b1), nil); bitcopy(inv, b1, bitlen(b1)); bitinvert(inv); r = bitand(inv, b2); bitfree(inv); return r; } int bitinvertandlen(Bits *b1, Bits *b2) { Bits *r; int n; r = bitinvertand(b1, b2); n = r->nhave; bitfree(r); return n; }