How to implement bitwise access in C++

  • 2020-04-02 03:13:17
  • OfStack

In a project I started, in order to save network bandwidth, data transmission in the network needs to achieve compact access. In fact, there are similar requirements in many fields such as national defense, scientific research, aerospace and military industry.
Achieve compact access, not byte by byte access, but access by bit. For example, with one byte, we can store 8 bool information and share the code (note: the algorithm in the code is worth optimizing) without further ado.

// the following is the function definition  


 
 
 
 
 
 
 
 
void ReadOneBit( byte* pBuffer, int nStart, int& nEnd,  byte& retByte ); 
 
 
 
 
 
 
 
 
 
 
template<typename T> 
void ReadDataFromBuffer( byte* pBuffer, int nStart, byte btLength, int& nEnd,  T& retData ); 
 
 
 
 
 
 
 
 
 
 
void ReadStringFromBuffer( byte* pBuffer, int nStart, int nCount, int& nEnd, char* pRetData ); 
 
 
 
 
 
 
 
 
 
 
 
void WriteOneBit( byte* pBuffer, byte btData, int nStart, int& nEnd ); 
 
 
 
 
 
 
 
 
 
 
template<typename T> 
void WriteDataToBuffer( byte* pBuffer, T tData, int nStart, byte btLength, int& nEnd ); 
 
 
 
 
 
 
 
 
 
 
void WtriteStringToBuffer( byte* pBuffer, char* pchar, int nStart, int nCount, int& nEnd ); 


// the following is the function implementation


void ReadOneBit( byte* pBuffer, int nStart, int& nEnd,  byte& retByte ) 
{ 
  byte btData = pBuffer[nStart/8]; 
  btData = btData << nStart%8; 
  retByte = btData >> 7; 
  nEnd = nStart+1; 
} 
 
template<typename T> 
void ReadDataFromBuffer( byte* pBuffer, int nStart, byte btLength, int& nEnd,  T& retData ) 
{ 
  //In order to read a
  retData = 0; 
  if ( btLength > sizeof(T)*8 ) 
    return ; 
   
  byte btData; 
  T tData; 
  while ( btLength-- ) 
  { 
    ReadOneBit(pBuffer, nStart, nStart, btData); 
    tData = btData << btLength; 
    retData |= tData; 
  } 
   
  nEnd = nStart; 
} 
 
void ReadStringFromBuffer( byte* pBuffer, int nStart, int nCount, int& nEnd, char* pRetData ) 
{ 
  for ( int nIndex=0; nIndex<nCount; nIndex++ ) 
  { 
    ReadDataFromBuffer(pBuffer, nStart, 8, nStart, pRetData[nIndex]); 
  } 
  nEnd = nStart; 
} 
 
 
void WriteOneBit( byte* pBuffer, byte btData, int nStart, int& nEnd ) 
{ 
  int nSet = nStart / 8; 
  byte c = pBuffer[nSet]; 
  switch ( btData ) 
  { 
  case 1: 
    c |= ( 1 << (7- nStart % 8) ); 
    break; 
  case 0: 
    c &= ( ~(1 << (7- nStart % 8) ) ); 
    break; 
  default: 
    return; 
  } 
  pBuffer [nSet] = c; 
  nEnd = nStart +1; 
} 
 
 
 
template<typename T> 
void WriteDataToBuffer( byte* pBuffer, T tData, int nStart, byte btLength, int& nEnd ) 
{ 
/* //Big end machine mode
  byte btDataLength = sizeof(T); 
  if ( btLength > sizeof(T)*8 ) 
    return; 
   
  int nDataStart = 0; //The first position of the data is 0, written sequentially
  while ( btLength-- ) 
  { 
    byte bitData; 
    ReadOneBit((byte*)&tData, nDataStart, nDataStart, bitData); 
    WriteOneBit(pBuffer, bitData, nStart, nStart); 
  } 
   
  nEnd = nStart; 
*/ 
 
  //Small endian mode: when writing to buffer, do not write bits sequentially
 
  //Gets the template footprint size
  byte btDataLength = sizeof(T); 
 
  //Verify that the length is out of bounds
  if ( btLength > sizeof(T)*8 ) 
    return; 
 
  //Converts the pending data to byte*
  byte* ptData = (byte*)&tData;  
 
  //Modulus and more
  int nSet = btLength / 8; 
  int nRin = btLength % 8; 
   
  //Defines byte data and bit data
  byte bitData; 
  byte byteData; 
  int nTempEnd; 
 
  //Write the rin data first
  byteData = ptData[nSet]; 
  while ( nRin-- ) 
  { 
    ReadOneBit(&byteData, 7-nRin, nTempEnd, bitData); 
    WriteOneBit(pBuffer, bitData, nStart, nStart); 
  } 
 
  //Set data
  while ( nSet ) 
  { 
    byteData = ptData[--nSet]; 
    //Write a byte
    int i=0; 
    while ( i!=8 ) 
    { 
      ReadOneBit(&byteData, i++, nTempEnd, bitData); 
      WriteOneBit(pBuffer, bitData, nStart, nStart); 
    } 
  } 
  nEnd = nStart; 
 
} 
 
 
void WtriteStringToBuffer( byte* pBuffer, char* pchar, int nStart, int nCount, int& nEnd ) 
{ 
  for ( int nIndex=0; nIndex<nCount; nIndex++ ) 
  { 
    WriteDataToBuffer(pBuffer, pchar[nIndex], nStart, 8, nStart); 
  } 
  nEnd = nStart; 
} 

The above is the entire content of this article, I hope to help you with your study.


Related articles: