C++中实现按位存取


在我创业的一个项目中,为了节约网络带宽,因此在网络中传输数据需要实现紧凑存取,在国防,科研,航天,军工等多个领域其实也有类似的需求。

实现紧凑存取,不是按一个字节一个字节地存取,而是按位存取。比如一个字节,我们可以存储8个bool信息,废话少说,直接分享代码(备注:里面的代码算法值得优化)。

  //以下为函数定义

  1.  
  2.  
  3. /***********************************************************************/ 
  4. /*   函数作用:从buffer读一个位                                        */ 
  5. /*   参数pBuffer[in]:指定buffer                                       */ 
  6. /*   参数nStart[in]:指定位置                                          */ 
  7. /*   参数nEnd[out]:返回结束位置                                       */ 
  8. /*   参数retByte[out]:返回读取结果值                                  */ 
  9. /*   返回:void                                                           */ 
  10. /***********************************************************************/ 
  11. void ReadOneBit( byte* pBuffer, int nStart, /* out */int& nEnd, /* out */ byte& retByte );  
  12.  
  13. /***********************************************************************/ 
  14. /*   函数作用:从指定buffer里读任意一段位置数据                        */ 
  15. /*   参数pBuffer[in]:指定buffer                                       */ 
  16. /*   参数nStart[in]:指定位置                                          */ 
  17. /*   参数btLength[in]:读取长度                                        */ 
  18. /*   参数nEnd[out]:返回结束位置                                       */ 
  19. /*   参数retData[out]:返回读取结果值,支持任意数据类型                */ 
  20. /*   返回:void                                                           */ 
  21. /***********************************************************************/ 
  22. template<typename T>  
  23. void  ReadDataFromBuffer( byte* pBuffer, int nStart, byte btLength, /* out */int& nEnd, /* out */ T& retData );  
  24.  
  25. /***********************************************************************/ 
  26. /*   函数作用:从指定buffer里读取一段字符串                            */ 
  27. /*   参数pBuffer[in]:指定buffer                                       */ 
  28. /*   参数nStart[in]:指定位置                                          */ 
  29. /*   参数nCount[in]:字符串长度                                        */ 
  30. /*   参数nEnd[out]:返回结束位置                                       */ 
  31. /*   参数pRetData[out]:返回读取字符串结果                             */ 
  32. /*   返回:void                                                           */ 
  33. /***********************************************************************/ 
  34. void ReadStringFromBuffer( byte* pBuffer, int nStart, int nCount, /* out */int& nEnd, /* out */char* pRetData );  
  35.  
  36.  
  37.  
  38. /***********************************************************************/ 
  39. /*   函数作用:向buffer写一个位                                        */ 
  40. /*   参数pBuffer[in]:指定buffer                                       */ 
  41. /*   参数btData[in]:需要写入的值                                      */ 
  42. /*   参数nStart[in]:指定位置                                          */ 
  43. /*   参数nEnd[out]:返回结束位置                                       */ 
  44. /*   返回:void                                                           */ 
  45. /***********************************************************************/ 
  46. void WriteOneBit( byte* pBuffer, byte btData, int nStart,  /* out */int& nEnd );  
  47.  
  48. /***********************************************************************/ 
  49. /*   函数作用:向指定buffer里写入任意一段数据                          */ 
  50. /*   参数pBuffer[in]:指定buffer                                       */ 
  51. /*   参数tData[in]:需要写入的数据,支持任意数据类型                   */ 
  52. /*   参数nStart[in]:指定位置                                          */ 
  53. /*   参数btLength[in]:读取长度                                        */ 
  54. /*   参数nEnd[out]:返回结束位置                                       */ 
  55. /*   返回:void                                                           */ 
  56. /***********************************************************************/ 
  57. template<typename T>  
  58. void  WriteDataToBuffer( byte* pBuffer, T tData, int nStart, byte btLength, /* out */int& nEnd );  
  59.  
  60. /***********************************************************************/ 
  61. /*   函数作用:向指定buffer里写取一段字符串                            */ 
  62. /*   参数pBuffer[in]:指定buffer                                       */ 
  63. /*   参数pchar[in]:需要写入的字符串                                   */ 
  64. /*   参数nStart[in]:指定位置                                          */ 
  65. /*   参数nCount[in]:字符串长度                                        */ 
  66. /*   参数nEnd[out]:返回结束位置                                       */ 
  67. /*   返回:void                                                           */ 
  68. /***********************************************************************/ 
  69. void WtriteStringToBuffer( byte* pBuffer, char* pchar, int nStart,  int nCount, /* out */int& nEnd  );  

