Есть ли стандартный способ, шаблон или идиома для работы с битами (для потоков, кодирования, ...)? - PullRequest
1 голос
/ 21 марта 2020

Недавно я увидел, как пишу метод, который кодирует символы в биты (делает Хаффман, но это не имеет значения). Не байты, а биты; группы менее 8 бит.

Я написал что-то вроде следующего, так как я не думаю, что есть единица меньшего размера, чем байт. Я использую массив байтов, и когда я помещаю биты в байты, иногда одна и та же группа битов будет находиться в одном и том же байте, иногда она будет разбита на соседние байты, ...

byte[] encoded = new byte[(this.encodedSize/8)+1];
int free = 8;//bits left in the current byte
int byteCounter = 0;
for (int i=0; i < input.length(); i++) {
    char c = input.charAt(i);
    Node n = this.frequencyTable.get(c);
    int v = n.bits;
    if (free >= n.depth) {
        free -= n.depth;
        encoded[byteCounter] = (byte)(encoded[byteCounter] | (v << free));
    } else {
        int overflow = n.depth-free;
        encoded[byteCounter] = (byte)(encoded[byteCounter] | (v >> overflow));
        byteCounter++;
        free = 8 - overflow;
        encoded[byteCounter] = (byte)(encoded[byteCounter] | ((((0x01 << overflow)-1) & v) << free));
    }
}

Это работает, но я обнаружил удивление, что мне пришлось самому писать этот код вместо того, чтобы использовать что-то нативное или предоставленное какой-то довольно базовой библиотекой. Как видите, мне нужно выполнить итерацию, сохранив счетчики того, сколько битов осталось в текущем байте или сколько битов в текущей группировке мне нужно добавить к следующему байту. Совершенно запутанный, я бы сказал.

Здесь я использовал java, но я думаю, что мой вопрос более обобщенный c. Это код, который вам нужно было бы написать для всего, что кодирует двоичный файл в файл, сетевой поток ... где то, что ваша кодировка представлена ​​битовыми группами, которые не кратны байту. Насколько я знаю, большинство, если не все методы, которые записывают двоичный файл в файл или сокет, будут делать не меньше, чем байтовые единицы.

Мой вопрос заключается в том, существует ли более традиционный, возможно, встроенный способ, в java или на любом другом языке, чтобы сделать это?

Я знаю, что java имеет BitSet для работы с отдельными битами, но это не поможет.

...