"OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierungen

Für allgemeine Fragen zur Programmierung mit PureBasic.
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: "OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierunge

Beitrag von ts-soft »

Ich geb es auf :mrgreen:
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
Sicro
Beiträge: 968
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: "OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierunge

Beitrag von Sicro »

PB-Hilfe hat geschrieben:SetXMLEncoding()

Encoding
Dies kann einer der folgenden Werte sein:
  • #PB_Ascii
  • #PB_Unicode (UTF16)
  • #PB_UTF8
Dies beeinflusst nur das Exportieren/Speichern des Baums. Die Daten im #XML Objekt werden immer im PB String-Format gespeichert (Ascii oder Unicode, abhängig von der Compiler-Option). Somit kann ein Unicode-Executable für das Speichern die Codierung ohne Probleme in #PB_Ascii ändern und anschließend zurück in eine andere, ohne dabei Informationen zum Baum im Speicher zu verlieren.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
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: "OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierunge

Beitrag von ts-soft »

Dies beeinflusst nur das Exportieren/Speichern des Baums.
und genauso das Importieren/Laden des Baums.

Bevor die Daten im PB-Stringformat genutzt werden, müssen sie ja erst mal geladen werden. Dabei ist es egal ob
LoadXML oder CatchXML, der String liegt da im UTF-8 Kodierung (oder andere, wenn eingestellt) vor. Erst nach dem
Importieren (Catchen, Laden), geht es mit PB-Stringformat weiter.
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
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

Re: "OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierunge

Beitrag von mhs »

ts-soft hat geschrieben:Bevor die Daten im PB-Stringformat genutzt werden, müssen sie ja erst mal geladen werden. Dabei ist es egal ob
LoadXML oder CatchXML, der String liegt da im UTF-8 Kodierung (oder andere, wenn eingestellt) vor. Erst nach dem
Importieren (Catchen, Laden), geht es mit PB-Stringformat weiter.
Ja richtig, allerdings liegt der XML String nicht als UTF-8 wie im Sourcode vor wie du meinst, sondern als Unicode String bereits im Speicher.

Jetzt nachdem ich nochmal eine Nacht darüber geschlafen habe, ist die Erklärung so simpel und einfach... Es liegt an der Kodierung selbst, bei Unicode, also UCS-2 ist die Länge immer fix 2 Byte pro Zeichen. Dabei spielt es für das Dekodieren eigentlich gar keine Rolle, welche Kodierung angegeben wird, es werden eh immer alle Bytes gelesen. Bei einem UTF-8 kodierten String sieht die Sache schon wieder anders aus, da hier ja 1-4 Byte verwendet werden. Es sind zwar die ersten 128 Zeichen gleich wie bei ASCII und deswegen kommen dort auch teilweise richtige Ergebnisse, aber sobald ein Zeichen 2 oder mehr Byte verwendet können die Strings nicht mehr dekodiert werden.

Der folgende Code demonstriert das auch sehr schön, wenn man bei #ENCODING mit allen drei Kodierungen spielt, bei dem Ausgangsstring in Unicode kommt immer das richtige Ergebnis:

Code: Alles auswählen

Define.s xml
Define *bufAscii, *bufUnicode, *bufUtf8

#ENCODING = #PB_Ascii

xml = "<window name='abc月2日更新'></window>"

