Does anyone have a library of functions that are good for bit manipulation? I need a function like memcpy, but with bits. That is, I want to copy any amount of bits from a source to a target, where neither needs to be aligned on byte boundaries.
Printable View
Does anyone have a library of functions that are good for bit manipulation? I need a function like memcpy, but with bits. That is, I want to copy any amount of bits from a source to a target, where neither needs to be aligned on byte boundaries.
I removed sensitive functions - it compiles. However, you will need to mess with the 'Endian-ness" of struct bitmap - this was written before there was Windoze.
I sure hope I didn't break it for you. I can't test it the way it is, or I would have made sure it works.
I've added comments and removed our specifications references and other stuff. I also removed our proprietary error checking routines. It should be good enough to get you going.
Code:/*
bitstr - library of bit routines
to create:
umask 044
cc - o bitstr.o bitstr.c
cp bitstr.o /usr/lib/bitstr.o
cp bitstr.h /usr/include
to link:
#include <bitstr.h> must be in header
cc myfile.c $LIB/bitstr.o -o myfile
change history
07/19/1989 10:28AM created jmc for HT 17881
08/02/1989 10:40AM add blockbit
jmc 07/14/1990 10:21AM add bitpattern
General -
functions all return (-1) on error
*/
#include <stdlib.h>
/* bit field structure used to move or identify individual bits in a byte
jmc 07/14/1990 10:21AM
*/
typedef struct bitmap{ // bitfields for a byte
unsigned b7:1;
unsigned b6:1;
unsigned b5:1;
unsigned b4:1;
unsigned b3:1;
unsigned b2:1;
unsigned b1:1;
unsigned b0:1;
};
union bits{ // allow moving a byte into the bitfields
unsigned char ch;
struct bitmap x;
} b;
/**********************************
function setbit -- set an single bit on
arguments -
char ch - input value
int bitnum - bit number (0-7) to turn on
***********************************/
int setbit(char ch,int bitnum){ // set bit bitnum on
static int values[9]={1,2,4,8,16,32,64,128};
return (ch | values[bitnum]);
}
/**********************************
function clrbit -- set an single bit off
arguments -
char ch - input value
int bitnum - bit number (0-7) to turn off
return value -
************************************/
int clrbit(char ch, int bitnum){ // clear bit bitnum
static int values[9]={254,253,251,247,239,223,191,127};
return (ch & values[bitnum]);
}
/******************************************
function bitpattern
purpose - create 8 byte string showing pattern of 1's & 0's
arguments:
dest char pointer to receive 1's & 0's
ch source byte to analyze
return value - 8 byte string that represents the bit pattern in a byte
*******************************************/
char *bitpattern(char *dest, char ch){ // create a bit pattern string: 0's & 1's
const char one='1',
zero = '0';
union bits{ // allow moving a byte into the bitfields
unsigned char ch;
struct bitmap x;
} b;
int i;
for(i=0;i<8;i++)*(dest+i)=zero; // set all the bits to zero
b.ch = (unsigned)ch; // move the char into the union
if(b.x.b7) *(dest+0)=one; // for each bit set, put a '1' in the string
if(b.x.b6) *(dest+1)=one;
if(b.x.b5) *(dest+2)=one;
if(b.x.b4) *(dest+3)=one;
if(b.x.b3) *(dest+4)=one;
if(b.x.b2) *(dest+5)=one;
if(b.x.b1) *(dest+6)=one;
if(b.x.b0) *(dest+7)=one;
return dest;
}
/****************************************
function ffc
finds first clear bit - moving from lowest to highest
argument char src
return value 1-8 for bit positions 0= no bit
*****************************************/
int ffc(register unsigned src){
register int i=0;
// no validity check - no error possible except segfault
if(src<255) // no bits clear means zero
for(i=1;src&1;src=src>>1,i++); // shift right until we find clr bit
return i;
}
/****************************************
function ffs
finds first set bit - moving from lowest to highest
argument char src
return value 1-8 for bit positions 0= no bit
*****************************************/
int ffs(unsigned char src){ // find first bit set
register int i=0;
// no error posibble, except segfault - invalid ptr
if(src) // no bits set means zero
for(i=1;~src&1;src=src>>1,i++);// shift right until we find first set bit
return i;
}
/*******************************************
function chrcnt
count the number of a given character in a buffer
arguments
char *szsrc - pointer to char string
int ch - comparison character - the one to count
return value - 0 = none found 1..n number found
********************************************/
int chrcnt(register char *szsrc,const int ch){
register int i=0,
cnt=0;
// no validity check for arguments only failure segfault
for(i=0;*(szsrc+i);i++)
if(*(szsrc+i)==ch) cnt++;
return cnt;
}
/********************************************
function isbitset
check if a bit is set
arguments
char ch - the byte to check
int check - the bit number (0-7) to check
*********************************************/
int isbitset(unsigned char ch,const int check){ // is bit #check set 1=yes
const int values[8]={1,2,4,8,16,32,64,128};
unsigned int chk=0;
// return range error if found
if (check <0 || check > 7) return (-1);
chk=ch;
chk = ch & (~values[chk]);
return !(ch==chk);
}
/********************************************
*********************************************/
int isbitclr(unsigned char ch,const int check){ // is bit # check clear 1=yes
// return range error if found - performed in isbitset()
return !(isbitset(ch,check));
}
/*******************************************
function blockbit
block transfer of bits stream via and/or
arguments
dest - pointer to destination of block transfer
src - pointer to source of bit stream
cnt - number of bits to transfer
method - 1 = & the bit streams
0 = | the bit streams
(-1) = copy the bitstreams
return value 0 - success (-1) error
********************************************/
int blockbit(char *dest, char *src, const int cnt,const int method){
int flag=0; // odd bits detected
unsigned char odd=0x00; // odd bit carrier
register char *buf, *s;
char tmp[9];
int i=0;
int j=0;
// check for validity of arguments
if(method < 0 || method > 1 || cnt < 0 ) return (-1);
if(cnt==0) return 0; // no change but valid argument
flag=cnt%8; // check for odd bit processing
j=cnt/8;
switch (method){
case (-1):
for(i=0;i<=j;i++) *(dest+i)=*(src+i);
break;
case 0:
for(i=0;i<=j;i++) *(dest+i)= *(dest+i) | *(src+i);
break;
case 1:
for(i=0;i<=j;i++) *(dest+i)= *(dest+i) & *(src+i);
break;
default:
break;
}
if(flag){
odd= *(dest+i);
if(method==1) odd = odd & *(src+i);
if(method==0) odd = odd | *(src+i);
bitpattern(tmp,odd);
for(buf=tmp,j=0;j<flag;j++)
if(*buf=='1')
setbit(*(dest+i),j);
else
clrbit(*(dest+i),j);
}
return 0;
}
Funny how businesses frequently get dragged in by the latest and greatest but when it comes down to the developers you still end up with stuff that's 14 years old. I wonder why :)Code:07/19/1989 10:28AM created jmc for HT 17881
Thanks a lot jim, but I fear that the tiny bit I really need is not there :(
That would be a blockbit that can start at odd bit offsets.
I want to combine 7 data streams to 1, with the transferred amount sometimes being less than a byte.