Page 6 of 40
Posted: Tue Mar 21, 2006 3:45 pm
by gnozal
webbmeister wrote:Found the zip.pb example at last.
Using zip.pb (Num 3) on PB4B7 i get the following error message when I try to compile.....
[COMPILER] Line 34: 'Structure' or 'Interface' already declared: tm_date
any ideas?
If it's already declared, just inactivate the lines.
Code: Select all
; Structure tm_date
; tm_sec.l; /* seconds after the minute - [0,59] */
; tm_min.l; /* minutes after the hour - [0,59] */
; tm_hour.l; /* hours since midnight - [0,23] */
; tm_mday.l; /* day of the month - [1,31] */
; tm_mon.l; /* months since January - [0,11] */
; tm_year.l; /* years - [1980..2044] */
; EndStructure
Posted: Wed Mar 22, 2006 11:44 am
by webbmeister
Where do I place the dll and lib files for this?
Posted: Wed Mar 22, 2006 5:45 pm
by webbmeister
Look folks, you will have to bear with me on this. Im not a beginner as far as general programming technique is concerned, but in terms of using libs & dlls etc and where to put them, I am a big clueless.
What I want to do is ZIP c:\test.txt to c:\test.zip. I am using version 4 beta 7. A simple working example would be great + which lib files / dlls do I need to place where.
I know it's a lot to ask

Posted: Wed Mar 22, 2006 6:25 pm
by gnozal
webbmeister wrote:Look folks, you will have to bear with me on this. Im not a beginner as far as general programming technique is concerned, but in terms of using libs & dlls etc and where to put them, I am a big clueless.
What I want to do is ZIP c:\test.txt to c:\test.zip. I am using version 4 beta 7. A simple working example would be great + which lib files / dlls do I need to place where.
I know it's a lot to ask

