[英]Is there anyone that knows what the following code possibly does?
/* utf-8: 0xc0, 0xe0, 0xf0, 0xf8, 0xfc */
static unsigned char _mblen_table_utf8[] =
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
};
我敢打赌,这与编码有关,
但是它是如何工作的呢?
更新
while (str < ptr)
{
j = mblen[(*str)];
tree_nput(r->tree, cr, sizeof(struct rule_item), str, j);
str += j;
}
}
因为多字节字符串中的字符具有可变的长度,所以此表将每个字符映射为一个长度。
后64个字符宽于1个字节,长度为2
到6
。
用法将是这样的:
unsigned char current_char = *mbstr;
for (i = 0; i < _mblen_table_utf8[current_char]; i++) {
/* treat *mbstr++ as a part of the current character */
}
从历史上看,每个字符都用7位(然后是8位)编码,这足以编码欧洲语言的字母。
每个人只有128个头文字是通用的,其余128个是通过代码页进行标准化的( ISO-8859-1是一个示例)。
由于每个字符都编码在几个字节上,因此需要对更长的字母语言(例如中文)进行编码导致了Unicode工作 。
UTF-8是一种以有效的可变代码长度方式编码Unicode字符的方法。 这意味着您读取的第一个字节确定了字符字节序列的长度。
基本上,您的表是一个查找表,用于检查从用作表索引的字节开始的字符有多少字节。 您将在此处看到此表的另一个版本以及说明。
我添加了表索引作为注释,以使其更清晰:
/* utf-8: 0xc0, 0xe0, 0xf0, 0xf8, 0xfc */
static unsigned char _mblen_table_utf8[] =
{
/*0x00*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0x10*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0x20*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0x30*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0x40*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0x50*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0x60*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0x70*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0x80*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0x90*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0xA0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0xB0*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
/*0xC0*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/*0xD0*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
/*0xE0*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
/*0xF0*/ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1
};
该数组似乎是一个查找表,用于确定给定第一个字节的UTF-8字符中的字节数。 基本上,第一个字节(作为无符号值)用作数组的索引,该索引处的元素给出UTF-8字符的字节序列长度。
无效和中间序列字节似乎在此表中映射为1字节,因此,如果遇到不适当的情况,使用此表的代码可能会将它们视为单个字符(除非它专门忽略了它们)。
此类表的一种用途是计算UTF-8字符串中的字符(不是字节,而是Unicode字符)。 每次计算一个字符时,您都要查找长度并向前移动字符的字节序列的长度,而不是向前移动一个字节...只要您从字符的开头开始并且字符串为一直有效的UTF-8。
无需任何进一步的细节,上面的代码就可以做到这一点:它声明了一个静态的无符号char数组,并使用大括号内的值对其进行了初始化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.