Orion9

|
Posted: Tue Oct 06, 2026 14:07 Post subject: |
|
|
yozhik
Да, похоже, теряет. Тип "handle" тоже не работает. Тип hwnd не проверял, а вот int_ptr и uint_ptr работают. Тип "int64" тоже вроде рабочий.
| AkulaBig wrote: | | Почему-то крякозябры перестали преобразовываться по очень интересной схеме. С половины данных. То-есть пол строки преобразовалось, а половина нет. |
Может быть. Преобразовывается то, что после двойных точек. Но если двойных точек две-три, или кроме символов 0xFFFB есть что-то еще, то образуются новые кракозябры.
Решение от болвана - переводить посимвольно, но нужно ли?
 Hidden text | Code: | #Requires AutoHotkey v2.0
/**
* Высокоскоростной разбор буфера без DllCall внутри цикла.
* Идеально синхронизирует латиницу, UTF-8 и битый ANSI (CP1251).
*/
FastDecodeAndFixBuffer(rawBuffer, bytesCount) {
if (bytesCount <= 0)
return ""
outString := ""
ptr := rawBuffer.Ptr
endPtr := ptr + bytesCount
while (ptr < endPtr) {
b1 := NumGet(ptr, "UChar")
; --- 1. Стандартная латиница и ASCII (1 байт в UTF-8) ---
if (b1 < 0x80) {
outString .= Chr(b1)
ptr += 1
continue
}
; --- 2. Потенциальный правильный UTF-8 (2 байта: Кириллица, Греческий, Арабский) ---
if (b1 >= 0xC2 && b1 <= 0xDF) {
; Проверяем, есть ли следующий байт и является ли он валидным байтом продолжения (10xxxxxx)
if (ptr + 1 < endPtr) {
b2 := NumGet(ptr + 1, "UChar")
if (b2 >= 0x80 && b2 <= 0xBF) {
; Склеиваем два байта по формуле Unicode
charUnit := ((b1 & 0x1F) << 6) | (b2 & 0x3F)
outString .= Chr(charUnit)
ptr += 2
continue
}
}
}
; --- 3. Потенциальный правильный UTF-8 (3 байта: Иероглифы) ---
if (b1 >= 0xE0 && b1 <= 0xEF) {
if (ptr + 2 < endPtr) {
b2 := NumGet(ptr + 1, "UChar")
b3 := NumGet(ptr + 2, "UChar")
if (b2 >= 0x80 && b2 <= 0xBF && b3 >= 0x80 && b3 <= 0xBF) {
charUnit := ((b1 & 0x0F) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F)
outString .= Chr(charUnit)
ptr += 3
continue
}
}
}
; --- 4. Потенциальный правильный UTF-8 (4 байта: Эмодзи, редкие знаки) ---
if (b1 >= 0xF0 && b1 <= 0xF4) {
if (ptr + 3 < endPtr) {
b2 := NumGet(ptr + 1, "UChar")
b3 := NumGet(ptr + 2, "UChar")
b4 := NumGet(ptr + 3, "UChar")
if (b2 >= 0x80 && b2 <= 0xBF && b3 >= 0x80 && b3 <= 0xBF && b4 >= 0x80 && b4 <= 0xBF) {
charUnit := ((b1 & 0x07) << 18) | ((b2 & 0x3F) << 12) | ((b3 & 0x3F) << 6) | (b4 & 0x3F)
outString .= Chr(charUnit)
ptr += 4
continue
}
}
}
; --- 5. ВЫРАВНИВАНИЕ БРАКА: Это изолированный байт ANSI (CP1251) ---
; Если байт попал сюда, значит он не прошел проверку на UTF-8.
; Для русской кодовой страницы 1251: коды 0xC0...0xFF — это буквы А-Я и а-я.
if (b1 >= 0xC0 && b1 <= 0xFF) {
; Математическое смещение из таблицы CP1251 в Unicode (диапазон U+0410...U+044F)
; 0xC0 (А в CP1251) становится 0x0410 (А в Unicode)
outString .= Chr(b1 + 0x0350)
} else if (b1 == 0xA8) {
outString .= "Ё"
} else if (b1 == 0xB8) {
outString .= "ё"
} else {
; Любой другой неопознанный битый байт (например, системный 0x80)
outString .= Chr(0xFFFD)
}
ptr += 1 ; Шагаем строго на 1 байт, так как это был одиночный ANSI символ
}
return outString
}
|
|
|