Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.06.05;
Скачать: CL | DM;

Вниз

Пара вопросов про Unicode   Найти похожие ветки 

 
Fr0sT   (2009-10-20 15:52) [0]

Копаясь в коде и переделывая его под Unicode (а точнее, и для Unicode, и для Ansi), столкнулся с двумя вопросами в использовании функций MultiByteToWideChar:

1) Как определить, сколько байт (символов исходной строки) успешно сконвертировано в WideChar, если функция возвращает только количество результирующих WideChar

Для чего это нужно: я конвертирую информацию из буфера, который может произвольным образом разделить строки. То есть нередка ситуация, когда в одну итерацию в конце буфера остаётся кусок unicode символа, остальная часть которого получается только в следующей итерации. Чтобы не терять этот символ, нужно знать, сколько байт реально было сконвертировано, и перенести остаток в начало буфера перед следующим чтением в него. Пока что для этого я использую
CharCnt := WideCharToMultiByte(CP, 0, pDestW, WCharCnt, nil, 0, nil, nil);
то есть сразу же конвертирую полученную Wide строку обратно, тем самым получая искомое количество исходных символов. Возможно, есть другой, более правильный и быстрый способ?

2) Как обращаться с кодировками utf16*

MultiByteToWideChar возвращает ошибку, если кодовая страница равна одной из этих кодировок. В хелпе везде указано, что они «available only to managed applications». Что это значит? Я гуглил, но ничего внятного не нашёл. Порылся в SysUtils.TEncoding, они там вручную копируют байты один в один для little-endian и с перестановкой порядка для big-endian. Но неужели обращение с этими кодировками не предусмотрено в MultiByteToWideChar?

P.S. Варианты типа &laquo;заюзай TEncoding и не парь мозги&raquo; не подходят &#151; хочу обратной совместимости с D < 2009.


 
palva ©   (2009-10-20 20:01) [1]

Наверно, лучше определить границу последнего символа и давать на преобразование строку без неполных символов. Первый байт символа UTF8 имеет единицу в двух старших битах (когда символ состоит из нескольких байтов), либо нуль в старшем бите (состоит из одного байта).

А ваш метод будет вносить дополнительные ошибки в случае, если в середине строки встретился ошибочный символ. Насколько я понимаю, он просто исчезнет из результирующей строки, и по вашему алгоритму вы будете дублировать последний символ, либо выходить на середину символа.

В документации на API описан флаг, который нужно установить, чтобы функция сигнализировала об ошибке, если в строке были плохие символы. Было бы корректнее установить этот флаг и проверять код ошибки.



Страницы: 1 вся ветка

Текущий архив: 2011.06.05;
Скачать: CL | DM;

Наверх




Память: 0.47 MB
Время: 0.009 c
15-1297514092
NailMan
2011-02-12 15:34
2011.06.05
Наконец то я решился на это...


2-1298177204
Gu
2011-02-20 07:46
2011.06.05
Версия SQL клиента и сервера - узнать


2-1294930060
Scott Storch
2011-01-13 17:47
2011.06.05
загрузка dll из ресурса


15-1297841206
И. Павел
2011-02-16 10:26
2011.06.05
Явамастер


15-1297805399
Юрий
2011-02-16 00:29
2011.06.05
С днем рождения ! 16 февраля 2011 среда