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) {