将值作为任意数量的位写入 C++ 中的字节缓冲区中;

发布于 2024-11-07 18:30:41 字数 1487 浏览 0 评论 0原文

嘿,我需要将位值打包到 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浪菊怪哟 2024-11-14 18:30:41

只需删除所有 public 关键字,我想说您的 C++ 实现就在那里。

Just remove all the public keywords, and I would say that you have your C++ implementation right there.

昔梦 2024-11-14 18:30:41

只要您仅使用字节缓冲区,就可以一对一地翻译 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文