ich habe hier mal wieder meine altbewährten Funktionen zum Schreiben und
Lesen von strukturierten Variablen in und aus einer Datei und zum Kopieren
einer strukturierten Variablen in eine andere ausgepackt und erneuert.
///Edit 1:
+ Funktionen etwas verkürzt.
///Edit 2:
+ Vielleicht etwas schneller
+ WriteSizeStructure() zum Ermitteln der Bytes, die bei WriteStructure() geschrieben werden
///Edit 3:
+ Vereinfachung für Strukturen mit statischen Arrays (s. Beispiel)
///Edit 4:
+ Ascii, Unicode und Integer hinzugefügt
+ CopyStructure() entfernt, da es das jetzt nativ gibt
+ Funktioniert erst ab der nächsten Beta
///Edit 5:
+ Jetzt geht es auch mit der aktuellen Beta
///Edit 6:
+ Proceduren geben nun einen Integer zurück (Danke ts-soft)
+ Beispiele sind kompatibel zu Windows und Linux (Danke ts-soft)
///Edit 7:
+ Code verkürzt
+ Code schneller gemacht
Der folgende Code funktioniert mit PB V4.50 beta 3 unter Linux und Windows.
Code: Alles auswählen
Structure test1
	id.l
	Name.s
	points.f[10]  ;<-----------
EndStructure         ;        |
Structure Strukt     ;        |
	Byte.b           ;        |
	word.w           ;        |
	Long.l           ;        |
	Quad.q           ;        |
	String1.s        ;        |
	Float.f          ;        |
	test1.test1[5]   ;<----   |
	String2.s        ;    |   |
	Double.d         ;    |   |
EndStructure         ;    |   |
Global Struc_Strukt.s    ;|   |
Struc_Strukt =    "bwlqsf[5ls[10f]]sd" ; Die Struktur selbst in einem String
Structure AllTypes
	StructureUnion
		b.b : c.c : w.w : l.l : f.f : d.d : q.q : a.a : u.u : i.i
	EndStructureUnion
EndStructure
Procedure.i WriteSizeStructure(*Var.AllTypes, *Struc.Character, *extralength.Integer = 0)
	Protected length.l = 0, mode.l = 0, c.l, *Start, alllength.l = 0, strlength.i
	
	While *Struc\c And (*Struc\c <> ']' Or mode)
		If mode = 0
			If *Struc\c = 's'
				*Var + length
				alllength + length + SizeOf(String)
				If *extralength
					*extralength\i + Len(PeekS(*Var\i))
				Else
					strlength + Len(PeekS(*Var\i))
				EndIf
				*Var + SizeOf(String)
				length = 0
			ElseIf *Struc\c = '['
				*Var + length
				alllength + length
				*Start = *Struc
				mode = 1
				c = 0
				length = 0
			Else
				length + PeekA(?WriteReadStructure + *Struc\c - 'a')
			EndIf
		Else
			Select *Struc\c
				Case '[' : mode + 1 ;weitere Verschachtelungen ignorieren
				Case ']' : mode - 1
				Default
					If *Struc\c >= '0' And *Struc\c <= '9' And mode = 1
						c * 10 + *Struc\c - '0'
						*Start + SizeOf(Character)
					EndIf
			EndSelect
			If mode = 0 ;Wenn Ende der Verschachtelung gefunden
				While c
					length = WriteSizeStructure(*Var, *Start + SizeOf(Character), @strlength)
					alllength + length
					*Var + length
					c - 1
				Wend
				length = 0
			EndIf
		EndIf
		*Struc + SizeOf(Character)
	Wend
	ProcedureReturn alllength + length + strlength
EndProcedure
Procedure.i WriteStructure(FileID, *Var.AllTypes, *Struc.Character)
	Protected length.l = 0, mode.l = 0, c.l, *Start, alllength.l = 0
	
	While *Struc\c And (*Struc\c <> ']' Or mode)
		If mode = 0
			If *Struc\c = 's'
				If length : WriteData(FileID, *Var, length) : *Var + length : alllength + length : EndIf
				length = StringByteLength(PeekS(*Var\i))
				WriteInteger(FileID, length)
				If length : WriteData(FileID, *Var\i, length) : EndIf
				alllength + SizeOf(Integer)
				*Var + SizeOf(Integer)
				length = 0
			ElseIf *Struc\c = '['
				If length : WriteData(FileID, *Var, length) : *Var + length : alllength + length : EndIf
				*Start = *Struc
				mode = 1
				c = 0
				length = 0
			Else
				length + PeekA(?WriteReadStructure + *Struc\c - 'a')
			EndIf
		Else
			Select *Struc\c
				Case '[' : mode + 1 ;weitere Verschachtelungen ignorieren
				Case ']' : mode - 1
				Default
					If *Struc\c >= '0' And *Struc\c <= '9' And mode = 1
						c * 10 + *Struc\c - '0'
						*Start + SizeOf(Character)
					EndIf
			EndSelect
			If mode = 0 ;Wenn Ende der Verschachtelung gefunden
				While c
					length = WriteStructure(FileID, *Var, *Start + SizeOf(Character))
					alllength + length
					*Var + length
					c - 1
				Wend
				length = 0
			EndIf
		EndIf
		*Struc + SizeOf(Character)
	Wend
	If length : WriteData(FileID, *Var, length) : EndIf
	ProcedureReturn alllength + length
EndProcedure
Procedure.i ReadStructure(FileID, *Var.AllTypes, *Struc.Character)
	Protected length.l, alllength.l, mode.l, c.l, *Start, *s.String, *mem
	
	While *Struc\c And (*Struc\c <> ']' Or mode)
		If mode = 0
			If *Struc\c = 's'
				If length : ReadData(FileID, *Var, length) : *Var + length : alllength + length : EndIf
				length = ReadInteger(FileID)
				*s = *Var
				InitializeStructure(*s, String)
				If length
					*mem = AllocateMemory(length)
					If *mem
						ReadData(FileID, *mem, length)
						*s\s = PeekS(*mem, length)
						FreeMemory(*mem)
					EndIf
				EndIf
				alllength + SizeOf(Integer)
				*Var + SizeOf(Integer)
				length = 0
			ElseIf *Struc\c = '['
				If length : ReadData(FileID, *Var, length) : *Var + length : alllength + length : EndIf
				*Start = *Struc
				mode = 1
				c = 0
				length = 0
			Else
				length + PeekA(?WriteReadStructure + *Struc\c - 'a')
			EndIf
		Else
			Select *Struc\c
				Case '[' : mode + 1
				Case ']' : mode - 1
				Default
					If *Struc\c >= '0' And *Struc\c <= '9' And mode = 1
						c * 10 + *Struc\c - '0'
						*Start + SizeOf(Character)
					EndIf
			EndSelect
			If mode = 0
				While c
					length = ReadStructure(FileID, *Var, *Start + SizeOf(Character))
					alllength + length
					*Var + length
					c - 1
				Wend
				length = 0
			EndIf
		EndIf
		*Struc + SizeOf(Character)
	Wend
	If length : ReadData(FileID, *Var, length) : EndIf
	ProcedureReturn alllength + length
EndProcedure
DataSection
	WriteReadStructure:
		Data.a SizeOf(Ascii), SizeOf(Byte), SizeOf(Character), SizeOf(Double), 0
		Data.a SizeOf(Float), 0, 0, SizeOf(Integer), 0
		Data.a 0, SizeOf(Long), 0, 0, 0
		Data.a 0, SizeOf(Quad), 0, 0, 0
		Data.a SizeOf(Unicode), 0, SizeOf(Word), 0, 0
		Data.a 0
EndDataSection
Var1.Strukt
Var1\Byte = 123
Var1\word = 23432
Var1\Long = 13579123
Var1\Quad = 2468012343344533
Var1\String1 = "Hallo du!"
Var1\Float = 1234.1234
Var1\String2 = "Ich bin NTQ!"
Var1\Double = 123456789.123456789
For a = 0 To 4
	Var1\test1[a]\id = a + 1
	Var1\test1[a]\Name = "Name: " + Str(Random(100000000))
	For b = 0 To 9
		Var1\test1[a]\points[b] = a * 100 + b + 101
	Next
Next
MessageRequester("Struktur Größe", Str(WriteSizeStructure(Var1, @Struc_Strukt)) + " Bytes")
Var2.Strukt
CopyStructure(Var1, Var2, Strukt)
MessageRequester("Kopierte Struktur", "Byte: " + Str(Var2\Byte) + Chr(13) + "Word: " + Str(Var2\word) + Chr(13) + "Long: " + Str(Var2\Long) + Chr(13) + "Quad: " + Str(Var2\Quad) + Chr(13) + "String1: " + Var2\String1 + Chr(13) + "Float: " + Str(Var2\Float) + Chr(13) + "String2: " + Var2\String2 + Chr(13) + "Double: " + StrD(Var2\Double))
For a = 0 To 4
	Debug Var2\test1[a]\id
	Debug Var2\test1[a]\Name
	For b = 0 To 9
		Debug Var2\test1[a]\points[b]
	Next
Next
Debug GetCurrentDirectory()
If CreateFile(0, ".\test_structure.txt")
	WriteStructure(0, Var1, @Struc_Strukt)
	CloseFile(0)
	CompilerSelect #PB_Compiler_OS
		CompilerCase #PB_OS_Linux
			If FileSize("/usr/bin/bless") >= 0
				RunProgram("bless", ".\test_structure.txt", "./", #PB_Program_Wait)
			Else
				MessageRequester("Warnung!", "Hexeditor 'bless' wurde nicht gefunden.")
			EndIf
		CompilerCase #PB_OS_Windows
			RunProgram(".\test_structure.txt", "", "./", #PB_Program_Wait)
	CompilerEndSelect
EndIf
If ReadFile(0, ".\test_structure.txt")
	Var3.Strukt
	ReadStructure(0, Var3, @Struc_Strukt)
	CloseFile(0)
	MessageRequester("Ausgelesene Struktur", "Byte: " + Str(Var3\Byte) + Chr(13) + "Word: " + Str(Var3\word) + Chr(13) + "Long: " + Str(Var3\Long) + Chr(13) + "Quad: " + Str(Var3\Quad) + Chr(13) + "String1: " + Var3\String1 + Chr(13) + "Float: " + Str(Var3\Float) + Chr(13) + "String2: " + Var3\String2 + Chr(13) + "Double: " + StrD(Var3\Double))
	For a = 0 To 4
		Debug Var3\test1[a]\id
		Debug Var3\test1[a]\Name
		For b = 0 To 9
			Debug Var3\test1[a]\points[b]
		Next
	Next
EndIf




 
  
 
