# Byte buffer writer

Posted on

Problem

This is a fraction of the binary writer I’m writing, and I’m trying find some way to improve it.

``````using System;
using System.Collections.Generic;

public class ByteBuffer
{
// List used to hold all bytes that will be read
private List<byte> buffer = new List<byte>(32);

private int bitIndex = 0;

/// <summary>
/// Writes an n bits byte onto the buffer.
/// </summary>
public void Write(byte source, int n)
{
if ((n + bitIndex) / 8 > buffer.Count)
{
buffer.AddRange(new byte[(n + bitIndex) / 8 - buffer.Count]);
}

for (int i = 0; i < n; i++)
{
buffer[(bitIndex + i) / 8] |= (byte)(((source >> (n - 1 - i)) & 1) << (int)(7 - (bitIndex + i) % 8));
}

bitIndex += n;
}
}
``````

Solution

I’m going to go out on a limb, not knowing the full extent of the use cases of the class, but there’s a pretty decent class, `BitArray` that might handle your needs as such:

``````using System;
using System.Collections;

public class ByteBuffer
{
// List used to hold all bytes that will be read
private BitArray buffer;

/// <summary>
/// Writes an n bits byte onto the buffer.
/// </summary>
public void Write(byte source, int n)
{
buffer = Append(buffer, source, n);
}

private static BitArray Append(BitArray current, byte source, int n)
{
var count = current == null ? 0 : current.Count;
var bools = new bool[count + n];

if (count > 0)
{
current.CopyTo(bools, 0);
}

if (n > 0)
{
var after = new BitArray(new[] { source });

for (int i = 0; i < n; i++)
{
bools[count + i] = after[i];
}
}

return new BitArray(bools);
}
}
``````

If you’re after efficiency, you shouldn’t write bit by bit. For example, if `bitIndex` is currently 3 and you’re writing the full 8 bits, just two steps are necessary: writing 5 bits to one byte and then the remaining 3 bits to another byte.

And depending on what you do, writing directly to some `Stream` might make more sense than using a `List<byte>`.

Also, you should probably check the input and throw and exception if `n` is not between 1 and 8.

I ended up with an implementation that looks like this:

``````using System.Diagnostics;

public class ByteBuffer
{
public byte[] tempBuffer = new byte;

public int tempIndex = 0;

/// <summary>
/// Writes the given number of bits.
/// </summary>
public void Write(byte value, int bits)
{
Debug.Assert(bits > 0 && bits < 9, "Number of bits must be between 1 and 8.");

int localBitLen = (tempIndex % 8);
if (localBitLen == 0)
{
tempBuffer[tempIndex >> 3] = value;
tempIndex += bits;
return;
}

tempBuffer[tempIndex >> 3] &= (byte)(255 >> (8 - localBitLen)); // clear before writing
tempBuffer[tempIndex >> 3] |= (byte)(value << localBitLen); // write first half

// need write into next byte?
if (localBitLen + bits > 8)
{
tempBuffer[(tempIndex >> 3) + 1] &= (byte)(255 << localBitLen); // clear before writing
tempBuffer[(tempIndex >> 3) + 1] |= (byte)(value >> (8 - localBitLen)); // write second half
}

tempIndex += bits;
}
}
``````

I was able to do it with the help of some calculators (I just hate being bad with bitwise operations).

I had to use a `byte[]` rather than a stream since I can’t write directly on the stream back-buffer. I might implement the Read, and exponential expansion for the buffer tomorrow.

Posted in C#Tagged