对nginx中utf-8编码格式解析函数的理解


/*

 * ngx_utf8_decode() decodes two and more bytes UTF sequences only

 * the return values:

 *    0x80 - 0x10ffff         valid character

 *    0x110000 - 0xfffffffd   invalid sequence

 *    0xfffffffe              incomplete sequence

 *    0xffffffff              error

 */

 /*

  * 0 ~ 0x7f  0xxx|xxxx

  * 0x80 ~ 0x7ff  110x|xxxx 10xx|xxxx

  * 0x800 ~ 0xffff 1110|xxxx 10xx|xxxx 10xx|xxxx

  * 0x10000 ~ 0x10ffff 1111|0xxx 10xx|xxxx 10xx|xxxx 10xx|xxxx

  *

  *该程序首先根据多字节数据的首字节获取表示的实际Unicode码值的区间,该多字节的长度

  *然后依次提取实际存储的Unicode码值,并存放在u中

  *len 表示除去一个字节之外,理论上还有多少字节

  *valid 表示该多字节所对应的Unicode编码必须大于的Unicode编码值

  *u表示utf-8编码对应的多字节Unicode码值

  * u >  0xf0 则对应 0x10000 ~ 0x10ffff Unicode编码区间 因为只有该区间的utf-8编码的首字节11110xxxx大于0xf0

  * u > 0xe0 则对应 0x800 ~ 0xffff Unicode编码区间 因为只有该区间的utf-8编码的首字节小于11110xxxx,但大于 1110xxxx,且1110xxxx大于0xe0

  * u > 0xc0 则对应 0x80 ~ 0x7ff Unicode编码区间,同样的理由,110xxxxx 大于0xc0 ,假如所有的xxxxx位全为0,则必然退化成单字节表示

  */

uint32_t

ngx_utf8_decode(u_char **p, size_t n)

{

    size_t    len;

    uint32_t  u, i, valid;

    u = **p;

    if (u > 0xf0) {

        u &= 0x07;

        valid = 0xffff;

        len = 3;

    } else if (u > 0xe0) {

        u &= 0x0f;

        valid = 0x7ff;

        len = 2;

    } else if (u > 0xc0) {

        u &= 0x1f;

        valid = 0x7f;

        len = 1;

    } else {

        (*p)++;

        return 0xffffffff;

    }

    if (n - 1 < len) {

        return 0xfffffffe;

    }

    (*p)++;

    while (len) {

        i = *(*p)++;

        if (i < 0x80) {

            return 0xffffffff;

        }

        u = (u << 6) | (i & 0x3f);

        len--;

    }

    if (u > valid) {

        return u;

    }

    return 0xffffffff;

}

没有更多推荐了,返回首页