對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;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章