'===========================================================================
' Subject: ZIP VIEWER FOR QB                  Date: 12-04-97 (09:42)       
'  Author: The ABC Programmer                 Code: QB, QBasic, PDS        
'  Origin: Check PB.ABC for PB Version      Packet: MISC.ABC
'===========================================================================
'----------------------------[ ZIP Viewer ]-------------------------------
' No frills .ZIP Viewer for QB by William Yu (12-03-97)  Public Domain.
' With help from: Steve Wierenga (his Pascal code to be precise).
'
' If you're wondering how I got the Date/Time thing to work, check this:
'
'   bits     field              It's just one long 32-bit number
'   ----     -----              Pretty cool for only 4 bytes worth.
'   0-5   =  seconds
'   6-11  =  minutes
'   12-16 =  hours
'   17-21 =  days
'   22-25 =  months
'   26-31 =  years
'
'-------------------------------------------------------------------------

DECLARE SUB ZipView (ZIPFile AS STRING)

DEFINT A-Z
CONST SIG = &H4034B50            ' Signature
                           
TYPE ZFHeader                    ' Zip File Header
    Signature AS LONG
    Version AS INTEGER           ' actual Word
    GPBFlag AS INTEGER           ' actual Word
    Compress AS INTEGER          ' Compression type
    DateTime AS LONG
    CRC32 AS LONG
    CSize AS LONG
    USize AS LONG
    FileNameLen AS LONG
    ExtraField AS INTEGER        ' Not sure
END TYPE
DIM SHARED CompTypes(0 TO 9) AS STRING * 9

FOR I = 0 TO 9
  READ CompTypes(I)
NEXT I
DATA Stored,Shrunk,Reduced1,Reduced2,Reduced3
DATA Reduced4,Imploded,Deflated,DeflatN,DeflatX

CLS
PRINT ".ZIP Viewer (Public Domain) by William Yu, with help from Steve Wierenga": PRINT
ZipView COMMAND$

END

SUB ZipView (ZIPFile AS STRING) ' View the ZIP File
 DIM TotalU AS LONG
 DIM TotalC AS LONG
 DIM TotalF AS INTEGER
 DIM Hdr AS ZFHeader
 DIM F AS STRING
 DIM Year AS LONG
 DIM Month AS LONG
 DIM Day AS LONG
 DIM Hour AS LONG
 DIM Minute AS LONG
 DIM Secs AS LONG

  IF ZIPFile = "" THEN
    PRINT "Usage: ZIPVIEW [Path:\]filename.ZIP"
    EXIT SUB
  END IF

  ' Init Variables
  TotalU = 0: TotalC = 0: TotalF = 0

  ZIP = FREEFILE
  OPEN ZIPFile FOR BINARY AS ZIP
  IF LOF(ZIP) = 0 THEN             ' Check if files exists
    PRINT ZIPFile; " does not exist!"' if not, exit
    CLOSE ZIP
    KILL ZIPFile
    EXIT SUB
  END IF
  PRINT "Searching: "; ZIPFile: PRINT
  PRINT USING "\          \ \      \ \     \ \  \ \      \ \      \ \       \ \      \"; "FileName"; " Length"; " Size"; "Rate"; " Date"; "  Time"; "  Method"; " CRC-32"
  PRINT USING "\          \ \      \ \     \ \  \ \       \ \      \ \       \ \      \"; "------------"; "--------"; "-------"; "----"; "--------"; "--------"; "--------"; "--------"
  DO
    GET ZIP, , Hdr                   ' Read File Header
    IF (Hdr.Signature = SIG) THEN    ' Is a header
      F = SPACE$(Hdr.FileNameLen)    ' Grab filename
      GET ZIP, LOC(ZIP) - 1, F
      Year = Hdr.DateTime
      Year = Year \ (2 ^ 25) AND &H7F
      Month = Hdr.DateTime
      Month = Month \ (2 ^ 21) AND &HF
      Day = Hdr.DateTime
      Day = Day \ (2 ^ 16) AND &H1F
      Hour = Hdr.DateTime
      Hour = Hour \ (2 ^ 11) AND &H1F
      Minute = Hdr.DateTime
      Minute = Minute \ (2 ^ 5) AND &H3F
      Secs = Hdr.DateTime AND &H3F
      M$ = LTRIM$(STR$(Month))
      D$ = LTRIM$(STR$(Day))
      IF LEN(M$) = 1 THEN M$ = "0" + M$
      IF LEN(D$) = 1 THEN D$ = "0" + D$
      A$ = M$ + "-" + D$ + "-" + LTRIM$(STR$(Year + 80))' Year starts at 1980
      H$ = LTRIM$(STR$(Hour))
      M$ = LTRIM$(STR$(Minute))
      S$ = LTRIM$(STR$(Secs))
      IF LEN(H$) = 1 THEN H$ = "0" + H$
      IF LEN(M$) = 1 THEN M$ = "0" + M$
      IF LEN(S$) = 1 THEN S$ = "0" + S$
      B$ = H$ + ":" + M$ + ":" + S$
      PRINT USING "\          \ \      \ \     \ \  \ \       \ \       \ \      \ \      \"; F; STR$(Hdr.USize); STR$(Hdr.CSize); STR$(INT(100 - Hdr.CSize / Hdr.USize * 100)) + "%"; A$; B$; CompTypes(Hdr.Compress); LCASE$(HEX$(Hdr.CRC32))
      TotalU = TotalU + Hdr.USize' Increment size uncompressed
      TotalC = TotalC + Hdr.CSize' Increment size compressed
      TotalF = TotalF + 1
    END IF
    SEEK ZIP, LOC(ZIP) + Hdr.CSize + 1'+ Hdr.ExtraField
  LOOP UNTIL Hdr.Signature <> SIG '  No more Files
  PRINT STRING$(72, "-")
  PRINT USING "\          \ \      \ \     \ \  \ \       \ \       \"; STR$(TotalF); STR$(TotalU); STR$(TotalC); STR$(INT(100 - TotalC / TotalU * 100)) + "%";
  CLOSE ZIP
END SUB
