parse_string是进行json字符串解析的函数。
1、首先判断待处理的json数据是不是字符串
2、计算字符串的长度
3、分配内存
4、遍历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;
}