目前很多协议都定义为json的方式进行通信,使用的是cJSON,但是由于json内容的多样化,序列化和反序列化会比较麻烦,容易出错,也不方便理解,所以定义了一套易用的方式来统一对cJSON进行序列化和反序列化
支持序列化和反序列化的操作;
序列化和反序列化对应JSON格式,容易阅读;
支持option类型的JSON
{ "code": "000000", "desc": "success", "biz": [ { "audioPath": "/mnt/card/test1.pcm", "orderFileId": null, "orderUploadStatus": 0, "orderUploadedSize": null, "cloudFileId": 3933, "cloudUploadStatus": 0, "cloudUploadedSize": null, "isError": 1, "errorDesc": "获取上传音频信息失败" } ] }
以上部分如果使用cSON暴露的接口直接使用,会产生一大堆的逻辑判断和定义,序列化的地方多了还容易导致可能的内存泄露等问题,封装的序列化使用如下:
如上图所示,JSON格式的定义和序列化过程从结构上都是一一对应上的,比较直观和理解,容易修改。
#ifndef CJSON_USER_DEFINE_H #define CJSON_USER_DEFINE_H #ifdef __cplusplus extern "C" { #endif #include #define JSON_DESERIALIZE_CREATE_OBJECT_START(json_obj) \ cJSON *json_obj = cJSON_CreateObject(); #define JSON_DESERIALIZE_ADD_ARRAY_TO_OBJECT(json_obj, key, value) \ cJSON_AddItemToObject(json_obj, key, value); #define JSON_DESERIALIZE_ADD_OBJECT_TO_OBJECT(json_obj, key, value) \ cJSON_AddItemToObject(json_obj, key, value); #define JSON_DESERIALIZE_ADD_STRING_TO_OBJECT(json_obj, key, value) \ cJSON_AddItemToObject(json_obj, key, cJSON_CreateString(value)); #define JSON_DESERIALIZE_ADD_INT_TO_OBJECT(json_obj, key, value) \ cJSON_AddItemToObject(json_obj, key, cJSON_CreateNumber(value)); #define JSON_DESERIALIZE_CREATE_ARRAY_START(json_array) \ cJSON *json_array = cJSON_CreateArray(); #define JSON_DESERIALIZE_ADD_ARRAY_TO_ARRAY(json_array, sub_json_array) \ cJSON_AddItemToArray(json_array, sub_json_array); #define JSON_DESERIALIZE_ADD_OBJECT_TO_ARRAY(json_array, json_obj) \ cJSON_AddItemToArray(json_array, json_obj); #define JSON_DESERIALIZE_CREATE_END(json_obj) \ if (json_obj) cJSON_Delete(json_obj); #define JSON_DESERIALIZE_STRING(json_doc, str, len) \ { \ char *s = cJSON_PrintUnformatted(json_doc); \ if (s) { \ snprintf(str, len, "%s", s); \ free(s); \ s = NULL; \ } \ } #define JSON_SERIALIZE_START(json_root, json_string, ret) \ { \ cJSON *json_root = NULL; \ do { \ if (NULL == json_string) { \ ret = -1; \ break; \ } \ json_root = cJSON_Parse(json_string); \ if (NULL == json_root) { \ ret = -2; \ break; \ } #define JSON_SERIALIZE_GET_INT(json_doc, key, value, ret, jump) \ if (NULL == json_doc) { \ ret = -1; \ printf("%s error\n", key); \ break; \ } \ if (cJSON_HasObjectItem(json_doc, key)) { \ value = cJSON_GetObjectItem(json_doc, key)->valueint; \ } \ else { \ ret = -3; \ if (jump) break; \ } #define JSON_SERIALIZE_GET_STRING(json_doc, key, value, ret, jump) \ if (NULL == json_doc) { \ printf("%s error\n", key); \ ret = -1; \ break; \ } \ if (cJSON_HasObjectItem(json_doc, key)) { \ value = cJSON_GetObjectItem(json_doc, key)->valuestring; \ } \ else { \ ret = -4; \ if (jump) break; \ } #define JSON_SERIALIZE_GET_STRING_COPY(json_doc, key, value, len, ret, jump) \ if (NULL == json_doc) { \ printf("%s error\n", key); \ ret = -1; \ break; \ } \ if (cJSON_HasObjectItem(json_doc, key)) { \ snprintf(value, len, "%s", cJSON_GetObjectItem(json_doc, key)->valuestring); \ } \ else { \ ret = -5; \ if (jump) break; \ } #define JSON_SERIALIZE_GET_ARRAY(json_doc, key, value, ret, jump) \ cJSON *value = NULL; \ if (NULL == json_doc) { \ ret = -1; \ break; \ } \ if (cJSON_HasObjectItem(json_doc, key)) { \ value = cJSON_GetObjectItem(json_doc, key); \ } \ else { \ ret = -6; \ if (jump) break; \ } #define JSON_SERIALIZE_ARRAY_FOR_EACH_START(json_doc, sub_item, pos, total) \ int pos, total; \ total = cJSON_GetArraySize(json_doc); \ for (pos = 0; pos < total; pos++) { \ cJSON *sub_item = cJSON_GetArrayItem(json_doc, pos); #define JSON_SERIALIZE_ARRAY_FOR_EACH_END() \ } #define JSON_SERIALIZE_GET_OBJECT(json_doc, key, value, ret, jump) \ cJSON *value = NULL; \ if (NULL == json_doc) { \ ret = -1; \ break; \ } \ if (cJSON_HasObjectItem(json_doc, key)) { \ value = cJSON_GetObjectItem(json_doc, key); \ } \ else { \ ret = -7; \ if (jump) break; \ } #define JSON_SERIALIZE_END(json_root, ret) \ if (NULL != json_root) { \ cJSON_Delete(json_root); \ json_root = NULL; \ } \ ret = 0; \ } while (0); \ } #ifdef __cplusplus } #endif #endif // CJSON_USER_DEFINE_H