ich überlege gerade wie ich effizient und sicher einen UTF-8-String empfangen könnte, ohne dass ein einzelnes Zeichen auf zwei Pakete aufgeteilt wird.
Eine andere Anwendung, die nicht in Purebasic geschrieben wurde, schickt mir UTF-8 kodierte Strings. Jetzt kann es ja passieren, dass ein einzelnes Zeichen aus mehr als einem Byte besteht und somit in zwei Paketen ankommt. Oder 'ReceiveNetworkData()' teilt einen solchen String in zwei Häppchen auf. Das heißt ja, ich sollte nicht versuchen jedes Paket einzeln in einen Unicode-String zu konvertieren und dann zusammenzusetzen, sondern nur so weit konvertieren bis ein halbes UTF-8-Zeichen auftritt.
Ich habe mir jetzt erst mal so beholfen, dass ich mir eine eigene PeekUTF8()-Funktion geschrieben habe, die mir den lesbaren Teil eines halben UTF-8-Strings und die noch fehlenden Bytes zurück gibt. Im Code unten erstelle ich einen UTF-8-String und schneide immer wieder ein Byte hinten ab um damit meine Funktion zu füttern. Das funktioniert soweit gut, aber könnte vermutlich effizienter lösbar sein. Habt ihr darüber schon einmal nachgedacht?
Code: Alles auswählen
EnableExplicit
Procedure.s PeekUTF8(*memory.Ascii, size.i, *remainder.Integer)
Protected result.s, pos.i = 0, characters.i, *c.Ascii = *memory
Protected cLen.i
While pos < size
;Debug RSet(Bin(*c\a), 8, "0") + " " + *c\a
If *c\a & %11110000 = %11110000
cLen = 4
ElseIf *c\a & %11100000 = %11100000
cLen = 3
ElseIf *c\a & %11000000 = %11000000
cLen = 2
ElseIf *c\a & %10000000 = %10000000
Debug "Kein gültiges UTF-8-Zeichen gefunden!"
ProcedureReturn ""
Else
cLen = 1
EndIf
If (pos + cLen > size)
Break
EndIf
characters + 1
pos + cLen
If (*c\a = 0)
Break
EndIf
*c + cLen
Wend
If (*remainder)
*remainder\i = size - pos
EndIf
ProcedureReturn PeekS(*memory, characters, #PB_UTF8)
EndProcedure
Define *utf8 = AllocateMemory(1024)
Define size.i = PokeS(*utf8, "Schweiß", -1, #PB_UTF8) + 1
Debug "Bytes: " + size
Define i.i, hex.s = ""
For i = 0 To size - 1
hex + RSet(Hex(PeekA(*utf8 + i), #PB_Ascii), 2, "0") + " "
Next
Debug "Hex: " + hex
Debug ""
Define remainder.i
For i = 0 To 3
Debug "Mit " + i + " fehlenden Bytes am Ende:"
Debug PeekUTF8(*utf8, size - i, @remainder)
Debug "Restbytes: " + remainder
Debug ""
Next