Как работает поддержка TinyXML в UTF-8? - PullRequest
12 голосов
/ 29 сентября 2008

Я использую TinyXML для анализа / построения файлов XML. Теперь, согласно документации , эта библиотека поддерживает многобайтовые наборы символов через UTF-8. Пока все хорошо, я думаю. Но единственный API, который предоставляет библиотека (для получения / установки имен элементов, имен и значений атрибутов, ... всего, где используется строка), - через std::string или const char*. Это заставляет меня сомневаться в моем собственном понимании поддержки набора многобайтовых символов. Как строка, которая поддерживает только 8-битные символы, может содержать 16-битный символ (если только она не использует кодовую страницу, которая сводит на нет утверждение «поддерживает Unicode»)? Я понимаю, что теоретически можно взять 16-битную кодовую точку и разделить ее на 2 символа в std::string, но это не приведет к преобразованию std::string в строку «Юникод», это сделает его недействительным для большинства целей и может случайно работать при записи в файл и при чтении другой программой.

Итак, кто-нибудь может объяснить мне, как библиотека может предложить «8-битный интерфейс» (std::string или const char*) и при этом поддерживать строки «Юникод»?

(я, вероятно, перепутал некоторую терминологию Unicode здесь; извините за любую путаницу из-за этого).

Ответы [ 3 ]

8 голосов
/ 29 сентября 2008

Во-первых, utf-8 хранится в константных символьных строках, как сказал @quinmars. И это не только надмножество 7-битного ASCII (кодовые точки <= 127 всегда кодируются одним байтом как сами по себе), более того, осторожно, чтобы байты с этими значениями никогда не использовались как часть кодирования многобайтовых значений для кодовых точек > = 128. Таким образом, если вы видите байт == 44, это символ «<» и т. Д. Все метасимволы в XML находятся в 7-битном ASCII. Таким образом, можно просто проанализировать XML, разбивая строки, о которых говорят метасхемы, вставляя фрагменты (возможно, включая не-ASCII-символы) в char * или std :: string, и возвращаемые фрагменты остаются действительными строками UTF-8, даже если парсер специально не знал UTF-8. </p>

Далее (не специфично для XML, но довольно умно), даже более сложные вещи, как правило, просто работают (тм). Например, если вы сортируете лексикографически UTF-8 по байтам, вы получаете тот же ответ, что и лексикографически сортировать его по кодам, несмотря на изменение количества используемых байтов, поскольку префикс байтов вводит более длинный (и, следовательно, более высокий) код точки численно больше, чем точки для меньших значений).

2 голосов
/ 29 сентября 2008

UTF-8 совместим с 7-битным кодом ASCII. Если значение байта больше 127, это означает, что начинается многобайтовый символ. В зависимости от значения первого байта вы можете увидеть, сколько байтов займет символ, это может быть 2-4 байта, включая первый байт (возможны также технические 5 или 6, но они недопустимы utf-8) Вот хороший ресурс о UTF-8: UTF-8 и FAQ по Unicode , также вики-страница для utf8 очень информативна. Поскольку UTF-8 основывается на символах и заканчивается на 0, вы можете использовать стандартные строковые функции для большинства вещей. Единственное, что важно, это то, что количество символов может отличаться от количества байтов. Такие функции, как strlen (), возвращают количество байтов, но не обязательно количество символов.

0 голосов
/ 29 сентября 2008

Используя от 1 до 4 символов для кодирования одной кодовой точки Unicode.

...