I have a binary file that I want to read. Let's say its "foo.bin".
I want to read all the bytes into an byte array.
byte[] data = File.ReadAllBytes("foo.bin")
I want to split these bytes into binary numbers of length x.
(Using a custom class BinaryChunk, but any type of binary / bool[] / byte[] will work fine.)
struct BinaryChunk {
bool[] data,
int size
}
BinaryChunk[] binaryChunks = SplitDataIntoBinaryChunksOfSize(data, x)
*Note that "x" is in bits, not bytes.
Examples in case you still have no idea what I'm talking about:
(Shortened "SplitDataIntoBinaryChunksOfSize" into "SplitData" for obvious reasons)
bool[] foo = new bool[]{0b11100110, 0b00010110};
SplitData(foo, 3) //-> 111, 001, 100, 001, 011, 000
// 1 1 1 0 0 1 1 0;0 0 0 1 0 1 1 0XXXXXXXXXXXXXXXX
//-> 1 1 1;0 0 1;1 0 0;0 0 1;0 1 1;0 0 0
SplitData(foo, 12) //-> 111001100001, 011000000000
// 1 1 1 0 0 1 1 0;0 0 0 1 0 1 1 0XXXXXXXXXXXXXXXX
//-> 1 1 1 0 0 1 1 0 0 0 0 1;0 1 1 0 0 0 0 0 0 0 0 0
Thinking about using BitArray, but I haven't used it enough to know how to use it.
Anyone got any ideas?
EDIT: heres a quick solution if anyone needs one i guess
class BinaryStream {
//binary data in bytes
byte[] data;
//length of data
int size;
public BinaryStream(byte[] data) {
this.data = data;
this.size = data.Length;
}
public void MoveBytes(int splicesize) {
//moves the binarystream to the left (<<) in bytes
size -= splicesize;
byte[] cutdata = new byte[size];
for (int i = 0; i < size; i++) { cutdata[i] = data[i + splicesize]; }
data = cutdata;
}
public byte this[int membytes] {
//gets the byte at index unless its not in the array then its 0
get { return membytes < size ? data[membytes] : byte.MinValue; }
set { if (membytes < size) data[membytes] = value; }
}
public static BinaryStream operator <<(BinaryStream binstream, int membits) {
//a left shift operator (in bits)
binstream.MoveBytes(membits / 8);
membits %= 8;
if (membits == 0) return binstream;
for (int i = 0; i < binstream.size; i++) {
//moves the byte at index i, then grabs the next item and appends it
binstream[i] <<= membits;
binstream[i] |= (byte) (binstream[i + 1] >> (8 - membits));
}
return binstream;
}
}
Above is a simple BinaryStream class (a bit similar to a Queue<bool>), doesn't have much functionality yet since its just for helping to solve the problem.
Temporary Solution:
byte[][] SplitData(byte[] data, int bits) {
//setup
byte[][] split = new byte[data.Length * 8 / bits][];
int chunkSize = bits / 8 + 1; //chunksize in bytes
BinaryStream bstream = new BinaryStream(data);
for (int i = 0; i < split.Length; i++) {
split[i] = new byte[chunkSize];
int copy = bits; //number of bits to copy
int j = 0; //index at split[] to copy to
while (copy > 0) {
if (copy < 8) {
//copy less than a byte
split[i][j] = (byte) ((bstream[0] & (255 << (8 - copy))) >> (8 - copy));
bstream <<= copy;
} else {
//copy a full byte
split[i][j] = bstream[0];
bstream.MoveBytes(1);
}
copy -= 8;
j++;
}
}
return split;
}
Time Complexity: O(n^2) where n is the data length. Space Complexity: O(n) where n is the data length.
Not the best solution nor elegant, but it works for now.