diff --git a/src/sfs/sfsZipFS.pas b/src/sfs/sfsZipFS.pas
index 9fb1137e0ca70d054282ddc68c6a01a190b67717..ee1cc1c272b7e6c42e884a78f643632fe376f570 100644 (file)
--- a/src/sfs/sfsZipFS.pas
+++ b/src/sfs/sfsZipFS.pas
// dfwad : D2D:F wad archives
//
{.$DEFINE SFS_DEBUG_ZIPFS}
+{.$DEFINE SFS_ZIPFS_FULL}
{$MODE DELPHI}
{.$R-}
unit sfsZipFS;
SysUtils, Classes, Contnrs, sfs;
-
type
- TSFSZipVolumeType = (sfszvNone, sfszvZIP, sfszvF2DAT, sfszvVTDB, sfszvDFWAD);
+ TSFSZipVolumeType = (
+ sfszvNone,
+ sfszvZIP,
+ {$IFDEF SFS_ZIPFS_FULL}
+ sfszvF2DAT,
+ sfszvVTDB,
+ {$ENDIF}
+ sfszvDFWAD
+ );
TSFSZipVolume = class(TSFSVolume)
protected
fType: TSFSZipVolumeType;
procedure ZIPReadDirectory ();
+ procedure DFWADReadDirectory ();
+ {$IFDEF SFS_ZIPFS_FULL}
procedure F2DATReadDirectory ();
procedure VTDBReadDirectory ();
- procedure DFWADReadDirectory ();
+ {$ENDIF}
procedure ReadDirectory (); override;
procedure removeCommonPath (); override;
result := true;
end;
+{$IFDEF SFS_ZIPFS_FULL}
function F2DATCheckMagic (st: TStream): Boolean;
var
dsize, fiSz: Integer;
if (fcnt < 0) or (dofs < 32) or (dofs+fcnt*8 > st.Size) then exit;
result := true;
end;
+{$ENDIF}
function DFWADCheckMagic (st: TStream): Boolean;
var
end;
end;
+
{ TSFSZipVolume }
procedure TSFSZipVolume.ZIPReadDirectory ();
var
end;
end;
+{$IFDEF SFS_ZIPFS_FULL}
procedure TSFSZipVolume.F2DATReadDirectory ();
var
dsize: Integer;
fi.fMethod := 255;
end;
end;
+{$ENDIF}
procedure TSFSZipVolume.DFWADReadDirectory ();
// idiotic format
begin
case fType of
sfszvZIP: ZIPReadDirectory();
+ {$IFDEF SFS_ZIPFS_FULL}
sfszvF2DAT: F2DATReadDirectory();
sfszvVTDB: VTDBReadDirectory();
+ {$ENDIF}
sfszvDFWAD: DFWADReadDirectory();
else raise ESFSError.Create('invalid zipped SFS');
end;
function TSFSZipVolume.OpenFileByIndex (const index: Integer): TStream;
var
zs: TZDecompressionStream;
- fs: TStream;
+ fs, rs: TStream;
gs: TSFSGuardStream;
kill: Boolean;
buf: packed array [0..1023] of Char;
zs := nil;
fs := nil;
gs := nil;
+ rs := nil;
if fFiles = nil then exit;
if (index < 0) or (index >= fFiles.Count) or (fFiles[index] = nil) then exit;
kill := false;
fs.Seek(TSFSZipFileInfo(fFiles[index]).fOfs, soBeginning);
if TSFSZipFileInfo(fFiles[index]).fMethod = 255 then
begin
- zs := TZDecompressionStream.Create(fs)
+ // sorry, pals, DFWAD is completely broken, so users of it should SUFFER
+ if TSFSZipFileInfo(fFiles[index]).fSize = -1 then
+ begin
+ TSFSZipFileInfo(fFiles[index]).fSize := 0;
+ //writeln('trying to determine file size for [', TSFSZipFileInfo(fFiles[index]).fPath, TSFSZipFileInfo(fFiles[index]).fName, ']');
+ zs := TZDecompressionStream.Create(fs);
+ try
+ while true do
+ begin
+ rd := zs.read(buf, 1024);
+ //writeln(' got ', rd, ' bytes');
+ if rd > 0 then Inc(TSFSZipFileInfo(fFiles[index]).fSize, rd);
+ if rd < 1024 then break;
+ end;
+ //writeln(' resulting size: ', TSFSZipFileInfo(fFiles[index]).fSize, ' bytes');
+ // recreate stream
+ FreeAndNil(zs);
+ fs.Seek(TSFSZipFileInfo(fFiles[index]).fOfs, soBeginning);
+ except
+ //writeln('*** CAN''T determine file size for [', TSFSZipFileInfo(fFiles[index]).fPath, TSFSZipFileInfo(fFiles[index]).fName, ']');
+ FreeAndNil(zs);
+ if kill then FreeAndNil(fs);
+ result := nil;
+ exit;
+ end;
+ end;
+ rs := TSFSPartialStream.Create(fs, TSFSZipFileInfo(fFiles[index]).fOfs, TSFSZipFileInfo(fFiles[index]).fPackSz, true);
+ zs := TZDecompressionStream.Create(rs);
+ rs := nil;
end
else
begin
- zs := TZDecompressionStream.Create(fs, true {-15}{MAX_WBITS});
- end;
- // sorry, pals, DFWAD is completely broken, so users of it should SUFFER
- if TSFSZipFileInfo(fFiles[index]).fSize = -1 then
- begin
- TSFSZipFileInfo(fFiles[index]).fSize := 0;
- //writeln('trying to determine file size for [', TSFSZipFileInfo(fFiles[index]).fPath, TSFSZipFileInfo(fFiles[index]).fName, ']');
- try
- while true do
- begin
- rd := zs.read(buf, 1024);
- //writeln(' got ', rd, ' bytes');
- if rd > 0 then Inc(TSFSZipFileInfo(fFiles[index]).fSize, rd);
- if rd < 1024 then break;
- end;
- //writeln(' resulting size: ', TSFSZipFileInfo(fFiles[index]).fSize, ' bytes');
- // recreate stream
- FreeAndNil(zs);
- fs.Seek(TSFSZipFileInfo(fFiles[index]).fOfs, soBeginning);
- zs := TZDecompressionStream.Create(fs)
- except
- //writeln('*** CAN''T determine file size for [', TSFSZipFileInfo(fFiles[index]).fPath, TSFSZipFileInfo(fFiles[index]).fName, ']');
- FreeAndNil(zs);
- if kill then FreeAndNil(fs);
- result := nil;
- exit;
- end;
+ rs := TSFSPartialStream.Create(fs, TSFSZipFileInfo(fFiles[index]).fOfs, TSFSZipFileInfo(fFiles[index]).fPackSz, true);
+ zs := TZDecompressionStream.Create(rs, true {-15}{MAX_WBITS});
+ rs := nil;
end;
gs := TSFSGuardStream.Create(zs, fs, true, kill, false);
zs := nil;
result := TSFSPartialStream.Create(gs, 0, TSFSZipFileInfo(fFiles[index]).fSize, true);
end;
except
+ FreeAndNil(rs);
FreeAndNil(gs);
FreeAndNil(zs);
if kill then FreeAndNil(fs);
@@ -541,11 +564,14 @@ function TSFSZipVolumeFactory.IsMyVolumePrefix (const prefix: TSFSString): Boole
begin
result :=
SFSStrEqu(prefix, 'zip') or
- SFSStrEqu(prefix, 'jar') or
+ SFSStrEqu(prefix, 'dfwad')
+ {$IFDEF SFS_ZIPFS_FULL}
+ or SFSStrEqu(prefix, 'jar') or
SFSStrEqu(prefix, 'fout2') or
SFSStrEqu(prefix, 'vtdb') or
- SFSStrEqu(prefix, 'wad') or
- SFSStrEqu(prefix, 'dfwad');
+ SFSStrEqu(prefix, 'wad')
+ {$ENDIF}
+ ;
end;
procedure TSFSZipVolumeFactory.Recycle (vol: TSFSVolume);
vt: TSFSZipVolumeType;
begin
vt := sfszvNone;
- if ZIPCheckMagic(st) then vt := sfszvZIP
+ if ZIPCheckMagic(st) then vt := sfszvZIP
else if DFWADCheckMagic(st) then vt := sfszvDFWAD
+ {$IFDEF SFS_ZIPFS_FULL}
else if F2DATCheckMagic(st) then vt := sfszvF2DAT
- else if VTDBCheckMagic(st) then vt := sfszvVTDB;
+ else if VTDBCheckMagic(st) then vt := sfszvVTDB
+ {$ENDIF}
+ ;
if vt <> sfszvNone then
begin
initialization
zipf := TSFSZipVolumeFactory.Create();
SFSRegisterVolumeFactory(zipf);
-finalization
- SFSUnregisterVolumeFactory(zipf);
+//finalization
+// SFSUnregisterVolumeFactory(zipf);
end.