OpenHarmony之分布式软总线json_payload.c(四)

76 阅读4分钟

前言

之前博客已经分析了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;
    }
}
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到以下知识点。
`欢迎大家关注公众号<程序猿百晓生>,可以了解到以下知识点。`
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......

/*
    函数功能: 解析服务数据
    函数参数:
        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组织服务发布数据和解析数据的细节分析完毕。