2009-09-08 11 views
5

Zajmuję się biblioteką C# o nazwie BitStream, która umożliwia pisanie i odczytywanie dowolnej liczby bitów do standardowego obiektu C# Stream. Zauważyłem, co wydawało mi się dziwną decyzją projektową:Projektowanie strumienia bitów w C#

Podczas dodawania bitów do pustego bajtu, bity są dodawane do MSB bajtu. Np

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 

Jednak przy przedstawieniu bity w wielu jako wejście, pierwszy bit liczby wejściowego LSB. Na przykład:

//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) 

Wydaje mi się niespójny. Ponieważ w tym przypadku, "stopniowo" kopiując bajt jak w poprzednim przykładzie (pierwsze cztery bity, a następnie cztery ostatnie bity), nie otrzymamy oryginalnego bajtu. Musimy skopiować go "wstecz" (najpierw cztery ostatnie bity, potem pierwsze cztery bity).

Czy jest jakiś powód takiego projektu, którego mi brakuje? Jakakolwiek inna implementacja strumienia bitów z tym zachowaniem? Jakie są względy związane z projektem?

Wygląda na to, że strumień bitowy zachowuje się w sposób, który uważam za spójny. Sprawdź, ile przesuwa bajt przed wskaźnikiem src w .

marginesie:

Pierwszy bajtdodanej, pierwszy bajt w tablicy bajtów. Na przykład

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 

Odpowiedz

3

Oto kilka dodatkowych rozważań:

W przypadku Boolean - tylko jeden bit jest wymagane do reprezentowania prawdziwe lub fałszywe. Kiedy ten bit zostanie dodany na początku strumienia, strumień bitów wynosi "1." Po rozszerzeniu tego strumienia do długości bajtów wymusza dopełnienie zer bitów do końca strumienia, nawet jeśli te bity nie istniały w strumieniu. Pozycja w strumieniu jest ważną informacją, podobnie jak wartości bitów, a strumień bitów "1000000" lub 0x80 zabezpiecza oczekiwanie, że kolejne czytniki strumienia mogą mieć to, że pierwszy odczytany bit jest pierwszym bitem, który został dodany.

Po drugie, inne typy danych, takie jak liczby całkowite, wymagają większej liczby bitów do reprezentacji, więc zajmą więcej miejsca w strumieniu niż bajty. Mieszanie różnych typów danych w tym samym strumieniu może być bardzo trudne, gdy nie są wyrównane na granicach bajtów.

Wreszcie, jeśli korzystasz z procesora Intel x86, twoja architektura procesora to "little-endian", co oznacza LSB, tak jak opisujesz. Jeśli chcesz przechowywać wartości w strumieniu jako big-endian, musisz dodać w swoim kodzie warstwę konwersji - podobnie do tego, co pokazałeś powyżej, gdzie przesyłasz po jednym bajcie do strumienia w żądanej kolejności .Jest to denerwujące, ale często wymagane, jeśli musisz współdziałać z dużymi endianowymi skrzynkami uniksowymi lub wymaganymi przez specyfikację protokołu.

Nadzieję, że pomaga!

1

Czy istnieje powód do tego projektu, że jestem brakujące? Jakakolwiek inna implementacja strumienia bitów z tym zachowaniem? Jakie są względy związane z projektem?

Wątpię, czy za znaczeniem było jakieś znaczące znaczenie. Technicznie nie ma to znaczenia, o ile pisarz i czytelnik zgadzają się na zamówienie.

+0

Wydaje mi się niespójne. Ponieważ w tym przypadku, gdy "stopniowo" Ale pokazałem to ma znaczenie. Cytat: "kopiowanie bajtów, jak w poprzednim przykładzie (pierwsze cztery bity, a następnie cztery ostatnie bity), nie otrzymamy oryginalnego bajtu. Musimy skopiować go" wstecz "(najpierw cztery ostatnie bity, potem pierwsze cztery bity). " –

+0

Tak jak powiedziałem, kiedy zarówno czytelnik, jak i pisarz zgadzają się na zamawianie bitów, nie ma to znaczenia. IMO należy używać metody BitStream zarówno do odczytu, jak i zapisu. Jeśli masz inne intencje, takie jak czytanie wynikowych bajtów, powinieneś po prostu napisać własny strumień. –

1

Zgadzam się z Elazarem.

Jak wskazuje, jest to przypadek, w którym czytelnik i autor nie zgadzają się co do kolejności bitów. W rzeczywistości są one niezgodne.