//----------------------------------------------------------------------------------------------------------------------
// (c) Alex 'Shirson' Nevskiy 2006
//  Shirson's Compressed Data unit
//----------------------------------------------------------------------------------------------------------------------
unit _scd;

interface

uses Classes,zlib,Windows,SysUtils,graphics;

type
  TFiledata=record
    Name:string[40];
    FullName:string;
    Pos:int64;
    Size:int64;
  end;

  TAFiledata=array of TFiledata;

  var
    DataStream:TMemoryStream;
    Datalist:TAFileData;
    TempDir:string;
    TMS: TMemoryStream;


procedure GetSCD (Name:String);
procedure GetData(Name:String; var ms:TMemoryStream); overload;
procedure GetData(Name:String; var tb:TBitMap); overload;
function  GetData(Name:String; var Pnt:Pointer):integer; overload;

//function GetFile(Name:String):string;
//procedure clearfile(Name:String);

implementation

//----------------------------------------------------------------------------------------------------------------------

procedure GetSCD(Name:String);
var a:integer;
    l:word;
    inbuff, outbuff:pointer;
begin
  TMS:= TMemoryStream.Create;
  SetLength(TempDir, MAX_PATH);
  GetTempPath(MAX_PATH, PChar(TempDir));
  SetLength(TempDir, StrLen(PChar(TempDir)));
  DataStream:=TMemoryStream.Create;
  setlength(Datalist,0);
  DataStream.LoadFromFile(name);
  DataStream.Seek(-2,soFromEnd);
  DataStream.Read(l,2);
  DataStream.Position:=0;
  DataStream.Size:=DataStream.Size-2;
  getmem(inbuff,DataStream.Size);
  DataStream.Read(inbuff^,DataStream.Size);
  DecompressBuf(inbuff,DataStream.Size,0,outbuff,a);
  DataStream.Clear;
  DataStream.Write(outbuff^,a);
  DataStream.Seek(-56*l,soFromEnd);
  Setlength(Datalist,l);
  for a:=0 to l-1 do
  begin
    DataStream.Read(Datalist[a].Name,40);
    DataStream.Read(Datalist[a].Pos,8);
    DataStream.Read(Datalist[a].Size,8);
  end;
end;

//----------------------------------------------------------------------------------------------------------------------

procedure GetData(Name:String; var ms:TMemoryStream); overload;
var a:integer;
    f:boolean;
    s:string;
begin
  s:=lowercase(Name);
  f:=false;
  a:=0;
  while (a<=high(DataList)) and (not f) do
    if Datalist[a].Name=s then
      f:=true
    else
      inc(a);
  if not f then
    begin
      messagebox(0,pchar('No '+Name+' resource!'),pchar('!!!'),MB_OK+MB_ICONWARNING);
      halt(0);
    end;
  DataStream.Position:=DataList[a].Pos;
  ms.Clear;
  ms.CopyFrom(DataStream,Datalist[a].Size);
  ms.Position:=0;
end;

//----------------------------------------------------------------------------------------------------------------------

procedure GetData(Name:String; var tb:TBitMap); overload;
var a:integer;
    f:boolean;
    ms:Tmemorystream;
    s:string;
begin
  s:=lowercase(Name);
  f:=false;
  a:=0;
  ms:=Tmemorystream.Create;
  while (a<=high(DataList)) and (not f) do
    if Datalist[a].Name=s then
      f:=true
    else
      inc(a);
  if not f then
    begin
      messagebox(0,pchar('No '+s+' resource!'),pchar('!!!'),MB_OK+MB_ICONWARNING);
      halt(0);
    end;
  DataStream.Position:=DataList[a].Pos;
  ms.Clear;
  ms.CopyFrom(DataStream,Datalist[a].Size);
  ms.Position:=0;
  tb.loadfromstream(ms);
end;

//----------------------------------------------------------------------------------------------------------------------

//function GetFile(Name:String):string;
//var a:integer;
//    f:boolean;
//    ms:TMemoryStream;
//begin
//  ms:=TMemoryStream.Create;
//  f:=false;
//  a:=0;
//  while (a<high(DataList)) and (not f) do
//    if Datalist[a].Name=Name then
//      f:=true
//    else
//      inc(a);
//  DataStream.Position:=DataList[a].Pos;
//  ms.Clear;
//  ms.CopyFrom(DataStream,Datalist[a].Size);
//  ms.Position:=0;
//  result:=tempdir+name;
//  ms.SaveToFile(result);
//  ms.Free;
//end;

//----------------------------------------------------------------------------------------------------------------------

function GetData(Name:String; var Pnt:Pointer):integer; overload;
var a:integer;
    f:boolean;
    s:string;
begin
  s:=lowercase(Name);
  f:=false;
  a:=0;
  while (a<=high(DataList)) and (not f) do
    if Datalist[a].Name=s then
      f:=true
    else
      inc(a);
  if not f then
  begin
    messagebox(0,pchar('No '+s+' resource!'),pchar('!!!'),MB_OK+MB_ICONWARNING);
    halt(0);
  end;
  result:=Datalist[a].Size;
  DataStream.Position:=DataList[a].Pos;
  getmem(pnt,result);
  DataStream.Read(Pnt^,result);
end;

//----------------------------------------------------------------------------------------------------------------------

//procedure clearfile(Name:String);
//begin
//  deletefile(pchar(tempdir+name));
//end;

//----------------------------------------------------------------------------------------------------------------------

end.
