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;