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🚀,不定期分享原创知识。
  • 想要获取更多完整鸿蒙最新学习资源,请看下图提示:
    在这里插入图片描述
你可以在图形界面中添加一个复选框(QCheckBox),让用户选择是否需要回传cid。然后在on_submit函数中,根据复选框的状态设置payload中的stream参数,如果复选框被选中,则stream为False,否则为True。具体代码实现如下: ``` def on_submit(self): prompt = self.prompt_edit.toPlainText() question = self.question_edit.toPlainText() api_url = "https://api.devbit.cn/ai/api/ai/chat" api_key = "ZXlKMGVYQWlPaUpLVjFRaUxDSmhiR2NpT2lKSVV6STFOaUo5LmV5SjBkQ0k2TkN3aVlYVmtJam9pTlRNeE5XTmpZekV3TlRnME5HSTNNVGcyWmpoa09XRTVOVFppTnpGbU5HWWlMQ0pzZFNJNkltZGhiMmhoYjNkbGJpSXNJbVY0Y0NJNk1UWTROVFUwT0RjNU9Td2lkWElpT2pJc0ltcDBhU0k2SWtGUVNWOVVUMHRGVGw4MU16RTFZMk5qTVRBMU9EUTBZamN4T0RabU9HUTVZVGsxTm1JM01XWTBaaTAwSW4wLjM0WWhudzVpblNRVTZROWpkZ0RxRHlCQk1GM2xmN01HYTZBcXZJMV9ydjA=" headers = { "Authorization": "Bearer "+api_key, "Accept": "application/json" } stream = not self.cid_cb.isChecked() # 如果复选框被选中,则stream为False,否则为True payload = { "prompt": prompt, "question": question, "cid": self.cid if self.cid_cb.isChecked() else "", # 如果复选框被选中,则传递cid,否则不传递 "stream": stream } response = requests.post(api_url, json=payload, headers=headers) if response.status_code == 200: print(response.json()) json_response = response.json() self.cid = str(json_response['data']['cid']) self.json_response_edit.setText(str(json_response['data']['answer'])) else: print("Request failed with error code {reaponse.status_code}") self.json_response_edit.setText(f"请求失败,错误码 {response.status_code}") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值