Aktuelle Zeit: 23.10.2018 10:23

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 27 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste
Autor Nachricht
 Betreff des Beitrags: PipiFax-ZIP-Include [all OS]
BeitragVerfasst: 06.04.2011 12:20 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
Ich brauche des öfteren eine einfache Art eine Datei in ein Zip-File zu komprimieren (z.B. für die Backupfunktion meines History Viewers).
Seit 20.06.2011 kann man auch zip-Dateien entpacken.

Es gibt viele Dinge wie pureZIP von gnozal oder die minizip von ts-soft,
aber ich wollte etwas, das auch bei allen OS funktioniert (und keine library ist).

Update (29.12.2012)
Dateinamen werden korrekt GEzippt (Danke an ts-soft)

Update (30.04.2012)
Dateinamen mit Umlauten werden korrekt entzippt.
(Da ist das zib-Format ein wenig altbacken, ich fürchte die Zip-Routine produziert beim zippen von Umlautdateinamen auch falsche Namen.
Muss ich mal bei Gelegenheit abändern)

Update (29.04.2012)
Zip-Dateien mit Extrafields werden nun auch unterstützt (Fehler von DROOPY gemeldet).

Neu (20.06.2011)
Entzippen-Funktion hinzugefügt.

Herausgekommen ist das hier:
Code:
;/--------------
;| Pipifax Zip
;| Last modified: 29.12.2012
;|
;| Mini-Include to
;| create a zip file with just ONE file in it.
;| Extract zip files
;|
;| Should work with Win, Linux and MacOS
;|
;| (c)HeX0R 2012
;|
;/--------------

Structure z_stream
   *next_in;    /* next input byte */
   avail_in.l;  /* number of bytes available at next_in */
   total_in.l;  /* total nb of input bytes read so far */

   *next_out;   /* next output byte should be put there */
   avail_out.l; /* remaining free space at next_out */
   total_out.l; /* total nb of bytes output so far */

   *msg;        /* last error message, NULL if no error */
   *state;      /* not visible by applications */

   *zalloc;     /* used to allocate the internal state */
   *zfree;      /* used to free the internal state */
   *opaque;     /* private data object passed to zalloc and zfree */

   data_type.l; /* best guess about the data type: binary or text */
   adler.l;     /* adler32 value of the uncompressed data */
   reserved.l;  /* reserved for future use */
   CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
   Dummy.l
   CompilerEndIf
EndStructure

