一个按比特位拷贝数据的函数copybits

一个按比特位拷贝数据的函数

没有进行特别的优化。其实还可以在拷贝源开始位置和目标开始位置是2的整数倍位置的时候进行优化。

说明

这个函数用于从src数组首地址跳过sbb个字节,又跳过ssb个比特位,拷贝nbits个比特位的数据到dest数组首地址跳过dbb个字节,又跳过dsb个比特位位置。

一个按比特位拷贝数据的函数copybits_第1张图片

代码如下

  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 = sbb*8 + ssb;  //源开始的比特位置
 52   int dbgb = dbb*8 + 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 }

 

 

你可能感兴趣的:(copy)