将值作为任意数量的位写入 C++ 中的字节缓冲区中;
嘿,我需要将位值打包到 C++ 中的字节缓冲区中。我的 Buffer 类有一个 char 数组和一个位置,类似于 Java 的 ByteBuffer。我需要一种好方法将位打包到此缓冲区中,如下所示:
void put_bits(int amount, uint32_t value);
它需要支持最多 32 位。我见过一个用 Java 实现的解决方案(在打包位之前需要开始/结束访问方法),但我不确定如何在 C++ 中执行此操作,因为字节序和其他低级因素并没有像它们那样隐藏在爪哇。
我有一个声明为 endianness()
的内联函数,它返回 0(定义为 BIG_ENDIAN
)或 1(定义为 LITTLE_ENDIAN
),可以使用,但我只是不确定如何正确地将位打包到字节缓冲区中。
这是我需要实现的 Java 版本:
public void writeBits(int numBits, int value) {
int bytePos = bitPosition >> 3;
int bitOffset = 8 - (bitPosition & 7);
bitPosition += numBits;
for(; numBits > bitOffset; bitOffset = 8) {
buffer[bytePos] &= ~ bitMaskOut[bitOffset];
buffer[bytePos++] |= (value >> (numBits-bitOffset)) & bitMaskOut[bitOffset];
numBits -= bitOffset;
}
if(numBits == bitOffset) {
buffer[bytePos] &= ~ bitMaskOut[bitOffset];
buffer[bytePos] |= value & bitMaskOut[bitOffset];
}
else {
buffer[bytePos] &= ~ (bitMaskOut[numBits]<<(bitOffset - numBits));
buffer[bytePos] |= (value&bitMaskOut[numBits]) << (bitOffset - numBits);
}
}
这也需要这两种方法:
public void initBitAccess() {
bitPosition = currentOffset * 8;
}
public void finishBitAccess() {
currentOffset = (bitPosition + 7) / 8;
}
我应该如何解决这个问题?谢谢。
编辑:我还需要能够在写入位之前和之后写入正常字节。
Hey, I need to pack bit values into a byte buffer in C++. My Buffer class has a char array and a position, similar to Java's ByteBuffer. I need a good way to pack bits into this buffer, like so:
void put_bits(int amount, uint32_t value);
It needs to support up to 32 bits. I've seen a solution implemented in Java (that requires start/end access methods before bits can be packed) but I'm not sure how to do this in C++ because the endianness and other low level factors aren't hidden like they are in Java.
I have an inline function declared as endianness()
which returns 0 (defined as BIG_ENDIAN
) or 1 (defined as LITTLE_ENDIAN
) that can be used, but I'm just not sure how to properly pack bits into a byte buffer.
This is the Java version of what I need to implement:
public void writeBits(int numBits, int value) {
int bytePos = bitPosition >> 3;
int bitOffset = 8 - (bitPosition & 7);
bitPosition += numBits;
for(; numBits > bitOffset; bitOffset = 8) {
buffer[bytePos] &= ~ bitMaskOut[bitOffset];
buffer[bytePos++] |= (value >> (numBits-bitOffset)) & bitMaskOut[bitOffset];
numBits -= bitOffset;
}
if(numBits == bitOffset) {
buffer[bytePos] &= ~ bitMaskOut[bitOffset];
buffer[bytePos] |= value & bitMaskOut[bitOffset];
}
else {
buffer[bytePos] &= ~ (bitMaskOut[numBits]<<(bitOffset - numBits));
buffer[bytePos] |= (value&bitMaskOut[numBits]) << (bitOffset - numBits);
}
}
Which requires these two methods as well:
public void initBitAccess() {
bitPosition = currentOffset * 8;
}
public void finishBitAccess() {
currentOffset = (bitPosition + 7) / 8;
}
How should I go about solving this? Thanks.
EDIT: I also still need to be able to write normal bytes before and after writing bits.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只需删除所有
public
关键字,我想说您的C++
实现就在那里。Just remove all the
public
keywords, and I would say that you have yourC++
implementation right there.只要您仅使用字节缓冲区,就可以一对一地翻译 Java 代码。只有当您将字节指针解释为另一种类型并尝试在字节缓冲区中存储完整的 int 时,才会变得危险。
在这种情况下,您甚至不需要 endianness 函数,因为您将字节存储在字节缓冲区中,并且不需要转换或调整大小或其他任何内容。
As long as you use the byte buffer only as such, you can translate the Java code one-to-one. It only gets dangerous if you interpret a byte pointer as another type and try to store a complete int in the byte buffer.
You don't even need the
endianness
function in this case, since you store a byte in a byte buffer, and there is nothing to convert or adjust size or whatever.