У вас есть несколько разумных вариантов.
1. Конверсия
Первый - преобразовать ваш UTF32 в UTF16 и использовать их с NSString, поскольку UTF16 - это «родная» кодировка NSString. Это не так уж сложно. Если символ UTF32 находится в BMP (например, старшие два байта равны 0), вы можете просто привести его к unichar
напрямую. Если он находится в любой другой плоскости, вы можете преобразовать его в суррогатную пару символов UTF16. Вы можете найти правила на странице Википедии . Но быстрое (не проверенное) преобразование будет выглядеть как
UTF32Char inputChar = // my UTF-32 character
inputChar -= 0x10000;
unichar highSurrogate = inputChar >> 10; // leave the top 10 bits
highSurrogate += 0xD800;
unichar lowSurrogate = inputChar & 0x3FF; // leave the low 10 bits
lowSurrogate += 0xDC00;
Теперь вы можете создать строку NSString, используя оба символа одновременно:
NSString *str = [NSString stringWithCharacters:(unichar[]){highSurrogate, lowSurrogate} length:2];
Чтобы вернуться назад, вы можете использовать [NSString getCharacters:range:]
, чтобы получить обратно unichar, а затем обратить вспять алгоритм суррогатной пары, чтобы вернуть ваш символ UTF32 (любые символы, которые не находятся в диапазоне 0xD800-0xDFFF
, должны быть просто приведены к UTF32 непосредственно).
2. Байт-буферы
Другой вариант - позволить NSString выполнять преобразование напрямую, без использования cStrings. Чтобы преобразовать значение UTF32 в строку NSString, вы можете использовать что-то вроде следующего:
UTF32Char inputChar = // input UTF32 value
inputChar = NSSwapHostIntToLittle(inputChar); // swap to little-endian if necessary
NSString *str = [[[NSString alloc] initWithBytes:&inputChar length:4 encoding:NSUTF32LittleEndianStringEncoding] autorelease];
Чтобы вернуть его снова, вы можете использовать
UTF32Char outputChar;
if ([str getBytes:&outputChar maxLength:4 usedLength:NULL encoding:NSUTF32LittleEndianStringEncoding options:0 range:NSMakeRange(0, 1) remainingRange:NULL]) {
outputChar = NSSwapLittleIntToHost(outputChar); // swap back to host endian
// outputChar now has the first UTF32 character
}