unit Storage;

interface

uses
  Classes, SysUtils, Device, Channel, Int;

type

  { TStorage }

  TStorage = class(TDevice)
  private
    FFileName: string;
    function GetSize: Integer;
    procedure SetFileName(AValue: string);
    procedure SetSize(AValue: Integer);
  public
    FFile: TFileStream;
    Position: Integer;
    function ReadByte(Address: TInt): Byte;
    function ReadData(Size: TIntSize): TInt;
    function ReadPosition(Size: TIntSize): TInt;
    function ReadSize(Size: TIntSize): TInt;
    procedure WriteData(Size: TIntSize; Value: TInt);
    procedure WritePosition(Size: TIntSize; Value: TInt);
    procedure WriteSize(Size: TIntSize; Value: TInt);
    function GetHandlers: THandlers; override;
    constructor Create;
    destructor Destroy; override;
    property FileName: string read FFileName write SetFileName;
    property Size: Integer read GetSize write SetSize;
  end;


implementation

{ TStorage }

procedure TStorage.SetFileName(AValue: string);
begin
  if FFileName = AValue then Exit;
  if AValue = '' then FreeAndNil(FFile);
  FFileName := AValue;
  if FFileName <> '' then begin
    if FileExists(FFileName) then FFile := TFileStream.Create(FFileName, fmOpenReadWrite)
      else FFile := TFileStream.Create(FFileName, fmCreate);
  end;
end;

function TStorage.GetSize: Integer;
begin
  Result := FFile.Size;
end;

procedure TStorage.SetSize(AValue: Integer);
begin
  FFile.Size := AValue;
end;

function TStorage.ReadByte(Address: TInt): Byte;
begin
  Result := 0;
  FFile.Position := Address;
  FFile.Read(Result, 1);
end;

function TStorage.ReadData(Size: TIntSize): TInt;
begin
  FFile.Position := Position;
  FFile.Read(Result, Size);
  Inc(Position, Size);
end;

function TStorage.ReadPosition(Size: TIntSize): TInt;
begin
  Result := Position;
end;

function TStorage.ReadSize(Size: TIntSize): TInt;
begin
  Result := FFile.Size;
end;

procedure TStorage.WriteData(Size: TIntSize; Value: TInt);
begin
  FFile.Position := Position;
  FFile.Write(Value, Size);
  Inc(Position, Size);
end;

procedure TStorage.WritePosition(Size: TIntSize; Value: TInt);
begin
  Position := Value;
end;

procedure TStorage.WriteSize(Size: TIntSize; Value: TInt);
begin
  FFile.Size := Value;
end;
function TStorage.GetHandlers: THandlers;
begin
  Result := THandlers.Create;
  Result.ReadHandlers.Add(ReadData);
  Result.ReadHandlers.Add(ReadPosition);
  Result.ReadHandlers.Add(ReadSize);
  Result.WriteHandlers.Add(WriteData);
  Result.WriteHandlers.Add(WritePosition);
  Result.WriteHandlers.Add(WriteSize);
end;

constructor TStorage.Create;
begin
  FileName := 'Storage.dat';
  Position := 0;
end;

destructor TStorage.Destroy;
begin
  FreeAndNil(FFile);
  inherited;
end;

end.

