一个按比特位拷贝数据的函数copybits
2015年06月30日[TOC] 博客园文章地址 http://www.cnblogs.com/oloroso/archive/2015/06/30/4610120.html
一个按比特位拷贝数据的函数
没有进行特别的优化。其实还可以在拷贝源开始位置和目标开始位置是2的整数倍位置的时候进行优化。
说明
这个函数用于从src数组首地址跳过sbb个字节,又跳过ssb个比特位,拷贝nbits个比特位的数据到dest数组首地址跳过dbb个字节,又跳过dsb个比特位位置。
代码如下
1 include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <assert.h> 5 6 //二进制打印输出 7 void Bp(unsigned char n)
8 {
9 int i; 10 for (i=7;i>=0;i–)
11 {
12 printf(“%u“,(n>>i)&1);
13 } 14 } 15 16 //按比特位拷贝 17 // 从src数组首地址跳过sbb个字节,又跳过ssb个比特位,拷贝nbits个比特位的数据到 18 // dest数组首地址跳过dbb个字节,又跳过dsb个比特位位置 19 int copybits(const unsigned char* src,int sbb/source begin byte/,int ssb/source skip bit/, 20 unsigned char* dest,int dbb/dest begin byte/,int dsb/dest skip bit/,int nbits) 21 { 22 // assert(src && dest && sbb>=0 && ssb>=0 && dbb>=0 && dsb>=0 && nbits>=0); 23 if(src ==NULL || dest == NULL)return -1; 24 if(sbb < 0 || ssb < 0 || dbb < 0 || dsb <0)return -2; 25 if(nbits==0)return 0; 26 27 if(ssb == dsb){ 28 //边界对其情况 29 //1拷贝对齐部分 30 int copybyte=(nbits -(8-ssb))/8; 31 memmove(dest+dbb+1,src+sbb+1,copybyte); 32 //2拷贝前端不完整字节 33 if(ssb != 0){ 34 unsigned char s=src[sbb]; 35 s &= 0xFF>>ssb; 36 dest[dbb] &= 0xFF<<(8-ssb); 37 dest[dbb] |= s; 38 } 39 //拷贝后端不完整字节 40 int endbit=(nbits - (8- ssb))%8; 41 if(endbit != 0){ 42 unsigned char s=src[sbb+1+copybyte]; 43 s &= 0xFF<<(8-endbit); 44 dest[dbb+1 + copybyte] &= 0xFF>>endbit; 45 dest[dbb+1 + copybyte] |= s;
46 } 47 return (8 - endbit); 48 } 49 //————————————————- 50 51 int sbgb = sbb8 + ssb; //源开始的比特位置 52 int dbgb = dbb8 + dsb; //目标开始比特位置 53 int i,ret; 54 int k1,m1,k2,m2; 55 unsigned char s; 56 if(((dest - src)*8+dbgb) < sbgb ){ 57 // 目标开始位置在源开始位置左边 58 for(i=0;i<nbits;++i){ 59 //拷贝某个位 60 //1、源位置 目标位置 61 k1=(sbgb+i)>>3; k2=(dbgb+i)>>3; 62 m1=(sbgb+i)&0x7; m2=(dbgb+i)&0x7; 63 s=src[k1]; 64 s &= 0x80>>m1; //获取源比特位 65 if(m1!=m2){ //偏移位 66 s = m1<m2? (s>>(m2-m1)):(s<<(m1-m2)); 67 } 68 dest[k2] &= (~(0x80>>m2)); //目标位置0 69 dest[k2] |= s; //目标位赋值 70 } 71 } 72 else{ 73 for(i=nbits-1; i >=0 ;–i){ 74 //拷贝某个位 75 //1、源位置 目标位置 76 k1=(sbgb+i)>>3; k2=(dbgb+i)>>3; 77 m1=(sbgb+i)&0x7; m2=(dbgb+i)&0x7; 78 s=src[k1]; 79 s &= 0x80>>m1; //获取源比特位 80 if(m1!=m2){ //偏移位 81 s = m1<m2? (s>>(m2-m1)):(s<<(m1-m2)); 82 } 83 dest[k2] &= (~(0x80>>m2)); //目标位置0 84 dest[k2] |= s; //目标位赋值 85 } 86 87 } 88 return (8 - (dbgb+nbits)%8); 89 } 90 91 92 93 94 int main() 95 { 96 int i; 97 unsigned char src[10]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};//{0,0x1F,0x0F,0x0F,0x70,0,0,1,1}; 98 unsigned char dst[10]={0,0,0,0,0,0,0,0,0}; 99 100 printf(“%d\n“,copybits(src,1,3,dst,0,5,24)); 101 102 for(i=0;i<10;++i){ 103 //printf(”\t%2x\t%2x\n”,src[i],dst[i]); 104 Bp(src[i]); 105 putchar(‘ ‘); 106 } 107 putchar(‘\n‘); 108 for(i=0;i<10;++i){ 109 //printf(”\t%2x\t%2x\n”,src[i],dst[i]); 110 Bp(dst[i]); 111 putchar(‘ ‘); 112 } 113 putchar(‘\n‘); 114 return 0; 115 }