Contributor: SCOTT BAKER unit ZipView; interface uses dos; type barray= array[1..8192] of byte; ZipPtr=^ZipRec; ZipRec= Record version_made: word; version_extr: word; flags: word; comp_method: word; last_mod_time: word; last_mod_date: word; crc_32: longint; compressed_size: longint; uncompressed_size: longint; fname_length: word; extra_length: word; comment_length: word; disk_num_start: word; internal_attr: word; external_attr: longint; rel_ofs: longint; name: string[12]; Next: ZipPtr; end; bptr = ^barray; const ZipMethod: array[0..9] of string[15] = ('stored ', 'shrunk ', 'reduced-1', 'reduced-2', 'reduced-3', 'reduced-4', 'imploded ', 'unknown ', 'unknown ', 'unknown '); var totallength,totalsize,numfiles: longint; firstzip: zipptr; lineout: string; outPtr: pointer; procedure LoadZip(filename: string); procedure DisplayZip; procedure DisposeZip; implementation var f: file of barray; buffer: barray; addr: longint; bufptr: word; {$F+} Procedure CallProc; inline($FF/$1E/OutPtr); {$F-} Function NextByte: byte; var i: integer; begin; inc(addr); inc(bufptr); if bufptr=8193 then begin; {$I-} read(f,buffer); {$I+} i:=ioresult; bufptr:=1; end; nextbyte:=buffer[bufptr]; end; procedure LoadZip(filename: string); var b: byte; f2: file of byte; fs: longint; LastZip,Zip: ZipPtr; Bytes: Bptr absolute zip; a: integer; sr: searchrec; begin; firstzip:=nil; { assign(f2,filename); reset(F2); fs:=filesize(f2); close(f2);} findfirst(filename,anyfile,sr); fs:=sr.size; assign(f,filename); reset(f); addr:=0; if fs>65535 then begin; seek(f,(fs div 8192)-4); addr:=addr+((fs div 8192)-4)*8192; end; {$I-} read(f,buffer); {$I+} a:=ioresult; bufptr:=0; b:=nextbyte; repeat; if b=$50 then begin; b:=nextbyte; if b=$4b then begin; b:=nextbyte; if b=$01 then begin; b:=nextbyte; if b=$02 then begin; new(zip); zip^.next:=nil; if firstzip=nil then firstzip:=zip else lastzip^.next:=zip; lastzip:=zip; for a:=1 to 42 do bytes^[a]:=nextbyte; zip^.name:=''; for a:=1 to zip^.fname_length do zip^.name:=zip^.name+chr(nextbyte); b:=nextbyte; end; end; end; end else b:=nextbyte; until addr>=fs; end; procedure OutLine(s: string); begin; lineout:=s; if OutPtr=NIL then writeln(s) else CallProc; end; function format_date(date: word): string; var s,s2: string; y,m,d: word; begin m:=(date shr 5) and 15; d:=( (date ) and 31); y:=(((date shr 9) and 127)+80); str(m,s); while length(s)<2 do s:='0'+s; s:=s+'-'; str(d,s2); while length(s2)<2 do s2:='0'+s2; s:=s+s2+'-'; str(y,s2); while length(s2)<2 do s2:='0'+s2; s:=s+s2; format_date:=s; end; function format_time(time: word): string; var s,s2: string; h,m,se: word; begin h:=(time shr 11) and 31; m:=(time shr 5) and 63; se:=(time shl 1) and 63; str(h,s); while length(S)<2 do s:='0'+s; s:=s+':'; str(m,s2); while length(s2)<2 do s2:='0'+s2; s:=s+s2; format_time:=s; end; procedure DisplayHeader; begin; OutLine('Filename Length Size Method Date Time Ratio'); OutLine('------------ ------- ------- --------- -------- ----- -----'); end; procedure DisplayFooter; var s,s2: string; average: real; begin; OutLine('------------ ------- ------- -----'); average:=100-totalsize/totallength*100; str(numfiles:12,s); str(totallength:7,s2); s:=s+' '+s2+' '; str(totalsize:7,s2); s:=s+s2+' '; str(average:4:0,s2); s:=s+s2+'%'; outline(s); end; procedure DisplayZip; var curzip: zipptr; s,s2: string; begin; numfiles:=0; totallength:=0; totalsize:=0; DisplayHeader; curzip:=firstzip; while curzip<>nil do begin; s:=curzip^.name; while length(s)<14 do s:=s+' '; str(curzip^.uncompressed_size,s2); while length(s2)<7 do s2:=' '+s2; s:=s+s2+' '; str(curzip^.compressed_size,s2); while length(s2)<7 do s2:=' '+s2; s:=s+s2+' '; s:=s+ZipMethod[curzip^.comp_method]+' '; s:=s+format_date(curzip^.last_mod_date)+' '+format_time(curzip^.last_mod_time)+' '; str(100-curzip^.compressed_size/curzip^.uncompressed_size*100:1:1,s2); s2:=s2+'%'; while length(s2)<5 do s2:=' '+s2; s:=s+s2; Outline(s); totallength:=totallength+curzip^.uncompressed_size; totalsize:=totalsize+curzip^.compressed_size; inc(numfiles); curzip:=curzip^.next; end; if (numfiles=0) or (totallength=0) or (totalsize=0) then begin; outline('No valid file entries detected.'); end else begin; displayfooter; end; end; procedure DisposeZip; var curzip,savezip: zipptr; begin; curzip:=firstzip; while curzip<>nil do begin; savezip:=curzip^.next; dispose(curzip); curzip:=savezip; end; end; begin; OutPtr:=Nil; end. { -------------------------- CUT HERE -----------------------------} { TEST PROGRAM } uses zipview; var s: string; begin; write('File to Zip-View ? '); readln(s); LoadZip(s); DisplayZip; DisposeZip; end.