FromUtf8 ещё раз
Модератор: Дед Пахом
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
-
- Посетитель
- Сообщения: 36
- Зарегистрирован: 05 Февраль 2006, 17:49
- Откуда: Orenburg
- Контактная информация:
FromUtf8 ещё раз
Встала задача по парсингу XML и заполнению БД.
Я благодарю Юрия Философова и Олега А. Руденко за их разъяснения по работе
с XML и классами на нашем форуме.
Распутал работу файла cpxml.clw и других xmlclass.inc XMLCONV.CLW ...
Anatoly Medyntsev добросовестно проштудировал expat.
Универсализм - это наше всё на все случаи жизни!
Пришлось делать свой парсер для конкретных БОЛЬШИХ файлов.
Встала задача перекодировки UTF-8 в CP-1251, она же Windows-1251
MS_1251 и CP-1251.
Я благодарю Юрия Философова и Олега А. Руденко за их разъяснения по работе
с XML и классами на нашем форуме.
Распутал работу файла cpxml.clw и других xmlclass.inc XMLCONV.CLW ...
Anatoly Medyntsev добросовестно проштудировал expat.
Универсализм - это наше всё на все случаи жизни!
Пришлось делать свой парсер для конкретных БОЛЬШИХ файлов.
Встала задача перекодировки UTF-8 в CP-1251, она же Windows-1251
MS_1251 и CP-1251.
Clarion v.6-11 и т.п. Код-всё, данные-частности
-
- Посетитель
- Сообщения: 36
- Зарегистрирован: 05 Февраль 2006, 17:49
- Откуда: Orenburg
- Контактная информация:
FromUtf8 ещё раз
Я восхищён Робертом Пайком - по его книге и K&R учился Си.
Превращение громоздкого 4-байтового U+cod из таблицы 256х256
в облегченный Utf-8 (почти таблица 16х16) привело
к фактическому стандарту во всех опер системах.
Разобрался с перекодировкой из Utf-8. Мягко говоря - охренел!!!
Utf-8 преобразовать в U+cod, затем в нужную кодовую страницу...
Вызовы из ОС функций, подгрузка-привязка DLL...
Конвертация в 1251 из utf-8
Blength = MultiByteToWideChar (CP_UTF8, 0, address(S), -1, address(Buffer2), 0)
RetCode = MultiByteToWideChar (CP_UTF8, 0, address(S), -1, address(Buffer2), Blength)
RetCode = WideCharToMultiByte (CP_ACP0, 0, address(Buffer2),Blength, address(Buffer1), Slength, 0, 0)
Универсализм - это наше всё на все случаи жизни!
Превращение громоздкого 4-байтового U+cod из таблицы 256х256
в облегченный Utf-8 (почти таблица 16х16) привело
к фактическому стандарту во всех опер системах.
Разобрался с перекодировкой из Utf-8. Мягко говоря - охренел!!!
Utf-8 преобразовать в U+cod, затем в нужную кодовую страницу...
Вызовы из ОС функций, подгрузка-привязка DLL...
Конвертация в 1251 из utf-8
Blength = MultiByteToWideChar (CP_UTF8, 0, address(S), -1, address(Buffer2), 0)
RetCode = MultiByteToWideChar (CP_UTF8, 0, address(S), -1, address(Buffer2), Blength)
RetCode = WideCharToMultiByte (CP_ACP0, 0, address(Buffer2),Blength, address(Buffer1), Slength, 0, 0)
Универсализм - это наше всё на все случаи жизни!
Clarion v.6-11 и т.п. Код-всё, данные-частности
-
- Посетитель
- Сообщения: 36
- Зарегистрирован: 05 Февраль 2006, 17:49
- Откуда: Orenburg
- Контактная информация:
FromUtf8 ещё раз
Пришлось вспоминать перекодировку в DOS системах.
В обычном INI-файле делаются секции для каждой кодировки.
Алгоритм прост.
Делаются 2 строки-массива -код1 и код2.
Ищется байт-символ в одной строке-массиве и по индексу-позиции
берётся байт-символ из той-же позиции строки-массива код2.
Всё. Сколько кодировок - столько строк-массивов символов в файле.
Даже транслит сделан подобно.
Неужели никто не делал? Обратился в Интернет - и сразу нашлась
таблица соответствия кодов Utf_8 с кодами СP-1251, CP-866, КОИ-8...
Посмотрел. посчитал и получил...
В обычном INI-файле делаются секции для каждой кодировки.
Алгоритм прост.
Делаются 2 строки-массива -код1 и код2.
Ищется байт-символ в одной строке-массиве и по индексу-позиции
берётся байт-символ из той-же позиции строки-массива код2.
Всё. Сколько кодировок - столько строк-массивов символов в файле.
Даже транслит сделан подобно.
Неужели никто не делал? Обратился в Интернет - и сразу нашлась
таблица соответствия кодов Utf_8 с кодами СP-1251, CP-866, КОИ-8...
Посмотрел. посчитал и получил...
Clarion v.6-11 и т.п. Код-всё, данные-частности
-
- Посетитель
- Сообщения: 36
- Зарегистрирован: 05 Февраль 2006, 17:49
- Откуда: Orenburg
- Контактная информация:
FromUtf8 ещё раз
Код: Выделить всё
FromUtf8 PROCEDURE(STRING StrIn)
DATE
outStr &STRING, AUTO ! ссылка на выходная строка
inStr &STRING, AUTO ! ссылка на входная строка
i SIGNED,AUTO ! индекс-позиция входной строки
j SIGNED(1) ! индекс-позиция выходной строки
! он же счётчик сконвертированных символов
CODE
inStr &= StrIn ! укажем ссылку-реферал на строку UTF-8 откуда
outStr &= NEW STRING(SIZE(inStr)) ! конструктор выходной строки
! или указать ссылку на строку вывода - куда
LOOP i = 1 TO SIZE(inStr) ! цикл по входной строке
IF VAL(inStr[i]) <= 07FH ! номер символа меньше 127 -Latin
outStr[j] = inStr[i] ! без конвертации в позицию новой строки
end
IF VAL(inStr[i]) = 194 ! номер след. символа 1251
i += 1 ! след символ
outStr[j] = inStr[i]
end
IF VAL(inStr[i]) = 208 ! русские символы из 2-х байт
i += 1 ! след символ
IF VAL(inStr[i]) = 129 ! буква Ё
outStr[j] = CHR(VAL(inStr[i]) + 39)
else
IF VAL(inStr[i]) >143
outStr[j] = CHR(VAL(inStr[i]) + 48)
end
END
END
IF VAL(inStr[i]) = 209 ! русские символы
i += 1 ! след символ
IF VAL(inStr[i]) = 145 ! буква ё
outStr[j] = CHR(VAL(inStr[i]) + 39)
else
IF VAL(inStr[i]) < 144
outStr[j] = CHR(VAL(inStr[i]) + 112)
end
END
END
! здесь проверка символов кириллицы - не русских букв
j += 1 ! счётчик сконвертированных символов
END
! вариант возврата результата
V = CLIP (outStr) ! пробелы в конце убираем
DISPOSE (outStr) ! Освободить память в куче
RETURN V ! вернём строку
но это работает - проверенно.
и никаких обёрток!!!...
Clarion v.6-11 и т.п. Код-всё, данные-частности
- Игорь Столяров
- Ветеран движения
- Сообщения: 6551
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 5 раз
- Поблагодарили: 21 раз
FromUtf8 ещё раз
Здравствуйте ! 
А зачем вот это всё ?
Более 20 лет конвертация кодировок делается через WinAPI ... есть разные реализации, например:

