{$MODE OBJFPC}
uses
  dtypes,
  dbitstream;

type
TStream = object
  S: AnsiString;
  I: LongInt;
  function Read(var Buffer; Count: LongInt): LongInt;
end;

function TStream.Read(var Buffer; Count: LongInt): LongInt;
begin
  // Assert(Count = 1);
  if I > Length(S) then
    Exit(0);
  Move(S[I], Buffer, 1);
  Inc(I);
  Exit(1);
end;

var
  V: TUint32;
  Stream: TStream;
  BitReader: TBitReader;
  I: LongInt;

begin
  Stream.S := #255#2#4#255;
  Stream.I := 1;
  BitReader.Init(@Stream.Read);
  while not BitReader.EOS do
    Write(BitReader.ReadBit);
  Writeln;

  Write('8 bits: ');
  Stream.I := 1;
  BitReader.Reinit(@Stream.Read);
  while not BitReader.EOS do begin
    Write(BitReader.ReadRest, ' ');
  end;
  Writeln;

  Write('2 bits: ');
  Stream.I := 1;
  BitReader.Reinit(@Stream.Read);
  while not BitReader.EOS do begin
    Write(BitReader.ReadRest(2), ' ');
  end;
  Writeln;

  Write('3 bits: ');
  Stream.I := 1;
  BitReader.Reinit(@Stream.Read);
  while not BitReader.EOS do begin
    Write(BitReader.ReadRest(3), ' ');
  end;
  Writeln;

  Write('9 bits: ');
  Stream.I := 1;
  BitReader.Reinit(@Stream.Read);
  while BitReader.ReadUint(9, V) do begin
    Write(V, ' ');
  end;
  Writeln;

  BitReader.Done;
end.
