Seite 1 von 3
SizeOf( structure ) / ASCII-Größe unter Unicode ermitteln?
Verfasst: 23.01.2018 13:18
von Kurzer
Hallo,
ist es mit irgendwelchen Tricks möglich unter PB 5.6x mittels SizeOf() die Größe einer Struktur zu ermitteln, so als würde sie im ASCII-Modus compiliert werden?
Ich habe folgende Struktur vorliegen.
Code: Alles auswählen
Structure strBHC_Header
sMagicWord.s{4}
wDatabaseType.w
sUserdefinedDatabaseTypecode.s{8}
lVersion.l
sDescription.s{30}
EndStructure
Debug SizeOf(strBHC_Header)
; ergibt 90 statt 48 wie im ASCII mode
Die aktuellen Versionen von PB compilieren ja nur noch im Unicode Modus, daher werden die Strings in der Struktur mit 2 Bytes je Zeichen gezählt. Da ich die Struktur aber als ASCII in eine Datei schreibe, ist die korrekte Größe 48 Bytes. SizeOf() zeigt jedoch 90 Bytes an statt 48.
Ich kann natürlich eine Konstante definieren, die die korrekte Größe enthält, aber ich würde es gern automatisch ermitteln lassen, damit ich mir bei einer Erweiterung des Headers keine weiteren Gedanken machen muss. Kann man SizeOf() irgendwie in den ASCII Mode zwingen?
Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel
Verfasst: 23.01.2018 15:01
von mk-soft
Wenn die Struktur als Block gespeichert werden soll, so sind die Strings auch als Unicode hinterlegt.
Eine Wandlung von Strukturen mit statischen Strings und Werten von ein Unicode-Programm zu ASCII-Strukturen ist sehr Aufwendig.
Ist eigentlich auch nicht erforderlich.
Wend die Daten auch in Unicode gespeichert werden, hast du auch keine Probleme mit irgendwelchen Sonderzeichen.
Ausserdem macht es sonst auch keinen sinn die Strukturgröße auszuwerten.
Blödes Beispiel mit Sonderzeichen
Code: Alles auswählen
Structure strBHC_Header
sMagicWord.s{4}
wDatabaseType.w
sUserdefinedDatabaseTypecode.s{8}
lVersion.l
sDescription.s{30}
EndStructure
Debug SizeOf(strBHC_Header)
; ergibt 90 statt 48 wie im ASCII mode
Structure sData
Header.strBHC_Header
;
sData.s{100}
EndStructure
*mem.sData = AllocateStructure(sData)
With *mem
\Header\sMagicWord = "Test"
; etc
\sData = "Hello World! äöü@ áóí"
EndWith
If CreateFile(0, GetHomeDirectory() + "TestData.bin")
Debug "Save datablock"
WriteData(0, *mem, SizeOf(sData))
CloseFile(0)
EndIf
*mem2.sData = AllocateStructure(sData)
If ReadFile(0, GetHomeDirectory() + "TestData.bin")
Debug "Read datablock"
ReadData(0, *mem2, SizeOf(sData))
CloseFile(0)
EndIf
Debug *mem2\Header\sMagicWord
Debug *mem2\sData
FreeStructure(*mem)
FreeStructure(*mem2)
P.S.
Ich kompiliere meine Programme nur noch in Unicode wegen den Problem mit den ganzen Zeichensätzen..
Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel
Verfasst: 23.01.2018 16:13
von Kurzer
Ich schreibe den header in der Tat immer als ASCII in die Datei, da er von mir so definiert wurde und eine feste Länge haben soll (48 Bytes).
Beim Schreiben gehe ich so vor, dass ich jedes Strukturfeld einzeln schreibe und bei den Strings durch entsprechende Berechnung mit SizeOf(Character) in beiden Fällen (ASCII und Unicode mode) die korrekte Anzahl an Zeichen schreibe. Das Casten nach ASCII übernimmt dann WriteString() für mich.
Code: Alles auswählen
If CreateFile(0, *this\sFilename, #PB_Ascii)
; Schreiben des Datenbank-Headers
WriteString(0, *this\strBHC_Header\sMagicWord, #PB_Ascii)
WriteWord(0, *this\strBHC_Header\wDatabaseType)
WriteString(0, Left(*this\strBHC_Header\sUserdefinedDatabaseTypecode + Space(SizeOf(strBHC_Header\sUserdefinedDatabaseTypecode) / SizeOf(Character)), SizeOf(strBHC_Header\sUserdefinedDatabaseTypecode) / SizeOf(Character)), #PB_Ascii)
WriteLong(0, *this\strBHC_Header\lVersion)
WriteString(0, Left(*this\strBHC_Header\sDescription + Space(SizeOf(strBHC_Header\sDescription) / SizeOf(Character)), SizeOf(strBHC_Header\sDescription) / SizeOf(Character)), #PB_Ascii)
; ... weiterer code
CloseFile(0)
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
Beim Einlesen einer solchen Datei möchte ich mittels FileSeek() diesen Header ggf. überspringen und hätte dabei gern
benutzt, da ich dann bei einer Erweiterung des Headers diese Stelle nicht mit anpassen müsste.
Momentan habe ich mir aber einfach eine Konstante mit der Länge des Headers definiert, so muss ich bei einer Erweiterung des Headers keine weiteren Anpassungen vornehmen.
Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel
Verfasst: 23.01.2018 19:19
von Sicro
Code: Alles auswählen
Structure strBHC_Header
sMagicWord.a[4]
wDatabaseType.w
sUserdefinedDatabaseTypecode.a[8]
lVersion.l
sDescription.a[30]
EndStructure
Debug SizeOf(strBHC_Header)
Define Header.strBHC_Header
; Schreiben
PokeS(@Header\sMagicWord[0], "ABCD", -1, #PB_Ascii)
; Lesen
Debug PeekS(@Header\sMagicWord[0], -1, #PB_Ascii)
Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel
Verfasst: 23.01.2018 21:40
von Kurzer
Hallo Sicro,
danke für den weiteren Denkanstoß.
Für Peek und Poke noch zwei Macros erstellen und dann ist das schon recht passabel nutzbar.
Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel
Verfasst: 23.01.2018 22:46
von mk-soft
Ich bin immer noch der Meinung das Textdaten in Unicode oder in UTF8 gespeichert werden sollten.
Der ASCII Zeichensatz reicht in unseren globalen Zeitalter einfach nicht mehr aus.
Muss aber jeder für sich entscheiden.

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel
Verfasst: 23.01.2018 23:03
von mhs
Code: Alles auswählen
Structure strBHC_Header
sMagicWord.s{4}
wDatabaseType.w
sUserdefinedDatabaseTypecode.s{8}
lVersion.l
sDescription.s{30}
EndStructure
Macro SizeOf_strBHC_Header
SizeOf(strBHC_Header) - (SizeOf(strBHC_Header\sMagicWord) + SizeOf(strBHC_Header\sUserdefinedDatabaseTypecode) + SizeOf(strBHC_Header\sDescription)) / 2
EndMacro
Debug SizeOf_strBHC_Header
Vielleicht ein etwas anderer Ansatz bei dem Änderungen an der Struktur nur berücksichtigt werden müssen, wenn neue String Elemente hinzukommen oder wegfallen.
Persönlich würde ich auch utf8 bevorzugen.
Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel
Verfasst: 24.01.2018 00:09
von Kurzer
mk-soft hat geschrieben:Ich bin immer noch der Meinung das Textdaten in Unicode oder in UTF8 gespeichert werden sollten.
Der ASCII Zeichensatz reicht in unseren globalen Zeitalter einfach nicht mehr aus.
Muss aber jeder für sich entscheiden.

Prinzipiell gebe ich dir recht. Hier handelt es sich aber um einen internen Header fester Größe in einem selbst entwickelten Dateiformat dessen Aufbau ich über ASCII und Unicode-Grenzen hinweg identisch halten möchte.
In dem Header sind zwar Stringdaten enthalten, diese enthalten aber nur eine interne Kurzbeschreibung. In diesem Header sind keine Daten enthalten die der Anwender zu Gesicht bekommt.
Wenn du dir z.B. eine in Unicode compilierte Exe Datei ansiehst, dann findest du dort ebenfalls noch einen ASCII-String: "This program cannot be run in DOS mode".
Hier wurde am PE-Executable Format auch nichts erweitert als Unicode sich durchgesetzt hat.

Ich würde es in meinem Fall ähnlich sehen.
Den Dokumententext eines neuen Textverarbeitungs-Dateiformats würde ich natürlich nicht im reinen ASCII Format in einer Datei speichern, da stimme ich dir zu.

Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel
Verfasst: 24.01.2018 00:50
von Josh
Ich verstehe nicht ganz, warum du eine andere Größe für die Struktur haben willst. Die Struktur ist eben 90 Bytes und zum Speichern der Struktur benötigst du auch 90 Bytes. Der einzige Unerschied der sich für dich ergibt, dass du z.B. in das Strukturfeld sDescription.s{30} 60 Ascii Zeichen schreiben kannst und nicht nur 30.
Wenn du allerdings weißt, dass du in dieses Feld 30 Ascii Zeichen schreiben willst und die Struktur im Ascii- und Unicode-Mode verwenden willst, dann würde ich schreiben:
Re: SizeOf( structure ) / ASCII-Größe unter Unicode ermittel
Verfasst: 24.01.2018 10:25
von Kurzer
Josh hat geschrieben:Ich verstehe nicht ganz, warum du eine andere Größe für die Struktur haben willst.
Genau das möchte ich nicht. Ich möchte, dass die Headergröße immer 48 Byte lang ist, egal ob ich das Programm ASCII Modus oder im Unicode Modus compiliere.
Die Strukturgröße bzw. die Berechnung derselben soll eben dazu dienen, zu "errechnen" wie groß der Header in der Datei ist. Der Header ist in der Datei physikalisch immer 48 Byte lang. Wenn ich eine solche Datei dann mit einem im Unicode-Modus compilierten Programm einlese, dann nützt mir die Unicodegröße des Headers (90 Byte) nichts. Die wäre dann falsch. Deswegen soll sie immer nach "ASCII Modus-Regeln" berechnet werden.