繁体   English   中英

有谁知道下面的代码可能做什么?

[英]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个字节,长度为26

用法将是这样的:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM