Größe von Fixed Strings

Hier werden, insbesondere in den Beta-Phasen, Bugmeldungen gepostet. Das offizielle BugForum ist allerdings hier.
Little John

Beitrag von Little John »

Hallo HeX0R, ich habe zwei kleine Verbesserungsvorschläge.

a) Wenn man in der Structure die beiden Elemente vertauscht:

Code: Alles auswählen

Structure _LOCAL_FIXED_STRUCTURE_
   *String
   Length.l
EndStructure
dann kann man im folgenden das + OffsetOf(_LOCAL_FIXED_STRUCTURE_\String) weglassen, da das dann immer 0 ist. Der Code wird so etwas besser lesbar.

b) Ich würde in den Namen das LOCALweglassen. Du hast zwar in Deinem vorangegangenen Beispiel den FIXED STRING lokal deklariert, aber dieser neue Datentyp lässt sich ja auch anders verwenden:

Code: Alles auswählen

Global *achValue = CREATE_FIXED_STRING(#MAX_VALUE_NAME)
Eine Frage noch: Wozu steht in der Procedure FILL_LOCAL_FIXED_STRING() am Ende der zweiten Zeile

Code: Alles auswählen

 + SizeOf(CHARACTER)
//Nachtrag:
Und muss in derselben Prozedur nicht auch *a\Length der passende Wert zugewiesen werden? Z.B. so:

Code: Alles auswählen

Procedure.l FILL_FIXED_STRING (*a.FIXED_STRING_STRUCTURE, String.s)
   If *a\Lenght > StringByteLength(String)
      *a\Lenght = StringByteLength(String)
   EndIf
   CopyMemory(@String, *a, *a\Length)
EndProcedure
Gruß, Little John
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

Das SizeOf(CHARACTER) steht da, damit das Nullbyte auch noch geschrieben
wird.
Und *a\Length sollte man logischerweise nicht ändern, weil der FIXED String
ja seine Länge behalten soll und bei Zuweisung eines größeren Strings der
einfach abgeschnitten wird. Bei den nativen Strings ist es ja genauso.
Little John

Beitrag von Little John »

NicTheQuick hat geschrieben:Und *a\Length sollte man logischerweise nicht ändern, weil der FIXED String
ja seine Länge behalten soll und bei Zuweisung eines größeren Strings der
einfach abgeschnitten wird. Bei den nativen Strings ist es ja genauso.
In dieser Routine von HeX0R

Code: Alles auswählen

Procedure.s READ_LOCAL_FIXED_STRING(*a._LOCAL_FIXED_STRUCTURE_)
   ProcedureReturn PeekS(*a + OffsetOf(_LOCAL_FIXED_STRUCTURE_\String), *a\Length)
EndProcedure
wird jeweils der aktuelle Wert von *a\Length verwendet. Deshalb meine ich schon, dass dieser Wert beim Schreiben eben auch jeweils entsprechend zugewiesen werden muss.
NicTheQuick hat geschrieben:Das SizeOf(CHARACTER) steht da, damit das Nullbyte auch noch geschrieben wird.
Hier wird aber kein Nullbyte benötigt, da beim Lesen des Strings dessen Ende aufgrund seiner Länge bekannt ist.

Gruß, Little John
Benutzeravatar
HeX0R
Beiträge: 3042
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:

Beitrag von HeX0R »

Little John hat geschrieben:
NicTheQuick hat geschrieben:Und *a\Length sollte man logischerweise nicht ändern, weil der FIXED String
ja seine Länge behalten soll und bei Zuweisung eines größeren Strings der
einfach abgeschnitten wird. Bei den nativen Strings ist es ja genauso.
In dieser Routine von HeX0R

Code: Alles auswählen

Procedure.s READ_LOCAL_FIXED_STRING(*a._LOCAL_FIXED_STRUCTURE_)
   ProcedureReturn PeekS(*a + OffsetOf(_LOCAL_FIXED_STRUCTURE_\String), *a\Length)
EndProcedure
wird jeweils der aktuelle Wert von *a\Length verwendet. Deshalb meine ich schon, dass dieser Wert beim Schreiben eben auch jeweils entsprechend zugewiesen werden muss.
Es geht darum, dass PeekS solange ausliest bis das gesetzte NullByte kommt, oder eben bis zur Gesamtlänge des fixed-Strings (dann ohne NullByte).
Deswegen muss man auch das Nullbyte mitschreiben, ich fürchte da sind ein paar Verständnisprobleme.
Die Routine ist genau richtig so, wie sie war.

Und das Argument der Lesbarkeit kann ich nun gar nicht nachvollziehen, schliesslich sind das Prozeduren, die du includest und fertig.
Little John

Beitrag von Little John »

HeX0R hat geschrieben:Es geht darum, dass PeekS solange ausliest bis das gesetzte NullByte kommt, oder eben bis zur Gesamtlänge des fixed-Strings (dann ohne NullByte).
Deswegen muss man auch das Nullbyte mitschreiben, ich fürchte da sind ein paar Verständnisprobleme.
Die Routine ist genau richtig so, wie sie war.
Stimmt, ich hatte Deinen Ansatz nicht richtig verstanden. So wie ich es meinte -- also nur auf der aktuellen Stringlänge basierend -- geht es allerdings offenbar auch. :)

