1 (* Copyright (C) Doom 2D: Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 // grouping files with packing:
17 // zip, pk3: PKZIP-compatible archives (store, deflate)
18 // dfwad : D2D:F wad archives
19 //
20 {.$DEFINE SFS_DEBUG_ZIPFS}
21 {$INCLUDE ../shared/a_modes.inc}
22 {$SCOPEDENUMS OFF}
23 {.$R+}
26 interface
28 uses
32 type
36 protected
44 public
49 public
56 implementation
58 uses
62 type
64 public
83 {.$IFDEF ENDIAN_LITTLE}
84 begin
99 var
101 begin
111 var
113 begin
125 { TSFSZipVolume }
127 var
143 begin
144 // search for central dir pointer
150 try
153 begin
155 begin
156 cdsize := LongWord(buf[f+8])+(LongWord(buf[f+9])<<8)+(LongWord(buf[f+10])<<16)+(LongWord(buf[f+11])<<24);
158 break;
161 finally
166 begin
167 // wow, we got central directory! process it
170 begin
174 begin
177 // skip uninteresting fields
182 // skip uninteresting fields
185 // now skip name, extra and comment
191 //writeln('file #', high(fileOffsets), ' found at ', hdrofs);
192 end
194 begin
198 end
199 else
200 begin
201 break;
206 end
207 else
208 begin
212 // read local directory
213 repeat
215 begin
217 //writeln('reading file #', fileIdx, ' at ', fileOffsets[fileIdx]);
223 begin
225 // skip data descriptor
227 begin
229 continue;
231 break;
245 begin
250 // here we should process extra field: it may contain utf8 filename
252 begin
257 // Info-ZIP Unicode Path Extra Field?
259 begin
264 begin
265 //writeln('!!!!!!!!!!!!');
272 //writeln('++++++ [', fi.fName, ']');
276 // skip it
278 begin
283 // skip the rest
287 begin
288 // encrypted file: skip it
293 begin
294 // not stored. not deflated. skip.
298 if (length(fi.fName) = 0) or (fname[length(fi.fName)] = '/') or (fname[length(fi.fName)] = '\') then
299 begin
301 end
302 else
303 begin
313 // skip packed data
317 (*
318 if (sign <> 'PK'#1#2) and (sign <> 'PK'#5#6) then
319 begin
320 {$IFDEF SFS_DEBUG_ZIPFS}
321 WriteLn(ErrOutput, 'end: $', IntToHex(fFileStream.Position, 8));
322 WriteLn(ErrOutput, 'sign: $', sign[0], sign[1], '#', ord(sign[2]), '#', ord(sign[3]));
323 {$ENDIF}
324 raise ESFSError.Create('invalid .ZIP archive (no central dir)');
325 end;
326 *)
331 // idiotic format
332 var
339 begin
344 // read files
346 begin
353 begin
359 // new directory?
361 begin
364 continue;
367 //writeln('DFWAD: [', curpath, '] [', fname, '] at ', fofs, ', size ', fpksize);
368 // create file record
380 begin
389 var
391 begin
396 try
398 begin
399 result := TSFSPartialStream.Create(fFileStream, TSFSZipFileInfo(fFiles[index]).fOfs, TSFSZipFileInfo(fFiles[index]).fSize, false);
400 end
401 else
402 begin
403 rs := TSFSPartialStream.Create(fFileStream, TSFSZipFileInfo(fFiles[index]).fOfs, TSFSZipFileInfo(fFiles[index]).fPackSz, false);
404 result := TUnZStream.Create(rs, TSFSZipFileInfo(fFiles[index]).fSize, true, (TSFSZipFileInfo(fFiles[index]).fMethod <> 255));
406 except
409 exit;
414 { TSFSZipVolumeFactory }
416 begin
417 result :=
426 begin
430 function TSFSZipVolumeFactory.Produce (const prefix, fileName: AnsiString; st: TStream): TSFSVolume;
431 var
433 begin
439 begin
442 try
446 {$ENDIF}
451 end
452 else
453 begin
459 var
461 initialization
464 //finalization
465 // SFSUnregisterVolumeFactory(zipf);