如何在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;
}
以上就是本文的全部内容,希望对大家的学习有所帮助。