Основная проблема в UILexerCheckIsMultiByte. Для декодирования потоков utf8 вам нужно посмотреть
на первых (старших) 2 битах каждого байта.
если они "01", это 8-битный код символа,
если они равны «11», то это первый байт многобайтовой последовательности,
если они равны 10, это один байт внутри многобайтовой последовательности.
Ваше первое двоичное сравнение корректно:
(ch & 0xC0) == 0xC0 - это замаскирует первые два бита и проверит наличие шаблона "11xxxxxx" (x означает, что все равно)
но ваше следующее сравнение неверно. при первом запуске вы проверяете:
(ch & 0xE0) == 0xC0 - это замаскирует первые три бита и проверит наличие шаблона «11xxxxx», но вы должны проверить «10xxxxxx».
так что, возможно, вы посмотрите на следующий код:
есть две версии strlen и одна функция для подсчета количества байтов многобайтовой последовательности.
/* gcc -Wall -o strlen strlen.c */
#include "stdio.h"
int utf8charsize(char *s)
{
int cnt=0;
if( *s ) {
cnt++;
if( (*s & 0xc0) == 0x0c0 ) { /* binary is 11xxxxxx */
while( (s[cnt] & 0xc0) == 0x80 ) /* binary code is 10xxxxxx */
cnt++;
}
}
printf("-- %d\n", cnt );
return cnt;
}
int utf8strlen(char *s)
{
int cnt=0;
int clen;
while(*s) {
clen=utf8charsize(s);
cnt++;
s+=clen;
}
return cnt;
}
int utf8strlen2(char *s)
{
int cnt=0;
while(*s) {
cnt++;
if( (*s++ & 0xc0) == 0x0c0 ) { /* binary is 11xxxxxx */
while( (*s & 0xc0) == 0x80 ) /* binary code is 10xxxxxx */
s++;
}
}
return cnt;
}
int main(int argc, char **argv)
{
if( argc > 1 )
printf("%d %d\n", utf8strlen(argv[1]), utf8strlen2(argv[1]));
return 0;
}