Gruß, Little John
Benutzeravatar
HeX0R
Beiträge: 3042
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:

Beitrag von HeX0R »

Little John hat geschrieben:So wie ich es meinte -- also nur auf der aktuellen Stringlänge basierend -- geht es allerdings offenbar auch. :)
Schon mal versucht erst einen langen String und dann einen kurzen einzusetzen ?
Little John hat geschrieben:a) Wenn man in der Structure die beiden Elemente vertauscht:
Code:
Structure _LOCAL_FIXED_STRUCTURE_
*String
Length.l
EndStructure
dann kann man im folgenden das + OffsetOf(_LOCAL_FIXED_STRUCTURE_\String) weglassen, da das dann immer 0 ist. Der Code wird so etwas besser lesbar.
Das ist übrigens auch Käse, weil du dann die Length Variable mit deinem String überschreibst.
Benutzeravatar
HeX0R
Beiträge: 3042
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:

Beitrag von HeX0R »

Abgespeckte Form:

Code: Alles auswählen

Procedure.l CREATE_LOCAL_FIXED_STRING(Length.l)
	Protected *a.LONG

	*a = AllocateMemory(4 + Length * SizeOf(CHARACTER))
	If *a
		*a\l = Length
	EndIf

	ProcedureReturn *a
EndProcedure

Procedure.l FILL_LOCAL_FIXED_STRING(*a.LONG, String.s)
	If StringByteLength(String) < *a\l
		CopyMemory(@String, *a + 4, StringByteLength(String) + SizeOf(CHARACTER))
	Else
		CopyMemory(@String, *a + 4, *a\l)
	EndIf
EndProcedure

Procedure.s READ_LOCAL_FIXED_STRING(*a.LONG)
	ProcedureReturn PeekS(*a + 4, *a\l)
EndProcedure

Macro FREE_LOCAL_FIXED_STRING(a)
	FreeMemory(a)
EndMacro
Little John

Beitrag von Little John »

HeX0R hat geschrieben:
Little John hat geschrieben:So wie ich es meinte -- also nur auf der aktuellen Stringlänge basierend -- geht es allerdings offenbar auch. :)
Schon mal versucht erst einen langen String und dann einen kurzen einzusetzen ?
Ja.
HeX0R hat geschrieben:
Little John hat geschrieben:a) Wenn man in der Structure die beiden Elemente vertauscht:
Code:
Structure _LOCAL_FIXED_STRUCTURE_
*String
Length.l
EndStructure
dann kann man im folgenden das + OffsetOf(_LOCAL_FIXED_STRUCTURE_\String) weglassen, da das dann immer 0 ist. Der Code wird so etwas besser lesbar.
Das ist übrigens auch Käse, weil du dann die Length Variable mit deinem String überschreibst.
Nein.

Code: Alles auswählen

Structure FIXED_STRING_STRUCTURE
   *String
   Length.l
EndStructure

Procedure.l CreateFixedString (Length.l)
   Protected *a.FIXED_STRING_STRUCTURE
   
   *a        = AllocateMemory(Length*SizeOf(CHARACTER) + 4)
   *a\Length = Length
   ProcedureReturn *a
EndProcedure

Procedure.l FillFixedString (*a.FIXED_STRING_STRUCTURE, String.s)
   If *a\Length > StringByteLength(String)
      *a\Length = StringByteLength(String)
   EndIf
   CopyMemory(@String, *a, *a\Length)
EndProcedure

Procedure.s ReadFixedString (*a.FIXED_STRING_STRUCTURE)
   ProcedureReturn PeekS(*a, *a\Length)
EndProcedure

Macro FreeFixedString (a)
   FreeMemory(a)
EndMacro

;--------------------------------------------------------

Procedure Demo()
   Protected *a = CreateFixedString(1000)

   FillFixedString(*a, "Ja Mei, wie kimmst denn du da her ?")
   Debug ReadFixedString(*a)

   FillFixedString(*a, "Hallo")
   Debug ReadFixedString(*a)
   
   FreeFixedString(*a)
EndProcedure

Demo()
Gruß, Little John
Benutzeravatar
HeX0R
Beiträge: 3042
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:

Beitrag von HeX0R »

Little John hat geschrieben: Nein.
Doch :roll:

Code: Alles auswählen

Procedure Demo()
	Protected *a.FIXED_STRING_STRUCTURE = CreateFixedString(1000)

	Debug "Länge des fixed Strings:" + Str(*a\Length)
	FillFixedString(*a, "Ja Mei, wie kimmst denn du da her ?")
	Debug "Länge des fixed Strings:" + Str(*a\Length)

	FreeFixedString(*a)
EndProcedure
Den Rest schenk ich mir, weil du es eh nicht einsehen (verstehen) würdest, wundere dich aber nicht, wenn du ab und an einen IMA bekommst bei deinem Code.

Ich habe fertig hier.
Benutzeravatar
Thalius
Beiträge: 476
Registriert: 17.02.2005 16:17
Wohnort: Basel / Schweiz

Beitrag von Thalius »

@Little John
Hexor hat scho recht. Ausserdem brauchts SizeOf(CHARACTER) - dann funzts auch mit dem Unicode... ;)
"...smoking hash-tables until until you run out of memory." :P
Antworten