Home » Tutorials » Datenspeicherung » Archivformate – Cabinet-API

Archivformate – Cabinet-API

Vorarbeit

Die Cabinet API benötigt Callback-Funktionen zur Speicher- und Dateiverwaltung. Diese müssen vollständig C-kompatibel sein – deshalb sind für Delphi einige Vorarbeiten zu leisten.
Die Speicherverwaltung ist noch relativ trivial. Es müssen lediglich die beiden C-Funktionen malloc und free bereitgestellt werden, die im wesentlichen ihren Delphi-Vettern GetMem und FreeMem entsprechen.

function FCAllocMem(cb : TULONG) : PVoid; cdecl;
begin
  GetMem(Result, cb);
end;

function FCFreeMem(memory : PVoid) : Pointer; cdecl;
begin
  FreeMem(memory);
  Result := Nil;
end;

Bei der Dateiverwaltung ist etwas mehr zu leisten. Zur Demonstration folgen hier die Funktionen zum Öffnen und Schreiben von Dateien:

function FCOpenFile(pszFile: PChar; oflag: Integer;
  pmode: Integer; err: PInteger; pv: Pointer): Integer; cdecl;
var
  f : PFile;
begin
{$IOCHECKS OFF}

  if (((oflag and $400)=$400) and ((oflag and $100)=$100)) then
  begin
    if FileExists(string(pszFile)) = true then
    begin
      Result := -1;
      Exit;
    end;
  end;

  GetMem(f,sizeof(File));
  AssignFile(f^,pszfile);

  if (((oflag and $100) = $100) or ((oflag and $200)=$200)) then
     Rewrite(f^,1) // Create
  else
     Reset(f^,1);

   if IoResult = 0 then
     Result := Integer(f)
   else
     Result := -1;

{$IOCHECKS ON}
end;

Der Parameter oflag kann sich aus den Hexadezimalen Flags 100h, 200h und 400h zusammensetzten.
Die ersten beiden stehen für das neu erzeugen einer Datei, während das letzte Flag in Kombination mit dem ersten bewirkt, das bei schon existierender Datei ein Fehler ausgegeben wird.

function FCWriteFile(hf : Integer; memory : PVoid; cb : TUINT;
  err : PInteger; pv : Pointer) : TUINT; cdecl;
var
  tr : integer;

begin
{$IOCHECKS OFF}
  Blockwrite(PFile(hf)^, memory^, cb, tr);
  if (IOResult <> 0) then
  begin
    Result := -1;
    Err^ := -1;
  end
  else
    Result := tr;
{$IOCHECKS ON}
end;