107 lines
3.2 KiB
C#
107 lines
3.2 KiB
C#
namespace ClHcaSharp
|
|
{
|
|
internal class BitReader
|
|
{
|
|
private static readonly uint[] mask32 = new uint[]
|
|
{
|
|
0xFFFFFFFF, 0x7FFFFFFF, 0x3FFFFFFF, 0x1FFFFFFF,
|
|
0x0FFFFFFF, 0x07FFFFFF, 0x03FFFFFF, 0x01FFFFFF
|
|
};
|
|
|
|
private static readonly uint[] mask24 = new uint[]
|
|
{
|
|
0xFFFFFF, 0x7FFFFF, 0x3FFFFF, 0x1FFFFF,
|
|
0x0FFFFF, 0x07FFFF, 0x03FFFF, 0x01FFFF
|
|
};
|
|
|
|
private static readonly uint[] mask16 = new uint[]
|
|
{
|
|
0xFFFF, 0x7FFF, 0x3FFF, 0x1FFF,
|
|
0x0FFF, 0x07FF, 0x03FF, 0x01FF
|
|
};
|
|
|
|
private static readonly uint[] mask8 = new uint[]
|
|
{
|
|
0xFF, 0x7F, 0x3F, 0x1F,
|
|
0x0F, 0x07, 0x03, 0x01
|
|
};
|
|
|
|
private readonly byte[] data;
|
|
private readonly int dataSize;
|
|
private int currentBit;
|
|
|
|
public BitReader(byte[] data)
|
|
{
|
|
this.data = data;
|
|
dataSize = data.Length * 8;
|
|
}
|
|
|
|
public int Bit => currentBit;
|
|
|
|
public int Peek(int bits)
|
|
{
|
|
int bit = currentBit;
|
|
int bitsRemaining = bit & 7;
|
|
int size = dataSize;
|
|
|
|
uint value = 0;
|
|
|
|
if (bit + bits <= size)
|
|
{
|
|
int bitOffset = bits + bitsRemaining;
|
|
int bitLeft = size - bit;
|
|
|
|
if (bitLeft >= 32 && bitOffset >= 25)
|
|
{
|
|
int dataOffset = bit >> 3;
|
|
value = data[dataOffset];
|
|
value = (value << 8) | data[dataOffset + 1];
|
|
value = (value << 8) | data[dataOffset + 2];
|
|
value = (value << 8) | data[dataOffset + 3];
|
|
value &= mask32[bitsRemaining];
|
|
value >>= 32 - bitsRemaining - bits;
|
|
}
|
|
else if (bitLeft >= 24 && bitOffset >= 17)
|
|
{
|
|
int dataOffset = bit >> 3;
|
|
value = data[dataOffset];
|
|
value = (value << 8) | data[dataOffset + 1];
|
|
value = (value << 8) | data[dataOffset + 2];
|
|
value &= mask24[bitsRemaining];
|
|
value >>= 24 - bitsRemaining - bits;
|
|
}
|
|
else if (bitLeft >= 16 && bitOffset >= 9)
|
|
{
|
|
int dataOffset = bit >> 3;
|
|
value = data[dataOffset];
|
|
value = (value << 8) | data[dataOffset + 1];
|
|
value &= mask16[bitsRemaining];
|
|
value >>= 16 - bitsRemaining - bits;
|
|
}
|
|
else
|
|
{
|
|
int dataOffset = bit >> 3;
|
|
value = data[dataOffset];
|
|
value &= mask8[bitsRemaining];
|
|
value >>= 8 - bitsRemaining - bits;
|
|
}
|
|
|
|
return (int)value;
|
|
}
|
|
|
|
return (int)value;
|
|
}
|
|
|
|
public int Read(int bits)
|
|
{
|
|
int value = Peek(bits);
|
|
currentBit += bits;
|
|
return value;
|
|
}
|
|
|
|
public void Skip(int bits)
|
|
{
|
|
currentBit += bits;
|
|
}
|
|
}
|
|
} |