我有以下与代码点和代理对相对应的变化范围的定义:
https://en.wikipedia.org/wiki/UTF-16#Description
我的代码基于Clang implementation中的ConvertUTF.c
。
我目前正在努力解决如何做到这一点。
与我想要了解的LLVM实现最相关的代码是:
unsigned short bytesToWrite = 0;
const u32char_t byteMask = 0xBF;
const u32char_t byteMark = 0x80;
u8char_t* target = *targetStart;
utf_result result = kConversionOk;
const u16char_t* source = *sourceStart;
while (source < sourceEnd) {
u32char_t ch;
const u16char_t* oldSource = source; /* In case we have to back up because of target overflow. */
ch = *source++;
/* If we have a surrogate pair, convert to UTF32 first. */
if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) {
/* If the 16 bits following the high surrogate are in the source buffer... */
if (source < sourceEnd) {
u32char_t ch2 = *source;
/* If it's a low surrogate, convert to UTF32. */
if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) {
ch = ((ch - UNI_SUR_HIGH_START) << halfShift)
+ (ch2 - UNI_SUR_LOW_START) + halfBase;
++source;
} else if (flags == kStrictConversion) { /* it's an unpaired high surrogate */
--source; /* return to the illegal value itself */
result = kSourceIllegal;
break;
}
} else { /* We don't have the 16 bits following the high surrogate. */
--source; /* return to the high surrogate */
result = kSourceExhausted;
break;
}
} else if (flags == kStrictConversion) {
/* UTF-16 surrogate values are illegal in UTF-32 */
if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) {
--source; /* return to the illegal value itself */
result = kSourceIllegal;
break;
}
}
...
具体来说,他们在评论中说:
如果我们有代理项对,请先转换为UTF32。
然后:
如果它是低代理,请转换为UTF32。
我迷失了“如果我们......”和“如果它......”以及我在阅读评论时的回答:“我们有什么?”和“它是什么?”
我相信ch
和ch2
是第一个char16和下一个char16(如果存在),检查第二个是否是代理对的一部分,然后沿着每个char16走(或者你沿着一对字符走路?)直到最后。
我迷失了他们如何使用UNI_SUR_HIGH_START
,UNI_SUR_HIGH_END
,UNI_SUR_LOW_START
,UNI_SUR_LOW_END
以及他们使用halfShift
和halfBase
。
维基百科还指出:
由于数字值与其名称不匹配,有人试图将“高”和“低”代理重命名为“领先”和“尾随”。这似乎在最近的Unicode标准中被放弃了。
在任何回复中记下“领先”和“尾随”也可能有助于澄清事情。
答案 0 :(得分:2)
ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END
检查ch
是否在高代理范围内,即[D800-DBFF]。而已。然后做同样的事情来检查ch2
是否在低代理范围内,意味着[DC00-DFFF]。
halfShift
和halfBase
只是按照UTF-16解码算法的规定使用,它将一对代理转换为它们代表的标量值。这里没有什么特别的事情;它是该算法的教科书实现,没有任何技巧。