Parse zip file without using a library

Share your advanced PureBasic knowledge/code with the community.
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Parse zip file without using a library

Post by Rings »

Code: Select all

Structure typZipLocalFileHead ; 30 bytes
    zlfhSignature.l; As Long ' 0x04034B50
    zlfhVersion.w; As Integer
    zlfhBitFlag.w; As Integer
    zlfhCompression.w; As Integer
    zlfhModFileTime.w; As Integer
    zlfhModFileData.w; As Integer
    zlfhCRC.l; As Long
    zlfhCompressedSize.l; As Long
    zlfhUncompressedSize.l; As Long
    zlfhFileNameLength.w; As Integer
    zlfhExtraFieldLength.w; As Integer
EndStructure

Procedure ListZipFile(Filename.s)
  ReadHead.typZipLocalFileHead
 FF=ReadFile(#PB_Any,Filename)
 If FF
  again:
  ReadHead\zlfhSignature= ReadLong(ff)
  If ReadHead\zlfhSignature=$4034B50
   ;Debug "valid Zip File!"
   FileSeek(FF,Loc(ff)-4)
   ;Debug Loc(FF)
     
   Laenge = ReadData(FF, @ReadHead, SizeOf(ReadHead))
   ;Debug Loc(FF)
     
   With ReadHead
     ; Get the file name
     If \zlfhFileNameLength<>0  
      FileString.s = Space(\zlfhFileNameLength)
      ;Debug Loc(FF)
      Laenge = ReadData(FF, @FileString, \zlfhFileNameLength)
      ;Debug Loc(FF)
      Debug Filestring
     EndIf
     Debug"  Compressed="  + Str(\zlfhCompressedSize) + " UnCompressed="  + Str(\zlfhUnCompressedSize)
     ;Debug \zlfhExtraFieldLength
     ;Debug \zlfhBitFlag
     
     ; Work out how much extra Data To skip over
     SeekSize = \zlfhCompressedSize
     If \zlfhExtraFieldLength
      SeekSize + \zlfhExtraFieldLength
     EndIf
     If (\zlfhBitFlag & $4) 
      SeekSize  + 12
     EndIf
     
     ;Debug Seeksize
   
   EndWith 
   
   ;Seek To Next record
   Seeksize + Loc(FF)
   ;Debug Seeksize
   FileSeek(FF,Seeksize)
   ; Increment file count
   Filecount + 1
   Goto again 
  
  Else
   Debug "no more entries in ZIP"
  EndIf
  Debug Str(Filecount) + " in ZipFile"
  
  CloseFile(FF)
 EndIf

EndProcedure

FileName.s= "c:\B0712021_Botek_Werk3_HMI.zip"
ListZipFile(FileName) 
changed code to open file readonly
Last edited by Rings on Fri Jul 25, 2008 1:39 pm, edited 3 times in total.
SPAMINATOR NR.1
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Very nice. :)

It always displays a 'no valid ZIP' right at the end though! Ah, I see why; easily fixed.

Thanks.
I may look like a mule, but I'm not a complete ass.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Parse zip file without using a library

Post by PB »

Thanks for translating this Visual Basic code, but it doesn't seem to work yet?
At least not with any zip files that I tested it with. I get no debug output at all.
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Re: Parse zip file without using a library

Post by Rings »

PB wrote:Thanks for translating this Visual Basic code, but it doesn't seem to work yet?
At least not with any zip files that I tested it with. I get no debug output at all.
what would you espect from a quick VB port from me ?
:lol:

anyway, can you post the zipfiles that did not work ?
(mine here works okay)
SPAMINATOR NR.1
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Yes works fine here on zips created by WinZip 8.1 and IZarc.
I may look like a mule, but I'm not a complete ass.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> can you post the zipfiles that did not work ?

Here's one: http://www.sendspace.com/file/fh0ewy
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

debugger wrote :
NViewLib/
Compressed=0 UnCompressed=0
NViewLib/NViewLib.dll
Compressed=132009 UnCompressed=265216
NViewLib/NViewLib.rtf
Compressed=4540 UnCompressed=18723
no valid ZIP
3 in ZipFile
seems okay, one directory and 2 files
SPAMINATOR NR.1
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Ah, I worked it out. If the zip file is marked as ReadOnly, it won't work. Try it. :)
milan1612
Addict
Addict
Posts: 894
Joined: Thu Apr 05, 2007 12:15 am
Location: Nuremberg, Germany
Contact:

