cJSON代码阅读(5)——解析JSON字符串

来源:互联网 发布:网上开淘宝店的条件 编辑:程序博客网 时间:2024/06/07 13:04
parse_string是进行json字符串解析的函数。
1、首先判断待处理的json数据是不是字符串
2、计算字符串的长度
3、分配内存
4、遍历json当中的字符串中的每一个字符,如果是普通字符,就直接保存,如果是转义字符需要进行特殊处理(具体见代码)

5、返回下一个json数据的位置

// 解析字符串static const char *parse_string(cJSON *item,const char *str){    const char *ptr=str+1;    char *ptr2;    char *out;    int len=0;    unsigned uc,uc2;    // 判断是不是字符串    if (*str!='\"')    {        ep=str;        return 0;    }/* not a string! */    // 计算字符串的长度(一直往后遍历,直到遇到双引号)    while (*ptr!='\"' && *ptr && ++len)        if (*ptr++ == '\\')            ptr++;/* Skip escaped quotes. */    // 为字符串分配内存    out=(char*)cJSON_malloc(len+1);/* This is how long we need for the string, roughly. */    // 判断内存是否分配失败    if (!out)        return 0;    // ptr指向原始json数据    ptr=str+1;    // ptr2指向需要保存字符串的缓存区    ptr2=out;    // 遍历字符串    while (*ptr!='\"' && *ptr)    {        // 如果没有遇到转义字符,就直接保存原始的字符        if (*ptr!='\\')            *ptr2++=*ptr++;        // 如果遇到转义字符,需要进行解析        else        {            // 首先指向下一个原始字符            ptr++;            // 判断这个转义的字符是什么,然后保存相应的字符            switch (*ptr)            {            case 'b': *ptr2++='\b';break;            case 'f': *ptr2++='\f';break;            case 'n': *ptr2++='\n';break;            case 'r': *ptr2++='\r';break;            case 't': *ptr2++='\t';break;                // 将编码从utf16转换为utf8            case 'u': /* transcode utf16 to utf8. */                uc=parse_hex4(ptr+1);ptr+=4;/* get the unicode char. */                if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)break;/* check for invalid.*/                if (uc>=0xD800 && uc<=0xDBFF)/* UTF16 surrogate pairs.*/                {                    if (ptr[1]!='\\' || ptr[2]!='u')break;/* missing second-half of surrogate.*/                    uc2=parse_hex4(ptr+3);ptr+=6;                    if (uc2<0xDC00 || uc2>0xDFFF)break;/* invalid second-half of surrogate.*/                    uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));                }                len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;                switch (len) {                case 4:                    *--ptr2 =((uc | 0x80) & 0xBF);                    uc >>= 6;                case 3:                    *--ptr2 =((uc | 0x80) & 0xBF);                    uc >>= 6;                case 2:                    *--ptr2 =((uc | 0x80) & 0xBF);                    uc >>= 6;                case 1:                    *--ptr2 =(uc | firstByteMark[len]);                }                ptr2+=len;                break;            default:  *ptr2++=*ptr; break;            }            ptr++;        }    }    // 以0结束字符串    *ptr2=0;    // 跳过双引号    if (*ptr=='\"') ptr++;    // 设置类型以及数据    item->valuestring=out;    item->type=cJSON_String;    return ptr;}


0 0