PackMemory() auf Linux, UnpackMemory() auf Windows -> FAIL

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

PackMemory() auf Linux, UnpackMemory() auf Windows -> FAIL

Beitrag von Kukulkan »

Hallo,

Ich muss unter einem Linux Server ein paar Daten mit PackMemory packen, welche dann unter Windows wieder entpackt werden müssen. Leider geht das in fast allen Fällen schief.

Unter Linux packen und Linux entpacken -> ok
Unter Linux packen und Windows entpacken -> geht nicht

Um das genauer zu untersuchen, habe ich diese beiden Test-Codes erstellt.

Pack-Code (Linux):

Code: Alles auswählen

SourceFile.s      = "INSTALL.txt"
DestinationFile.s = "INSTALL.pak"

FilesizeUnpacked.l = FileSize(SourceFile.s)

; speicher reservieren
MemoryPointerUnpacked.l = AllocateMemory(FilesizeUnpacked.l)
MemoryPointerPacked.l   = AllocateMemory(FilesizeUnpacked.l + 8)

; datei in speicher lesen
ReadFile(1, SourceFile.s)
  ReadData(1, MemoryPointerUnpacked.l, FilesizeUnpacked.l)
CloseFile(1)

; datei packen
FileSizePacked.l = PackMemory(MemoryPointerUnpacked.l, MemoryPointerPacked.l, FilesizeUnpacked.l, 9)
If FileSizePacked.l < 1
  Debug "Packing " + SourceFile.s + " failed!"
Else
  ; speichern
  If FileSize(DestinationFile.s) > -1: DeleteFile(DestinationFile.s): EndIf
  
  If OpenFile(1, DestinationFile.s)
    WriteData(1, MemoryPointerPacked.l, FileSizePacked.l)
    CloseFile(1)
    Debug "Filesize before: " + Str(FilesizeUnpacked.l) + " bytes"
    Debug "Filesize after : " + Str(FilesizePacked.l) + " bytes"
    Debug "File saved. Finished."
  Else
    Debug "Error writing " + DestinationFile.s
  EndIf
EndIf
Entpack-Code (Windows):

Code: Alles auswählen

SourceFile.s = "INSTALL.pak"

FilesizePacked.l = FileSize(SourceFile.s)

If FilesizePacked.l < 1: Debug "Can not open file " + SourceFile.s: End: EndIf

; speicher reservieren
MemoryPointerPacked.l   = AllocateMemory(FilesizePacked.l)
MemoryPointerUnpacked.l = AllocateMemory(FilesizePacked.l * 4) ; 4 faches reservieren

; datei in speicher lesen
ReadFile(1, SourceFile.s)
  ReadData(1, MemoryPointerPacked.l, FilesizePacked.l)
CloseFile(1)

; datei entpacken
FilesizeUnpacked.l = UnpackMemory(MemoryPointerPacked.l, MemoryPointerUnpacked.l)
If FileSizeUnpacked.l < 1
  Debug "Unpacking " + SourceFile.s + " failed!"
Else
  Debug "Successfully extracted file to " + Str(FilesizeUnpacked.l) + " bytes"
EndIf
Ich hab zum Testen mal die Datei INSTALL aus dem Purebasic Linux-Install genommen, mit .txt umbenannt und damit getestet. geht aber auch mit anderen Daten. Immer das gleiche Resultat.

Kann mir da jemand helfen bzw. das Problem nachvollziehen? In beiden Fällen arbeite ich auf 32 Bit Systemen (Ubuntu 10.04 LTS und Windows XP SP3).

Kukulkan
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: PackMemory() auf Linux, UnpackMemory() auf Windows -> FA

Beitrag von Thorium »

Liegt daran das unter Windows eine andere Packlib verwand wird als unter Linux. Obwohl schon oft drauf hingewiesen wurde, wurde das in der Hilfe nicht korrigiert.
Lösung: Nutze zlib
zlib liegt PureBasic bei und ist schneller und komprimiert besser als JCalG1.
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: PackMemory() auf Linux, UnpackMemory() auf Windows -> FA