Post by milan1612 »

PB wrote:Ah, I worked it out. If the zip file is marked as ReadOnly, it won't work. Try it. :)
That's because Rings used OpenFile instead of ReadFile... :wink:
Windows 7 & PureBasic 4.4
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> That's because Rings used OpenFile instead of ReadFile

Eureka! :) I changed it to ReadFile and it works perfectly now.
(Well, except that he also uses Goto too! :twisted: ).

But seriously: thank you, Rings, for porting the Visual Basic code.
User avatar
bobobo
Enthusiast
Enthusiast
Posts: 206
Joined: Mon Jun 09, 2003 8:30 am

Post by bobobo »

Everybody DO use GOTO .. (if loops are used)
look at Your pb's ASM output and search for JMP.

so what ?
사십 둘 .
User avatar
Rings
Moderator
Moderator
Posts: 1435
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

PB wrote:(Well, except that he also uses Goto too! :twisted: ).
what wrong with the native equivalent of the
JMP (CPU's instruction set) Command :wink:
SPAMINATOR NR.1
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

The Goto thing was a joke. :) But since there was a reaction, how could the
code be modified NOT to use it, since so many people say that any code can
be written without Goto if they really wanted to. To those people: show me.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Code: Select all

Structure typZipLocalFileHead ; 30 bytes 
    zlfhSignature.l; As Long ' 0x04034B50 
    zlfhVersion.w; As Integer 
    zlfhBitFlag.w; As Integer 
    zlfhCompression.w; As Integer 
    zlfhModFileTime.w; As Integer 
    zlfhModFileData.w; As Integer 
    zlfhCRC.l; As Long 
    zlfhCompressedSize.l; As Long 
    zlfhUncompressedSize.l; As Long 
    zlfhFileNameLength.w; As Integer 
    zlfhExtraFieldLength.w; As Integer 
EndStructure 

Procedure ListZipFile(Filename.s) 
  ReadHead.typZipLocalFileHead 
 FF=ReadFile(#PB_Any,Filename) 
 If FF 
  Repeat
    ReadHead\zlfhSignature= ReadLong(ff) 
    If ReadHead\zlfhSignature=$4034B50 
      ;Debug "valid Zip File!" 
      FileSeek(FF,Loc(ff)-4) 
      ;Debug Loc(FF) 
      
      Laenge = ReadData(FF, @ReadHead, SizeOf(ReadHead)) 
      ;Debug Loc(FF) 
      
      With ReadHead 
        ; Get the file name 
        If \zlfhFileNameLength<>0  
          FileString.s = Space(\zlfhFileNameLength) 
          ;Debug Loc(FF) 
          Laenge = ReadData(FF, @FileString, \zlfhFileNameLength) 
          ;Debug Loc(FF) 
          Debug Filestring 
        EndIf 
        Debug"  Compressed="  + Str(\zlfhCompressedSize) + " UnCompressed="  + Str(\zlfhUnCompressedSize) 
        ;Debug \zlfhExtraFieldLength 
        ;Debug \zlfhBitFlag 
      
        ; Work out how much extra Data To skip over 
        SeekSize = \zlfhCompressedSize 
        If \zlfhExtraFieldLength 
          SeekSize + \zlfhExtraFieldLength 
        EndIf 
        If (\zlfhBitFlag & $4) 
          SeekSize  + 12 
        EndIf 
      
        ;Debug Seeksize 
    
      EndWith 
    
      ;Seek To Next record 
        Seeksize + Loc(FF) 
      ;Debug Seeksize 
      FileSeek(FF,Seeksize) 
      ; Increment file count 
      Filecount + 1 
    Else 
      If fileCount = 0
        Debug "no valid ZIP" 
      EndIf
      quitLoop = 1
    EndIf 
  Until quitLoop
  Debug Str(Filecount) + " in ZipFile" 
  
  CloseFile(FF) 
 EndIf 

EndProcedure 

FileName.s= "arrayClass.zip" 
ListZipFile(FileName) 
I may look like a mule, but I'm not a complete ass.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

:)
Post Reply