我正在尝试编写c函数ReadInt32,WriteInt32,用于在流缓冲区中按顺序打包位,并考虑到大小优化。 但是我的函数没有按预期工作,我在缓冲区中写入后找不到相同的值。我需要一些帮助来指出我误解的地方和地点。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BITSET(x,n) (x | ( 1 << n))
#define BITCLEAR(x,n) (x & ~(1 << n))
#define ISBITSET(x,n) ((x & (1 << n)) != 0)
/**
@param nbits The number of bits to write
@param val the integer value to write
@param bufptr a pointer on the buffer to write in
@param nbitswritten the number of bits already written in the previous write.
@return the number of bits actually written.
*/
int WriteInt32(int nbits, int val, uint8_t* bufptr, int nbitswritten)
{
uint8_t* p=(uint8_t*)&val;
uint8_t* ptr = &(*(bufptr+nbitswritten));
for (int i=0; i<nbits; i++)
{
int bpos = (i&0x7);
*(ptr+(i>>3)) = ISBITSET(*(p+(i>>3)), bpos) ? (BITSET(*(ptr+(i>>3)), bpos)) : (BITCLEAR(*(ptr+(i>>3)), bpos));
}
return (nbitswritten + nbits);
}
int ReadInt32(int nbits, int& val, uint8_t* ptr, int nbitsread)
{
val = 0;
uint8_t* p = &(*(ptr+nbitsread));
for (int i=0; i<nbits; i++)
{
uint8_t ch = *(p+(i>>3));
int bpos = (i&0x7);
val = (ISBITSET(ch, bpos) ? BITSET(val, bpos) : BITCLEAR(val, bpos));
}
return (nbitsread+nbits);
}
int main (int argc, const char * argv[])
{
int value = 289; // for example I want to encode this value on 10 bits
unsigned char buf[50];
// packing
int nbitswritten = 0;
nbitswritten = WriteInt32 (10, value, buf, 50, nbitswritten);
// unpacking - read from buffer
int nbitsread = 0;
int rvalue;
nbitsread = ReadInt32(10, rvalue, buf, nbitsread);
if ( value == rvalue)
printf("encoding & decoding ok\n");
else
printf("encoding or decoding failed\n");
return 0;
};
谢谢 奥利弗
答案 0 :(得分:0)
这是我自己的问题的答案。如何写/读一个编码小于其自然大小的整数。 如果它可以帮助某人。非常好。 ;)
为例:
struct dd
{
short var1:5; // This variable is encoded on 5 bits
int var2:11; // This variable is encoded on 11 bits
uint8_t var3:3; // This variable is encoded on 3 bits
};
uint8_t buffer[100];
bzero(buffer, 100);
int nbitswritten = 0;
struct dd vardd = { 16, 452, 3 };
// write stuff
nbitswritten = WriteBits(5, vardd.var1, buffer, 100, nbitswritten);
nbitswritten = WriteBits(11, vardd.var2, buffer, 100, nbitswritten);
nbitswritten = WriteBits(3, vardd.var3, buffer, 100, nbitswritten);
// read back
int v1, v2, v3;
int nbitsread = 0;
struct dd result;
nbitsread = ReadInt(5, v1, buffer, 100, nbitsread);
nbitsread = ReadInt(11, v2, buffer, 100, nbitsread);
nbitsread = ReadInt(3, v3, buffer, 100, nbitsread);
result.var1 = (short)v1;
result.var2 = v2;
result.var3 = (uint8_t)v3;
实际上,Read功能来自Torque Engine库! 这是我稍加修改的版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BITSET(x,n) (x | ( 1 << n))
#define BITCLEAR(x,n) (x & ~(1 << n))
#define ISBITSET(x,n) ((x & (1 << n)) != 0)
/**
@param nbits The number of bits to write
@param val the value to write
@param bufptr the buffer to write to/in
@param buflen the maximum buffer length in byte/octet
@param nbitswritten the number of bits in bufptr already written.
@return the number of bits written;
*/
int WriteBits(int nbits, const void * val, uint8_t * bufptr, int buflen, int nbitswritten)
{
if (!bufptr || !val || !nbits || !buflen)
return 0;
if ( nbitswritten >= buflen<<8L )
return 0;
if ( nbits+nbitswritten>buflen<<8L )
return 0;
uint8_t* p=(uint8_t*)val;
int n = nbitswritten;
for (int i=0; i<nbits; i++)
{
int sbpos = (i&0x7);
int dbpos = (n&0x7);
*(bufptr+(n>>3)) = ISBITSET(*(p+(i>>3)), sbpos) ? (BITSET(*(bufptr+(n>>3)), dbpos)) : (BITCLEAR(*(bufptr+(n>>3)), dbpos));
n++;
}
nbitswritten = n;
return (n);
}
int ReadBits(int nbits, void * val, uint8_t * bufptr, int buflen, int nbitsread)
{
if (!nbits)
return 0;
uint8_t * stPtr = (bufptr + (nbitsread >> 3));
int byteCount = (nbits + 7) >> 3;
uint8_t * ptr = (TUint8*)val;
int downShift = nbitsread & 0x7;
int upShift = 8 - downShift;
uint8_t curB = *stPtr;
const uint8_t *stEnd = bufptr + buflen;
while(byteCount--)
{
stPtr++;
uint8_t nextB = stPtr < stEnd ? *stPtr : 0;
*ptr++ = (curB >> downShift) | (nextB << upShift);
curB = nextB;
}
nbitsread += nbits;
return nbitsread;
}
int ReadInt(int nbits, int &val, uint8_t * bufptr, int buflen, int nbitsread)
{
int ret = ReadBits(nbits, &val, bufptr, buflen, nbitsread);
if (nbits != 32) {
val &= (1<<nbits)-1;
}
return ret;
}
橄榄