DLL in the same directory than the EXE
Libraries in %Purebasic%\PureLibraries\UserLibraries
Dos Date to PBDate
Posted: Wed Mar 22, 2006 9:23 pm
by PAMKKKKK
Hi gnozal!
I puzzled a bit arround the DOS Formated Date in the PureZIP_GetFileInfo Function.
I found some hints in the WinAPI-Help for the function DosDateTimeToFileTime_().
Here is my solution in pure PureB (only tested on WinXP !):
Code: Select all
ArchiveFileName.s = "c:\temp\test.zip"
Procedure.l DosDateToPBdate(dosDate.l)
; Converts a Zip-Dos-Date to PureBasic-Date
; The dosdate count only every 2 second. So you must do: second * 2
; Format is: %hh:%ii:%ss
TimeDos.s = Str(dosDate>>11&%11111) +":" + Str(dosDate>>5&%111111) +":" + Str(dosDate&%11111 * 2)
; The dosdate beginns to count from 01.January.1980. So you must add 1980 to the Year
; DateDos.s = Format is the German dateformat : %dd.%mm.%yyyy
DateDos.s = Str(dosDate>>16&%11111) +"." + Str(dosDate>>21&%1111) +"." + Str(dosDate>>25&%1111111 + 1980)
; Parse The Date and Time to System Date
ProcedureReturn ParseDate("%dd.%mm.%yyyy %hh:%ii:%ss", DateDos + " " + TimeDos)
EndProcedure
FileInfo.PureZIP_FileInfo
For FileNumberInArchive = 0 To PureZIP_GetFileCount(ArchiveFileName.s)
PureZIP_GetFileInfo(ArchiveFileName.s, FileNumberInArchive, @FileInfo)
Debug FileInfo\Version ; version made by
Debug FileInfo\VersionNeeded ; version needed to extract
Debug FileInfo\flag ; general purpose bit Flag
Debug FileInfo\CompressionMethod ; compression method
; last mod file date (in Dos format)
Debug FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss",DosDateToPBdate(FileInfo\dosDate))
Debug FileInfo\Crc32 ; crc-32
Debug FileInfo\CompressedSize ; compressed size
Debug FileInfo\unCompressedSize ; uncompressed size
Debug FileInfo\SizeFilename ; filename length
Debug FileInfo\SizeFileExtra ; extra field length
Debug FileInfo\SizeFileComment ; file comment length
Debug FileInfo\DiskNumStart ; disk number start
Debug FileInfo\internal_fa ; internal file attributes
Debug FileInfo\external_fa ; external file attributes
; The month in tm_date structur is month -1 for compatible reasons !!
; See: http://www.purebasic.fr/english/viewtopic.php?p=115673#115673
; tm_date (Date)
Debug Str(FileInfo\tmu_date\tm_mday)+"."+Str(FileInfo\tmu_date\tm_mon)+"."+Str(FileInfo\tmu_date\tm_year)
; tm_date (Time)
Debug Str(FileInfo\tmu_date\tm_hour)+":"+Str(FileInfo\tmu_date\tm_min)+":"+Str(FileInfo\tmu_date\tm_sec)
Debug FileInfo\FileName ; filename
Debug "-------------------------------------------------------"
Next
Please do this code in your Helpfile as an example for using the PureZIP_GetFileInfo()
Re: Dos Date to PBDate
Posted: Thu Mar 23, 2006 9:05 am
by gnozal
PAMKKKKK wrote:Please do this code in your Helpfile as an example for using the PureZIP_GetFileInfo()
Thanks.
For the next release.
Many Thanks
Posted: Thu Mar 23, 2006 12:53 pm
by cabaptista
Very good library. Thanks for sharing it with us.
Just a thing: It is possible to add a parameter to AddFile(s) Function(s) telling what is the compreesion rate that we want to compress files ?
Re: Many Thanks
Posted: Thu Mar 23, 2006 1:57 pm
by gnozal
cabaptista wrote:Very good library. Thanks for sharing it with us.
Just a thing: It is possible to add a parameter to AddFile(s) Function(s) telling what is the compreesion rate that we want to compress files ?
It's allways the maximum compression rate (method Z_DEFLATED with Z_BEST_COMPRESSION).
Posted: Thu Mar 23, 2006 4:57 pm
by cabaptista
Ok gnozal,
Thanks for the info about compression rate.
But my question is:
Why don´t you let us choose which compression rate we want ?
Like in WinRAR when we add files, we can choose if we want to compress in BEST, NORMAL, ...
This could be a extra optional parameter in AddFile(s) Function(s).
If you can managed that, i will start to make an application to use your LIB.

Posted: Thu Mar 23, 2006 5:27 pm
by gnozal
cabaptista wrote:Why don´t you let us choose which compression rate we want ?
It's not very usefull : not much speed difference between NORMAL and BEST, if that's your concern. Why do you need it ?
Posted: Thu Mar 23, 2006 6:49 pm
by cabaptista
Well, check this image from a ZIP application for instance.
http://pwp.netcabo.pt/cesar-baptista/images/ZipAddFiles.jpg
They use the compression method.
I would like to use this in the application i want to do with your LIB.
By the way, what about a SFX archive function ?
That would be nice, also.
If it could be done, of course.

