Это не Паскаль, это типизированный Бейсик.
Вот мой рабочий код — каждый вызов читает одну кодовую позицию, перемещая первый указатель на нужное кол-во слов вперёд. Переведёшь в нужные тебе соглашения по работе? — например, ты можешь читать информацию не из памяти, а из файла или ещё откуда-то.
enum {
SURROGATE_MIN = 0xD800,
SURROGATE_MAX = 0xDFFF,
SURROGATE_LO_MIN = SURROGATE_MIN,
SURROGATE_HI_MIN = 0xDC00,
SURROGATE_LO_MAX = SURROGATE_HI_MIN - 1,
SURROGATE_HI_MAX = SURROGATE_MAX,
UNICODE_MAX = 0x10FFFF,
U8_1BYTE_MAX = 0x7F,
U8_2BYTE_MIN = 0x80,
U8_2BYTE_MAX = 0x7FF,
U8_3BYTE_MIN = 0x800,
U8_3BYTE_MAX = 0xFFFF,
U8_4BYTE_MIN = 0x10000,
U8_4BYTE_MAX = UNICODE_MAX,
U16_1WORD_MAX = 0xFFFF,
U16_2WORD_MIN = 0x10000,
U16_2WORD_MAX = UNICODE_MAX,
};
#define CHAR_BOM L'\uFEFF'
#define UNICODE_NONE (0xFFFFFFFFUL)
#define UNICODE_BAD (0xFFFFFFFEUL)
unsigned long str::getCp(const uint16_t*& aCurr, const uint16_t* aEnd)
{
if (aCurr == aEnd)
return UNICODE_NONE;
unsigned long cp = *(aCurr++);
if (cp < SURROGATE_HI_MIN) {
if (cp < SURROGATE_MIN) { // Low BMP char => OK
return cp;
} else { // Leading surrogate
if (aCurr == aEnd)
return UNICODE_BAD;
unsigned long trailing = *aCurr;
if (trailing < SURROGATE_HI_MIN || trailing > SURROGATE_HI_MAX)
return UNICODE_BAD;
++aCurr;
return (((cp & 0x3FF) << 10) | (trailing & 0x3FF)) + 0x10000;
}
} else {
if (cp <= SURROGATE_MAX) { // Trailing surrogate
return UNICODE_BAD;
} else { // High BMP char => OK
return cp;
}
}
}
Параметры: первый (передан по сцылке) — подвижная «каретка», второй указывает за конец строки.
Возвращает: NONE, если читать больше нечего, BAD, если считал херню, и кодовую позицию — если таковая всё-таки считалась.
Алгоритм: читаем слово. Двумя сравнениями относим его к одному из четырёх диапазонов: 1) нижний диапазон базовой плоскости, 2) нижний суррогатный символ; 3) верхний суррогатный символ; 4) верхний диапазон базовой плоскости. Если 1 или 4, так его и возвращаем, если 3 — видим херню.
Если же 2, считываем слово, не смещая каретки. Если слово не верхний суррогатный символ — херня. В противном случае смещаем каретку и собираем номер кодовой позиции.