如何在C++中实现按位存取
在我创业的一个项目中,为了节约网络带宽,因此在网络中传输数据需要实现紧凑存取,在国防,科研,航天,军工等多个领域其实也有类似的需求。
实现紧凑存取,不是按一个字节一个字节地存取,而是按位存取。比如一个字节,我们可以存储8个bool信息,废话少说,直接分享代码(备注:里面的代码算法值得优化)。
//以下为函数定义
/***********************************************************************/ /*函数作用:从buffer读一个位*/ /*参数pBuffer[in]:指定buffer*/ /*参数nStart[in]:指定位置*/ /*参数nEnd[out]:返回结束位置*/ /*参数retByte[out]:返回读取结果值*/ /*返回:void*/ /***********************************************************************/ voidReadOneBit(byte*pBuffer,intnStart,/*out*/int&nEnd,/*out*/byte&retByte); /***********************************************************************/ /*函数作用:从指定buffer里读任意一段位置数据*/ /*参数pBuffer[in]:指定buffer*/ /*参数nStart[in]:指定位置*/ /*参数btLength[in]:读取长度*/ /*参数nEnd[out]:返回结束位置*/ /*参数retData[out]:返回读取结果值,支持任意数据类型*/ /*返回:void*/ /***********************************************************************/ template<typenameT> voidReadDataFromBuffer(byte*pBuffer,intnStart,bytebtLength,/*out*/int&nEnd,/*out*/T&retData); /***********************************************************************/ /*函数作用:从指定buffer里读取一段字符串*/ /*参数pBuffer[in]:指定buffer*/ /*参数nStart[in]:指定位置*/ /*参数nCount[in]:字符串长度*/ /*参数nEnd[out]:返回结束位置*/ /*参数pRetData[out]:返回读取字符串结果*/ /*返回:void*/ /***********************************************************************/ voidReadStringFromBuffer(byte*pBuffer,intnStart,intnCount,/*out*/int&nEnd,/*out*/char*pRetData); /***********************************************************************/ /*函数作用:向buffer写一个位*/ /*参数pBuffer[in]:指定buffer*/ /*参数btData[in]:需要写入的值*/ /*参数nStart[in]:指定位置*/ /*参数nEnd[out]:返回结束位置*/ /*返回:void*/ /***********************************************************************/ voidWriteOneBit(byte*pBuffer,bytebtData,intnStart,/*out*/int&nEnd); /***********************************************************************/ /*函数作用:向指定buffer里写入任意一段数据*/ /*参数pBuffer[in]:指定buffer*/ /*参数tData[in]:需要写入的数据,支持任意数据类型*/ /*参数nStart[in]:指定位置*/ /*参数btLength[in]:读取长度*/ /*参数nEnd[out]:返回结束位置*/ /*返回:void*/ /***********************************************************************/ template<typenameT> voidWriteDataToBuffer(byte*pBuffer,TtData,intnStart,bytebtLength,/*out*/int&nEnd); /***********************************************************************/ /*函数作用:向指定buffer里写取一段字符串*/ /*参数pBuffer[in]:指定buffer*/ /*参数pchar[in]:需要写入的字符串*/ /*参数nStart[in]:指定位置*/ /*参数nCount[in]:字符串长度*/ /*参数nEnd[out]:返回结束位置*/ /*返回:void*/ /***********************************************************************/ voidWtriteStringToBuffer(byte*pBuffer,char*pchar,intnStart,intnCount,/*out*/int&nEnd);
//以下为函数实现
voidReadOneBit(byte*pBuffer,intnStart,/*out*/int&nEnd,/*out*/byte&retByte) { bytebtData=pBuffer[nStart/8]; btData=btData<<nStart%8; retByte=btData>>7; nEnd=nStart+1; } template<typenameT> voidReadDataFromBuffer(byte*pBuffer,intnStart,bytebtLength,/*out*/int&nEnd,/*out*/T&retData) { //顺序读位 retData=0; if(btLength>sizeof(T)*8) return; bytebtData; TtData; while(btLength--) { ReadOneBit(pBuffer,nStart,nStart,btData); tData=btData<<btLength; retData|=tData; } nEnd=nStart; } voidReadStringFromBuffer(byte*pBuffer,intnStart,intnCount,/*out*/int&nEnd,/*out*/char*pRetData) { for(intnIndex=0;nIndex<nCount;nIndex++) { ReadDataFromBuffer(pBuffer,nStart,8,nStart,pRetData[nIndex]); } nEnd=nStart; } voidWriteOneBit(byte*pBuffer,bytebtData,intnStart,/*out*/int&nEnd) { intnSet=nStart/8; bytec=pBuffer[nSet]; switch(btData) { case1: c|=(1<<(7-nStart%8)); break; case0: c&=(~(1<<(7-nStart%8))); break; default: return; } pBuffer[nSet]=c; nEnd=nStart+1; } template<typenameT> voidWriteDataToBuffer(byte*pBuffer,TtData,intnStart,bytebtLength,/*out*/int&nEnd) { /*//大端机模式 bytebtDataLength=sizeof(T); if(btLength>sizeof(T)*8) return; intnDataStart=0;//数据的第一位位置为0,顺序写入 while(btLength--) { bytebitData; ReadOneBit((byte*)&tData,nDataStart,nDataStart,bitData); WriteOneBit(pBuffer,bitData,nStart,nStart); } nEnd=nStart; */ //小端机模式:写buffer的时候,不能顺序写位 //获得模版占用字节大小 bytebtDataLength=sizeof(T); //校验长度是否越界 if(btLength>sizeof(T)*8) return; //将待写数据转为byte* byte*ptData=(byte*)&tData; //求模与余 intnSet=btLength/8; intnRin=btLength%8; //定义字节数据与位数据 bytebitData; bytebyteData; intnTempEnd; //先写rin数据 byteData=ptData[nSet]; while(nRin--) { ReadOneBit(&byteData,7-nRin,nTempEnd,bitData); WriteOneBit(pBuffer,bitData,nStart,nStart); } //再写Set数据 while(nSet) { byteData=ptData[--nSet]; //写一个byte inti=0; while(i!=8) { ReadOneBit(&byteData,i++,nTempEnd,bitData); WriteOneBit(pBuffer,bitData,nStart,nStart); } } nEnd=nStart; } voidWtriteStringToBuffer(byte*pBuffer,char*pchar,intnStart,intnCount,/*out*/int&nEnd) { for(intnIndex=0;nIndex<nCount;nIndex++) { WriteDataToBuffer(pBuffer,pchar[nIndex],nStart,8,nStart); } nEnd=nStart; }
以上就是本文的全部内容,希望对大家的学习有所帮助。