歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

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;  
Copyright © Linux教程網 All Rights Reserved