Posted: Thu Mar 23, 2006 10:26 pm
by PAMKKKKK
@cabaptista
I really agree with gnozal that the kompression strenght an acutual Computer dosn´t itch.
You have 2choices for the User
Kompression or no compression.
if you want, make al list box with the following Picks:
Normal (is with compression)
Fastest (is witout compression)
Best (is with best compression. )
by the way, here my DosDate back and forward solution:
Code: Select all
Procedure.l DosDateToPBdate(dosDate.l)
; Converts a Zip-Dos-Date to PureBasic-Date
; The dosdate count only every 2 second. So you must do: second * 2
; The dosdate beginns to count from 01.January.1980. So you must add 1980 to the Year
ProcedureReturn Date(dosDate>>25&127 + 1980,dosDate>>21&15,dosDate>>16&31,dosDate>>11&31,dosDate>>5&63,dosDate&31 * 2)
EndProcedure
Procedure.l PBdateToDosDate(PBdate.l)
DosYear = Year(PBdate)
; Dosdate can only between 1.1.1980 and 31.12.2107
If DosYear < 1980 Or DosYear > 2107
ProcedureReturn 0
EndIf
DosYear = (DosYear-1980)<<25
DosMonth = Month(PBdate)<<21
DosDay = Day(PBdate)<<16
DosHour = Hour(PBdate)<<11
DosMinute = Minute(PBdate)<<5
; Dos Time Ticks only every 2. second
DosSecond = Second(PBdate)/2
ProcedureReturn DosYear + DosMonth + DosDay + DosHour + DosMinute + DosSecond
EndProcedure
; Lets Test ......
Debug FormatDate("%dd.%mm.%yyyy %hh:%ii:%ss",DosDateToPBdate(PBdateToDosDate(Date())))
Posted: Thu Mar 23, 2006 10:44 pm
by cabaptista
Ok,
I agree with you PAMKKKKK and i might have a combo box for user to choose from Fastest, Normal and Best compression method.
But then, when i'm compressing the files i've to tell the application which method to use (by default, compresson is always made with Best says Gnozal), so i must have a optional parameter to choose from.
Do you understand ?
Posted: Fri Mar 24, 2006 10:33 am
by gnozal
cabaptista wrote:By the way, what about a SFX archive function ?
That would be nice, also.
If it could be done, of course.

