cJSON代码阅读(4)——解析JSON数据的流程

来源:互联网 发布:wamp设置mysql密码 编辑:程序博客网 时间:2024/06/06 00:56
解析JSON数据的主函数是cJSON_Parse,这个函数默认调用不带选项的cJSON_ParseWithOpts函数。

cJSON_ParseWithOpts函数首先创建一个JSON节点,然后跳过空白字符,接着调用parse_value函数进行数据的解析,然后判断解析是否出错,如果出错,那么释放内存,然后返回空指针,全局变量ep(char*类型)记录了出错的位置。如果没有出错,那么返回树形结构的JSON节点。

/* Parse an object - create a new root, and populate. */// 带选项解析json数据cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated){    // 是否到达末尾    const char *end=0;    // 创建一个新的json节点    cJSON *c=cJSON_New_Item();    // ep是一个全局的静态变量(这个参数的作用目前还不知道:好象是记录解析达到的最终位置)    ep=0;    // 分配内存失败,返回    if (!c)        return 0;       /* memory fail */    // 开始解析    // parse_value是进行解析的主要函数    // 它里面会根据节点的不同类型调用不同的解析函数    // 如果遇到数组或者对象,可能还会进行递归调用    end=parse_value(c,skip(value));    // end==0,出错,返回0    if (!end)    {        // 删除节点(以及它的子节点)        cJSON_Delete(c);        return 0;    }/* parse failure. ep is set. */    /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */    // 判断是否需要以null结束    if (require_null_terminated)    {        // 跳过空白字符        end=skip(end);        // 如果最后end还有字符,表示格式错误等,返回0        if (*end)        {            cJSON_Delete(c);            ep=end;            return 0;        }    }    // 判断是否需要返回解析的尾部    if (return_parse_end)        *return_parse_end=end;    // 返回json节点    return c;}

skip函数的作用是跳过字符串中的控制字符(和空白字符)
/* Utility to jump whitespace and cr/lf */// 跳过一切的空白字符static const char *skip(const char *in){    while (in && *in && (unsigned char)*in<=32)        in++;    return in;}


parse_value函数事实上进行数据解析的函数,会根据不同字符串内容的不同,调用不同的解析函数(例如parse_object等函数,parse_object这些函数内部可能又会递归调用parse_value进行解析)进行具体的解析

/* Parser core - when encountering text, process appropriately. */// 解析json格式的主要函数,解析值static const char *parse_value(cJSON *item,const char *value){    if (!value)        return 0;/* Fail on null. */    // 如果这个值是null,表明是null节点    if (!strncmp(value,"null",4))    {        item->type=cJSON_NULL;        return value+4;    }    // 如果这个值是false,那么表示这是一个布尔节点    if (!strncmp(value,"false",5))    {        item->type=cJSON_False;        return value+5;    }    // 如果这个值是true,表示这个节点是布尔节点    if (!strncmp(value,"true",4))    {        item->type=cJSON_True;        item->valueint=1;        return value+4;    }    // 如果是双引号开头,那么表示这个是一个字符串    if (*value=='\"')    {        // 开始解析字符串        return parse_string(item,value);    }    // 如果以负号开头或者以数字开头,那么表示这是一个数值    if (*value=='-' || (*value>='0' && *value<='9'))    {        // 开始解析数值        return parse_number(item,value);    }    // 如果以左中括号开头,那么表示是一个数组    if (*value=='[')    {        // 开始解析数组        return parse_array(item,value);    }    // 如果以左大括号开头,那么表示是一个对象    if (*value=='{')    {        return parse_object(item,value);    }    // 记录解析的位置    ep=value;    // 到达这里表示解析出错    return 0;/* failure. */}


0 0
原创粉丝点击