Проектирование BitStream на C#

Я рассматриваю библиотеку C# под названием BitStream, которая позволяет вам писать и читать любое количество битов в стандартный объект C# Stream. Я заметил, как мне показалось, странное дизайнерское решение:

При добавлении битов к пустому байту биты добавляются к старшему биту байта. Например:

var s = new BitStream();
s.Write(true);
Debug.Assert(s.ToByteArray()[0] == 0x80);  // and not 0x01

var s = new BitStream();
s.Write(0x7,0,4);
s.Write(0x3,0,4);
Debug.Assert(s.ToByteArray()[0] == 0x73); // and not 0x37

Однако при указании битов числа как входных первым битом входного числа является младший бит. Например

//s.Write(int input,int bit_offset, int count_bits)
//when referencing the LSB and the next bit we'll write
s.Write(data,0,2); //and not s.Write(data,data_bits_number,data_bits_number-2)

Мне это кажется непоследовательным. Так как в этом случае при "постепенном" копировании байта как в предыдущем примере (первые четыре бита, а потом последние четыре бита) мы не получим исходный байт. Нам нужно скопировать его «назад» (сначала последние четыре бита, потом первые четыре бита).

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

Кажется, что битовый поток ffmpeg ведет себя так, как я считаю последовательным. Посмотрите на величину сдвига байта, прежде чем ORобозначить его указателем src в функция put_bits.

В качестве примечания:

Первый добавленный байт является первым байтом в массиве байтов. Например

var s = new BitStream();
s.Write(0x1,0,4);
s.Write(0x2,0,4);
s.Write(0x3,0,4);
Debug.Assert(s.ToByteArray()[0] == 0x12); // and not s.ToByteArray()[1] == 0x12

person Elazar Leibovich    schedule 08.09.2009    source источник


Ответы (3)


Вот некоторые дополнительные соображения:

В случае логического значения требуется только один бит для представления истинного или ложного значения. Когда этот бит добавляется к началу потока, битовый поток равен «1». Когда вы расширяете этот поток до длины в байтах, он принудительно добавляет нулевые биты в конец потока, даже если эти биты не существовали в потоке с самого начала. Позиция в потоке является важной информацией, как и значения битов, и битовый поток "1000000" или 0x80 гарантирует, что последующие читатели потока могут иметь ожидание того, что первый бит, который они прочитают, будет первым добавленным битом.

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

Наконец, если вы работаете на Intel x86, архитектура вашего процессора является «прямой», что означает, что сначала LSB, как вы описываете. Если вам нужно хранить значения в потоке с обратным порядком байтов, вам нужно будет добавить в свой код слой преобразования — аналогично тому, что вы показали выше, где вы вставляете по одному байту за раз в поток в том порядке, в котором хотите. . Это раздражает, но обычно требуется, если вам нужно взаимодействовать с блоками Unix с обратным порядком байтов или когда это может потребоваться в спецификации протокола.

Надеюсь, это поможет!

person csharpguy    schedule 22.02.2010

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

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

person csharptest.net    schedule 10.09.2009
comment
Мне это кажется непоследовательным. Так как в этом случае, когда постепенно Но я просто показал, что это имеет значение. Цитата: скопировав байт как в предыдущем примере (первые четыре бита, а потом последние четыре бита), мы не получим исходный байт. Нам нужно скопировать его в обратном порядке (сначала последние четыре бита, затем первые четыре бита). - person Elazar Leibovich; 13.09.2009
comment
Как я уже сказал, когда и читатель, и писатель согласны с порядком битов, это не имеет значения. IMO, вы должны использовать BitStream как для чтения, так и для записи. Если у вас есть другие намерения, такие как чтение результирующих байтов, вам, вероятно, следует просто написать свой собственный поток. - person csharptest.net; 13.09.2009

Я согласен с Элазаром.

Как он/она указывает, это тот случай, когда читатель и писатель НЕ согласны с порядком битов. На самом деле они несовместимы.

person chennai    schedule 25.03.2010