1
0
mirror of https://github.com/chylex/Brotli-Builder.git synced 2024-12-22 07:42:47 +01:00
Brotli-Builder/BrotliLib/Serialization/Reader/BitReader.cs

64 lines
1.8 KiB
C#

using System;
using System.Collections.Generic;
namespace BrotliLib.Serialization.Reader{
public class BitReader : IBitReader{
private const int MaxChunkSize = BitStream.ByteSize * sizeof(int);
public int Index { get; private set; }
private readonly IEnumerator<bool> enumerator;
/// <summary>
/// Initializes a new <see cref="BitReader"/> at the beginning of the specified <see cref="BitStream"/>.
/// </summary>
/// <param name="stream">Input bit stream.</param>
public BitReader(BitStream stream){
this.enumerator = stream.GetEnumerator();
this.Index = 0;
}
// Implementation
public bool NextBit(){
if (!enumerator.MoveNext()){
throw new IndexOutOfRangeException("No more bits left in the stream.");
}
++Index;
return enumerator.Current;
}
public int NextChunk(int bits){
if (bits > MaxChunkSize){
throw new ArgumentOutOfRangeException(nameof(bits), "Cannot retrieve a chunk larger than " + MaxChunkSize + " bits in one call.");
}
int value = 0;
for(int bit = 0; bit < bits; bit++){
if (NextBit()){
value |= 1 << bit;
}
}
return value;
}
public void AlignToByteBoundary(){
int relativeIndex = Index & BitStream.ByteMask;
if (relativeIndex > 0){
for(int bitsLeft = BitStream.ByteSize - relativeIndex; bitsLeft > 0; bitsLeft--){
NextBit();
}
}
}
public byte NextAlignedByte(){
AlignToByteBoundary();
return (byte)NextChunk(BitStream.ByteSize);
}
}
}