一个按比特位拷贝数据的函数
没有进行特别的优化。其实还可以在拷贝源开始位置和目标开始位置是2的整数倍位置的时候进行优化。
说明
这个函数用于从src数组首地址跳过sbb个字节,又跳过ssb个比特位,拷贝nbits个比特位的数据到dest数组首地址跳过dbb个字节,又跳过dsb个比特位位置。
代码如下
include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h> //二进制打印输出
void Bp(unsigned char n)
{
int i;
for (i=;i>=;i--)
{
printf("%u",(n>>i)&);
}
} //按比特位拷贝
// 从src数组首地址跳过sbb个字节,又跳过ssb个比特位,拷贝nbits个比特位的数据到
// dest数组首地址跳过dbb个字节,又跳过dsb个比特位位置
int copybits(const unsigned char* src,int sbb/*source begin byte*/,int ssb/*source skip bit*/,
unsigned char* dest,int dbb/*dest begin byte*/,int dsb/*dest skip bit*/,int nbits)
{
// assert(src && dest && sbb>=0 && ssb>=0 && dbb>=0 && dsb>=0 && nbits>=0);
if(src ==NULL || dest == NULL)return -;
if(sbb < || ssb < || dbb < || dsb <)return -;
if(nbits==)return ; if(ssb == dsb){
//边界对其情况
//1拷贝对齐部分
int copybyte=(nbits -(-ssb))/;
memmove(dest+dbb+,src+sbb+,copybyte);
//2拷贝前端不完整字节
if(ssb != ){
unsigned char s=src[sbb];
s &= 0xFF>>ssb;
dest[dbb] &= 0xFF<<(-ssb);
dest[dbb] |= s;
}
//拷贝后端不完整字节
int endbit=(nbits - (- ssb))%;
if(endbit != ){
unsigned char s=src[sbb++copybyte];
s &= 0xFF<<(-endbit);
dest[dbb+ + copybyte] &= 0xFF>>endbit;
dest[dbb+ + copybyte] |= s;
}
return ( - endbit);
}
//------------------------------------------------- int sbgb = sbb* + ssb; //源开始的比特位置
int dbgb = dbb* + dsb; //目标开始比特位置
int i,ret;
int k1,m1,k2,m2;
unsigned char s;
if(((dest - src)*+dbgb) < sbgb ){
// 目标开始位置在源开始位置左边
for(i=;i<nbits;++i){
//拷贝某个位
//1、源位置 目标位置
k1=(sbgb+i)>>; k2=(dbgb+i)>>;
m1=(sbgb+i)&0x7; m2=(dbgb+i)&0x7;
s=src[k1];
s &= 0x80>>m1; //获取源比特位
if(m1!=m2){ //偏移位
s = m1<m2? (s>>(m2-m1)):(s<<(m1-m2));
}
dest[k2] &= (~(0x80>>m2)); //目标位置0
dest[k2] |= s; //目标位赋值
}
}
else{
for(i=nbits-; i >= ;--i){
//拷贝某个位
//1、源位置 目标位置
k1=(sbgb+i)>>; k2=(dbgb+i)>>;
m1=(sbgb+i)&0x7; m2=(dbgb+i)&0x7;
s=src[k1];
s &= 0x80>>m1; //获取源比特位
if(m1!=m2){ //偏移位
s = m1<m2? (s>>(m2-m1)):(s<<(m1-m2));
}
dest[k2] &= (~(0x80>>m2)); //目标位置0
dest[k2] |= s; //目标位赋值
} }
return ( - (dbgb+nbits)%);
} int main()
{
int i;
unsigned char src[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};//{0,0x1F,0x0F,0x0F,0x70,0,0,1,1};
unsigned char dst[]={,,,,,,,,}; printf("%d\n",copybits(src,,,dst,,,)); for(i=;i<;++i){
//printf("\t%2x\t%2x\n",src[i],dst[i]);
Bp(src[i]);
putchar(' ');
}
putchar('\n');
for(i=;i<;++i){
//printf("\t%2x\t%2x\n",src[i],dst[i]);
Bp(dst[i]);
putchar(' ');
}
putchar('\n');
return ;
}