Contributor: EDWIN GROOTHUIS { > Does anyone know where I can obtain source for reading a ZIP > file. I know I could just shell and execute PKUNZIP, but the > looks horrible. 8-) I would like to do it as transparently as > possible (and without shelling :) TIA! } Type ZFHeader=Record Signature :longint; Version,GPBFlag,Compress,Date,Time:word; CRC32,CSize,USize :longint; FNameLen,ExtraField :word; end; type PZipArchive=^TZipArchive; TZipArchive=object(TGeneralArchive) constructor Init; procedure FindFirst(var sr:SearchRec);virtual; procedure FindNext(var sr:SearchRec);virtual; private Hdr:ZFHeader; function GetHeader(var sr:SearchRec):string; end; implementation uses Objects,OOAVUtil; Const SIG = $04034B50; { Signature } constructor TZipArchive.Init; begin FillChar(Hdr,sizeof(Hdr),0); end; function TZipArchive.GetHeader(var sr:SearchRec):string; var b:byte; FName:string; begin fillchar(sr,sizeof(sr),0); if _FArchive^.GetPos=_FArchive^.GetSize then exit; _Farchive^.Read(Hdr,SizeOf(Hdr)); if _FArchive^.Status<>stOk then exit; { Why checking for Hdr.FNamelen=0? Because the comments inserted in a ZIP-file are at the last field } if Hdr.FNameLen=0 then exit; FName:=''; Repeat _FArchive^.Read(b,1); If b<>0 Then FName:=FName+Chr(b); Until (length(FName)=Hdr.FNameLen) or (b=0); if b=0 then begin GetHeader:=''; exit; end; _FArchive^.Seek(_FArchive^.GetPos+Hdr.CSize+Hdr.ExtraField); sr.Size:=Hdr.USize; sr.Time:=Hdr.Date+Hdr.Time*longint(256*256); GetHeader:=FName; end; procedure TZipArchive.FindFirst(var sr:SearchRec); var FName:string; found:boolean; begin found:=false; repeat FName:=GetHeader(sr); if FName='' then begin found:=true; sr.Name:=''; end; while pos('/',FName)<>0 do FName[pos('/',FName)]:='\'; if Fits(FName,_SearchDir+_SearchFile) then begin sr.Name:=copy(FName,length(_SearchDir)+1,12); found:=true; end; until found; end; procedure TZipArchive.FindNext(var sr:SearchRec); var FName:string; found:boolean; begin found:=false; repeat FName:=GetHeader(sr); if FName='' then begin found:=true; sr.Name:=''; end; while pos('/',FName)<>0 do FName[pos('/',FName)]:='\'; if Fits(FName,_SearchDir+_SearchFile) then begin sr.Name:=copy(FName,length(_SearchDir)+1,12); found:=true; end; until found; end;