Unicode чехол складывается в верхний регистр

Я пытаюсь реализовать библиотеку для чтения файлов формата Microsoft CFB (Compound File Binary) в соответствии с официальной спецификацией этого формата. Спецификация доступна с этого сайта.

В двух словах - некоторые структуры файла хранятся в красно-черном дереве. У меня проблема с предикатом сравнения, используемым для хранения этих структур в этом дереве. В спецификации говорится, что если имена (строки хранятся как UTF-16, стандарт в API Windows) этих структур различны, необходимо выполнить итерацию по каждой кодовой точке UTF-16 и:

(...) преобразование в верхний регистр с помощью алгоритма преобразования регистра по умолчанию в Юникоде, простой вариант преобразования регистра (простые преобразования регистра) со следующими примечаниями.<2> Сравните каждое двоичное значение кодовой точки UTF-16 в верхнем регистре.

<2> Ссылка говорит, что:

или Windows XP и Windows Server 2003: реализация составного файла соответствует стандартному алгоритму преобразования регистра Unicode 3.0.1, простое сворачивание регистра ( http://www.unicode.org/Public/3.1-Update1/CaseFolding-4.txt) со следующими исключениями.

Однако, когда я посмотрел указанный файл сворачивания регистра и прочитал упомянутое в нем UTR #21 "Отображение регистра", я понял, что сворачивание регистра определяется как операция, которая гораздо больше похожа на нижний регистр, а не на верхний регистр. корпус.

Используя CaseFolding-4.txt, мы можем получить сопоставления заглавных букв в верхнем регистре и строчных. Отображение всегда 1 к 1, поскольку здесь не нужны полные свертки (те, которые расширяются до нескольких символов). Однако обратное отображение букв нижнего регистра в верхний регистр больше не является простым. Например,

0392; C; 03B2; # GREEK CAPITAL LETTER BETA
03D0; C; 03B2; # GREEK BETA SYMBOL

Таким образом, мы не можем знать, 03B2 следует преобразовать в 0392 или же 03D0, Стандарт определяет что-то вроде складывания в верхний регистр? Может быть, я должен использовать сворачивание регистра, а затем преобразовать в верхний регистр? Или я правильно понял спецификацию?

2 ответа

Решение

Резюме: формулировка, используемая Microsoft... сбивает с толку, если не сказать больше. Похоже, что должно быть сделано простое отображение в верхнем регистре, хотя я не уверен.


Фон

Частично путаница может заключаться в разнице между свертыванием и отображением дел. Отображение регистра отображает каждый символ в указанном регистре. Свертывание регистра, хотя оно основано на нижнем регистре, определено так, чтобы приводить к символам без регистра ( UTR # 21 §1.3).

Сейчас существует два варианта картографирования и складывания карт, простой и полный. В отличие от простого преобразования, полное можно изменить длину строки, и, как вы правильно заметили, здесь не требуется. Спецификация конкретно упоминает простую и, вероятно, единственную ясную вещь в этом ответе. Я чувствую необходимость упомянуть в будущем, что в текущем стандарте Unicode (6.3.0) упоминается, что преобразование регистра по умолчанию является полным, хотя версия, на которую ссылается Microsoft (3.1.1), по-видимому, не делает этого различия.

Спек Анализ

(...) преобразование в верхний регистр с помощью алгоритма преобразования регистра по умолчанию в Юникоде, простой вариант преобразования регистра (простые преобразования регистра) со следующими примечаниями.<2> Сравните каждое двоичное значение кодовой точки UTF-16 в верхнем регистре.

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

Для Windows XP и Windows Server 2003: реализация составного файла соответствует стандартному алгоритму преобразования регистра Unicode 3.0.1, простое сворачивание регистра ( http://www.unicode.org/Public/3.1-Update1/CaseFolding-4.txt) со следующими исключениями.

Они на самом деле упоминают файл данных сворачивания дела! На данный момент, я не уверен, что думать. Моя основная мысль заключается в том, что Microsoft хочет сворачивать корпус, хотя ошибочно полагал, что он основан на верхнем, а не на нижнем корпусе. Хотя это даже натянуто, но ближе всего я смог примирить это возможное противоречие, и я надеюсь, что есть лучшее объяснение.

В разделе 2.6.1 я нашел следующее, которое поддерживает некоторую форму верхнего регистра:

[...] имя записи каталога сравнивается с помощью специального нечувствительного к регистру отображения верхнего регистра, описанного в Красно-черном дереве.

Обратите внимание, что они на самом деле используют термин сопоставление здесь.

Список исключений

Взглянув на список исключений для упомянутых Windows XP и Windows Server 2003, большинство записей представляют собой вычитания, указывающие на то, что Microsoft хочет сохранить четкие позиции кода. Однако в таблице кодовые точки фактически перечислены в обратном порядке по отношению к файлу данных свертывания регистра Unicode.

Одно из объяснений этого заключается в том, что это просто причуды дисплея. Эта идея сбита последним рядом, где они вычитают преобразование случая 0x03C2 -> 0x03C2, Это преобразование не существует в файле данных, так как преобразование 0x03C2 -> 0x03C3 делает (преобразование в незарегистрированном случае считается преобразованным в себя).

Другое объяснение состоит в том, что они действительно ошибочно полагают, что это правильное обратное отображение. Как вы уже упоминали, это создает проблемы, так как обратное отображение не всегда простое. В противном случае это толкование было бы хорошо.

Третье толкование состоит в том, чтобы считать их ссылку на файл свертывания данных случая Unicode неправильной. Это, конечно, заставляет меня чувствовать себя неловко, но если бы они действительно имели в виду первоначальное отображение случаев, они могли просто предоставить ссылку в качестве краткого справочного ориентира. Список исключений, о котором они упоминают, имеет заголовки столбцов, такие как "Кодовая точка UTF-16 в нижнем регистре", но мы знаем, что на самом деле сворачивание регистров происходит без учета регистра.

Кроме того, я рассмотрел список исключений для более поздних операционных систем, надеясь получить более глубокое понимание. Я нашел больше путаницы. В частности добавление 0x03C3 -> 0x03A3 беспокоит меня Так как список исключений и файл Unicode перечисляют их кодовые точки в обратном порядке, оказывается, что преобразование уже находится в файле данных и не нуждается в добавлении. Эта часть спецификации не хочет быть понятой!

Заключение

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

  • Простое отображение в верхнем регистре
  • Простое сворачивание регистра с последующим простым отображением верхнего регистра
  • Простой чехол складной

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

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

Кажется, что единственный способ узнать наверняка - это связаться с Microsoft или тщательно изучить двоичные файлы, чтобы узнать, какой метод используется.

В разделе 3.13 Алгоритмы регистров по умолчанию (стр. 115) Стандартной версии Unicode 6.2 - Базовая спецификация текст ссылается на UnicodeData.txt. Это содержит:

03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392
03D0;GREEK BETA SYMBOL;Ll;0;L;<compat> 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392

что указывает на то, что греческая буква Beta действительно должна отображаться на греческий символ Beta, а в качестве отступления указывает, что эти два символа имеют некоторый уровень совместимости. Он также содержит остаток от двунаправленной конверсии, которую вы ищете. Вам также может понадобиться посмотреть SpecialCasing.txt для граничных случаев.

Другие вопросы по тегам