std.utf
Кодирование и декодирование строк UTF-8, UTF-16 и UTF-32.
Поддержка символов UTF ограничена '\u0000' <= character <= '\U0010FFFF'.
| Категория | Функции |
|---|---|
| Декодирование | decode decodeFront |
| Ленивое декодирование | byCodeUnit byChar byWchar byDchar byUTF |
| Кодирование | encode toUTF8 toUTF16 toUTF32 toUTFz toUTF16z |
| Длина | codeLength count stride strideBack |
| Индекс | toUCSindex toUTFindex |
| Проверка | isValidDchar validate |
| Разное | replacementDchar UseReplacementDchar UTFException |
- См. также:
-
Википедия
http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335
- Лицензия:
- Лицензия Boost 1.0.
- Авторы:
- Уолтер Брайт и Джоонатан М. Дэвис
- Источник
- std/utf.d
- class UTFException: core.exception.UnicodeException;
-
Исключение, выбрасываемое при ошибках в функциях std.utf.
- Примеры:
-
import std.exception : assertThrown; char[4] buf; assertThrown!UTFException(encode(buf, cast(dchar) 0xD800)); assertThrown!UTFException(encode(buf, cast(dchar) 0xDBFF)); assertThrown!UTFException(encode(buf, cast(dchar) 0xDC00)); assertThrown!UTFException(encode(buf, cast(dchar) 0xDFFF)); assertThrown!UTFException(encode(buf, cast(dchar) 0x110000));
- pure nothrow @nogc @safe this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null);
pure nothrow @safe this(string msg, size_t index, string file = __FILE__, size_t line = __LINE__, Throwable next = null); -
Стандартные конструкторы исключений.
- const string toString();
-
- Возвращает:
- Строку, подробно описывающую недействительную последовательность UTF.
- pure nothrow @nogc @safe bool isValidDchar(dchar c);
-
Проверяет, является ли заданный Юникод-код точкой действительным.
- Параметры:
dchar cкод точки для проверки
- Возвращает:
-
trueтогда и только тогда, когдаcявляется действительной Юникод-кодовой точкой
- Примечание
-
'\uFFFE'и'\uFFFF'считаются действительнымиisValidDchar, так как они разрешены для внутреннего использования приложением, но не допускаются для обмена по стандарту Юникод.
- Примеры:
-
assert( isValidDchar(cast(dchar) 0x41)); assert( isValidDchar(cast(dchar) 0x00)); assert(!isValidDchar(cast(dchar) 0xD800)); assert(!isValidDchar(cast(dchar) 0x11FFFF));
- uint stride(S)(auto ref S str, size_t index)
Constraints: if (is(S : const(char[])) || isRandomAccessRange!S && is(immutable(ElementType!S) == immutable(char)));
uint stride(S)(auto ref S str)
Constraints: if (is(S : const(char[])) || isInputRange!S && is(immutable(ElementType!S) == immutable(char)));
uint stride(S)(auto ref S str, size_t index)
Constraints: if (is(S : const(wchar[])) || isRandomAccessRange!S && is(immutable(ElementType!S) == immutable(wchar)));
pure @safe uint stride(S)(auto ref S str)
Constraints: if (is(S : const(wchar[])));
uint stride(S)(auto ref S str)
Constraints: if (isInputRange!S && is(immutable(ElementType!S) == immutable(wchar)) && !is(S : const(wchar[])));
uint stride(S)(auto ref S str, size_t index = 0)
Constraints: if (is(S : const(dchar[])) || isInputRange!S && is(immutable(ElementEncodingType!S) == immutable(dchar))); -
Вычисляет длину последовательности UTF, начинающейся с
indexвstr.- Параметры:
S strдиапазон ввода единиц кода UTF. Должен быть диапазоном с произвольным доступом, если indexпередаетсяsize_t indexначальный индекс последовательности UTF (по умолчанию: 0)
- Возвращает:
- Количество единиц кода в последовательности UTF. Для UTF-8 это значение от 1 до 4 (согласно RFC 3629, раздел 3). Для UTF-16 это либо 1, либо 2. Для UTF-32 всегда 1.
- Выбрасывает:
- Может выбросить исключение
UTFException, еслиstr[index]не является началом действительной последовательности UTF.
- Примечание
-
strideбудет анализировать только первыйstr[index]элемент. Она не будет полностью проверять действительность последовательности UTF, а также не будет проверять присутствие последовательности: не будет гарантировать, чтоindex + stride(str, index) <= str.length.
- Примеры:
-
writeln("a".stride); // 1 writeln("λ".stride); // 2 writeln("aλ".stride); // 1 writeln("aλ".stride(1)); // 2 writeln("𐐷".stride); // 4
- uint strideBack(S)(auto ref S str, size_t index)
Constraints: if (is(S : const(char[])) || isRandomAccessRange!S && is(immutable(ElementType!S) == immutable(char)));
uint strideBack(S)(auto ref S str)
Constraints: if (is(S : const(char[])) || isRandomAccessRange!S && hasLength!S && is(immutable(ElementType!S) == immutable(char)));
uint strideBack(S)(auto ref S str)
Constraints: if (isBidirectionalRange!S && is(immutable(ElementType!S) == immutable(char)) && !isRandomAccessRange!S);
uint strideBack(S)(auto ref S str, size_t index)
Constraints: if (is(S : const(wchar[])) || isRandomAccessRange!S && is(immutable(ElementType!S) == immutable(wchar)));
uint strideBack(S)(auto ref S str)
Constraints: if (is(S : const(wchar[])) || isBidirectionalRange!S && is(immutable(ElementType!S) == immutable(wchar)));
uint strideBack(S)(auto ref S str, size_t index)
Constraints: if (isRandomAccessRange!S && is(immutable(ElementEncodingType!S) == immutable(dchar)));
uint strideBack(S)(auto ref S str)
Constraints: if (isBidirectionalRange!S && is(immutable(ElementEncodingType!S) == immutable(dchar))); -
Вычисляет длину последовательности UTF, заканчивающейся за единицей кода до
indexвstr.- Параметры:
S strдвунаправленный диапазон единиц кода UTF. Должен быть диапазоном с произвольным доступом, если indexпередаетсяsize_t indexиндекс, следующий за концом последовательности UTF (по умолчанию: str.length)
- Возвращает:
- Количество единиц кода в последовательности UTF. Для UTF-8 это значение от 1 до 4 (согласно RFC 3629, раздел 3). Для UTF-16 это либо 1, либо 2. Для UTF-32 всегда 1.
- Выбрасывает:
- Может выбросить исключение
UTFException, еслиstr[index]не находится за концом действительной последовательности UTF.
- Примечание
-
strideBackбудет анализировать только элемент вstr[index - 1]элементе. Она не будет полностью проверять действительность последовательности UTF, а также не будет проверять присутствие последовательности: не будет гарантировать, чтоstrideBack(str, index) <= index.
- Примеры:
-
writeln("a".strideBack); // 1 writeln("λ".strideBack); // 2 writeln("aλ".strideBack); // 2 writeln("aλ".strideBack(1)); // 1 writeln("𐐷".strideBack); // 4
- pure @safe size_t toUCSindex(C)(const(C)[] str, size_t index)
Constraints: if (isSomeChar!C); -
Учитывая
indexвstrи предполагая, чтоindexнаходится в начале последовательности UTF,toUCSindexопределяет количество символов UCS доindex. Таким образом,indexявляется индексом единицы кода в начале кодовой точки, а возвращаемое значение показывает, сколько кодовых точек в строке находится в этой кодовой точке.- Примеры:
-
writeln(toUCSindex(`hello world`, 7)); // 7 writeln(toUCSindex(`hello world`w, 7)); // 7 writeln(toUCSindex(`hello world`d, 7)); // 7 writeln(toUCSindex(`Ma Chérie`, 7)); // 6 writeln(toUCSindex(`Ma Chérie`w, 7)); // 7 writeln(toUCSindex(`Ma Chérie`d, 7)); // 7 writeln(toUCSindex(`さいごの果実 / ミツバチと科学者`, 9)); // 3 writeln(toUCSindex(`さいごの果実 / ミツバチと科学者`w, 9)); // 9 writeln(toUCSindex(`さいごの果実 / ミツバチと科学者`d, 9)); // 9
- pure @safe size_t toUTFindex(C)(const(C)[] str, size_t n)
Constraints: if (isSomeChar!C); -
Учитывая индекс UCS
nвstr, возвращает индекс UTF. Таким образом,nпоказывает, сколько кодовых точек в строке находится в кодовой точке, и возвращается индекс массива единицы кода.- Примеры:
-
writeln(toUTFindex(`hello world`, 7)); // 7 writeln(toUTFindex(`hello world`w, 7)); // 7 writeln(toUTFindex(`hello world`d, 7)); // 7 writeln(toUTFindex(`Ma Chérie`, 6)); // 7 writeln(toUTFindex(`Ma Chérie`w, 7)); // 7 writeln(toUTFindex(`Ma Chérie`d, 7)); // 7 writeln(toUTFindex(`さいごの果実 / ミツバチと科学者`, 3)); // 9 writeln(toUTFindex(`さいごの果実 / ミツバチと科学者`w, 9)); // 9 writeln(toUTFindex(`さいごの果実 / ミツバチと科学者`d, 9)); // 9
- alias UseReplacementDchar = std.typecons.Flag!"useReplacementDchar".Flag;
-
Указывает, следует ли заменять недействительный UTF на
replacementDchar - dchar decode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(auto ref S str, ref size_t index)
Constraints: if (!isSomeString!S && isRandomAccessRange!S && hasSlicing!S && hasLength!S && isSomeChar!(ElementType!S));
pure @trusted dchar decode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(auto ref S str, ref size_t index)
Constraints: if (isSomeString!S); -
Декодирует и возвращает кодовую точку, начинающуюся с
str[index].indexсмещается на позицию после декодированной кодовой точки. Если кодовая точка не соответствует формату, выбрасывается исключениеUTFException, аindexостается неизменным.decode будет работать только со строками и диапазонами произвольного доступа с кодовыми единицами с длиной и возможностью нарезки, в то время как
decodeFrontбудет работать с любым диапазоном ввода кодовых единиц.- Параметры:
useReplacementDchar если недействительный UTF, возвращает replacementDchar вместо выброса исключения S strвходная строка или индексируемый диапазон size_t indexначальный индекс в s[]; увеличивается на количество обработанных единиц кода
- Возвращает:
- декодированный символ
- Выбрасывает:
-
UTFExceptionеслиstr[index]не является началом действительной последовательности UTF и useReplacementDchar равенNo.useReplacementDchar
- Примеры:
-
size_t i; assert("a".decode(i) == 'a' && i == 1); i = 0; assert("å".decode(i) == 'å' && i == 2); i = 1; assert("aå".decode(i) == 'å' && i == 3); i = 0; assert("å"w.decode(i) == 'å' && i == 1); // ë as a multi-code point grapheme i = 0; assert("e\u0308".decode(i) == 'e' && i == 1); // ë as a single code point grapheme i = 0; assert("ë".decode(i) == 'ë' && i == 2); i = 0; assert("ë"w.decode(i) == 'ë' && i == 1);
- dchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str, out size_t numCodeUnits)
Constraints: if (!isSomeString!S && isInputRange!S && isSomeChar!(ElementType!S));
pure @trusted dchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str, out size_t numCodeUnits)
Constraints: if (isSomeString!S);
dchar decodeFront(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str)
Constraints: if (isInputRange!S && isSomeChar!(ElementType!S));
-
decodeFront— это вариантdecode, который специально декодирует первую кодовую точку. В отличие отdecode,decodeFrontпринимает любой диапазон входных единиц кода (а не только строку или диапазон с произвольным доступом). Он также получает диапазон поrefи удаляет элементы по мере их декодирования. ЕслиnumCodeUnitsпередаётся, он устанавливается в число единиц кода, входящих в декодированную кодовую точку.- Параметры:
useReplacementDchar если UTF недействителен, возвращает replacementDchar вместо исключения S strстрока-вход или индексируемый диапазон size_t numCodeUnitsустанавливается в число обработанных единиц кода
- Возвращает:
- декодированный символ
- Выбрасывает:
-
UTFException, еслиstr.frontне является началом допустимой последовательности UTF. Если исключение выброшено, то нет гарантии относительно числа удаленных единиц кода, поскольку это зависит от типа используемого диапазона и того, сколько единиц кода нужно было удалить, прежде чем кодовая точка была определена как недопустимая.
- Примеры:
-
import std.range.primitives; string str = "Hello, World!"; assert(str.decodeFront == 'H' && str == "ello, World!"); str = "å"; assert(str.decodeFront == 'å' && str.empty); str = "å"; size_t i; assert(str.decodeFront(i) == 'å' && i == 2 && str.empty);
- dchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str, out size_t numCodeUnits)
Constraints: if (isSomeString!S);
dchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str, out size_t numCodeUnits)
Constraints: if (!isSomeString!S && isSomeChar!(ElementType!S) && isBidirectionalRange!S && (isRandomAccessRange!S && hasLength!S || !isRandomAccessRange!S));
dchar decodeBack(UseReplacementDchar useReplacementDchar = No.useReplacementDchar, S)(ref S str)
Constraints: if (isSomeString!S || isRandomAccessRange!S && hasLength!S && isSomeChar!(ElementType!S) || !isRandomAccessRange!S && isBidirectionalRange!S && isSomeChar!(ElementType!S)); -
decodeBack— это вариантdecode, который специально декодирует последнюю кодовую точку. В отличие отdecode,decodeBackпринимает любой двунаправленный диапазон единиц кода (а не только строку или диапазон с произвольным доступом). Он также получает диапазон поrefи удаляет элементы по мере их декодирования. ЕслиnumCodeUnitsпередаётся, он устанавливается в число единиц кода, входящих в декодированную кодовую точку.- Параметры:
useReplacementDchar если UTF недействителен, возвращает replacementDcharвместо исключенияS strстрока-вход или двунаправленный диапазон size_t numCodeUnitsуказывает число обработанных единиц кода
- Возвращает:
- Декодированный символ UTF.
- Выбрасывает:
-
UTFException, еслиstr.backне является концом допустимой последовательности UTF. Если исключение выброшено, то самstrостаётся неизменным, но нет гарантии относительно значенияnumCodeUnits(при передаче).
- Примеры:
-
import std.range.primitives; string str = "Hello, World!"; assert(str.decodeBack == '!' && str == "Hello, World"); str = "å"; assert(str.decodeBack == 'å' && str.empty); str = "å"; size_t i; assert(str.decodeBack(i) == 'å' && i == 2 && str.empty);
- pure @safe size_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(out char[4] buf, dchar c);
pure @safe size_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(out wchar[2] buf, dchar c);
pure @safe size_t encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(out dchar[1] buf, dchar c); -
Кодирует
cв статический массивbufи возвращает фактическую длину закодированного символа (число между1и4для буферовchar[4]и число между1и2для буферовwchar[2]).- Выбрасывает:
-
UTFExceptionеслиcне является допустимой кодовой точкой UTF.
- Примеры:
-
import std.exception : assertThrown; import std.typecons : Yes; char[4] buf; assert(encode(buf, '\u0000') == 1 && buf[0 .. 1] == "\u0000"); assert(encode(buf, '\u007F') == 1 && buf[0 .. 1] == "\u007F"); assert(encode(buf, '\u0080') == 2 && buf[0 .. 2] == "\u0080"); assert(encode(buf, '\uE000') == 3 && buf[0 .. 3] == "\uE000"); assert(encode(buf, 0xFFFE) == 3 && buf[0 .. 3] == "\xEF\xBF\xBE"); assertThrown!UTFException(encode(buf, cast(dchar) 0x110000)); encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000); auto slice = buf[]; writeln(slice.decodeFront); // replacementDchar
- Примеры:
-
import std.exception : assertThrown; import std.typecons : Yes; wchar[2] buf; assert(encode(buf, '\u0000') == 1 && buf[0 .. 1] == "\u0000"); assert(encode(buf, '\uD7FF') == 1 && buf[0 .. 1] == "\uD7FF"); assert(encode(buf, '\uE000') == 1 && buf[0 .. 1] == "\uE000"); assert(encode(buf, '\U00010000') == 2 && buf[0 .. 2] == "\U00010000"); assert(encode(buf, '\U0010FFFF') == 2 && buf[0 .. 2] == "\U0010FFFF"); assertThrown!UTFException(encode(buf, cast(dchar) 0xD800)); encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000); auto slice = buf[]; writeln(slice.decodeFront); // replacementDchar
- Примеры:
-
import std.exception : assertThrown; import std.typecons : Yes; dchar[1] buf; assert(encode(buf, '\u0000') == 1 && buf[0] == '\u0000'); assert(encode(buf, '\uD7FF') == 1 && buf[0] == '\uD7FF'); assert(encode(buf, '\uE000') == 1 && buf[0] == '\uE000'); assert(encode(buf, '\U0010FFFF') == 1 && buf[0] == '\U0010FFFF'); assertThrown!UTFException(encode(buf, cast(dchar) 0xD800)); encode!(Yes.useReplacementDchar)(buf, cast(dchar) 0x110000); writeln(buf[0]); // replacementDchar
- pure @safe void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(ref char[] str, dchar c);
pure @safe void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(ref wchar[] str, dchar c);
pure @safe void encode(UseReplacementDchar useReplacementDchar = No.useReplacementDchar)(ref dchar[] str, dchar c); -
Кодирует
cв кодировкеstrи добавляет её вstr.- Выбрасывает:
-
UTFExceptionеслиcне является допустимой кодовой точкой UTF.
- Примеры:
-
char[] s = "abcd".dup; dchar d1 = 'a'; dchar d2 = 'ø'; encode(s, d1); writeln(s.length); // 5 writeln(s); // "abcda" encode(s, d2); writeln(s.length); // 7 writeln(s); // "abcdaø"
- pure nothrow @nogc @safe ubyte codeLength(C)(dchar c)
Constraints: if (isSomeChar!C); -
Возвращает число единиц кода, необходимых для кодирования кодовой точки
cпри использовании типа символаCдля её кодирования.- Примеры:
-
writeln(codeLength!char('a')); // 1 writeln(codeLength!wchar('a')); // 1 writeln(codeLength!dchar('a')); // 1 writeln(codeLength!char('\U0010FFFF')); // 4 writeln(codeLength!wchar('\U0010FFFF')); // 2 writeln(codeLength!dchar('\U0010FFFF')); // 1
- size_t codeLength(C, InputRange)(InputRange input)
Constraints: if (isInputRange!InputRange && !isInfinite!InputRange && isSomeChar!(ElementType!InputRange)); -
Возвращает число единиц кода, необходимых для кодирования
strв строке, тип символа которой —C. Это особенно полезно при извлечении одной строки с длиной другой, если типы двух строк используют разные типы символов.- Параметры:
C тип символа для получения длины кодирования InputRange inputдиапазон ввода для вычисления длины кодирования
- Возвращает:
- Число единиц кода в
inputпри кодировании вC.
- Примеры:
-
assert(codeLength!char("hello world") == "hello world".length); assert(codeLength!wchar("hello world") == "hello world"w.length); assert(codeLength!dchar("hello world") == "hello world"d.length); assert(codeLength!char(`プログラミング`) == `プログラミング`.length); assert(codeLength!wchar(`プログラミング`) == `プログラミング`w.length); assert(codeLength!dchar(`プログラミング`) == `プログラミング`d.length); string haystack = `Être sans la verité, ça, ce ne serait pas bien.`; wstring needle = `Être sans la verité`; assert(haystack[codeLength!char(needle) .. $] == `, ça, ce ne serait pas bien.`);
- pure @safe void validate(S)(in S str)
Constraints: if (isSomeString!S); -
Проверяет, является ли
strправильно сформированным Unicode.- Выбрасывает:
-
UTFExceptionеслиstrне является правильно сформированным.
- Примеры:
-
import std.exception : assertThrown; char[] a = [167, 133, 175]; assertThrown!UTFException(validate(a));
- string toUTF8(S)(S s)
Constraints: if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S)); -
Кодирует элементы
sв UTF-8 и возвращает новую строку с элементами.- Параметры:
S sстрока для кодирования
- Возвращает:
- строка UTF-8
- См. также:
- Для ленивой, не выделяющей памяти версии этих функций, см.
byUTF.
- Примеры:
-
import std.algorithm.comparison : equal; // The ö is represented by two UTF-8 code units assert("Hellø"w.toUTF8.equal(['H', 'e', 'l', 'l', 0xC3, 0xB8])); // 𐐷 is four code units in UTF-8 assert("𐐷"d.toUTF8.equal([0xF0, 0x90, 0x90, 0xB7]));
- wstring toUTF16(S)(S s)
Constraints: if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S)); -
Кодирует элементы
sв UTF-16 и возвращает новый GC-выделенныйwstringэлементов.- Параметры:
S sдиапазон для кодирования
- Возвращает:
- строка UTF-16
- См. также:
- Для ленивой, не выделяющей памяти версии этих функций, см.
byUTF.
- Примеры:
-
import std.algorithm.comparison : equal; // these graphemes are two code units in UTF-16 and one in UTF-32 writeln("𤭢"d.length); // 1 writeln("𐐷"d.length); // 1 assert("𤭢"d.toUTF16.equal([0xD852, 0xDF62])); assert("𐐷"d.toUTF16.equal([0xD801, 0xDC37]));
- dstring toUTF32(S)(S s)
Constraints: if (isInputRange!S && !isInfinite!S && isSomeChar!(ElementEncodingType!S)); -
Кодирует элементы
sв UTF-32 и возвращает новый GC-выделенныйdstringэлементов.- Параметры:
S sдиапазон для кодирования
- Возвращает:
- строка UTF-32
- См. также:
- Для ленивой, не выделяющей памяти версии этих функций, см.
byUTF.
- Примеры:
-
import std.algorithm.comparison : equal; // these graphemes are two code units in UTF-16 and one in UTF-32 writeln("𤭢"w.length); // 2 writeln("𐐷"w.length); // 2 assert("𤭢"w.toUTF32.equal([0x00024B62])); assert("𐐷"w.toUTF32.equal([0x00010437]));
- template toUTFz(P) if (isPointer!P && isSomeChar!(typeof(*P.init)))
-
Возвращает строку в стиле C с нулевым завершением, эквивалентную
str.strне должна содержать вложенных'\0'символов, так как любая функция C будет рассматривать первый встреченный'\0'как конец строки. Еслиstr.emptyравноtrue, то возвращается строка, содержащая только'\0'.toUTFzпринимает любой тип строки и шаблонизируется по типу указателя на символ, который вы хотите преобразовать. Она будет избегать выделения новой строки, если это возможно, но есть неплохая вероятность, что ей придётся выделить новую строку — особенно при работе с типами символов, отличными отchar.
Предупреждение 1: Если результатtoUTFzравенstr.ptr, то если что-либо изменит символ, следующий за концомstr(который является завершающим символом'\0'строки), то строка больше не будет завершаться нулём. Наиболее вероятные сценарии для этого — если вы добавляете кstrсимволы, и не происходит перевыделения, или когдаstrявляется фрагментом более крупного массива, и вы изменяете символ в большем массиве, который находится в позиции за концомstr. Ещё один случай, когда это может произойти, — если у вас есть изменяемый массив символов непосредственно послеstrв памяти (например, если это переменные-члены в определённом пользователем типе, где один объявлен сразу после другого), и этот массив символов случайно начинался с'\0'. Такие сценарии никогда не возникнут, если вы немедленно используете строку с нулевым завершением после вызоваtoUTFzи функция C, использующая её, не хранит ссылку на неё. Также они маловероятны, даже если вы сохраните строку с нулевым завершением (приведённые выше случаи — лишь некоторые примеры, когда это может произойти). Однако, если вы сохранили строку с нулевым завершением и хотите быть абсолютно уверены, что строка останется завершённой нулём, то просто добавьте'\0'к строке и используйте её свойствоptr, а не вызывайтеtoUTFz.
Предупреждение 2: При передаче указателя на символ функции C, и функция C хранит его по какой-либо причине, убедитесь, что в вашем коде D хранится ссылка на него. В противном случае он может исчезнуть во время цикла сбора мусора, что приведёт к неприятной ошибке, когда C-код попытается его использовать.- Примеры:
-
auto p1 = toUTFz!(char*)("hello world"); auto p2 = toUTFz!(const(char)*)("hello world"); auto p3 = toUTFz!(immutable(char)*)("hello world"); auto p4 = toUTFz!(char*)("hello world"d); auto p5 = toUTFz!(const(wchar)*)("hello world"); auto p6 = toUTFz!(immutable(dchar)*)("hello world"w);
- pure @safe const(wchar)* toUTF16z(C)(const(C)[] str)
Constraints: if (isSomeChar!C); -
toUTF16z— это вспомогательная функция дляtoUTFz!(const(wchar)*).Кодирует строку
sв UTF-16 и возвращает закодированную строку.toUTF16zподходит для вызова функций 'W' в Win32 API, которые принимают аргументLPCWSTR.- Примеры:
-
string str = "Hello, World!"; const(wchar)* p = str.toUTF16z; writeln(p[str.length]); // '\0'
- pure nothrow @nogc @safe size_t count(C)(const(C)[] str)
Constraints: if (isSomeChar!C); -
Возвращает общее количество кодовых точек, закодированных в
str.- Заменяет
- Эта функция заменяет
toUCSindex.
- Стандарты:
- Unicode 5.0, ASCII, ISO-8859-1, WINDOWS-1252
- Исключения:
-
UTFExceptionеслиstrне соответствует формату.
- Примеры:
-
writeln(count("")); // 0 writeln(count("a")); // 1 writeln(count("abc")); // 3 writeln(count("\u20AC100")); // 4
- enum dchar replacementDchar;
-
Вставляется вместо недопустимых последовательностей UTF.
- Ссылки
- http://en.wikipedia.org/wiki/Replacement_character#Replacement_character
- auto byCodeUnit(R)(R r)
Constraints: if (isConvertibleToString!R && !isStaticArray!R || isInputRange!R && isSomeChar!(ElementEncodingType!R)); -
Итерация по диапазону char, wchar или dchar по кодовым единицам.
Цель состоит в том, чтобы обойти специальный случай декодирования, который выполняет
std.range.primitives.frontдля массивов символов. В результате, использование диапазонов сbyCodeUnitможет бытьnothrow, в то время какstd.range.primitives.frontвыбрасывает исключение при обнаружении недопустимых последовательностей Unicode.
Кодовая единица — это строительный блок кодировок UTF. Как правило, отдельная кодовая единица не представляет то, что воспринимается как полный символ (т.е. кластер графем в терминологии Unicode). Многие символы кодируются несколькими кодовыми единицами. Например, кодовые единицы UTF-8 дляøравны0xC3 0xB8. Это означает, что отдельная единицаbyCodeUnitчасто не образует символ сама по себе. Попытка обработать её как единый символ при итерации по полученному диапазону даст бессмысленные результаты.- Параметры:
R rдиапазон ввода символов (включая строки) или тип, который неявно преобразуется в тип строки.
- Возвращает:
- Если
rне является автоматически декодируемой строкой (т.е. узкой строкой или типом, определённым пользователем, который неявно преобразуется в тип строки), то возвращаетсяr. В противном случаеrпреобразуется в соответствующий тип строки (если это не строка) и оборачивается в диапазон с произвольным доступом, где тип кодирования элемента строки (его кодовая единица) является типом элемента диапазона, и этот диапазон возвращается. Диапазон имеет срезы. Еслиrдостаточно необычен, чтобы быть структурой или классом, который сам по себе является диапазоном ввода символов (т.е. у него есть API диапазона ввода как методы членов), и он неявно преобразуется в тип строки, то возвращаетсяr, и не происходит неявного преобразования. Еслиrоборачивается в новый диапазон, то этот диапазон имеет свойствоsourceдля возвращения строки, которая в настоящее время содержится в этом диапазоне.
- См. также:
- См. документацию по
std.uniдля справочной информации по терминологии Unicode. Для диапазона, итерирующего по кластеру графем (написанному символу), см.std.uni.byGrapheme.
- Примеры:
-
import std.range.primitives; import std.traits : isAutodecodableString; auto r = "Hello, World!".byCodeUnit(); static assert(hasLength!(typeof(r))); static assert(hasSlicing!(typeof(r))); static assert(isRandomAccessRange!(typeof(r))); static assert(is(ElementType!(typeof(r)) == immutable char)); // contrast with the range capabilities of standard strings (with or // without autodecoding enabled). auto s = "Hello, World!"; static assert(isBidirectionalRange!(typeof(r))); static if (isAutodecodableString!(typeof(s))) { // with autodecoding enabled, strings are non-random-access ranges of // dchar. static assert(is(ElementType!(typeof(s)) == dchar)); static assert(!isRandomAccessRange!(typeof(s))); static assert(!hasSlicing!(typeof(s))); static assert(!hasLength!(typeof(s))); } else { // without autodecoding, strings are normal arrays. static assert(is(ElementType!(typeof(s)) == immutable char)); static assert(isRandomAccessRange!(typeof(s))); static assert(hasSlicing!(typeof(s))); static assert(hasLength!(typeof(s))); }
- Примеры:
-
byCodeUnitне выполняет декодирование Unicodestring noel1 = "noe\u0308l"; // noël using e + combining diaeresis assert(noel1.byCodeUnit[2] != 'ë'); writeln(noel1.byCodeUnit[2]); // 'e' string noel2 = "no\u00EBl"; // noël using a precomposed ë character // Because string is UTF-8, the code unit at index 2 is just // the first of a sequence that encodes 'ë' assert(noel2.byCodeUnit[2] != 'ë');
- Примеры:
-
byCodeUnitпредоставляет свойствоsourceпри обёртывании узких строк.import std.algorithm.comparison : equal; import std.range : popFrontN; import std.traits : isAutodecodableString; { auto range = byCodeUnit("hello world"); range.popFrontN(3); assert(equal(range.save, "lo world")); static if (isAutodecodableString!string) // only enabled with autodecoding { string str = range.source; writeln(str); // "lo world" } } // source only exists if the range was wrapped { auto range = byCodeUnit("hello world"d); static assert(!__traits(compiles, range.source)); }
- alias byChar = byUTF!(char, Flag.yes).byUTF(R)(R r) if (isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R));
alias byWchar = byUTF!(wchar, Flag.yes).byUTF(R)(R r) if (isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R));
alias byDchar = byUTF!(dchar, Flag.yes).byUTF(R)(R r) if (isAutodecodableString!R && isInputRange!R && isSomeChar!(ElementEncodingType!R)); -
Итерация по диапазону ввода символов по char, wchar или dchar. Эти псевдонимы просто перенаправляют на
byUTFс соответствующим аргументом C.- Параметры:
R r диапазон ввода символов или массив символов
- template byUTF(C, UseReplacementDchar useReplacementDchar = Yes.useReplacementDchar) if (isSomeChar!C)
-
Итерация по диапазону ввода символов по типу char
Cпутём кодирования элементов диапазона.Последовательности UTF, которые не могут быть преобразованы в указанную кодировку, либо заменяются U+FFFD в соответствии с «5.22 Лучшая практика для замены U+FFFD» стандарта Unicode 6.2, либо приводят к выбросу UTFException. Следовательно, byUTF не симметричен. Этот алгоритм ленивый и не выделяет память.
@nogc,pure-ность,nothrow, и@safe-ность выводятся из параметраr.- Параметры:
C char,wchar, илиdcharuseReplacementDchar UseReplacementDchar.yes означает заменить недопустимый UTF на replacementDchar, UseReplacementDchar.no означает выброситьUTFExceptionдля недопустимого UTF
- Исключения:
-
UTFExceptionесли недопустимая последовательность UTF иuseReplacementDcharустановлено вUseReplacementDchar.yes
- GC
- Не использует GC, если
useReplacementDcharустановлено вUseReplacementDchar.no
- Возвращает:
- Векторный диапазон, если
Rявляется диапазоном и не является автоматически декодируемой строкой, как определено вstd.traits.isAutodecodableString, и если базовый диапазон также является векторным диапазоном. Или, еслиRявляется диапазоном и он является автоматически декодируемой строкой иis(ElementEncodingType!typeof(r) == C), то диапазон передаётся вbyCodeUnit. В противном случае — диапазон ввода символов.
- Примеры:
-
import std.algorithm.comparison : equal; // hellö as a range of `char`s, which are UTF-8 assert("hell\u00F6".byUTF!char().equal(['h', 'e', 'l', 'l', 0xC3, 0xB6])); // `wchar`s are able to hold the ö in a single element (UTF-16 code unit) assert("hell\u00F6".byUTF!wchar().equal(['h', 'e', 'l', 'l', 'ö'])); // 𐐷 is four code units in UTF-8, two in UTF-16, and one in UTF-32 assert("𐐷".byUTF!char().equal([0xF0, 0x90, 0x90, 0xB7])); assert("𐐷".byUTF!wchar().equal([0xD801, 0xDC37])); assert("𐐷".byUTF!dchar().equal([0x00010437]));
- Примеры:
-
import std.algorithm.comparison : equal; import std.exception : assertThrown; assert("hello\xF0betty".byChar.byUTF!(dchar, UseReplacementDchar.yes).equal("hello\uFFFDetty")); assertThrown!UTFException("hello\xF0betty".byChar.byUTF!(dchar, UseReplacementDchar.no).equal("hello betty"));
© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_utf.html