unit dautobuffer;

{$MODE FPC}
{$MODESWITCH DEFAULTPARAMETERS}
{$MODESWITCH OUT}
{$MODESWITCH RESULT}

interface

type
TAutoBuffer = object
private const
  FLAG_SHOULD_FREEMEM                     = 1 shl 0;
private
  FData: Pointer;
  FSize: SizeUInt;
  FFlags: PtrUInt;
public
  procedure Init; inline;
  procedure Done; inline;

  procedure Clear;
      // Sets the buffer to nil and deallocates memory if needed.

  function Allocate(Size: SizeUInt): Boolean;
      // Allocates memory with GetMem.

  function DataEnd: Pointer; inline;
  property Data: Pointer read FData;
  property Size: SizeUInt read FSize;
end;

implementation

procedure TAutoBuffer.Init;
begin
  FFlags := 0;
  FData := nil;
  FSize := 0;
end;

procedure TAutoBuffer.Done;
begin
  Clear;
end;

procedure TAutoBuffer.Clear;
begin
  if (FFlags and FLAG_SHOULD_FREEMEM) <> 0 then
    FreeMem(FData);
end;

function TAutoBuffer.Allocate(Size: SizeUInt): Boolean;
begin
  Clear;
  FData := GetMem(Size);
  FSize := Size;
  FFlags := FLAG_SHOULD_FREEMEM;
end;

function TAutoBuffer.DataEnd: Pointer;
begin
  Exit(FData + FSize);
end;

end.