*bufAscii   = AllocateMemory(StringByteLength(xml, #PB_Ascii)   + 1)
*bufUnicode = AllocateMemory(StringByteLength(xml, #PB_Unicode) + 2)
*bufUtf8    = AllocateMemory(StringByteLength(xml, #PB_UTF8)    + 1)

PokeS(*bufAscii,   xml, -1, #PB_Ascii)
PokeS(*bufUnicode, xml, -1, #PB_Unicode)
PokeS(*bufUtf8,    xml, -1, #PB_UTF8)

CatchXML(1, *bufAscii,   MemorySize(*bufAscii),   0, #ENCODING)
CatchXML(2, *bufUnicode, MemorySize(*bufUnicode), 0, #ENCODING)
CatchXML(3, *bufUtf8,    MemorySize(*bufUtf8),    0, #ENCODING)
CatchXML(4, @xml,        StringByteLength(xml),   0, #ENCODING)

Debug ComposeXML(1) + " (ascii)"
Debug ComposeXML(2) + " (unicode)"
Debug ComposeXML(3) + " (utf-8)"
Debug ComposeXML(4)
Ergo hat Sicro recht und die Kodierung in den Beispielen ist eigentlich falsch angegeben und müsste #PB_Unicode lauten, bzw. der gesamte CompilerIf Block könnte wegfallen, weil die internen Strings ja eh in der richtigen Kodierung vorliegen. Korrekterweise müsste dann nach dem CatchXML die Kodierung mit SetXMLEncoding() (im Unicode Modus) auf UTF-8 umgestellt werden, damit bei einem SaveXML die XML Datei auch als UTF-8 und nicht als UCS-2 gespeichert wird.
Zuletzt geändert von mhs am 09.04.2016 12:29, insgesamt 1-mal geändert.
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: "OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierunge

Beitrag von Nino »

ts-soft hat geschrieben:
mhs hat geschrieben:CatchXML liest direkt aus dem Speicher
der in diesem Falle eine UTF-8 kodierte Text-Datei ist, also der Source der PB-IDE!
Für mich stellt es sich nicht so dar.
Daraus dass das Datei-Format des Quelltextes UTF-8 ist, folgt nicht dass PureBasic Stringvariablen (die im RAM existieren und nicht in einer Datei) auch im UTF-8-Format vorliegen. Tatsächlich ist das offenbar auch nicht der Fall:

Code: Alles auswählen

; PB 5.42 LTS x64 unter Windows
; benutztes Dateiformat in der IDE: UTF-8

CompilerIf Not #PB_Compiler_Unicode
   CompilerError "Im Unicode-Modus kompilieren!"
CompilerEndIf

s$ = "Äpfel"

Debug s$
Debug PeekS(@s$, -1, #PB_Unicode)
Debug PeekS(@s$, -1, #PB_UTF8)
Ausgabe hat geschrieben:Äpfel
Äpfel
Benutzeravatar
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

Re: "OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierunge

Beitrag von mhs »

Nino hat geschrieben:Für mich stellt es sich nicht so dar.
Daraus dass das Datei-Format des Quelltextes UTF-8 ist, folgt nicht dass PureBasic Stringvariablen (die im RAM existieren und nicht in einer Datei) auch im UTF-8-Format vorliegen. Tatsächlich ist das offenbar auch nicht der Fall:
...
@Nino: Siehe mein letzter Post kurz vor dir :wink:
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: "OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierunge

Beitrag von Nino »

mhs hat geschrieben:@Nino: Siehe mein letzter Post kurz vor dir :wink:
Ja. :-)
Als ich meinen Beitrag schrieb, war Dein Post noch nicht da.
Außerdem zeigt mein Beitrag kurz und knapp den Kern des Missverständnisses und ist in sofern eine gute Ergänzung zu Deinem Post.
Benutzeravatar
Sicro
Beiträge: 968
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: "OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierunge

Beitrag von Sicro »

Unicode-Modus:
Code.pb [Strings sind UTF-8 / ASCII (abhängig davon, wie der Editor eingestellt ist)]
>>
Compiler [wandelt Strings von UTF-8 / ASCII zu UNICODE um]
>>
CatchXML() liest XML$, was nun den String in UNICODE enthält, weil der Compiler die Strings bereits von UTF-8 / ASCII zu UNICODE umgewandelt hat.
mhs hat geschrieben:bzw. der gesamte CompilerIf Block könnte wegfallen, weil die internen Strings ja eh in der richtigen Kodierung vorliegen.
Nein, CatchXML() liest ohne Kodierung-Angabe den String immer als UTF-8 (habe das im vorletztem Beitrag falsch geschrieben, sorry) und das wäre im Ascii- und im Unicode-Modus falsch bei internen Strings.

Edit: So, ich bin nun fertig mit der Editiererei :lol:
Zuletzt geändert von Sicro am 07.05.2016 15:10, insgesamt 2-mal geändert.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
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: "OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierunge

Beitrag von ts-soft »

Endlich hat er es geschnallt, hoffe ich mal :D
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
Sicro
Beiträge: 968
Registriert: 11.08.2005 19:08
Kontaktdaten:

Re: "OpenXMLDialog()"-Beispiel-Codes: merkwürdige Codierunge

Beitrag von Sicro »

ts-soft hat geschrieben:Endlich hat er es geschnallt, hoffe ich mal :D
Zeige mir mal bitte, wo wir gleicher Meinung sind. :)
ts-soft hat geschrieben:CatchXML liest den UTF-8 Code ein, der genauso vorliegt, wie als Textdatei auch, und wandelt ihn in Unicode (oder ASCII) um im Programm damit weiter zu arbeiten zu können.
Der String von XML$ liegt mit eingeschaltetem Unicode-Modus oder ohne eben nicht im UTF-8-Format vor. Beispiel-Codes, die dies beweisen, haben wir ja schon hier geschrieben. Du kannst auch mal das hier jeweils mit und ohne eingeschaltetem Unicode-Modus kompilieren und beide Kompilate mit einem Hex-Editor ansehen:

Code: Alles auswählen

XML$ = "Hallo!"
Ergebnis: In beiden Kompilaten ist kein UTF-8-String.
ts-soft hat geschrieben:
mhs hat geschrieben:CatchXML liest direkt aus dem Speicher
der in diesem Falle eine UTF-8 kodierte Text-Datei ist, also der Source der PB-IDE!
Den UTF-8-String bekommt CatchXML() nicht übergeben, weil da der Compiler den UTF-8-String der Source bereits in Unicode umgewandelt hat.
ts-soft hat geschrieben:Bevor die Daten im PB-Stringformat genutzt werden, müssen sie ja erst mal geladen werden. Dabei ist es egal ob
LoadXML oder CatchXML, der String liegt da im UTF-8 Kodierung (oder andere, wenn eingestellt) vor. Erst nach dem
Importieren (Catchen, Laden), geht es mit PB-Stringformat weiter.
Interne Strings im Unicode-Modus sind nicht UTF-8.

Egal, ich habe nun alle Informationen, die ich haben wollte. Danke euch allen :)
Zuletzt geändert von Sicro am 17.04.2016 14:03, insgesamt 1-mal geändert.
Bild
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Antworten