Re: ConvertFromAnsi mit Purebasic
Verfasst: 25.02.2018 16:49
Ansi und Ascii kannste getrost in einen Topf werfen. Reines Ascii gibt es kaum noch.
Für die zweite Hälfte ab 128 ist allerdings die Festlegung der Codepage erforderlich, damit die Wandlung ordnungsgemäß funktioniert. Ansonsten wäre das tatsächlich nur eine Ascii-Wandlung.
Leider kann ich bei #PB_ASCII nicht herausfinden, welche Codepage dort verwendet wird.
Ich habe deinen Code einfach mal übersetzt:
Allerdings funktioniert die Übersetzung der ANSI-Erweiterung nicht korrekt, weil die Übersetzungsformel nicht zu stimmen zu scheint. Hier muss auf jeden Fall die verwendete Codepage als Übersetzungstabelle (asciicode <-> ucs-2-code, ein Array bietet sich dafür an) zwischengesetzt werden.
Zudem hatte dein alter Code es irgendwie fertig gebracht, sowohl ANSI als auch ucs-2 mit derselben String-Klasse zu verwalten. Ich bezweifle, dass hier tatsächlich eine Wandlung von Ansi (1 byte) auf ucs-2 (2 byte) stattgefunden hat.
Ich tippe mal eher darauf, dass dein bisheriger Code einen bereits mittels falscher Codepage auf ucs-2 konvertierten String nachgepatcht hat.
Edit: #PB_Ascii verwendet zumindest unter Linux ISO 8859-1 (oder macht einfach Nullbytes zwischen die Chars und überlässt den Rest dem Schicksal). Allerdings haben weder diese noch die alten Codepages aus der Steinzeit das Tüddelchen-E an der Stelle 168.
Für die zweite Hälfte ab 128 ist allerdings die Festlegung der Codepage erforderlich, damit die Wandlung ordnungsgemäß funktioniert. Ansonsten wäre das tatsächlich nur eine Ascii-Wandlung.
Leider kann ich bei #PB_ASCII nicht herausfinden, welche Codepage dort verwendet wird.
Ich habe deinen Code einfach mal übersetzt:
Code: Alles auswählen
Procedure.s FnConvertFromAnsi(*ansiStr)
If *ansiStr = 0 : ProcedureReturn "" : EndIf
Protected str.s = ""
Protected *ptr = *ansiStr
Protected char = PeekA(*ptr) : *ptr + 1
While char <> 0
If char >= 192 And char <= 255
str+Chr(char - 192 + 1040)
ElseIf char = 168 ;Ё
str+Chr(1025)
ElseIf char = 184 ;ё
str+Chr(1105)
Else
str+Chr(char)
EndIf
char = PeekA(*ptr) : *ptr + 1
Wend
ProcedureReturn str
EndProcedure
*asciiString = AllocateMemory(5)
PokeA(*asciiString, 65) ;A
PokeA(*asciiString+1, 220) ;bottom block
PokeA(*asciiString+2, 221) ;half block, but not in CP 850
PokeA(*asciiString+3, 168) ;Ё
PokeA(*asciiString+4, 0)
Debug FnConvertFromAnsi(*asciiString) ;it is more a "PeekAnsiWithCustomCodePage()"
Zudem hatte dein alter Code es irgendwie fertig gebracht, sowohl ANSI als auch ucs-2 mit derselben String-Klasse zu verwalten. Ich bezweifle, dass hier tatsächlich eine Wandlung von Ansi (1 byte) auf ucs-2 (2 byte) stattgefunden hat.
Ich tippe mal eher darauf, dass dein bisheriger Code einen bereits mittels falscher Codepage auf ucs-2 konvertierten String nachgepatcht hat.
Edit: #PB_Ascii verwendet zumindest unter Linux ISO 8859-1 (oder macht einfach Nullbytes zwischen die Chars und überlässt den Rest dem Schicksal). Allerdings haben weder diese noch die alten Codepages aus der Steinzeit das Tüddelchen-E an der Stelle 168.