;All-OS compatible Import
;from jamirokwai [http://www.purebasic.fr/german/viewtopic.php?p=288981#p288981]
;{
CompilerSelect #PB_Compiler_OS
   CompilerCase #PB_OS_Windows
      ImportC "zlib.lib"
   CompilerCase #PB_OS_Linux
      ImportC #PB_Compiler_Home + "purelibraries/linux/libraries/zlib.a"
   CompilerCase #PB_OS_MacOS
      ImportC "/usr/lib/libz.dylib"     
   CompilerEndSelect
   compress2(*dest, *destLen, *source, sourceLen, level)
   uncompress(*a, *b, *c, d)
   inflateInit2_(*strm.z_stream, windowBits, *version, stream_size)
   inflate(*strm.z_stream, flush)
   inflateEnd(*strm.z_stream)
EndImport
;}

#Z_DEFAULT_COMPRESSION = -1
#Z_OK                  = 0
#Z_STREAM_END          = 1
#Z_FINISH              = 4

Structure _ZIP_Local_File_Header_
   signature.l ;0x04034b50
   VersionNeeded.w
   Generalflag.w
   Compressionmethod.w
   Last_modification.l
   CRC32.l
   Compressed_size.l
   Uncompressed_size.l
   Filename_length.w
   Extrafield_length.w
   *Filename
EndStructure

Structure _ZIP_Unicode_Path_Extra_Field_
   signature.w ;0x7075
   Size.w
   Version.b
   CRC32.l
   *FileName
EndStructure

Structure _ZIP_Data_Descriptor_
   signature.l ;0x08074b50
   CRC32.l
   Compressed_size.l
   Uncompressed_size.l
EndStructure

Structure _ZIP_Central_Directory_File_Header_
   signature.l ;0x02014b50
   madeby.w
   VersionNeeded.w
   Generalflag.w
   Compressionmethod.w
   Last_modification.l
   CRC32.l
   Compressed_size.l
   Uncompressed_size.l
   Filename_length.w
   Extrafield_length.w
   comment_length.w
   Disk_number_start.w
   Internal_file_attributes.w
   External_file_attributes.l
   offset_of_local_file_header.l
   *Filename
EndStructure

Structure _ZIP_End_of_central_directory_record_
   signature.l ;0x06054b50
   Number_of_this_disk.w
   Disk_Start.w
   Number_of_central_directory_records_on_disk.w
   Total_number_of_central_directory_records.w
   Size_of_central_directory.l
   Offset_of_start_of_central_directory.l
   filecomment_length.w
   *filecomment
EndStructure

Procedure UnixToMSDosDate(UnixDate)
   Protected Result, m
   
   m      = Year(UnixDate) - 1980
   Result | (m << 25)
   m      = Month(UnixDate)
   Result | (m << 21)
   m      = Day(UnixDate)
   Result | (m << 16)
   m      = Hour(UnixDate)
   Result | (m << 11)
   m      = Minute(UnixDate)
   Result | (m << 5)
   m      = Second(UnixDate) / 2
   Result | m
   
   ProcedureReturn Result
EndProcedure

Procedure MSDosDateToUnix(MSDos_Date)
   Protected Result, Y, M, D, H, Min, S
   
   Y      = 1980 + (MSDos_Date >> 25) & $7F
   M      = (MSDos_Date >> 21) & $0F
   D      = (MSDos_Date >> 16) & $1F
   H      = (MSDos_Date >> 11) & $1F
   Min    = (MSDos_Date >> 5) & $3F
   S      = (MSDos_Date & $1F) * 2
   Result = Date(Y, M, D, H, Min, S)
   
   ProcedureReturn Result
EndProcedure

Procedure CreateZipFile(FileToAdd.s, ZipFile.s)
   Protected i, j, k, l, Offset, Result, FID_Zip, FID_Orig, *B1, *B2
   Protected MSDos_Date
   Protected *ZLFH._ZIP_Local_File_Header_
   Protected *ZDD._ZIP_Data_Descriptor_ ;not used
   Protected *ZCDFH._ZIP_Central_Directory_File_Header_
   Protected *ZECDR._ZIP_End_of_central_directory_record_
   
   If FileSize(FileToAdd) > 0
      *ZLFH    = ?__ZIP_Local_File_Header_
      *ZDD     = ?__ZIP_Data_Descriptor_
      *ZCDFH   = ?__ZIP_Central_Directory_File_Header_
      *ZECDR   = ?__ZIP_End_of_central_directory_record_
      k        = CRC32FileFingerprint(FileToAdd)
      FID_Orig = ReadFile(#PB_Any, FileToAdd)
      If FID_Orig
         *B1 = AllocateMemory(Lof(FID_Orig))
         If *B1
            ReadData(FID_Orig, *B1, Lof(FID_Orig))
            i   = MemorySize(*B1)
            j   = i
            *B2 = AllocateMemory(i)
            If *B2
               If compress2(*B2, @i, *B1, j, #Z_DEFAULT_COMPRESSION) = #Z_OK
                  FID_Zip = CreateFile(#PB_Any, ZipFile)
                  If FID_Zip
                     l                       = StringByteLength(GetFilePart(FileToAdd), #PB_UTF8)
                     MSDos_Date              = UnixToMSDosDate(GetFileDate(FileToAdd, #PB_Date_Modified))
                     *ZLFH\Last_modification = MSDos_Date
                     *ZLFH\CRC32             = k
                     *ZLFH\Compressed_size   = i - 6
                     *ZLFH\Uncompressed_size = j
                     *ZLFH\Filename_length   = l
                     *ZLFH\Generalflag       = $800
                     WriteData(FID_Zip, *ZLFH, OffsetOf(_ZIP_Local_File_Header_\Filename))
                     WriteString(FID_Zip, GetFilePart(FileToAdd), #PB_UTF8)
                     WriteData(FID_Zip, *B2 + 2, i - 6)

                     Offset                          = Loc(FID_Zip)
                     *ZCDFH\External_file_attributes = GetFileAttributes(FileToAdd)
                     *ZCDFH\CRC32                    = k
                     *ZCDFH\Compressed_size          = i - 6
                     *ZCDFH\Uncompressed_size        = j
                     *ZCDFH\Generalflag              = $800
                     *ZCDFH\Filename_length          = l
                     *ZCDFH\Last_modification        = MSDos_Date
                     WriteData(FID_Zip, *ZCDFH, OffsetOf(_ZIP_Central_Directory_File_Header_\Filename))
                     WriteString(FID_Zip, GetFilePart(FileToAdd), #PB_UTF8)
                                    
                     *ZECDR\Size_of_central_directory            = OffsetOf(_ZIP_Central_Directory_File_Header_\Filename) + l
                     *ZECDR\Offset_of_start_of_central_directory = Offset
                     WriteData(FID_Zip, *ZECDR, OffsetOf(_ZIP_End_of_central_directory_record_\filecomment))
                     CloseFile(FID_Zip)
                     Result = #True
                  EndIf
               EndIf
               FreeMemory(*B2)
            EndIf
            FreeMemory(*B1)
         EndIf
         CloseFile(FID_Orig)
      EndIf
   EndIf
   
   ProcedureReturn Result
EndProcedure

Procedure ExtractZipFile(ZipFile.s, DestinationFolder.s)
   Protected i, j, Result, R, FID_Zip, FID_Orig, *B1, *B2, *B3._ZIP_Unicode_Path_Extra_Field_
   Protected FileName.s, PathAdd.s, Version.s, FileCount, FilesOK, *FileNameBuffer
   Protected ZLFH._ZIP_Local_File_Header_
   Protected STREAM.z_stream
   
   If FileSize(ZipFile) > OffsetOf(_ZIP_Local_File_Header_\Filename) And FileSize(DestinationFolder) = -2
      FID_Zip = ReadFile(#PB_Any, ZipFile)
      If FID_Zip
         Repeat
            R = 0
            ReadData(FID_Zip, @ZLFH, OffsetOf(_ZIP_Local_File_Header_\Filename))
            If ZLFH\signature = $04034b50
               FileName        = ""
               *FileNameBuffer = AllocateMemory(ZLFH\Filename_length + 2)
               ReadData(FID_Zip, *FileNameBuffer, ZLFH\Filename_length)
               If ZLFH\Generalflag & $800
                  FileName = PeekS(*FileNameBuffer, ZLFH\Filename_length, #PB_UTF8)
               Else
                  FileName = PeekS(*FileNameBuffer, ZLFH\Filename_length, #PB_Ascii)
               EndIf
               FreeMemory(*FileNameBuffer)
               If ZLFH\Extrafield_length
                  If *B3 = 0 Or MemorySize(*B3) < ZLFH\Extrafield_length
                     *B3 = ReAllocateMemory(*B3, ZLFH\Extrafield_length)
                  EndIf
                  ReadData(FID_Zip, *B3, ZLFH\Extrafield_length)
                  If *B3\signature = $7075
                     ;This filename is also in utf8 available
                     FileName = PeekS(*B3 + OffsetOf(_ZIP_Unicode_Path_Extra_Field_\FileName), (*B3\Size & $FFFF) - 5, #PB_UTF8)
                  EndIf
               EndIf
               Debug FileName
               PathAdd = ""
               For i = 1 To CountString(FileName, "/")
                  PathAdd + StringField(FileName, i, "/") + "/"
                  If FileSize(DestinationFolder + PathAdd) <> -2
                     CreateDirectory(DestinationFolder + PathAdd)
                  EndIf
               Next i
               If Right(FileName, 1) <> "/"
                  FileCount + 1
                  FID_Orig = CreateFile(#PB_Any, DestinationFolder + FileName)
                  If FID_Orig
                     If ZLFH\Uncompressed_size = 0
                        R = #True
                     ElseIf *B2 = 0 Or MemorySize(*B2) < ZLFH\Uncompressed_size
                        *B2 = ReAllocateMemory(*B2, ZLFH\Uncompressed_size)
                     EndIf
                     If *B2
                        If ZLFH\Uncompressed_size = ZLFH\Compressed_size
                           ;Not compressed!
                           R = #True
                           ReadData(FID_Zip, *B2, ZLFH\Uncompressed_size)
                           WriteData(FID_Orig, *B2, ZLFH\Uncompressed_size)
                        Else
                           If *B1 = 0 Or MemorySize(*B1) < ZLFH\Compressed_size
                              *B1 = ReAllocateMemory(*B1, ZLFH\Compressed_size)
                           EndIf
                           If *B1
                              Version = "1.2.5"
                              If inflateInit2_(@STREAM, -10, @Version, SizeOf(z_stream)) = #Z_OK
                                 STREAM\adler     = ZLFH\CRC32
                                 STREAM\next_in   = *B1
                                 STREAM\next_out  = *B2
                                 STREAM\avail_out = ZLFH\Uncompressed_size
                                 STREAM\avail_in  = ReadData(FID_Zip, *B1, ZLFH\Compressed_size)
                                 If inflate(@STREAM, #Z_FINISH) = #Z_STREAM_END
                                    If CRC32Fingerprint(*B2, ZLFH\UnCompressed_size) = ZLFH\CRC32 & $FFFFFFFF
                                       R = #True
                                       WriteData(FID_Orig, *B2, ZLFH\Uncompressed_size)
                                    EndIf
                                 EndIf
                                 inflateEnd(@STREAM)
                              EndIf
                           EndIf
                        EndIf
                     EndIf
                     CloseFile(FID_Orig)
                  EndIf
                  If R
                     SetFileDate(DestinationFolder + FileName, #PB_Date_Modified, MSDosDateToUnix(ZLFH\Last_modification))
                     FilesOK + 1
                  EndIf
               EndIf
            Else
               Break
            EndIf
         Until Eof(FID_Zip)
         CloseFile(FID_Zip)
      EndIf
   EndIf
   If *B1
      FreeMemory(*B1)
   EndIf
   If *B2
      FreeMemory(*B2)
   EndIf
   If *B3
      FreeMemory(*B3)
   EndIf
   
   If FileCount = FilesOK
      Result = #True
   EndIf
   ProcedureReturn Result
EndProcedure

DataSection
   __ZIP_Local_File_Header_:
   Data.l $04034b50
   Data.w $14, 0, 8
   Data.l 0, 0, 0, 0
   Data.w 0, 0
   __ZIP_Data_Descriptor_:
   Data.l $08074b50, 0, 0, 0
   __ZIP_Central_Directory_File_Header_:
   Data.l $02014b50
   Data.w $14, $14, 0, 8
   Data.l 0, 0, 0, 0
   Data.w 0, 0, 0, 0, 0
   Data.l 0, 0
   __ZIP_End_of_central_directory_record_:
   Data.l $06054b50
   Data.w 0, 0, 1, 1
   Data.l 0, 0
   Data.w 0
EndDataSection


Wer mehrere Dateien zippen möchte, oder gar ganze Verzeichnisse, darf das hier gerne mit dazubauen.

Gruß

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Zuletzt geändert von HeX0R am 29.12.2012 01:12, insgesamt 10-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: PipiFax-ZIP-Include [all OS]
BeitragVerfasst: 12.04.2011 21:05 
Offline

Registriert: 02.06.2008 16:10
Hi HeX0R,

funktioniert auf Mac OS X 10.6, wenn ich die Konstante #S_OK = 0 setze.
Was hat die denn sonst für einen Hintergrund bzw. Sinn?
Das erstellte Zip wird auch von Mac OS X wieder entpackt. Cool, danke!

Gruß
J.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: PipiFax-ZIP-Include [all OS]
BeitragVerfasst: 12.04.2011 21:16 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
HaHaHa,

ja o.k. keine Ahnung, warum ich da eine WinAPI-Konstante genommen habe,
vermutlich fand ich = 0 irreführend.

Ich verbessere das da oben gleich mal.

Und vielen Dank für die Bestätigung, dass es unter MacOS funktioniert!

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: PipiFax-ZIP-Include [all OS]
BeitragVerfasst: 13.04.2011 09:54 
Offline
Benutzeravatar

Registriert: 10.03.2005 14:01
Funktioniert prima bei mir. :allright:

Sowas würde ich mir auch für die umgekehrte Ausführung wünschen. Also nur simpel ein zipArchiv auspacken, nicht mehr.

_________________
:::: WIN 10 :: PB 5.31 :: (x86) ::::


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: PipiFax-ZIP-Include [all OS]
BeitragVerfasst: 13.04.2011 23:17 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
DrFalo hat geschrieben:
Sowas würde ich mir auch für die umgekehrte Ausführung wünschen. Also nur simpel ein zipArchiv auspacken, nicht mehr.


Das Problem dabei ist, dass ich dann auch gezippte Verzeichnisse unterstützen müsste,
weil ich ja nicht weiss, mit welchem zip der User die Funktion füttert.

Also "Problem" bedeutet hier:
Ich habe davon momentan keinen Nutzen und daher auch keine große Lust mich damit zu beschäftigen.

Der Source ist ja da und wartet nur darauf erweitert zu werden.

Oder:
vielleicht brauche ich es ja doch mal, oder mir ist langweilig und ich beschäftige mich mal wieder mit dem zip-Format,
oder PB macht endlich wahr, was vor Jahren schon angedeutet wurde, oder mir wächst ein Furunkel am *, oder...
;)

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: PipiFax-ZIP-Include [all OS]
BeitragVerfasst: 14.04.2011 00:16 
Offline
Benutzeravatar

Registriert: 10.03.2005 14:01
HeX0R hat geschrieben:
Oder:
vielleicht brauche ich es ja doch mal, oder mir ist langweilig und ich beschäftige mich mal wieder mit dem zip-Format,
oder PB macht endlich wahr, was vor Jahren schon angedeutet wurde, oder mir wächst ein Furunkel am *, oder...
;)

War ja auch nur ein frommer Wunsch. Weihnachten ist ja noch nicht und mit Furunkel am Hintern programmiert es sich schlecht im Sitzen. :mrgreen: Ich würds ja machen aber schon dein Code oben sind böhmische Dörfer für mich. Da schmeiss ich mich eben weiter auf ne zip.dll, den Umgang damit bekommt mein Althirn noch gebacken. <)

_________________
:::: WIN 10 :: PB 5.31 :: (x86) ::::


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: PipiFax-ZIP-Include [all OS]
BeitragVerfasst: 20.06.2011 21:48 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
Entzippen beliebiger zips (ohne Passwortschutz!) sollte jetzt auch gehen.

Zu beachten wäre, dass alle Einzeldateien im Memory als ein Block entpackt werden.
Ich war zu faul das anders zu lösen, also keine zips benutzen in denen ein 3Gig-DVD-Image steckt ;)

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: PipiFax-ZIP-Include [all OS]
BeitragVerfasst: 21.06.2011 07:19 
Offline
Benutzeravatar

Registriert: 10.03.2005 14:01
Hey interessant, Danke. :allright:
Wer eine einzippt will die meist auch wieder auszippen. :mrgreen:
Werd mich heute nachmittag mal mit beschäftigen.


Tante Edit (23.06.11):
War bissle faul die Tage, Rückmeldung folgt bis zum Wochenende wie ich doch hoffe. ;-)

_________________
:::: WIN 10 :: PB 5.31 :: (x86) ::::


Zuletzt geändert von rolaf am 23.06.2011 20:36, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: PipiFax-ZIP-Include [all OS]
BeitragVerfasst: 23.06.2011 20:15 
Offline
Benutzeravatar

Registriert: 15.03.2007 21:47
Zitat:
Zu beachten wäre, dass alle Einzeldateien im Memory als ein Block entpackt werden.

Das wollte ich auch schon anmerken. Mich würde aber darüber hinaus mal interessieren, wie groß man so einen Pack/Entpack-Puffer idealerweise wählt.

_________________
Kostenfreier Setup Creator | RCon Tool für DayZ

Bild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: PipiFax-ZIP-Include [all OS]
BeitragVerfasst: 23.06.2011 21:45 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
Du meinst, wenn du es in Einzelstücken ver/entpackst?

Keine Ahnung, da müsste man evtl. eigene Performance-Tests machen.

Eine gezippte 250MB Datei wurde aber mit obigem Code problemlos entpackt.
Von daher genügt es mir im moment zumindest. ;)

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 27 Beiträge ]  Gehe zu Seite 1, 2, 3  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 7 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye