cJSON源码解释(三)--渲染输出

 

cJSON输出

cJSON输出分为两种:格式化输出和非格式化输出

在输出的时候,cJSON并不是一边解释一边输出,而是把所有要输出的字符串都集合到一个输出字符串内存中才输出。

print_object很巧妙地使用了递归来输出

/* Render an object to text. */
static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p)
{
    char **entries=0,**names=0;
    char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
    cJSON *child=item->child;
    int numentries=0,fail=0;
    size_t tmplen=0;
    /* Count the number of entries. */
    while (child) {
        numentries++;
        child=child->next;
    }
        
    /* Explicitly handle empty object case */
    if (!numentries)
    {
        if (p) 
            out=ensure(p,fmt?depth+4:3);
        else    
            out=(char*)cJSON_malloc(fmt?depth+4:3);
        if (!out)    
            return 0;
        ptr=out;
        *ptr++='{
   ';
        if (fmt) {
            *ptr++='\n';
                for (i=0;i<depth-1;i++) 
                    *ptr++='\t';
        }
        *ptr++='}';
        *ptr++=0;
        return out;
    }
    if (p)
    {
        /* Compose the output: */
        i=p->offset;
        len=fmt?2:1;    ptr=ensure(p,len+1);    if (!ptr) return 0;
        *ptr++='{
   ';    if (fmt) *ptr++='\n';    *ptr=0;    p->offset+=len;
        child=item->child;depth++;
        while (child)
        {
            if (fmt)
            {
                ptr=ensure(p,depth);    
                if (!ptr) 
                    return 0;
                for (j=0;j<depth;j++) 
                    *ptr++='\t';
                p->offset+=depth;
            }
            print_string_ptr(child->string,p);
            p->offset=update(p);
            
            len=fmt?2:1;
            ptr=ensure(p,len);    
            if (!ptr) 
                return 0;
            *ptr++=':';if (fmt) *ptr++='\t';
            p->offset+=len;
            
            print_value(child,depth,fmt,p);
            p->offset=update(p);

            len=(fmt?1:0)+(child->next?1:0);
            ptr=ensure(p,len+1); if (!ptr) return 0;
            if (child->next) *ptr++=',';
            if (fmt) *ptr++='\n';*ptr=0;
            p->offset+=len;
            child=child->next;
        }
        ptr=ensure(p,fmt?(depth+1):2);     if (!ptr) return 0;
        if (fmt)    for (i=0;i<depth-1;i++) *ptr++='\t';
        *ptr++='}';*ptr=0;
        out=(p->buffer)+i;
    }
    else
    {
        /* Allocate space for the names and the objects */
        entries=(char**)cJSON_malloc(numentries*sizeof(char*));
        if (!entries) return 0;
        names=(char**)cJSON_malloc(numentries*sizeof(char*));
        if (!names) {cJSON_free(entries);return 0;}
        memset(entries,0,sizeof(char*)*numentries);
        memset(names,0,sizeof(char*)*numentries);

        /* Collect all the results into our arrays: */
        child=item->child;
        depth++;
        if (fmt) 
            len+=depth;
        while (child)
        {
            names[i]=str=print_string_ptr(child->string,0);
            entries[i++]=ret=print_value(child,depth,fmt,0);
            if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; //为什么要在两个strlen函数的后面+2+(fmt?2+depth:0) ?因为在组织一个有输出格式的字符串时,需要在key前面添加depth个制表符,第一个加2是为了逗号和换行符,第二个加2是冒号和value前面的一个制表符 (查看输出截图)
            child=child->next;
        }
        
        /* Try to allocate the output string */
        if (!fail)    out=(char*)cJSON_malloc(len);
        if (!out) fail=1;

        /* Handle failure */
        if (fail)
        {
            
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值