unit _filebuf;

interface

uses
  Windows, SysUtils, Classes;

{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}

type
  TReadFileBuf = class
  private
    { Private 먬뙻 }
    Filename:string;
    Count,Pos:integer;
    buf:array of byte;
  public
    { Public 먬뙻 }
    ReadMode:integer;
    procedure Init(fn:string); overload;
    procedure LoadFile;
    procedure LoadResource;
    function GetCount:integer;
    procedure SetPosition(_pos:integer);
    function GetPosition:integer;

    procedure GetVMString(var s:string);
    function GetMString:string;
    procedure GetVByte(var b:byte);
    function GetByte:byte;
    procedure GetVWord(var w:word);
    function GetWord:word;
    procedure GetVDWord(var dw:dword);
    function GetDWord:dword;
    procedure GetVInteger(var i:integer);
    function GetInteger:integer;
    procedure GetVBoolean(var b:boolean);
    function GetBoolean:boolean;
    procedure GetVDateTime(var d:TDateTime);
    function GetDateTime:TDateTime;
    procedure GetVSingle(var s:single);
    function GetSingle:single;
    procedure GetVDouble(var d:double);
    function GetDouble:double;
  end;

type
  TWriteFileBuf = class
  private
    { Private 먬뙻 }
    Filename:string;
    Count,Pos:integer;
    buf:array of byte;
    fs:TFileStream;
  public
    { Public 먬뙻 }
    procedure Init(fn:string);
    procedure SaveFile;
    procedure AddSizeBuffer;
    function GetCount:integer;

    procedure SetVMString(var s:string);
    procedure SetMString(s:string);
    procedure SetVByte(var b:byte);
    procedure SetByte(b:byte);
    procedure SetVWord(var w:word);
    procedure SetWord(w:word);
    procedure SetVDWord(var dw:dword);
    procedure SetDWord(dw:dword);
    procedure SetVInteger(var i:integer);
    procedure SetInteger(i:integer);
    procedure SetVBoolean(var b:boolean);
    procedure SetBoolean(b:boolean);
    procedure SetVDateTime(var d:TDateTime);
    procedure SetDateTime(d:TDateTime);
    procedure SetVSingle(var s:single);
    procedure SetSingle(s:single);
    procedure SetVDouble(var d:double);
    procedure SetDouble(d:double);
  end;

implementation

uses _m_Tools;

procedure TReadFileBuf.Init(fn:string);
begin
  ReadMode:=fmShareDenyWrite;
  Filename:=fn;
  Count:=0;
  Pos:=0;
  SetLength(buf,Count);
end;

procedure TReadFileBuf.LoadFile;
var
  fs:TFileStream;
begin
  fs:=TFileStream.Create(Filename,fmOpenRead or ReadMode);
  Count:=fs.Size;
  SetLength(buf,Count+1);
  fs.ReadBuffer(buf[0],Count);
  fs.Free;

  Pos:=0;
end;

procedure TReadFileBuf.LoadResource;
var
  rs:TResourceStream;
begin
  rs:=TResourceStream.Create(hInstance,Filename,RT_RCDATA);
  Count:=rs.Size;
  SetLength(buf,Count+1);
  rs.ReadBuffer(buf[0],Count);
  rs.Free;

  Pos:=0;
end;

function TReadFileBuf.GetCount:integer;
begin
  Result:=Count;
end;

procedure TReadFileBuf.SetPosition(_pos:integer);
begin
  Pos:=_pos;
end;

function TReadFileBuf.GetPosition:integer;
begin
  Result:=Pos;
end;

procedure TReadFileBuf.GetVMString(var s:string);
var
  size:byte;
begin
  size:=buf[Pos];
  inc(Pos);
  if size=0 then begin
    s:='';
    end else begin
    SetLength(s,size);
    CopyMemory(@s[1],@buf[Pos],size);
    inc(Pos,size);
  end;
end;

function TReadFileBuf.GetMString:string;
begin
  GetVMString(Result);
end;

procedure TReadFileBuf.GetVByte(var b:byte);
begin
  b:=buf[Pos];
  inc(Pos);
end;

function TReadFileBuf.GetByte:byte;
begin
  GetVByte(Result);
end;

procedure TReadFileBuf.GetVWord(var w:word);
begin
  CopyMemory(@w,@buf[Pos],2);
  inc(Pos,2);
end;

function TReadFileBuf.GetWord:word;
begin
  GetVWord(Result);
end;

procedure TReadFileBuf.GetVDWord(var dw:dword);
begin
  CopyMemory(@dw,@buf[Pos],4);
  inc(Pos,4);
end;

function TReadFileBuf.GetDWord:dword;
begin
  GetVDWord(Result);
end;

procedure TReadFileBuf.GetVInteger(var i:integer);
begin
  CopyMemory(@i,@buf[Pos],4);
  inc(Pos,4);
end;

function TReadFileBuf.GetInteger:integer;
begin
  GetVInteger(Result);
end;

