歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C++中實現按位存取

C++中實現按位存取

日期:2017/3/1 10:32:45   编辑:Linux編程
在我創業的一個項目中,為了節約網絡帶寬,因此在網絡中傳輸數據需要實現緊湊存取,在國防,科研,航天,軍工等多個領域其實也有類似的需求。

實現緊湊存取,不是按一個字節一個字節地存取,而是按位存取。比如一個字節,我們可以存儲8個bool信息,廢話少說,直接分享代碼(備注:裡面的代碼算法值得優化)。

  //以下為函數定義

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

//以下為函數實現

  1. void ReadOneBit( byte* pBuffer, int nStart, /* out */int& nEnd, /* out */ byte& retByte )
  2. {
  3. byte btData = pBuffer[nStart/8];
  4. btData = btData << nStart%8;
  5. retByte = btData >> 7;
  6. nEnd = nStart+1;
  7. }
  8. template<typename T>
  9. void ReadDataFromBuffer( byte* pBuffer, int nStart, byte btLength, /* out */int& nEnd, /* out */ T& retData )
  10. {
  11. //順序讀位
  12. retData = 0;
  13. if ( btLength > sizeof(T)*8 )
  14. return ;
  15. byte btData;
  16. T tData;
  17. while ( btLength-- )
  18. {
  19. ReadOneBit(pBuffer, nStart, nStart, btData);
  20. tData = btData << btLength;
  21. retData |= tData;
  22. }
  23. nEnd = nStart;
  24. }
  25. void ReadStringFromBuffer( byte* pBuffer, int nStart, int nCount, /* out */int& nEnd, /* out */char* pRetData )
  26. {
  27. for ( int nIndex=0; nIndex<nCount; nIndex++ )
  28. {
  29. ReadDataFromBuffer(pBuffer, nStart, 8, nStart, pRetData[nIndex]);
  30. }
  31. nEnd = nStart;
  32. }
  33. void WriteOneBit( byte* pBuffer, byte btData, int nStart, /* out */int& nEnd )
  34. {
  35. int nSet = nStart / 8;
  36. byte c = pBuffer[nSet];
  37. switch ( btData )
  38. {
  39. case 1:
  40. c |= ( 1 << (7- nStart % 8) );
  41. break;
  42. case 0:
  43. c &= ( ~(1 << (7- nStart % 8) ) );
  44. break;
  45. default:
  46. return;
  47. }
  48. pBuffer [nSet] = c;
  49. nEnd = nStart +1;
  50. }
  51. template<typename T>
  52. void WriteDataToBuffer( byte* pBuffer, T tData, int nStart, byte btLength, /* out */int& nEnd )
  53. {
  54. /* //大端機模式
  55. byte btDataLength = sizeof(T);
  56. if ( btLength > sizeof(T)*8 )
  57. return;
  58. int nDataStart = 0; //數據的第一位位置為0,順序寫入
  59. while ( btLength-- )
  60. {
  61. byte bitData;
  62. ReadOneBit((byte*)&tData, nDataStart, nDataStart, bitData);
  63. WriteOneBit(pBuffer, bitData, nStart, nStart);
  64. }
  65. nEnd = nStart;
  66. */
  67. //小端機模式:寫buffer的時候,不能順序寫位
  68. //獲得模版占用字節大小
  69. byte btDataLength = sizeof(T);
  70. //校驗長度是否越界
  71. if ( btLength > sizeof(T)*8 )
  72. return;
  73. //將待寫數據轉為byte*
  74. byte* ptData = (byte*)&tData;
  75. //求模與余
  76. int nSet = btLength / 8;
  77. int nRin = btLength % 8;
  78. //定義字節數據與位數據
  79. byte bitData;
  80. byte byteData;
  81. int nTempEnd;
  82. //先寫rin數據
  83. byteData = ptData[nSet];
  84. while ( nRin-- )
  85. {
  86. ReadOneBit(&byteData, 7-nRin, nTempEnd, bitData);
  87. WriteOneBit(pBuffer, bitData, nStart, nStart);
  88. }
  89. //再寫Set數據
  90. while ( nSet )
  91. {
  92. byteData = ptData[--nSet];
  93. //寫一個byte
  94. int i=0;
  95. while ( i!=8 )
  96. {
  97. ReadOneBit(&byteData, i++, nTempEnd, bitData);
  98. WriteOneBit(pBuffer, bitData, nStart, nStart);
  99. }
  100. }
  101. nEnd = nStart;
  102. }
  103. void WtriteStringToBuffer( byte* pBuffer, char* pchar, int nStart, int nCount, /* out */int& nEnd )
  104. {
  105. for ( int nIndex=0; nIndex<nCount; nIndex++ )
  106. {
  107. WriteDataToBuffer(pBuffer, pchar[nIndex], nStart, 8, nStart);
  108. }
  109. nEnd = nStart;
  110. }
Copyright © Linux教程網 All Rights Reserved