А зачем вот это всё ?

Более 20 лет конвертация кодировок делается через WinAPI ... есть разные реализации, например:
Код: Выделить всё
! Перекодировка строки текста UTF8 -> ANSI
UTF8toANSI Procedure(String sStr) !,String
UnicodeText String(Size(sStr)*2+2)
ANSIText String(Size(sStr)*2+2)
bytesWritten Long, Auto
Len Long, Auto
Code
If (Size(sStr) = 0) Or (sStr = '<0>') then Return ''
else
bytesWritten = MultiByteToWideChar(65001, 0,Address(sStr), Len(sStr), Address(UnicodeText),Size(UnicodeText))
Len = WideCharToMultiByte(GetACP(),0,Address(UnicodeText),bytesWritten,Address(ANSIText), Size(ANSIText),0,0)
If Len <= 0 then Return ''
else
Loop
If Sub(ANSIText,Len,1) = '<0>' then Len -= 1 else Break.
end
Return Sub(ANSIText,1,Len)
end
end
Приносим Вам свои неудобства !
-
- Посетитель
- Сообщения: 36
- Зарегистрирован: 05 Февраль 2006, 17:49
- Откуда: Orenburg
- Контактная информация:
FromUtf8 ещё раз
Просто ещё один частный вариант для частных случаев...
Clarion v.6-11 и т.п. Код-всё, данные-частности
- Игорь Столяров
- Ветеран движения
- Сообщения: 6551
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 5 раз
- Поблагодарили: 21 раз
FromUtf8 ещё раз
А Вы уверены что Ваша "табличка из интернета" сработает на всём многообразии версий Windows от 95 до 11 ?
Вы тестировали такое решение на всех вариантах кодовых страниц Windows и национальных кодировок ?
Приносим Вам свои неудобства !
-
- Посетитель
- Сообщения: 36
- Зарегистрирован: 05 Февраль 2006, 17:49
- Откуда: Orenburg
- Контактная информация:
FromUtf8 ещё раз
Делалось только для 1251
Другие кодовые страницы и кодировки даже не рассматривались.
Частный вариант для частного применения.
Другие кодовые страницы и кодировки даже не рассматривались.
Частный вариант для частного применения.
Clarion v.6-11 и т.п. Код-всё, данные-частности
- Дед Пахом
- Старичок
- Сообщения: 3015
- Зарегистрирован: 07 Июль 2005, 16:51
- Откуда: Москва, Россия
- Благодарил (а): 2 раза
- Поблагодарили: 15 раз
- Контактная информация:
FromUtf8 ещё раз
Не удивлюсь если MultiByteToWideChar/WideCharToMultiByte так и работают с таблицами.
С уважением, ДП
-
- Посетитель
- Сообщения: 36
- Зарегистрирован: 05 Февраль 2006, 17:49
- Откуда: Orenburg
- Контактная информация:
FromUtf8 ещё раз
Чуть обновил файл таблицы для знаков.
Clarion v.6-11 и т.п. Код-всё, данные-частности
-
- Посетитель
- Сообщения: 36
- Зарегистрирован: 05 Февраль 2006, 17:49
- Откуда: Orenburg
- Контактная информация:
FromUtf8 ещё раз
Добавил проверку 3- байтовых
Код: Выделить всё
FromUtf8 PROCEDURE(STRING StrIn)
DATE
outStr &STRING, AUTO ! ссылка на выходная строка
inStr &STRING, AUTO ! ссылка на входная строка
i SIGNED, AUTO ! индекс-позиция входной строки =0
j SIGNED, AUTO ! индекс-позиция выходной строки =0
! он же счётчик сконвертированных символов
in3b STRING ! для 3-х байтовых символов Utf-8 последний байт
out3b STRING ! символы 1251 соответственно
CODE
inStr &= StrIn ! укажем ссылку-реферал на строку UTF-8 откуда
outStr &= NEW STRING(SIZE(inStr)) ! конструктор выходной строки
! или указать ссылку на строку вывода - куда
! пара массивов для 3-х байтовых символов Utf-8 последний байт
in3b = '<147><147><152><153><154><156><157><158><160><161><162><166><176><185><186><172><150>'
out3b= '<150><151><145><146><130><147><148><132><134><135><149><133><137><139><155><136><185>'
LOOP i = 1 TO SIZE(inStr) ! цикл по входной строке
j += 1 ! счётчик сконвертированных символов
IF VAL(inStr[i]) <= 07FH ! номер символа меньше 127 -Latin
outStr[j] = inStr[i] ! без конвертации в позицию новой строки
end
IF VAL(inStr[i]) = 194 ! номер след. символа 1251
i += 1 ! след символ
outStr[j] = inStr[i]
end
IF VAL(inStr[i]) = 208 ! русские символы из 2-х байт
i += 1 ! след символ
IF VAL(inStr[i]) = 129 ! буква Ё
outStr[j] = CHR(VAL(inStr[i]) + 39)
else
IF VAL(inStr[i]) >143
outStr[j] = CHR(VAL(inStr[i]) + 48)
end
END
END
IF VAL(inStr[i]) = 209 ! русские символы
i += 1 ! след символ
IF VAL(inStr[i]) = 145 ! буква ё
outStr[j] = CHR(VAL(inStr[i]) + 39)
else
IF VAL(inStr[i]) < 144
outStr[j] = CHR(VAL(inStr[i]) + 112)
end
END
END ! русские символы 209
! здесь проверка символов кириллицы - не русских 15 штук 2-байтовые 209,210>143
! ищем знаки 3-байтовые, типа номер №, многоточие... евро
IF VAL(inStr[i]) = 226 ! 3-байтовые 226 - достаточно для проверки
i += 1 ! след символ
IF VAL(inStr[i]) = 132 ! 3-байтовые 132
i += 1 ! след символ
IF VAL(inStr[i]) = 162 ! дублирован 162, поэтому отдельно
outStr[j] = '<153>' ! товарныйзнак
cycle ! нашли - в начало цикла
end
end ! 3-байтовые 132
i += 1 ! след байт перескакиваем на символ
LOOP s# = 1 TO 17 ! SIZE(in3b)
IF VAL(in3b[s#]) = VAL(inStr[i]) ! 3-байтовые 128,130,132
outStr[j] = out3b[s#]
break ! нашли-искать не надо
end
end ! LOOP s# = 1 TO SIZE(in3b)
end ! IF VAL(inStr[i]) = 226
END ! LOOP i = 1 TO SIZE(inStr)
Clarion v.6-11 и т.п. Код-всё, данные-частности
-
- Посетитель
- Сообщения: 36
- Зарегистрирован: 05 Февраль 2006, 17:49
- Откуда: Orenburg
- Контактная информация:
FromUtf8 ещё раз
STRING(17) для строк пар кодов , чтобы компилятор не ругался
На тесте № нашёл.
На тесте № нашёл.
Clarion v.6-11 и т.п. Код-всё, данные-частности
-
- Посетитель
- Сообщения: 36
- Зарегистрирован: 05 Февраль 2006, 17:49
- Откуда: Orenburg
- Контактная информация:
FromUtf8 ещё раз
Добавил НЕ русские символы
Уменьшил время возвратом в начало цикла, когда нашли.
Полная перекодировка CP-1251
Уменьшил время возвратом в начало цикла, когда нашли.
Полная перекодировка CP-1251
Clarion v.6-11 и т.п. Код-всё, данные-частности