往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- OpenHarmony之分布式软总线coap头文件& coap组包分析
- OpenHarmony之分布式软总线discovery/coap/source/coap_socket.c
- OpenHarmony之分布式软总线nstackx_device.c(一)
- OpenHarmony之分布式软总线nstackx_device.c(二)
- OpenHarmony之分布式软总线discovery_service.h头文件
- OpenHarmony之分布式软总线discovery_service.c(一)
- OpenHarmony之分布式软总线discovery_service.c(二)
- OpenHarmony之分布式软总线discovery_service.c(三)
- OpenHarmony之分布式软总线discovery_service.c(四)
- OpenHarmony之分布式软总线discovery_service.c(五)
- OpenHarmony之分布式软总线json_payload.c(一)
- OpenHarmony之分布式软总线json_payload.c(二)
- OpenHarmony之分布式软总线json_payload.c(三)
- OpenHarmony之分布式软总线json_payload.c(四)
- 持续更新中……
前言
之前博客已经分析了cjson组织数据的细节– cjson数据组织细节 。下面分析cjson数据的细节。
json_payload.c分析
解析数据细节
/*
函数功能: 解析JSON格式设备信息
函数参数:
data: 包含JSON数据链表的头节点
dev : 用于保存解析后信息
函数返回: 成功返回0,否则返回-1
详细:
1. 从data中获取键“字符串”,用来访问对象中的条目
2. 判断item是否字符串,并且其对应的值长度不为0,将item对应的值拷贝到dev中对应的属性
*/
static int ParseDeviceJsonData(const cJSON *data, DeviceInfo *dev)
{
//根据键值提取JSON数据,cJSON_GetObjectItemCaseSensitive 用于层层解析cjson
cJSON *item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_ID);
if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
return NSTACKX_EINVAL;
}
//将item对应的值拷贝到dev中对应的属性,这里是deviceId
if (strcpy_s(dev->deviceId, sizeof(dev->deviceId), item->valuestring)) {
return NSTACKX_EFAILED;
}
//提取设备名字的cJSON对象 判断item是否是否是字符串并且对应的值不为空,将item对应的值拷贝到dev中对应的属性,这里是deviceName
item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_NAME);
if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
return NSTACKX_EINVAL;
}
if (strcpy_s(dev->deviceName, sizeof(dev->deviceName), item->valuestring)) {
return NSTACKX_EFAILED;
}
//提取设备类型的cjson对象,同时进行判断键值和对应的value,之后复制
item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_TYPE);
if (!cJSON_IsNumber(item) || (item->valuedouble < 0) || (item->valuedouble > 0xFF)) {
return NSTACKX_EINVAL;
}
dev->deviceType = (uint8_t)item->valuedouble;
//提取设备版本, 同时进程判断键值和对应的value,之后复制
item = cJSON_GetObjectItemCaseSensitive(data, JSON_HICOM_VERSION);
if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
return NSTACKX_EOK;
}
if (strcpy_s(dev->version, sizeof(dev->version), item->valuestring)) {
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
/*
函数功能: 解析WIFIip
函数参数:
1. data: 包含JSON数据链表的头节点
2. dev: 用于保存解析的信息
函数返回值: 无
详细:
1.根据JSON_DEVICE_WLAN_IP获取cJSON对象
2.判断是否为字符串,将值为点分十进制地址转为二进制网络字节序ip
3. 如果转换不成功,那么将设备网络通信状态设置为已经连接
*/
static void ParseWifiApJsonData(const cJSON *data, DeviceInfo *dev)
{
cJSON *item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_WLAN_IP);
if (cJSON_IsString(item)) {
//将点分十进制地址转为二进制网络字节序的IP地址
if (inet_pton(AF_INET, item->valuestring, &(dev->netChannelInfo.wifiApInfo.ip)) != 1) {
} else {
dev->netChannelInfo.wifiApInfo.state = NET_CHANNEL_STATE_CONNETED;
}
}
}
/*
函数功能:解析设备hash数据
函数参数:
1. data: 包含JSON数据链表的头节点
2. dev: 用于保存解析的信息
函数返回值:无
详细:
1. 根据JSON_DEVICE_HASH获取cJSON结构
2. 判断item是否为空,如果不为空,判断item类型type是否是string并且值不为空
3. 将值拷贝到dev->deviceHash
*/
static void ParseDeviceHashData(const cJSON *data, DeviceInfo *dev)
{
cJSON *item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_HASH);
if (item == NULL) {
return;
}
if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
return;
}
if (strcpy_s(dev->deviceHash, sizeof(dev->deviceHash), item->valuestring)) {
return;
}
}
/*
函数功能: 解析服务数据
函数参数:
1. data: 包含JSON数据链表的头节点
2. dev: 用于保存解析的信息
详细:
1. 根据JSON_SERVICE_DATA获取cJSON结构
2. 判断item是否为空,如果不为空,判断item类型type是否是string并且值不为空
3. 3. 将值拷贝到dev->serviceData
*/
static void ParseServiceDataJsonData(const cJSON *data, DeviceInfo *dev)
{
cJSON *item = NULL;
item = cJSON_GetObjectItemCaseSensitive(data, JSON_SERVICE_DATA);
if (item == NULL) {
return;
}
if (!cJSON_IsString(item)) {
return;
}
if (strcpy_s(dev->serviceData, sizeof(dev->serviceData), item->valuestring)) {
return;
}
}
/*
函数功能: 解析功能位图
函数参数:
1. data: 包含JSON数据链表的头节点
2. deviceInfo: 用于保存解析的信息
详细:
1. 根据JSON_CAPABILITY_BITMAP获取cJSON结构
2. 判断item—>type是否是数组类型
3. 遍历数组对象,获取其中cJSON结构体,并判断capability中type是否是Number类型,检查对应的值是否合法
4. 将值赋值给设备功能位图,并将功能数+1
5. 最后将功能数赋值给设备功能数属性
*/
static void ParseCapabilityBitmap(const cJSON *data, DeviceInfo *deviceInfo)
{
cJSON *capability = NULL;
cJSON *item = NULL;
uint32_t capabilityBitmapNum = 0;
item = cJSON_GetObjectItemCaseSensitive(data, JSON_CAPABILITY_BITMAP);
if (cJSON_IsArray(item)) {
//遍历数组对象,获取其中cJSON结构体
cJSON_ArrayForEach(capability, item) {
if (capabilityBitmapNum >= NSTACKX_MAX_CAPABILITY_NUM) {
break;
}
if (!cJSON_IsNumber(capability) || capability->valuedouble < 0 || capability->valuedouble > 0xFFFFFFFF) {
/* skip invalid capability */
continue;
}
deviceInfo->capabilityBitmap[capabilityBitmapNum++] = (uint32_t)capability->valuedouble;
}
}
deviceInfo->capabilityBitmapNum = capabilityBitmapNum;
}
总结
至此关于cJSON的介绍和鸿蒙中使用cJSON组织服务发布数据和解析数据的细节分析完毕。
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请看下图提示: