Page 1 of 2
Parse zip file without using a library
Posted: Fri Jul 25, 2008 8:54 am
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
Posted: Fri Jul 25, 2008 10:17 am
by srod
Very nice.
It always displays a 'no valid ZIP' right at the end though! Ah, I see why; easily fixed.
Thanks.
Re: Parse zip file without using a library
Posted: Fri Jul 25, 2008 10:44 am
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.
Re: Parse zip file without using a library
Posted: Fri Jul 25, 2008 10:53 am
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 ?
anyway, can you post the zipfiles that did not work ?
(mine here works okay)
Posted: Fri Jul 25, 2008 11:06 am
by srod
Yes works fine here on zips created by WinZip 8.1 and IZarc.
Posted: Fri Jul 25, 2008 12:05 pm
by PB
> can you post the zipfiles that did not work ?
Here's one:
http://www.sendspace.com/file/fh0ewy
Posted: Fri Jul 25, 2008 1:04 pm
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
Posted: Fri Jul 25, 2008 1:34 pm
by PB
Ah, I worked it out. If the zip file is marked as ReadOnly, it won't work. Try it.

Posted: Fri Jul 25, 2008 1:37 pm
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...

Posted: Fri Jul 25, 2008 1:46 pm
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!

).
But seriously: thank you, Rings, for porting the Visual Basic code.
Posted: Fri Jul 25, 2008 2:00 pm
by bobobo
Everybody DO use GOTO .. (if loops are used)
look at Your pb's ASM output and search for JMP.
so what ?
Posted: Fri Jul 25, 2008 2:01 pm
by Rings
PB wrote:(Well, except that he also uses Goto too!

).
what wrong with the native equivalent of the
JMP (CPU's instruction set) Command

Posted: Fri Jul 25, 2008 2:11 pm
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.
Posted: Fri Jul 25, 2008 2:22 pm
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)
Posted: Fri Jul 25, 2008 2:45 pm
by PB