78 lines
1.9 KiB
C#
78 lines
1.9 KiB
C#
using System;
|
|
using System.IO;
|
|
|
|
namespace Utils
|
|
{
|
|
public class BitReader
|
|
{
|
|
private readonly byte[] _masks = {128, 192, 224, 240, 248, 252, 254, 255};
|
|
private readonly Stream _stream;
|
|
|
|
private int _bitsRemaining;
|
|
private int _currentByte;
|
|
private bool _isDataPresent = true;
|
|
|
|
public BitReader(Stream stream)
|
|
{
|
|
_stream = stream;
|
|
}
|
|
|
|
public BitReader(byte[] arrayBytes)
|
|
{
|
|
_stream = new MemoryStream(arrayBytes);
|
|
}
|
|
|
|
public bool IsDataPresent
|
|
{
|
|
get
|
|
{
|
|
if (_bitsRemaining > 0) return true;
|
|
|
|
TryReadNext();
|
|
return _isDataPresent;
|
|
}
|
|
}
|
|
|
|
public bool ReadBit()
|
|
{
|
|
return ReadBits(1) != 0;
|
|
}
|
|
|
|
public byte ReadByte()
|
|
{
|
|
return (byte) ReadBits(8);
|
|
}
|
|
|
|
public ulong ReadBits(int length)
|
|
{
|
|
ulong data = 0;
|
|
while (length > 0)
|
|
{
|
|
if (_bitsRemaining == 0 && _isDataPresent)
|
|
TryReadNext();
|
|
|
|
var dataLength = Math.Min(length, _bitsRemaining);
|
|
|
|
var currentData = (ulong) (_currentByte & _masks[dataLength - 1]);
|
|
if (length > 8)
|
|
currentData = currentData << (length - 8);
|
|
else
|
|
currentData = currentData >> (8 - length);
|
|
data = data | currentData;
|
|
|
|
_currentByte = _currentByte << dataLength;
|
|
length -= dataLength;
|
|
_bitsRemaining -= dataLength;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
private void TryReadNext()
|
|
{
|
|
_currentByte = _stream.ReadByte();
|
|
_isDataPresent = _currentByte > -1;
|
|
if (_isDataPresent)
|
|
_bitsRemaining = 8;
|
|
}
|
|
}
|
|
} |