cJSON 使用笔记

cJSON:

/* cJSON Types: */
#define cJSON_Invalid (0)
#define cJSON_False  (1 << 0)
#define cJSON_True   (1 << 1)
#define cJSON_NULL   (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array  (1 << 5)
#define cJSON_Object (1 << 6)
#define cJSON_Raw    (1 << 7) /* raw json */

#define cJSON_IsReference 256
#define cJSON_StringIsConst 512

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

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

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

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

typedef struct cJSON_Hooks
{
      void *(*malloc_fn)(size_t sz);
      void (*free_fn)(void *ptr);
} cJSON_Hooks;

主要函数API:

//返回当前版本信息
/* returns the version of cJSON as a string */
CJSON_PUBLIC(const char*) cJSON_Version(void); 
printf("cJSON Version:%s\n" ,cJSON_Version());


/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
//从block中解析返回cJSON object
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
    int fd = -1;
    int rlen = 0;
    int file_size = 0;
    char *buf = NULL;
    struct stat stbuf;
    cJSON *root = NULL;
    if (access("data.db", F_OK) == -1)
    {
    //error data.db not exist
    }

    fd = open("data.db", O_RDONLY, 0666);
    if (fd < 0) {
        // error data.db can not open
    }

    if((fstat(fd, &stbuf)) != 0) {
       //get file stat error.
    }

    file_size = stbuf.st_size;
    printf("FILE SIZE :%d\n", file_size);
    buf = (char*)malloc(file_size+1);
    if(buf == NULL) {
       // malloc error.
    }

    rlen = read(fd, buf, file_size);
    if(rlen < 0)
    {
      //read error.
    }
    close(fd);

    root = cJSON_Parse(buf);
    if (root == NULL) {
       // parse json object error.
    }
    ...
    if (root)
      cJSON_Delete(root);  //注意:如果其他cJSON Object是从root GetItem 得到的,不能掉用cJSON_Delete删除object.


/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
//返回格式化后的json数据,包含换行等格式符,
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
char *data = NULL;
data = cJSON_Print(root);
printf("data:%s\n", cJSON_Print(root)); //会按数据项换行
{
  "name":"phenecy",
  "age":26,
  "weight":15.21
}


/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
//返回 未格式化后的json数据, 
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
char *data = NULL;
data = cJSON_PrintUnformatted(root);
printf("data:%s\n", cJSON_PrintUnformatted(root)); //数据都在一行
{"name":"phenecy","age":26,"weight":15.21}


/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);


/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
/* NOTE: If you are printing numbers, the buffer hat to be 63 bytes bigger then the printed JSON (worst case) */
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);


// 删除cJSON Object
/* Delete a cJSON entity and all subentities. */
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
if(root)
  cJSON_Delete(root);

// 返回json数组类型到size
/* Returns the number of items in an array (or object). */
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
int size = 0;
size = cJSON_GetArraySize(array); 

/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int item);
cJSON *item;
if (cJSON_IsArray(array)) // 判断array是否是Array类型
  item = cJSON_GetArrayItem(array, 0); //返回array的0个元素数据项。

//从object 获得 item “string”
/* Get item "string" from object. Case insensitive. */
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON *object, const char *string);
cJSON *item;
item = cJSON_GetObjectItem(root, "name");
if (item != NULL) 
{
  //use item
}

//从object 获得 item “string”, string大小写敏感  "Name" 和 "name" 不是同一个item
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON *object, const char *string);
cJSON *item;
item = cJSON_GetObjectItem(root, "name"); //"Name" 和 "name" 不是同一个item
if (item != NULL) 
{
  //use item
}

// 判断object 是否包含"string"这个item
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
if (cJSON_HasObjectItem(root, "name")) {
  // object root  has "name" item
}

// 返回错误信息
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
printf("cJSON Error:%s\n", cJSON_GetErrorPtr());

判断item的cJSON类型函数:

/* These functions check the type of an item */
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); //无效
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); // False  假值
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); // True  真值
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);  // Bool 布尔
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);  //Null 空
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); //数字 整型,浮点型
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); // 字符串
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);  // 数组
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); // Object
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);  // Raw
if (cJSON_IsInvalid(item)) {
   //无效的cJSON类型
}
if (cJSON_IsFalse(item)) {
   // item是cJSON  False数据类型
}

其他类型判断用法相似

创建指定cJSON数据类型item:

/* These calls create a cJSON item of the appropriate type. */
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
用例:
cJSON *item = NULL;
item = cJSON_CreateNull();
item = cJSON_CreateTrue();
item = cJSON_CreateFalse();
item = cJSON_CreateBool(1); //0:False, 1:True
item = cJSON_CreateNumber(18); // 整型
item = cJSON_CreateNumber(3.1415926);//浮点型
item = cJSON_CreateString("hello world"); //字符串


/* raw json */
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
用例:
cJSON *item = NULL;
item = cJSON_CreateRaw("Hi this is json raw data"); //创建Raw类型
item = cJSON_CreateArray(); //创建数组类型
item = cJSON_CreateObject(); 创建Object



