Запись значений в виде произвольного количества битов в байтовый буфер в C++

Эй, мне нужно упаковать битовые значения в байтовый буфер в C++. Мой класс Buffer имеет массив символов и позицию, аналогичную ByteBuffer в Java. Мне нужен хороший способ упаковать биты в этот буфер, например:

void put_bits(int amount, uint32_t value);

Он должен поддерживать до 32 бит. Я видел решение, реализованное на Java (которое требует методов начала/окончания доступа, прежде чем биты могут быть упакованы), но я не уверен, как это сделать на С++, потому что порядок следования байтов и другие низкоуровневые факторы не скрыты, как они в Яве.

У меня есть встроенная функция, объявленная как 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;
}

Как мне решить эту проблему? Спасибо.

РЕДАКТИРОВАТЬ: мне также нужно иметь возможность записывать обычные байты до и после записи битов.


person Blake    schedule 16.05.2011    source источник
comment
Что ж, версия Java в значительной степени соответствует C++, поэтому ее нетрудно перевести. Это домашнее задание?   -  person Cory Nelson    schedule 17.05.2011
comment
Обратитесь к библиотеке std::bitset: cplusplus.com/reference/stl/bitset   -  person yasouser    schedule 18.05.2011


Ответы (2)


Просто удалите все ключевые слова public, и я бы сказал, что у вас есть реализация C++.

person TonyK    schedule 16.05.2011
comment
Уверены ли вы? x86 по умолчанию работает с прямым порядком байтов, а Java по умолчанию работает с обратным порядком байтов. Не будет ли это иметь значение для чего-то подобного? - person Blake; 17.05.2011
comment
В данном случае это действительно не имеет значения, как указано в моем ответе. - person Roland Illig; 17.05.2011

Пока вы используете байтовый буфер только как таковой, вы можете транслировать код Java один к одному. Это становится опасным только в том случае, если вы интерпретируете указатель байта как другой тип и пытаетесь сохранить полное целое число в буфере байтов.

В этом случае вам даже не нужна функция endianness, так как вы сохраняете байт в буфере байтов, и нечего конвертировать или настраивать размер или что-то еще.

person Roland Illig    schedule 16.05.2011