procedure TReadFileBuf.GetVBoolean(var b:boolean);
begin
  if buf[Pos]=$00 then begin
    b:=True;
    end else begin
    b:=False;
  end;
  inc(Pos);
end;

function TReadFileBuf.GetBoolean:boolean;
begin
  GetVBoolean(Result);
end;

procedure TReadFileBuf.GetVDateTime(var d:TDateTime);
begin
  CopyMemory(@d,@buf[Pos],8);
  inc(Pos,8);
end;

function TReadFileBuf.GetDateTime:TDateTime;
begin
  GetVDateTime(Result);
end;

procedure TReadFileBuf.GetVSingle(var s:single);
begin
  CopyMemory(@s,@buf[Pos],4);
  inc(Pos,4);
end;

function TReadFileBuf.GetSingle:single;
begin
  GetVSingle(Result);
end;

procedure TReadFileBuf.GetVDouble(var d:double);
begin
  CopyMemory(@d,@buf[Pos],8);
  inc(Pos,8);
end;

function TReadFileBuf.GetDouble:double;
begin
  GetVDouble(Result);
end;

// -----------------------------------------------------
// TWriteFileBuf ---------------------------------------
// -----------------------------------------------------

procedure TWriteFileBuf.Init(fn:string);
begin
  Filename:=fn;
  Count:=1024*1024;
  Pos:=0;
  SetLength(buf,Count);

  fs:=TFileStream.Create(Filename,fmCreate or fmShareDenyWrite);
end;

procedure TWriteFileBuf.SaveFile;
begin
  fs.WriteBuffer(buf[0],Pos);
  fs.Free;
end;

procedure TWriteFileBuf.AddSizeBuffer;
begin
  fs.WriteBuffer(buf[0],Pos);
  Pos:=0;
end;

function TWriteFileBuf.GetCount:integer;
begin
  Result:=Count;
end;

procedure TWriteFileBuf.SetVMString(var s:string);
var
  len:byte;
begin
  if (Pos+$100)>=Count then AddSizeBuffer;

  len:=length(s);
  buf[Pos]:=len;
  inc(Pos);
  if len<>0 then begin
    CopyMemory(@buf[Pos],@s[1],len);
    inc(Pos,len);
  end;
end;

procedure TWriteFileBuf.SetMString(s:string);
begin
  SetVMString(s);
end;

procedure TWriteFileBuf.SetVByte(var b:byte);
begin
  if (Pos+$01)>=Count then AddSizeBuffer;
  buf[Pos]:=b;
  inc(Pos);
end;

procedure TWriteFileBuf.SetByte(b:byte);
begin
  SetVByte(b);
end;

procedure TWriteFileBuf.SetVWord(var w:word);
begin
  if (Pos+$02)>=Count then AddSizeBuffer;
  CopyMemory(@buf[Pos],@w,2);
  inc(Pos,2);
end;

procedure TWriteFileBuf.SetWord(w:word);
begin
  SetVWord(w);
end;

procedure TWriteFileBuf.SetVDWord(var dw:dword);
begin
  if (Pos+$04)>=Count then AddSizeBuffer;
  CopyMemory(@buf[Pos],@dw,4);
  inc(Pos,4);
end;

procedure TWriteFileBuf.SetDWord(dw:dword);
begin
  SetVDWord(dw);
end;

procedure TWriteFileBuf.SetVInteger(var i:integer);
begin
  if (Pos+$04)>=Count then AddSizeBuffer;
  CopyMemory(@buf[Pos],@i,4);
  inc(Pos,4);
end;

procedure TWriteFileBuf.SetInteger(i:integer);
begin
  SetVInteger(i);
end;

procedure TWriteFileBuf.SetVBoolean(var b:boolean);
begin
  if (Pos+$01)>=Count then AddSizeBuffer;
  if b=True then begin
    buf[Pos]:=$00;
    end else begin
    buf[Pos]:=$ff;
  end;
  inc(Pos);
end;

procedure TWriteFileBuf.SetBoolean(b:boolean);
begin
  SetVBoolean(b);
end;

procedure TWriteFileBuf.SetVDateTime(var d:TDateTime);
begin
  if (Pos+$08)>=Count then AddSizeBuffer;
  CopyMemory(@buf[Pos],@d,8);
  inc(Pos,8);
end;

procedure TWriteFileBuf.SetDateTime(d:TDateTime);
begin
  SetVDateTime(d);
end;

procedure TWriteFileBuf.SetVSingle(var s:single);
begin
  if (Pos+$04)>=Count then AddSizeBuffer;
  CopyMemory(@buf[Pos],@s,4);
  inc(Pos,4);
end;

procedure TWriteFileBuf.SetSingle(s:single);
begin
  SetVSingle(s);
end;

procedure TWriteFileBuf.SetVDouble(var d:double);
begin
  if (Pos+$08)>=Count then AddSizeBuffer;
  CopyMemory(@buf[Pos],@d,8);
  inc(Pos,8);
end;

procedure TWriteFileBuf.SetDouble(d:double);
begin
  SetVDouble(d);
end;

end.