/* These utilities create an Array of count items. */
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
用例:
int intarray[] = {1, 2, 3, 4, 5, 6, 7 ,8, 9, 0};
cJSON *array;
array = cJSON_CreateIntArray(intarray, sizeof(intarray)/sizeof(int)); // 第二个参数是要创建的数组长度, 10。
array = cJSON_CreateIntArray(intarray, sizeof(intarray)/sizeof(5)); //长度5
其他几个类型方法相似

添加元素操作:

/* Append item to the specified array/object. */
//添加item到数组
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
    cJSON *array = NULL;
    cJSON *item = NULL;
    array = cJSON_CreateArray();
    if (array == NULL) 
    {
        // ERROR
    }
    cJSON_AddItemToArray(array, cJSON_CreateString("Android"));
    cJSON_AddItemToArray(array, cJSON_CreateString("C++"));
    cJSON_AddItemToArray(array, cJSON_CreateNumber(25));


CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
        cJSON_AddItemToObject(tree, "name", cJSON_CreateString("henoey"));
        cJSON_AddItemToObject(tree, "age", cJSON_CreateNumber(52));
        cJSON_AddItemToObject(tree, "weight", cJSON_CreateNumber(45.3245500));
        cJSON_AddItemToObject(tree, "m", cJSON_CreateBool(1));
        cJSON_AddItemToObject(tree, "s", cJSON_CreateBool(0));
        cJSON_AddItemToObject(tree, "one", cJSON_CreateFalse());
        cJSON_AddItemToObject(tree, "tow", cJSON_CreateFalse());
        cJSON_AddItemToObject(tree, "w", cJSON_CreateNull());
        cJSON_AddItemToObject(tree, "y", cJSON_CreateRaw("123456789ljadjfkwoqwe"));


/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
 * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
 * writing to `item->string` */
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
/* Remove/Detatch items from Arrays/Objects. */
// 分离数组 which为下标到item
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
cJSON *item = NULL;
item = cJSON_DetachItemFromArray(array, 2);

// 删除数组 which为下标到item
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
cJSON_DeleteItemFromArray(array, 2);

//分离object item "string"
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
cJSON *item;
item = cJSON_DetachItemFromObject(root, "name");

//删除object item "string"
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
cJSON_DeleteItemFromObject(root, "name");

更新操作:

/* Update array items. */
//array插入item 
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); 
/* Shifts pre-existing items to the right. */
cJSON_InsertItemInArray(array, 3,  cJSON_CreateString("Android"));

//array replace item
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
cJSON_ReplaceItemInArray(array, 1 cJSON_CreateNumber(12));

CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
cJSON_ReplaceItemInObject(root, "newname", cJSON_CreateString("HeHe"));
/* Duplicate a cJSON item */
// 复制一个副本 ,recurse:1 递归子元素。创建一个新的完全相同 cJSON item.
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); //recurse:1 递归
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */

/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error. If not, then cJSON_GetErrorPtr() does the job. */
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);

//压缩算法
CJSON_PUBLIC(void) cJSON_Minify(char *json);
cJSON_Minify(root);

示例摘自:
https://blog.csdn.net/zhenyu5211314/article/details/52367185?locationNum=11&fps=1
CJSON和HPack。
CJSON压缩示例
原始JSON:

    [
      { // This is a point
        "x": 100, 
        "y": 100
      }, { // This is a rectangle
        "x": 100, 
        "y": 100,
        "width": 200,
        "height": 150
      },
      {}, // an empty object
    ]

CJSON压缩后:    
    {
      "templates": [ 
        [0, "x", "y"], [1, "width", "height"] 
      ],
      "values": [ 
        { "values": [ 1,  100, 100 ] }, 
        { "values": [2, 100, 100, 200, 150 ] }, 
        {} 
      ]
    }


HPack压缩示例
原始JSON:

    [{
      name : "Andrea",
      age : 31,
      gender : "Male",
      skilled : true
    }, {
      name : "Eva",
      age : 27,
      gender : "Female",
      skilled : true
    }, {
      name : "Daniele",
      age : 26,
      gender : "Male",
      skilled : false
    }]


HPack压缩后:
[["name","age","gender","skilled"],["Andrea",31,"Male",true],["Eva",27,"Female",true],["Daniele",26,"Male",false]]
/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))

    cJSON_AddStringToObject(item, "name", "phenecy");
    cJSON_AddNumberToObject(item, "age", 26);
    cJSON_AddNumberToObject(item, "weight", 15.21);
    cJSON_AddBoolToObject(item, "mared", false);
    cJSON_AddBoolToObject(item, "student", true);
    cJSON_AddFalseToObject(item, "fale");
    cJSON_AddTrueToObject(item, "tu");
    cJSON_AddNullToObject(item, "nu");
    cJSON_AddRawToObject(item ,"rea", "hello world, hi loge");


/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
/* helper for the cJSON_SetNumberValue macro */
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);


#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))

// 遍历array
/* Macro for iterating over an array */
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
   cJSON_ArrayForEach(ff, array) {
        if (ff != NULL) {
            if (cJSON_IsNull(ff)) {

            } else if (cJSON_IsNumber(ff)) {
                printf("is numer\n");
                printf("%d\n", ff->valueint);
            } else if (cJSON_IsString(ff)) {
                printf("is string\n");
                printf("%s\n", ff->valuestring);
            } else if (cJSON_IsObject) {
                printf("is object\n");
            }
        }
    }
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值