Auslesen einer binären Datei

Anfängerfragen zum Programmieren mit PureBasic.
Axolotl
Beiträge: 284
Registriert: 31.12.2008 16:34

Re: Auslesen einer binären Datei

Beitrag von Axolotl »

Mein zweites Konzept verwendet die CompareMemoryString() anstelle der CompareMemory(). Ist also durchaus ähnlich.

Ich denke, die Verwendung von Strings ist aufgrund von Unicode (2-Byte) und den byte-orientierten Headern problematisch.
Meine Idee wäre ja eher die Header byteweise (.ASCII) zu finden und dann die "richtigen Stellen" nach Strings zu wandeln...

BTW: Ich möchte ja niemandem den Programmier-Spass nehmen, deshalb (nur) Hilfe zur Selbsthilfe.
Using PureBasic latest stable version and current alpha/beta (x64) on Windows 11 Home
Benutzeravatar
H.Brill
Beiträge: 505
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Auslesen einer binären Datei

Beitrag von H.Brill »

Ich muß ja nur einmal den richtigen Anfangsoffset finden, da genügt ja der BOM EF BB BF. Und dann noch 4 Bytes dazu zählen.
Der richtige Anfangsoffset ist halt wichtig beim späteren Zerstückeln, damit die später zurückgespielten Dateien vom Gerät
wieder erkannt werden und man auch den Anfangsoffset für den Titel genau trifft.
Man muß sich vorstellen, daß diese Binärdaten hauptsächlich Steuerbefehle für das Gerät sind, das dann wieder
Musik daraus macht. Außer den Musiktiteln an Offset $39B bei jeder Einzeldatei ist da nichts Lesbares drin. Ich brauch da ja nur
Memoryblöcke mit Größe 25752 Bytes. Die sind dann gleichzeitig auch als einzelne Dateien zu speichern. Beim nächsten Lesen
wird der offset dann um 25752 erhöht und mit FileSeek drauf gesetzt und wieder 25752 Bytes eingelesen. Ist ja ziemlich simpel
und müßte ich auch hin bekommen.

Zu den Titeln habe ich noch folgende Infos gefunden :
Diese Dateien sind ein Bitstream, in dem die ASCII Zeichen für den Namen
aber nur 7 Bits belegen.

Man muss halt an der passenden Stelle im Bitstream nach den 7-Bit ASCII
Zeichen suchen.

Beispiel Datei "kneipe_2.UPG" von weiter oben ab Offset 0x39B:

0000039B 65 CE 8B 26 ¦ 84 54 08 10 ¦ 20 40 81 02 ¦ 04 08 10 20
000003AB 40 82 01 80 ¦ AD 52 BA 04 ¦ 08 10 20 40 ¦ 81 02 00 00

65 CE 8B 26 84 54 08

01100101 11001110 10001011 00100110 10000100 01010100 00001000

01 1001011 1001110 1000101 1001001 1010000 1000101 0100000

01001011 01001110 01000101 01001001 01010000 01000101 00100000

0x4B 0x4E 0x45 0x49 0x50 0x45 0x20
K N E I P E <SPACE>


Das passt so auch bei den anderen Beispieldateien, wie lang der Name
maximal sein kann muss man schauen (20 kommt aber wohl gut hin).
Ist halt jetzt die Frage, ob PB 7-Bit Ascii unterstützt. Normalerweise ist ja 1 Byte = 8 Bit.
Ist wohl noch ein Relikt aus den DOS-Zeiten und es steckt im Akkordeon ja bestimmt auch
ein MikroController. Das kennt man ja mittlerweile, z.b. daß Strings kein Nullbyte automatisch am
Ende haben, wenn es der Chip schickt.

Achja, wenn jemand jetzt mit Urheberrechten kommt : Der Graig aus den USA, der maßgeblich
an der Entwicklung betieligt war, hat laut Aussage meines Freundes da schon vor Jahren grünes Licht gegeben.
Er selber möchte aber keine Zeit mehr darin investieren. Von dem stammen auch so manche Informationen zum
Aufbau der Datei. Da brauche ich keine Angst haben.
PB 6.10
Benutzeravatar
HeX0R
Beiträge: 3047
Registriert: 10.09.2004 09:59
Computerausstattung: AMD Ryzen 7 5800X
96Gig Ram
NVIDIA GEFORCE RTX 3060TI/8Gig
Win11 64Bit
G19 Tastatur
2x 24" + 1x27" Monitore
Glorious O Wireless Maus
PB 3.x-PB 6.x
Oculus Quest 2 + 3
Kontaktdaten:

Re: Auslesen einer binären Datei

Beitrag von HeX0R »

Ich verstehe nicht wirklich was Du da sagt.
Der BOM kann Dir so hoch wie breit sein, weil er IMMER am Anfang Deiner Datei steht.
Damit kann man keinen Offset ermitteln.
Dann ignorierst Du auch die folgenden 4 Bytes, die Dir aber die Länge des XML Anteils anzeigen.
Über die Zusammensetzung des Datenteils, kann ich jetzt nicht wirklich viel finden in den ganzen Posts, außer, dass die Titel im 7Bit Ascii-Format sind.
Das kann PB nicht von Haus aus, lässt sich aber natürlich umsetzen.
Hier mal ein kleiner Code für den Start:

Code: Alles auswählen

Structure _SWAP_HELPER_
	b.b[0]
EndStructure

Procedure SwapLong(Value)       ;Changes a long from BidEndian to LittleEndian (which PB uses)
		Protected Result, *B._SWAP_HELPER_ = @Value
		Swap *B\b[0], *B\b[3]
		Swap *B\b[1], *B\b[2]
		ProcedureReturn PeekL(*B)
EndProcedure


Procedure InitUPA(File$)
	Protected FID, BOM, XMLPart$, Length
	
	FID = ReadFile(#PB_Any, File$)
	If FID
		BOM = ReadStringFormat(FID) ; <-- wird eh #PB_UTF8 sein, aber Du hast den Lesezeiger schonmal 3 Bytes weiter gebracht
		Length = ReadLong(FID)      ; <-- Länge des XML Anteils, aber in BigEndian Format
		Length = SwapLong(Length)   ; <-- Länge des XML Anteils im LittleEndian Format
		XMLPart$ = ReadString(FID, BOM | #PB_File_IgnoreEOL, Length)
		Debug XMLPart$              ; <-- XML Anteil, und Dein Lesezeiger sitzt jetzt genau dahinter, also am Anfang der Binärdaten
		
		
		CloseFile(FID)
	EndIf
EndProcedure

InitUPA("I:\test\UPG_ALL.UPA")
Benutzeravatar
H.Brill
Beiträge: 505
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: Auslesen einer binären Datei

Beitrag von H.Brill »

Hallo Hexor,
Naja, ich dachte, weil der BOM ja hinter dem XML steht.
Aber dein Code bringt mich ja weiter. Auf das SwapLong() wäre ich nie gekommen.
Dann habe ich ja direkt die Stelle zum blockweisen Weiterlesen mit ReadData().
Danke dafür.
PB 6.10
Antworten