Beitrag von ts-soft »

Scheint so, als wenn unterschiedliche Packroutinen genutzt werden. Dachte eigentlich immer es
gäbe zur Zeit nur den Unterschied von x86 zu x64.

Ist mir bisher nicht aufgefallen, da ich unter jedem OS zlib verwende, was ja auch mitgeliefert wird.
Da klappts dann auch unter versch. OS, sowie x86_x64.

Hier der code:

Code: Alles auswählen

; Autor: Thomas (ts-soft) Schulz
; PB-Version: 4.xx
; OS: windows/linux/MacOS

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux
    ImportC #PB_Compiler_Home + "purelibraries/linux/libraries/zlib.a"
CompilerCase #PB_OS_MacOS
  ImportC "/usr/lib/libz.dylib"
  CompilerCase #PB_OS_Windows
    ImportC "zlib.lib"
CompilerEndSelect
  compress2(*dest, *destLen, *source, sourceLen, level)
  uncompress(*dest, *destLen, *source, sourceLen)
EndImport

Procedure zipPackMemory(*source, sourceLen = #PB_Default, level = #PB_Default)
  Protected *dest, destLen
  
  If level < #PB_Default Or level > 9 : level = #PB_Default : EndIf
  If *source
    If sourceLen = #PB_Default : sourceLen = MemorySize(*source) : EndIf
    destLen = sourceLen + 13 + (Int(sourceLen / 100))
    *dest = AllocateMemory(destLen)
    If *dest
      If Not compress2(*dest, @destLen, *source, sourceLen, level)
        *dest = ReAllocateMemory(*dest, destLen)
        ProcedureReturn *dest
      EndIf
    EndIf
  EndIf
EndProcedure

Procedure zipUnpackMemory(*source, *dest)
  Protected sourceLen = MemorySize(*source)
  Protected destLen = MemorySize(*dest)

  If Not uncompress(*dest, @destLen, *source, sourceLen)
    ProcedureReturn destLen
  EndIf
EndProcedure
PS: die entpackte grösse schreibt man immer als Header zum Pack hinzu! Ausserdem noch eine
Prüfsumme (CRC, MD5 oder ähnlich).

Gruß
Thomas
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: PackMemory() auf Linux, UnpackMemory() auf Windows -> FA

Beitrag von Kukulkan »

Mist, das bringt mich jetzt echt in Schwierigkeiten :| . Was um alles in der Welt ist der Grund für diese Abweichung????

Danke für die Info zur zlib,

Kukulkan
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8675
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: PackMemory() auf Linux, UnpackMemory() auf Windows -> FA

Beitrag von NicTheQuick »

Also ich wusste das vorher auch noch nicht, aber ehrlich gesagt ist es doch sau dumm. Wozu hat der Pack-Algorithmus dann überhaupt einen Namen?
Bild
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: PackMemory() auf Linux, UnpackMemory() auf Windows -> FA

Beitrag von Thorium »

Wie gesagt, das will scheinbar keiner in der Hilfe korrigieren: http://www.purebasic.fr/german/viewtopi ... 05#p262405

Ich hatte deswegen mal extra die Entpackroutine von JCalG1 portiert, so das man wenigstens auf anderen Plattformen entpacken kann, sollte auch unter Linux funktionieren: http://www.purebasic.fr/english/viewtop ... 12&t=38606
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: PackMemory() auf Linux, UnpackMemory() auf Windows -> FA

Beitrag von Kukulkan »

Hi Thorium,

Danke für die Info. Das mit den unterschiedlichen Algorithmen ist ja wirklich blanker Unsinn. Dein Code entpackt das von Windows gepackte oder das von Linux gepackte Format?

Danke,

Kukulkan
Antworten