//以下为函数实现

  1.  
  2.  
  3. void ReadOneBit( byte* pBuffer, int nStart, /* out */int& nEnd, /* out */ byte& retByte )  
  4. {  
  5.     byte btData = pBuffer[nStart/8];  
  6.     btData = btData << nStart%8;  
  7.     retByte = btData >> 7;  
  8.     nEnd = nStart+1;  
  9. }  
  10.  
  11. template<typename T>  
  12. void  ReadDataFromBuffer( byte* pBuffer, int nStart, byte btLength, /* out */int& nEnd, /* out */ T& retData )  
  13. {  
  14.     //顺序读位  
  15.     retData = 0;  
  16.     if ( btLength > sizeof(T)*8 )  
  17.         return ;  
  18.       
  19.     byte btData;  
  20.     T tData;  
  21.     while ( btLength-- )  
  22.     {  
  23.         ReadOneBit(pBuffer, nStart, nStart, btData);  
  24.         tData = btData << btLength;  
  25.         retData |= tData;  
  26.     }  
  27.       
  28.     nEnd = nStart;  
  29. }  
  30.  
  31. void ReadStringFromBuffer( byte* pBuffer, int nStart, int nCount, /* out */int& nEnd, /* out */char* pRetData )  
  32. {  
  33.     for ( int nIndex=0; nIndex<nCount; nIndex++ )  
  34.     {  
  35.         ReadDataFromBuffer(pBuffer, nStart, 8, nStart, pRetData[nIndex]);  
  36.     }  
  37.     nEnd = nStart;  
  38. }  
  39.  
  40.  
  41. void WriteOneBit( byte* pBuffer, byte btData, int nStart,  /* out */int& nEnd )  
  42. {  
  43.     int nSet = nStart / 8;  
  44.     byte c = pBuffer[nSet];  
  45.     switch ( btData )  
  46.     {  
  47.     case 1:  
  48.         c |= ( 1 << (7- nStart % 8) );  
  49.         break;  
  50.     case 0:  
  51.         c &= ( ~(1 << (7- nStart % 8) ) );  
  52.         break;  
  53.     default:  
  54.         return;  
  55.     }  
  56.     pBuffer [nSet] = c;  
  57.     nEnd = nStart +1;  
  58. }  
  59.  
  60.  
  61.  
  62. template<typename T>  
  63. void  WriteDataToBuffer( byte* pBuffer, T tData, int nStart, byte btLength, /* out */int& nEnd )  
  64. {  
  65. /* //大端机模式  
  66.     byte btDataLength = sizeof(T);  
  67.     if ( btLength > sizeof(T)*8 )  
  68.         return;  
  69.       
  70.     int nDataStart = 0; //数据的第一位位置为0,顺序写入  
  71.     while ( btLength-- )  
  72.     {  
  73.         byte bitData;  
  74.         ReadOneBit((byte*)&tData, nDataStart, nDataStart, bitData);  
  75.         WriteOneBit(pBuffer, bitData, nStart, nStart);  
  76.     }  
  77.       
  78.     nEnd = nStart;  
  79. */ 
  80.  
  81.     //小端机模式:写buffer的时候,不能顺序写位  
  82.  
  83.     //获得模版占用字节大小  
  84.     byte btDataLength = sizeof(T);  
  85.  
  86.     //校验长度是否越界  
  87.     if ( btLength > sizeof(T)*8 )  
  88.         return;  
  89.  
  90.     //将待写数据转为byte*  
  91.     byte* ptData = (byte*)&tData;   
  92.  
  93.     //求模与余  
  94.     int nSet = btLength / 8;  
  95.     int nRin = btLength % 8;  
  96.       
  97.     //定义字节数据与位数据  
  98.     byte bitData;  
  99.     byte byteData;  
  100.     int nTempEnd;  
  101.  
  102.     //先写rin数据  
  103.     byteData = ptData[nSet];  
  104.     while ( nRin-- )  
  105.     {  
  106.         ReadOneBit(&byteData, 7-nRin, nTempEnd, bitData);  
  107.         WriteOneBit(pBuffer, bitData, nStart, nStart);  
  108.     }  
  109.  
  110.     //再写Set数据  
  111.     while ( nSet )  
  112.     {  
  113.         byteData = ptData[--nSet];  
  114.         //写一个byte  
  115.         int i=0;  
  116.         while ( i!=8 )  
  117.         {  
  118.             ReadOneBit(&byteData, i++, nTempEnd, bitData);  
  119.             WriteOneBit(pBuffer, bitData, nStart, nStart);  
  120.         }  
  121.     }  
  122.     nEnd = nStart;  
  123.  
  124. }  
  125.  
  126.  
  127. void WtriteStringToBuffer( byte* pBuffer, char* pchar, int nStart,  int nCount, /* out */int& nEnd  )  
  128. {  
  129.     for ( int nIndex=0; nIndex<nCount; nIndex++ )  
  130.     {  
  131.         WriteDataToBuffer(pBuffer, pchar[nIndex], nStart, 8, nStart);  
  132.     }  
  133.     nEnd = nStart;  

相关内容