1:功能描述

在本地有json配置文件,

  1. 通过该应用可以实现对配置文件的读取
  2. 将读取的信息转化成json格式,可以对其中的某一项,进行修改,添加,删除的操作
  3. 当添加的内容已存在,或这删除的内容不存在都会使用标志位保存
  4. 将更改后的json格式字符串,保存回源文件
  5. 如果json的字符串大小未变化,说明没有更动,则不会变动源文件的内容
  6. 设计了专门的函数,来检测添加和删除是否成功

2:代码实现

/*******************************************************************************
  * @file          cjson_test.c
  * @verison       v1.0.0
  * @copyright     COPYRIGHT © 2020 CSG
  * @author        ShiYanKai
  * @date:         2021-03-24
  * @brief
  * @bug
  * - 2021-03-24  SYK Created
*******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>

#include "cJSON.h"
#define FILE_PATH "./topo_config.json"
#define DEV_LIST_ADD    0
#define DEV_LIST_DEL    1
#define ADDRESS_LEN     6
#define ARRAY_LEN       128
#define UTC_YEAR        1900

typedef struct
{
    char addr[ARRAY_LEN];
    char desc[ARRAY_LEN];
    char manuID[ARRAY_LEN];
    unsigned char isReport;
    unsigned char flag;  //0:success 1:failed
}dev_list_t;
//打印CJSON
void printfJson(cJSON *json) {
    if (NULL == json) {
        return;
    }
    char *cjson=cJSON_Print(json);//深拷贝
    printf("json:%s\n", cjson);
    free(cjson);
}

static int time_get(char *time_str)
{
    struct tm tmp_tm;
    struct timeval tv;

    gettimeofday(&tv, NULL);
    localtime_r(&tv.tv_sec, &tmp_tm);

    sprintf(time_str, "%02d-%02d-%02d %02d:%02d:%02d", \
                              (tmp_tm.tm_year + UTC_YEAR),\
                              tmp_tm.tm_mon + 1,\
                              tmp_tm.tm_mday,\
                              tmp_tm.tm_hour,\
                              tmp_tm.tm_min,\
                              tmp_tm.tm_sec);
    return 0;
}

static int dev_list_find(cJSON *json, char *addr)
{
    cJSON *obj = NULL;
    cJSON *obj1 = NULL;
    int i = 0;
    int size = 0;

    if (NULL == json)
    {
        printf("passing a null pointer");
        return -1;
    }
    size = cJSON_GetArraySize(json);

    for (; i < size; i++)
    {
        obj1 = cJSON_GetArrayItem(json, i);

        for (obj = obj1->child; obj != NULL; obj = obj->next)
        {
            if ((strcmp(obj->string, "addr") == 0))
            {
               if (strcmp(obj->valuestring, addr) == 0)
               {
                    return i;
               }
            }
        }
    }

    return -1;
}
static int dev_list_add(cJSON *json, dev_list_t *dev_list, int num)
{
    cJSON *obj = NULL;
    cJSON *obj1 = NULL;
    cJSON *add_dev;
    int node_location;
    int i = 0;
    int size = 0;

    if (NULL == json)
    {
        printf("passing a null pointer");
        return -1;
    }

    add_dev = (cJSON *)malloc(sizeof(cJSON) * num);
    if (NULL == add_dev)
    {
        printf("malloc failed");
        return -1;
    }

    memset(add_dev, 0, sizeof(cJSON) * num);

    for (i = 0; i < num; i++)
    {
        add_dev = cJSON_CreateObject();
        cJSON_AddStringToObject(add_dev, "addr", dev_list->addr);
        cJSON_AddStringToObject(add_dev, "desc", dev_list->desc);
        cJSON_AddStringToObject(add_dev, "manuID", dev_list->manuID);
        cJSON_AddStringToObject(add_dev, "isReport", "1");

        node_location = dev_list_find(json, dev_list->addr);
        if (node_location >= 0)
        {
            printf("node is exist\n");
            dev_list->flag = 1;
        }
        else
        {
            cJSON_AddItemToArray(json, add_dev);
        }
        dev_list++;
        add_dev++;
   }

   return 0;
}
static int dev_list_del(cJSON *json, dev_list_t *dev_list, int num)
{
   int node_location;
   int i;

   for (i = 0; i < num; i++)
   {
       node_location = dev_list_find(json, dev_list->addr);
       if (node_location < 0)
       {
            printf("find node failed\n");
            dev_list->flag = 1;
       }
       else
       {
            cJSON_DeleteItemFromArray(json, node_location);
       }
       dev_list++;
   }

   return 0;
}

static int config_analysis_dev(cJSON *json, dev_list_t *dev_list, int num, int operation)
{
    cJSON *obj = NULL;
    cJSON *obj1 = NULL;
    int i = 0;
    int size = 0;
    int j = 0;

    if (NULL == json)
    {
        printf("passing a null pointer");
        return -1;
    }

    size = cJSON_GetArraySize(json);

    for (i = 0; i < size; i++)
    {
        obj1 = cJSON_GetArrayItem(json, i);

        for (obj = obj1->child; obj != NULL; obj = obj->next)
        {
            if ((strcmp(obj->string, "dev_list") == 0))
            {
                if(DEV_LIST_ADD == operation)
                {
                    dev_list_add(obj, dev_list, num);
                }

                if(DEV_LIST_DEL == operation)
                {
                    dev_list_del(obj, dev_list, num);
                }
                break;
            }
        }
    }
    return 0;
}   

int dev_list_change(dev_list_t *dev_list, int num, int operation)
{
    int fd = -1;
    int fd_w = -1;
    char *msg = NULL;
    struct stat file_stat;
    cJSON *json = NULL;
    cJSON *obj = NULL;
    char *new_str;
    int src_len;
    int dst_len;
    int ret;
    char time_str[32] = {0};

    fd = open(FILE_PATH, O_RDWR, 0666);
    if (-1 == fd)
    {
        perror("open failed\n");
        return -1;
    }

    if (-1 == stat(FILE_PATH, &file_stat))
    {
        printf("stat fail\n");
        return -1;
    }

    if (file_stat.st_size <= 0)
    {
        close(fd);
        printf("file size = %ld\n", file_stat.st_size);
        return -1;
    }
    src_len = file_stat.st_size;

    msg = (char *)malloc(src_len);
   if (NULL == msg)
    {
        close(fd);
        printf("malloc failed\n");
        return -1;
    }
    memset(msg, 0, src_len);

    if (-1 == read(fd, msg, src_len))
    {
        close(fd);
        printf("read failed\n");
        return -1;
    }
    close(fd);

    json = cJSON_Parse(msg);
    if (json == NULL)
    {
        free(msg);
        printf("json parse failed\n");
        return -1;
    }
    free(msg);

    for (obj = json->child; obj != NULL; obj = obj->next)
    {
        if (strcmp(obj->string, "port_dev") == 0)
        {
            if (obj->type == cJSON_Array)
            {
                if (0 == config_analysis_dev(obj, dev_list, num, operation))
                {
                    printf("config anlaysis device ok\n");
                }
            }
            break;
        }
    }

    time_get(time_str);
    printf("%s\n", time_str);
    cJSON_ReplaceItemInObject(json, "date", cJSON_CreateString(time_str));

    new_str = cJSON_Print(json);
    dst_len = strlen(new_str);

    if (dst_len == src_len)
    {
        cJSON_free(new_str);
        cJSON_Delete(json);
        printf("the file has not changed\n");
        return -1;
    }

    fd = open(FILE_PATH, O_RDWR | O_TRUNC, 0666);
    if (-1 == fd)
    {
        cJSON_free(new_str);
        cJSON_Delete(json);
        perror("open failed\n");
        return -1;
    }

    ret = write(fd, new_str, dst_len);
    fsync(fd);

    close(fd);
    cJSON_free(new_str);
    cJSON_Delete(json);

    return 0;
}

int add_del_response(dev_list_t *dev_list, int num, int operation)
{
    cJSON *root;
    cJSON *data;
    cJSON *dev_info;
    cJSON *dev;
    int status_code = 0;
    int i = 0;

    root = cJSON_CreateObject();
    dev = cJSON_CreateObject();
    data = cJSON_CreateArray();

    dev_info = (cJSON *)malloc(sizeof(cJSON) * num);
    if (NULL == dev_info)
    {
        printf("malloc failed\n");
        return -1;
    }

    dev = (cJSON *)malloc(sizeof(cJSON) * num);
    if (NULL == dev)
    {
        printf("malloc failed\n");
        return -1;
    }

    for (i = 0; i < num; i++)
    {
        dev_info = cJSON_CreateObject();
        dev = cJSON_CreateObject();

        cJSON_AddStringToObject(dev_info, "nodeId", dev_list->addr);

        cJSON_AddItemToObject(dev, "deviceInfo", dev_info);
        if (0 == dev_list->flag)
        {
            cJSON_AddStringToObject(dev, "statusCode", "0");
            if (DEV_LIST_ADD == operation)
            {
                cJSON_AddStringToObject(dev, "statusDesc", "add device success");
            }
            else
            {
                cJSON_AddStringToObject(dev, "statusDesc", "delete device success");
            }
        }
        else if (1 == dev_list->flag)
        {
            status_code = 1;
            cJSON_AddStringToObject(dev, "statusCode", "1");
            if (DEV_LIST_ADD == operation)
            {
                cJSON_AddStringToObject(dev, "statusDesc", "add device failed");
            }
            else
            {
                cJSON_AddStringToObject(dev, "statusDesc", "delete device failed");
            }
        }
        else
        {
            cJSON_AddStringToObject(dev, "statusCode", "null");
            cJSON_AddStringToObject(dev, "statusDesc", "the status flag is error");
        }

        cJSON_AddItemToArray(data, dev);

        dev_info++;
        dev++;
        dev_list++;
    }

    cJSON_AddStringToObject(root, "mid", "474");
    if (status_code)
   {
        cJSON_AddStringToObject(root, "statusCode", "1");
        cJSON_AddStringToObject(root, "statusDesc", "FAILED");
    }
    else
    {
        cJSON_AddStringToObject(root, "statusCode", "0");
        cJSON_AddStringToObject(root, "statusDesc", "SUCCESS");
    }

    cJSON_AddItemToObject(root, "data", data);
    printfJson(root);
    cJSON_free(root);
}

int main()
{
    int i = 0;
    dev_list_t *add_list;
    dev_list_t *add_list_del;
    dev_list_t *add_list_tmp;

    int num = 3;
    int num_del = 3;
    unsigned char *addr[3] = {"000000000014", "000000000012", "000000000013"};
    unsigned char *addr_del[3] = {"000000000011", "000000000013", "000000000015"};

//  int num = 1;
 //   int num_del = 1;
//  unsigned char *addr[1] = {"000000000015"};
//  unsigned char *addr_del[1] = {"000000000014"};
    add_list = (dev_list_t *)malloc(sizeof(dev_list_t) *num);
    add_list_del = (dev_list_t *)malloc(sizeof(dev_list_t) * num_del);
    add_list_tmp = add_list;

    for (i = 0; i < num; i++)
    {
        strncpy(add_list_tmp->addr, addr[i], sizeof(add_list_tmp->addr));
        strncpy(add_list_tmp->desc, "MCCB", sizeof(add_list_tmp->desc));
        strncpy(add_list_tmp->manuID, "1234", sizeof(add_list_tmp->desc));
        add_list_tmp->isReport = 1;
        add_list_tmp->flag = 0;
        add_list_tmp++;
    }

//  dev_list_change(add_list, num, DEV_LIST_ADD);
//  add_del_response(add_list, num, DEV_LIST_ADD);

#if 1
    add_list_tmp = add_list_del;

    for (i = 0; i < num_del; i++)
    {
        strncpy(add_list_tmp->addr, addr_del[i], sizeof(add_list_tmp->addr));
        strncpy(add_list_tmp->desc, "MCCB", sizeof(add_list_tmp->desc));
        strncpy(add_list_tmp->manuID, "1234", sizeof(add_list_tmp->desc));
        add_list_tmp->isReport = 1;
        add_list_tmp->flag = 0;
        add_list_tmp++;
    }

    dev_list_change(add_list_del, num_del, DEV_LIST_DEL);
    add_del_response(add_list_del, num_del, DEV_LIST_DEL);

    add_list_tmp = add_list_del;
    for (i = 0; i < num_del; i++)
    {
        if (add_list_tmp->flag)
        {
            printf("delete node failed, node(%s) don't exist\n", add_list_tmp->addr);
        }
        add_list_tmp++;
    }
#endif
}

3:源码

PATH

GitHub 加速计划 / cj / cJSON
10.45 K
3.16 K
下载
Ultralightweight JSON parser in ANSI C
最近提交(Master分支:2 个月前 )
424ce4ce This reverts commit 5b502cdbfb21fbe5f6cf9ffbd2b96e4281a741e6. Related to #860 4 个月前
32497300 - 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