Немного предистории. Пишу e-mail парсер, почти всё готово; остался последний затык. Парсер выдирает тело письма (одной строкой) и отсылает его в функцию определения кодировки. В функции строка сначала проверяется на Utf-8 (спасибо уважаемому amel27), если False, то на предмет одной из 4-ых ANSI кодировок - WIN, KOI, DOS, ISO. Далее, в зависимости от того, какую кодировку функция вернула, идет перевод строки в win-кодировку.
И все неплохо бы, но к сожалению, если передана DOS-строка, то проверка на UTF возвращает True, что неверно. Вот пример:
Файл dos.txt для тестов прилагаю к этому сообщению.
Можно ли как-то поправить функцию _StringIsUTF8Format, чтоб в данном примере возвращала False?
Вариант прочитать кодировку из заголовка письма не подходит, т.к. письма приходят закодированными в base64, и, естесвенно, в заголовках это и стоит.
PS Дальнейшее разбор показал, что функция неверно определяет строку только если она содержит одни только заглавные буквы в DOS - кодировке. К сожалению, у некоторых групп отправителей (в данном случае - у моряков) принято писать сообщения только в в верхнем регистре - это традиция такая.
Также если удалить лидирующие пробелы в 8-ой строке, функция опять же нормально отработает.
И все неплохо бы, но к сожалению, если передана DOS-строка, то проверка на UTF возвращает True, что неверно. Вот пример:
Код:
$s = FileReadLine ("dos.txt", 8)
ConsoleWrite ($s & @CRLF)
ConsoleWrite (_StringIsUTF8Format ($s) & @CRLF)
Func _StringIsUTF8Format($String)
Local $sAsc, $sLen = StringLen($String), $sExt = $sLen
For $i = 1 To $sLen
$sAsc = Asc(StringMid($String, $i, 1))
;~ ConsoleWrite ($sAsc & @CRLF)
If $sAsc > 128 then $ansi=""
If Not BitAND($sAsc, 0x80) Then
$sExt = 0
ElseIf Not BitXOR(BitAND($sAsc, 0xE0), 0xC0) Then
$sExt = 1
ElseIf Not (BitXOR(BitAND($sAsc, 0xF0), 0xE0)) Then
$sExt = 2
ElseIf Not BitXOR(BitAND($sAsc, 0xF8), 0xF0) Then
$sExt = 3
EndIf
If $i + $sExt > $sLen Then Return False
For $j = $i + 1 To $i + $sExt
$sAsc = Asc(StringMid($String, $j, 1))
If BitXOR(BitAND($sAsc, 0xC0), 0x80) Then Return False
Next
$i += $sExt
Next
If IsDeclared ("ansi") Then
Return True
Else
Return False
EndIf
EndFunc ; ==> _StringIsUTF8Format
Файл dos.txt для тестов прилагаю к этому сообщению.
Можно ли как-то поправить функцию _StringIsUTF8Format, чтоб в данном примере возвращала False?
Вариант прочитать кодировку из заголовка письма не подходит, т.к. письма приходят закодированными в base64, и, естесвенно, в заголовках это и стоит.
PS Дальнейшее разбор показал, что функция неверно определяет строку только если она содержит одни только заглавные буквы в DOS - кодировке. К сожалению, у некоторых групп отправителей (в данном случае - у моряков) принято писать сообщения только в в верхнем регистре - это традиция такая.
Также если удалить лидирующие пробелы в 8-ой строке, функция опять же нормально отработает.