A SFX is only an archive that opens itself : it's easy to do. I've done it for my LIB installer (it's a ZIP SFX)
http://www.purebasic.fr/english/viewtopic.php?t=18514. Just copy SFXstub + ZIParchive = SFXZIP (in the SFXstub is the code to open itself, like any other archive : If PureZIP_Archive_Read(GetFullExePath()) etc... ).
Posted: Sat Mar 25, 2006 11:53 am
by PAMKKKKK

I dont remark that gnozal hasn´t made any choice to change compression mode......
If you read the explanation for the Zipfile you see Zipfiles are very easy to made. (i done it yesterday in a quickhack)
Read the
appnote-xxxxxxxxx-pk.zip at:
ftp://ftp.info-zip.org/pub/infozip/doc and Code youre own ZIPfiles
Here is my solution of making Zipfiles without compression.
NOT TESTED VERY WELL !! only tested on WinXP.
Code: Select all
; example to make (uncompressed) Zipfiles
; For ZIP-Documention see ftp://ftp.info-zip.org/pub/infozip/doc (the appnote-pk.txt)
; author PAMKKKKK 25.March.2006
; PB 3.93
Structure ZipFileHeader
exV.w ;Version needed To extract 2 bytes
gpbFl.w ;general purpose bit flag 2 bytes
cM.w ;compression method 2 bytes
lMod.l ;last mod File time 2 bytes last mod File Date 2 bytes
Crc32.l ;crc-32 4 bytes
cSz.l ;compressed size 4 bytes
uncSz.l ;uncompressed size 4 bytes
Flen.w ;FileName length 2 bytes
extra.w ;extra field length 2 bytes
lenComnt.w ; File comment length 2 bytes
Disk.w ; disk number start 2 bytes
inFAttr.w ; internal File attributes 2 bytes
exFAttr.l ; external File attributes 4 bytes
Offs.l ; relative offset of local header 4 bytes
Comment.s; File comment (variable size)
Fname.s ;filename (variable size)
Fextra.s ;extra field (variable size)
OFilename.s ; Original Filename
EndStructure
NewList LocalFile.ZipFileHeader()
; WIN-API !!!!!!
Procedure.l FileDateToDosDate(File.s)
; Converts the last writetime to a Dos-Formated Time
; THE TIME CAN BE INCORRECT, IN CONTRYS WITH SUMMER AND WINTER TIME !!!
Handle=CreateFile_(@File.s,#GENERIC_READ,#FILE_SHARE_READ|#FILE_SHARE_WRITE,0,#OPEN_EXISTING,#FILE_ATTRIBUTE_NORMAL,0)
If Handle<>#INVALID_HANDLE_VALUE
GetFileTime_(Handle,0,0,FT.FILETIME) ; Last Writetime
Else
ProcedureReturn -1 ; Error File dosnt exist or not accesable
EndIf
FileTimeToDosDateTime_(FT,@FatDate.w,@FatTime.w)
CloseHandle_(Handle) ; Close the File
ProcedureReturn FatDate<<16 + FatTime
EndProcedure
;-Add_to_Locallist***********************************************
Procedure Add_to_Locallist(FileToAdd.s,Flags)
; Store Path relative or not...
If Flags&%1
FileName.s = FileToAdd
Else
FileName.s = GetFilePart(FileToAdd)
EndIf
; Filling LocalList
AddElement(LocalFile())
;WriteLong($04034B50) ; local File header signature 4 bytes (0x04034b50)
LocalFile()\exV = $000A ; Hardcoded Version need to be extract
LocalFile()\gpbFl = $0000 ; Hardcoded Flags
LocalFile()\cM = $0000 ; Hardcoded compression methode, cause no compression used yet!
LocalFile()\lMod = FileDateToDosDate(FileToAdd) ; Last mod FileDat in Dos Format (big-endian)
;LocalFile()\Crc32 = CRC32FileFingerprint(FileToAdd) CRC calculation made in Make_Zip (for performance)
LocalFile()\cSz = FileSize(FileToAdd) ; We dont compress so the Filesize is = compressionsize
LocalFile()\uncSz = FileSize(FileToAdd) ; simple the Uncompressed Filesize
LocalFile()\Flen = Len(FileName) ; length of the Filename
LocalFile()\extra = 0 ; Not used yet !
LocalFile()\lenComnt = 0 ; Not used yet ! ; File comment length 2 bytes
LocalFile()\Disk = 0 ; Not used yet ! ; disk number start 2 bytes
LocalFile()\inFAttr = 0 ; Not used yet ! ; internal File attributes 2 bytes
LocalFile()\exFAttr = 0 ; Not used yet ! ; external File attributes 4 bytes
;Offs.l ; Not used here ! relative offset is set by file writing.
LocalFile()\Comment = "" ; Not used yet ! ; File comment (variable size)
LocalFile()\Fname = FileName ; Path relative or not was made at the start of these Procedure
LocalFile()\Fextra = "" ; Not used yet !
LocalFile()\OFilename = FileToAdd ; Original File Path where the File is taken from
EndProcedure
;-Add_End_of_central_dir_record ********************************************
Procedure Add_End_of_central_dir_record(ZipFile.s,DirSz.l,headOffset.l)
ResetList(LocalFile())
HFile = OpenFile(#PB_Any, ZipFile)
If HFile
FileSeek(Lof()) ; append the header
WriteLong($06054B50) ;End of central dir signature 4 bytes (0x06054b50)
WriteWord(0) ;number of this Disk 2 bytes
WriteWord(0) ;number of the Disk with the start of the central Directory 2 bytes
WriteWord(CountList(LocalFile())) ;total number of entries in the central dir on this Disk 2 bytes
WriteWord(CountList(LocalFile())) ;total number of entries in the central dir 2 bytes
WriteLong(DirSz) ;size of the central Directory 4 bytes
WriteLong(headOffset) ;offset of start of central Directory with respect To the starting Disk number 4 bytes
WriteWord(0) ;ZipFile Comment length 2 bytes
WriteString("") ;ZipFile comment (variable size)
CloseFile(HFile)
EndIf
EndProcedure
;-Add_Central_Directory_Structure ********************************************
Procedure Add_Central_Directory_Structure(ZipFile.s)
ResetList(LocalFile())
HFile = OpenFile(#PB_Any, ZipFile)
If HFile
FileSeek(Lof()) ; append the header
headOffset = Lof()
While NextElement(LocalFile())
WriteLong($02014B50) ; central File header signature 4 bytes (0x02014b50)
WriteWord($0014) ;Version made by 2 bytes
WriteWord(LocalFile()\exV)
WriteWord(LocalFile()\gpbFl)
WriteWord(LocalFile()\cM)
WriteLong(LocalFile()\lMod)
WriteLong(LocalFile()\Crc32)
WriteLong(LocalFile()\cSz)
WriteLong(LocalFile()\uncSz)
WriteWord(LocalFile()\Flen)
WriteWord(LocalFile()\extra)
WriteWord(LocalFile()\lenComnt)
WriteWord(LocalFile()\Disk)
WriteWord(LocalFile()\inFAttr)
WriteLong($00000020);LocalFile()\exFAttr)
WriteLong(LocalFile()\Offs) ; relative offset of local header 4 bytes
WriteString(LocalFile()\Fname)
WriteString(LocalFile()\Fextra); extra field (variable size)
WriteString(LocalFile()\Comment); File comment (variable size)
Wend
DirSz.l = Lof() - headOffset
CloseFile(HFile)
EndIf
Add_End_of_central_dir_record(ZipFile,DirSz,headOffset)
EndProcedure
;- Make_Zip **************************************************
Procedure Make_Zip(ZipFile.s)
ResetList(LocalFile())
HFile = CreateFile(#PB_Any, ZipFile)
If HFile
While NextElement(LocalFile())
LocalFile()\Offs = Lof()
WriteLong($04034B50) ; local File header signature 4 bytes (0x04034b50)
WriteWord(LocalFile()\exV)
WriteWord(LocalFile()\gpbFl)
WriteWord(LocalFile()\cM)
WriteLong(LocalFile()\lMod)
; open File and do CRC32
FileSz=FileSize(LocalFile()\OFilename)
If FileSz
FileBuffer = AllocateMemory(FileSz); Buffer error dosn´t catch !
If FileBuffer
HAddFile = ReadFile(#PB_Any,LocalFile()\OFilename)
If HAddFile
L0 = ReadData(FileBuffer, FileSz) ; Buffer error dosn´t catch !
LocalFile()\Crc32 = CRC32Fingerprint(FileBuffer, FileSz)
CloseFile(HAddFile) ;closing File, File is in Buffer now
EndIf
EndIf
EndIf
WriteLong(LocalFile()\Crc32)
; compression is not used yet!
;if you want to compress do it here with the FileBuffer !!
WriteLong(LocalFile()\cSz)
WriteLong(LocalFile()\uncSz)
WriteWord(LocalFile()\Flen)
WriteWord(LocalFile()\extra)
WriteString(LocalFile()\Fname)
WriteString(LocalFile()\Fextra)
; writing File from Buffer to Zipfile
UseFile(HFile)
FileSeek(Lof()) ; append mode
WriteData( FileBuffer, FileSz)
FreeMemory(FileBuffer) ; clean up ;-)
Wend
CloseFile(HFile)
EndIf
; Adding the global header
Add_Central_Directory_Structure(ZipFile)
EndProcedure
; **************************************************
; MAIN
; **************************************************
; First add the files to the list
; Flag is only used for pathrelative or not at this time
; 0 = store filename only, 1 = store absolut path
Add_to_Locallist("C:\temp\Text1.txt",0)
Add_to_Locallist("C:\temp\Text2.txt",0)
Add_to_Locallist("C:\temp\Text3.txt",0)
Add_to_Locallist("C:\Windows\notepad.exe",0)
Add_to_Locallist("C:\temp\example.pdf",0)
; if the List is ready make the Zipfile
Make_Zip("C:\temp\ziptest.zip")
; Note
; at this time compression, diskspanning or other is not supported !!!
; if you want to compress see Note in Procedure Make_Zip()