1. Многим понятны преимущества, которые даёт юникод, расписывать не буду.
2. Уже обсуждалось - многие согласны. viewtopic.php?f=32&t=144
3. Прикрепляю библиотеку для работы с юникодом. Два файла размером 15-20Кб на Си - могут быть переведены в ассемблер.
Остальное данные.
Юникод
-
- Attachments
-
-
utf8proc-v1.1.5.tar.gz (103.33 KiB)
- utf8-proc
Downloaded 460 times
-
за либу спасибо , а насчёт Колибри - я бы предложил специфицировать, как и где в системе применяется юникод.
Было бы хорошо, если бы везде применялся. Я однобайтовую кодировку использую только при прямом выводе на текстовую консоль, причем даже здесь при желании можно добиться одновременного отображения 512 различных символов.
GNU GPL v2 License as specified on http://www.gnu.org. All Rights Reserved.
сколько всяких проверок бля, в одной простой функции
Code: Select all
utf8_1stBait_validation:
db 1,1,1,1,1,1,1,1
db 1,1,1,1,1,1,1,1
db 0,0,0,0,0,0,0,0
db 2,2,2,2,3,3,4,0
;GNU GPL v2 License as specified on http://www.gnu.org. All Rights Reserved.
; Reads utf-8 symbol into EAX at ESI.
; If function completes without error - ESI advances to next potential symbol
; Function foesn't validate unicode ranges
;---------------------------------------------------------------------------------------------------
; input: esi - pointer to memory with 4bait read access
; return:
; eax - value
; ecx - number of baits in utf-8 symbol, or =0 if invalid symbol
; CF=0 if ecx !=0, CF=1 if ecx=0
; detroyed:
; eflags, edx, esi+=ecx
utf8_nextChar:
cld
xor eax ,eax
lodsb
xor ecx, ecx
movzx edx, al
shr eax, 3
and edx, 1111111b
add cl, byte [utf8_1stBait_validation+eax] ; cl = number of bytes in the utf8 symbol
jz .err2
cmp cl, 3
ja .4
jz .3
jp .2
jmp @f
.2:
lodsb
and edx, 11111b
btr eax, 7 ; clear top bit and verify if bit is set
jnc .err
shl edx, 6
test al, $40
jnz .err
or edx, eax
; add your unicode range validation here for 2byte utf8 sequence
jmp @f
.3:
lodsw ; load 2 bytes
test eax, 0100'0000'0100'0000b ; verify that cleared bits are cleared
jnz .err
not eax
test eax, 1000'0000'1000'0000b ; verify that set bits are set
jnz .err
not eax
and edx, 1111b ; only low 4bits of 1st bait are valid
shl eax, 2
ror ax, 8 ; do
shr ah, 2 ; some
shr eax, 2 ; bit
shl edx, 12 ; swapping
and eax, $fff
or edx, eax
; add your unicode range validation here for 3byte utf8 sequence
jmp @f
.4:
dec esi
lodsd
shl edx, 8
test eax, $40404000
jnz .err
not eax
test eax, $80808000
jnz .err
not eax
mov dl, ah
bswap eax
shl dl, 2
shl eax, 2 ; eax: get rid of top 2bits in AL
shl edx, 10 ; edx[20:12] filled
shr ah, 2 ; eax: bring AH & AL together in one 12bit chunk
shr eax, 2 ; eax[11:0] filled
and edx, $1ff000
and eax, $fff
or edx, eax
; add your unicode range validation here for 4byte utf8 sequence
@@:
mov eax, edx
clc
.exit:
ret
.err2:
sub esi, 1
.err:
sub esi, ecx
xor ecx, ecx
stc
jmp .exit
Last edited by ilya on Mon Jul 16, 2012 4:47 am, edited 2 times in total.
А можно хранить кодпойнты как последовательность не из четырёх, а трёх байт Ибо больше и не надо. При этом: a) данные, которые занимает текст в такой кодировке, в среднем всего на 50% длинее чем в UTF-16 (а в некоторых случаях даже до 30% процентов короче); б) данные всегда будут фиксированной длины, никаких суррогатных пар, random access к символам в строке.
Единственный минус: в отличие от UTF-32, код-юниты не будут выравнены на 4-байтную границу, поэтому обработка будет чуть медленней (но это не критично).
P.S. А назвать это можно будет "UTF-24".
Единственный минус: в отличие от UTF-32, код-юниты не будут выравнены на 4-байтную границу, поэтому обработка будет чуть медленней (но это не критично).
P.S. А назвать это можно будет "UTF-24".
не стоит придумывать нестандартные решения - в будущем это сулит кучу проблем. Тем более выигрыш действительно невелик, возможно даже иллюзорен.
Я это в качестве внутреннего формата (для хранения строк, например, в ОЗУ) предложил. Преобразование UTF-24-to-UTF-x реализовать будет несложно.
UCS-2?
Не стоит окончательно отказываться от суррогатных пар. Просто начинать нужно с поддержки базовой плоскости. Считать все символы из дополнительных плоскостей некорректными для служебного применения (например, в именах файлов). Их коды можно рассматривать как некорректный символ с модификатором или как два некорректных символа.
А можно и как двух байт "Ибо больше и не надо" на практике, и остаешься в рамках стандарта.Joaquin wrote:А можно хранить кодпойнты как последовательность не из четырёх, а трёх байт Ибо больше и не надо.
У меня есть такая гипотеза, что проще всего будет перейти именно на UTF-8:
- разработан в группе Plan9 (те же создатели UNIX и их ученики);
- одобрен авторитетными стандартами;
- все алгоритмы, не использующие тот факт, что длина и позиция измеряется именно в символах, будут продолжать адекватно работать.
Предполагаю главные проблемы:
- вычисление длины строки в символах (а это может быть нужно для пользователя и пользовательского интерфейса) будет работать в несколько раз медленнее;
- символ уже больше не умещается даже в int (но это происходит крайне редко), а поиск (подсчёт) вхождения символа потребуется реализовывать как поиск (подсчёт) вхождения подстроки длиной в 1 - 6 байт (в контексте UTF-8 длина строки в символах <= длине строки в байтах - число ненулевых байтов до первого нулевого).
- разработан в группе Plan9 (те же создатели UNIX и их ученики);
- одобрен авторитетными стандартами;
- все алгоритмы, не использующие тот факт, что длина и позиция измеряется именно в символах, будут продолжать адекватно работать.
Предполагаю главные проблемы:
- вычисление длины строки в символах (а это может быть нужно для пользователя и пользовательского интерфейса) будет работать в несколько раз медленнее;
- символ уже больше не умещается даже в int (но это происходит крайне редко), а поиск (подсчёт) вхождения символа потребуется реализовывать как поиск (подсчёт) вхождения подстроки длиной в 1 - 6 байт (в контексте UTF-8 длина строки в символах <= длине строки в байтах - число ненулевых байтов до первого нулевого).
Требования к API Юникода есть?
Пишу сейчас реализацию, которую, как мне кажется, достаточно легко абстрагировать, ибо зависимостей минимум. TRawCodePage даже готов реализовать сам, если о формате таблиц перекодировок договоримся. Для "Колибри" вариантов два: или как-то собрать в FPC, или перенести код из дизассемблера, а потом переписать, если хочется. Есть добровольцы? Пример вывода DCU32Int прикладываю (оригинал на Паскале).
Что реализовано или будет реализовано в ближайшее время:
Хранимые данные для однобайтовой кодовой страницы -- 128 × SizeOf(WideChar) = 256 байт -- для Windows- или OEM-кодировок, и вплоть до 512 байт для EBCDIC. Таблица обратной трансляции строится уже в памяти, для Windows-1251 занимает порядка 8 КБ.
Все перекодировки делаются без потерь диакритик, появления кракозяблов и вопросиков. Именно поэтому мне и потребовалось писать собственную реализацию. Если строку нельзя представить в затребованном представлении -- это ошибка. При включённом бите coForceInvalid ошибочные символы заменяются "квадратиками".
Что пока не планируется к реализации, так это композиция-декомпозиция (NFD, NFKC, NFKD), UTF-7 и прочая редко используемая байда. Не думаю, что это актуально для "Колибри".
Пишу сейчас реализацию, которую, как мне кажется, достаточно легко абстрагировать, ибо зависимостей минимум. TRawCodePage даже готов реализовать сам, если о формате таблиц перекодировок договоримся. Для "Колибри" вариантов два: или как-то собрать в FPC, или перенести код из дизассемблера, а потом переписать, если хочется. Есть добровольцы? Пример вывода DCU32Int прикладываю (оригинал на Паскале).
Что реализовано или будет реализовано в ближайшее время:
- Перекодировка между представлениями Юникода (UTF-xx).
- Перекодировка между legacy-кодировками и Юникодом.
- Перекодировка из одной legacy-кодировки в другую через Юникод.
- Верхний-нижний регистр -- тоже через Юникод, для всех языков сразу.
- UTF-8 (включая CESU-8 и модифицированный UTF-8), UTF-16 (включая суррогатные пары, BE и LE), UTF-32 (BE и LE).
- 7-битная ASCII и ISO-8859-1 (Latin-1), не требующие таблицы перекодировки (для полноты концепций).
- Однобайтовые (включая EBCDIC) и двухбайтовые кодовые страницы (Shift-JIS, Big5 и пр.)
Хранимые данные для однобайтовой кодовой страницы -- 128 × SizeOf(WideChar) = 256 байт -- для Windows- или OEM-кодировок, и вплоть до 512 байт для EBCDIC. Таблица обратной трансляции строится уже в памяти, для Windows-1251 занимает порядка 8 КБ.
Все перекодировки делаются без потерь диакритик, появления кракозяблов и вопросиков. Именно поэтому мне и потребовалось писать собственную реализацию. Если строку нельзя представить в затребованном представлении -- это ошибка. При включённом бите coForceInvalid ошибочные символы заменяются "квадратиками".
Что пока не планируется к реализации, так это композиция-декомпозиция (NFD, NFKC, NFKD), UTF-7 и прочая редко используемая байда. Не думаю, что это актуально для "Колибри".
- Attachments
-
-
TSingleByteMemCodePage.asm (28.26 KiB)Downloaded 439 times
-
Offtop: Для Колибри? На паскале? Юникод? - Дайте два!
Мне так кажется это все надо в либу пихать.
Мне так кажется это все надо в либу пихать.
Набросал примерный API. Высказываемся.
- Attachments
-
-
Kolibri.pas (5.26 KiB)Downloaded 436 times
-
Я в паскале "не в зуб ногой". Лучше бы сделал текстовое описание. Как показывает практика даже хорошо прокомментированный код не всегда понятен, что уж говорить о известном только автору коде с мизером комментариев. Навык телепатии не прокачан.
Словесное описание -- парой сообщений выше.
Who is online
Users browsing this forum: No registered users and 2 guests