#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "mslp_sd.h"
#include "slp.h"
#include "mslp.h"
#include "mslpd_mask.h"
#define BIT(i,pc) getbit(i,pc)
static char getbit(int i, char *pc);
void mask_set(Mask *pMask, int bit, int val) {
int index = bit/8;
unsigned char mask = 1 << (7-bit%8);
if (val) pMask->pcMask[index] |= mask;
else pMask->pcMask[index] &= ~mask;
}
int mask_get(Mask *pMask, int bit) {
return BIT(bit,pMask->pcMask);
}
Mask * mask_create(int iBits) {
Mask *pm = (Mask *) safe_malloc(sizeof(Mask),NULL,0);
assert( pm );
pm->iLen = iBits/8+1;
pm->iBits = iBits;
pm->pcMask = safe_malloc(sizeof(pm->iLen),NULL,0);
assert( pm->pcMask );
return pm;
}
Mask * mask_invert(Mask *pm) {
Mask *pmClone = mask_clone(pm);
int i;
for (i = 0; i < pm->iLen; i++)
pmClone->pcMask[i] = ~(pm->pcMask[i]);
return pmClone;
}
Mask * mask_clone(Mask *pm) {
Mask *pmClone = (Mask*) safe_malloc(sizeof(Mask),(char*)pm,sizeof(Mask));
assert( pmClone );
pmClone->pcMask = safe_malloc(pm->iLen,pm->pcMask,pm->iLen);
assert( pmClone->pcMask );
return pmClone;
}
void mask_delete(Mask *pm) {
if (pm) {
if (pm->pcMask) SLPFree((void*)pm->pcMask);
SLPFree((void*)pm);
}
}
Mask * mask_and(Mask *pm1, Mask *pm2)
{
int i;
Mask *pmResult = mask_create(pm1->iBits);
if (pm1->iLen != pm2->iLen || pm1->iBits != pm2->iBits)
{
LOG( SLP_LOG_FAIL, "mask_and: unequal lengths");
return NULL;
}
pmResult->iBits = pm1->iBits;
for (i = 0; i < pm1->iLen; i++)
pmResult->pcMask[i] = (char) ((char)(0xFF & pm1->pcMask[i]) &
(char)(0xFF & pm2->pcMask[i]));
return pmResult;
}
Mask * mask_or(Mask *pm1, Mask *pm2)
{
int i;
Mask *pmResult = mask_create(pm1->iBits);
if (pm1->iLen != pm2->iLen || pm1->iBits != pm2->iBits)
{
LOG( SLP_LOG_FAIL, "mask_and: unequal lengths");
return NULL;
}
pmResult->iBits = pm1->iBits;
for (i = 0; i < pm1->iLen; i++)
pmResult->pcMask[i] = pm1->pcMask[i] | pm2->pcMask[i];
return pmResult;
}
int mask_next(Mask *pm, int val) {
while (pm->iIter < pm->iBits && BIT(pm->iIter,pm->pcMask) != val)
pm->iIter++;
if (pm->iIter == pm->iBits) return -1;
else return pm->iIter++;
}
void mask_reset(Mask *pm) {
pm->iIter = 0;
}
static char getbit(int i, char *pc) {
int index = i/8;
unsigned char mask = 1 << (7-i%8);
return (pc[index] & mask)?1:0;
}
#ifndef NDEBUG
void mask_show(Mask *pm) {
int i;
for (i = 0; i<pm->iBits ; i++ ) printf("%3d",i);
printf("\n");
for (i = 0;i<pm->iBits ;i++ ) printf("%3d",mask_get(pm,i));
printf("\n");
}
#endif