cJSON 庫的使用和優化


  部門的產品使用自己公司研發的系統,嵌入式web服務器移植的是goahead2.5的,服務器和前端使用JSON交互,移植的cJSON庫,所以這段時間對JSON的使用做個簡單的筆記,cJSON.h提供出來的接口很多,但是感覺平時使用的也就那么幾個。

  在做測試的時候,通過創建json對象,添加節點,然后保存,讀取,輸出這樣的一個流程,發現當添加節點數多的時候,會會出現長時間的等待,當時好像是一萬行的數據量,整個創建過程花費了2,3秒鍾,所以當更多數據量的時候,花費的時間可能更長。最后發現是這個函數導致的結果,源碼如下,可以看到它每添加一個item,都是從頭往后找,等找到最后一個節點的時候,然后把item賦值給最后一個節點的next,所以節點越多,時間也就更長了。

void   cJSON_AddItemToArray(cJSON *array, cJSON *item)

void   cJSON_AddItemToArray(cJSON *array, cJSON *item)
{ cJSON
*c=array->child; if (!item) return; if (!c) { array->child=item; } else { while (c && c->next) c=c->next; suffix_object(c,item); } }

  查看cJSON的結構體,會發現,json結構有next和pre兩個指針,也就是它的鏈表是個雙向鏈表,但是就奇怪為何找節點卻不用這個優點,非得單向去找。

typedef struct cJSON {
    struct cJSON *next,*prev;    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *child;        /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */

    int type;                    /* The type of the item, as above. */

    char *valuestring;            /* The item's string, if type==cJSON_String */
    int valueint;                /* The item's number, if type==cJSON_Number */
    double valuedouble;            /* The item's number, if type==cJSON_Number */

    char *string;                /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;

  所以解決的思路就在這了,有兩種方式解決:

  1,利用array的pre指針,每次插入item后,同時將其指針保存在array->child->pre中,這樣我每次插入節點,都只需要找到第一個節點的pre指針,然后將item插到該地址之后,即可。

  cJSON * c = array->child;
    if(!item)
    {
        return ;
    }
    if(!c)
    {
        array->child = item;
        array->child->prev = item;
    }
    else
    {
        array->child->prev->next = item;
        array->child->prev = item;
        item->next = NULL;
  }

  2,第二種方式就很簡單,通過修改json結構體實現目的,在結構體中添加一個成員 struct cJSON * last;每次添加item的時候,同時將它的指針賦值給array->child->last;

這樣每次添加的時候,只需要查找last指針就可以找到最后一個節點。

  cJSON * c = array->child;
    if(!item)
    {
        return ;
    }
    if(!c)
    {
        array->child = item;
        array->child->last = item;
    }
    else
    {
        array->child->last->next = item;
        array->child->last = item;
        item = NULL;
    }

  用的最多的object對象就是這些了。

#define cJSON_AddNullToObject(object,name) 
#define cJSON_AddTrueToObject(object,name) 
#define cJSON_AddFalseToObject(object,name) 
#define cJSON_AddBoolToObject(object,name,b)
#define cJSON_AddNumberToObject(object,name,n) 
#define cJSON_AddStringToObject(object,name,s) 

還有數組對象

void cJSON_AddItemToArray(cJSON *array, cJSON *item);
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);

如果是將一個數組添加進對象就可以用

void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);

void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);

當用完json對象時候,就必須記者刪除 

cJSON_Delete(cJSON*);

將一個字符串解析成json對象

extern cJSON *cJSON_Parse(const char *value);

將一個json對象轉換成char *,但是這個字符串必須是手動刪除

extern char  *cJSON_Print(cJSON *item);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM