title: Designing a BitStream in C#
body: <p>I'm looking at the C# library called <a href="http://www.codeproject.com/KB/cs/bitstream.aspx" rel="noreferrer">BitStream</a>, which allows you to write and read any number of bits to a standard C# <code>Stream</code> object. I noticed what seemed to me a strange design decision:</p>
  
  <p>When adding bits to an empty byte, the bits are added to the MSB of the byte. For example:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>However, when referencing bits in a number as the <em>input</em>, the first bit of the input number is the LSB. For example</p>
  
  <pre><code>//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)
  </code></pre>
  
  <p>It seems inconsistent to me. Since in this case, when "gradually" copying a byte like in the previous example (the first four bits, and then the last four bits), we will not get the original byte. We need to copy it "backwards" (first the last four bits, then the first four bits).</p>
  
  <p>Is there a reason for that design that I'm missing? Any other implementation of bits stream with this behaviour? What are the design considerations for that?</p>
  
  <p>It seems that <code>ffmpeg</code> bitstream behaves in a way I consider consistent. Look at the amount it shifts the byte before <code>OR</code>ing it with the <code>src</code> pointer in <a href="http://cekirdek.pardus.org.tr/~ismail/ffmpeg-docs/put__bits_8h-source.html#l00148" rel="noreferrer">the <code>put_bits</code> function</a>.</p>
  
  <p>As a side note:</p>
  
  <p>The first <em>byte</em> added, is the first byte in the byte array. For example</p>
  
  <pre><code>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
  </code></pre>