#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;
}
|