Zlib almost working (zip utility)

Blitz3D Forums/Blitz3D Userlibs/Zlib almost working (zip utility)

JoshK(Posted 2004) [#1]
http://www.zlib.net

I need help getting this zip routine to work. Here is the usage I envision:
f=ReadFile("somefile.zip")
Repeat
file$=NextZipFile(f)
If file$="" Exit
bank=ExtractZipFile(f,file$)
Forever

The only zlib function I call is uncompress, and I get an unexplained crash. Can anyone help? This would be a very useful routine to have.

Modified code from the archive, I think:
Function NextZipFile$(f)
If Eof(f) Return
headersig=ReadInt(f)
Select headersig

	Case $04034b50  ; this is a file  (0x04034b50) = 67324752
		version = ReadByte(f) + 256*(ReadByte(f))
		generalpurpose = ReadByte(f) + 256*(ReadByte(f))
		compmethod = ReadByte(f) + 256*(ReadByte(f))
		modtime = ReadByte(f) + (256 * ReadByte(f))
		moddate = ReadByte(f) + (256 * ReadByte(f))
		crc32 = ReadInt(f)
		compsize = ReadInt(f)
		uncompsize = ReadInt(f)
		fnlen = ReadByte(f) + 256*(ReadByte(f))
		extrafieldlen = ReadByte(f) + 256*(ReadByte(f))
	
		fn$ = ""
		For i = 1 To fnlen
			fn = fn + Chr(ReadByte(f))
			Next
		
		; skip file data and extra field data
		SeekFile f, FilePos(f)+compsize+extrafieldlen
	
		If generalpurpose And 8
			; If generalpurpose bit 3 is set, then CRC, compsize and uncompsize are incorrect in the header...
			crc32 = ReadByte(f)+ReadByte(f)+ReadByte(f)+ReadByte(f)
			compsize = ReadInt(f)
			uncompsize = ReadInt(f)
			EndIf
		
	Case $02014b50; this is a central directory record  (0x02014b50) = 33639248
		versionmadeby = ReadByte(f) + 256*(ReadByte(f))
		version = ReadByte(f) + 256*(ReadByte(f))
		generalpurpose = ReadByte(f) + 256*(ReadByte(f))
		compmethod = ReadByte(f) + 256*(ReadByte(f))
		modtime = ReadByte(f) + (256 * ReadByte(f))
		moddate = ReadByte(f) + (256 * ReadByte(f))
		crc32 = ReadInt(f)
		compsize = ReadInt(f)
		uncompsize = ReadInt(f)
		fnlen = ReadByte(f) + 256*(ReadByte(f))
		extrafieldlen = ReadByte(f) + 256*(ReadByte(f))
		commentlen = ReadByte(f) + 256*(ReadByte(f))
		disknumberstart = ReadByte(f) + 256*(ReadByte(f))
		internalfileattributes = ReadByte(f) + 256*(ReadByte(f))
		externalfileattributes = ReadInt(f)
		relativeoffsetoflocalheader = ReadInt(f)
			
		; skip file data and extra field data
		SeekFile f, FilePos(f)+compsize+extrafieldlen
			
		endofcentraldirsignature     = ReadInt(f) ; (0x06054b50) = 101010256
		numberofthisdisk             = ReadByte(f) + 256*(ReadByte(f))
		numberofdiskwithstart		 = ReadByte(f) + 256*(ReadByte(f))
		totalentriesincentraldirondisk = ReadByte(f) + 256*(ReadByte(f))
		totalentriesincentraldir       = ReadByte(f) + 256*(ReadByte(f))
		sizeofthecentraldir   = ReadInt(f)
		offsetofcentraldir    = ReadInt(f)
		commentlen        = ReadByte(f) + 256*(ReadByte(f))
		comment$ = ""
		For i = 1 To commentlen         
			comment = comment + Chr(ReadByte(f))
			Next

	End Select
Return fn
End Function

And the extract function:
Function ExtractZipFile(f,file$)
pos=FilePos(f)
SeekFile f,0
While Not Eof(f)
	headersig=ReadInt(f)
	Select headersig
	
		Case $04034b50  ; this is a file  (0x04034b50) = 67324752
			
			version = ReadByte(f) + 256*(ReadByte(f))
			generalpurpose = ReadByte(f) + 256*(ReadByte(f))
			compmethod = ReadByte(f) + 256*(ReadByte(f))
			modtime = ReadByte(f) + (256 * ReadByte(f))
			moddate = ReadByte(f) + (256 * ReadByte(f))
			crc32 = ReadInt(f)
			compsize = ReadInt(f)
			uncompsize = ReadInt(f)
			fnlen = ReadByte(f) + 256*(ReadByte(f))
			extrafieldlen = ReadByte(f) + 256*(ReadByte(f))
			
			fn$ = ""
			For i = 1 To fnlen
				fn = fn + Chr(ReadByte(f))
				Next
			
			; skip extra field data
			SeekFile f,FilePos(f)+extrafieldlen
			
			If Lower(fn)=Lower(file)
				sourcebank=CreateBank(compsize)
				destbank=CreateBank(uncompsize)
				For n=0 To compsize-1
					PokeByte sourcebank,n,ReadByte(f)
					Next
				SeekFile f,pos
				If zlib_Uncompress(destbank,uncompsize,sourcebank,compsize)
					FreeBank sourcebank
					Return destbank
					Else
					FreeBank sourcebank
					FreeBank destbank
					Return
					EndIf
				EndIf
			
			; skip file data and extra field data
			SeekFile f,FilePos(f)+compsize
		
			If generalpurpose And 8
				; If generalpurpose bit 3 is set, then CRC, compsize and uncompsize are incorrect in the header...
				crc32 = ReadByte(f)+ReadByte(f)+ReadByte(f)+ReadByte(f)
				compsize = ReadInt(f)
				uncompsize = ReadInt(f)
				EndIf
			
		Case $02014b50; this is a central directory record  (0x02014b50) = 33639248
			versionmadeby = ReadByte(f) + 256*(ReadByte(f))
			version = ReadByte(f) + 256*(ReadByte(f))
			generalpurpose = ReadByte(f) + 256*(ReadByte(f))
			compmethod = ReadByte(f) + 256*(ReadByte(f))
			modtime = ReadByte(f) + (256 * ReadByte(f))
			moddate = ReadByte(f) + (256 * ReadByte(f))
			crc32 = ReadInt(f)
			compsize = ReadInt(f)
			uncompsize = ReadInt(f)
			fnlen = ReadByte(f) + 256*(ReadByte(f))
			extrafieldlen = ReadByte(f) + 256*(ReadByte(f))
			commentlen = ReadByte(f) + 256*(ReadByte(f))
			disknumberstart = ReadByte(f) + 256*(ReadByte(f))
			internalfileattributes = ReadByte(f) + 256*(ReadByte(f))
			externalfileattributes = ReadInt(f)
			relativeoffsetoflocalheader = ReadInt(f)
				
			; skip file data and extra field data
			SeekFile f, FilePos(f)+compsize+extrafieldlen
				
			endofcentraldirsignature     = ReadInt(f) ; (0x06054b50) = 101010256
			numberofthisdisk             = ReadByte(f) + 256*(ReadByte(f))
			numberofdiskwithstart		 = ReadByte(f) + 256*(ReadByte(f))
			totalentriesincentraldirondisk = ReadByte(f) + 256*(ReadByte(f))
			totalentriesincentraldir       = ReadByte(f) + 256*(ReadByte(f))
			sizeofthecentraldir   = ReadInt(f)
			offsetofcentraldir    = ReadInt(f)
			commentlen        = ReadByte(f) + 256*(ReadByte(f))
			comment$ = ""
			For i = 1 To commentlen         
				comment = comment + Chr(ReadByte(f))
				Next
		End Select
	Wend
SeekFile f,pos
End Function

Zlib.decls:
.lib "dlls\zlib1.dll"
zlib_Uncompress%(destination*,destinationlength%,source*,sourcelength%) : "uncompress"