interface

interface

cjson_impl.c

#include "cJSON/cJSON.h"
#include "cson.h"
#include <string.h>
#include <stdio.h>

cson_t  cjson_impl_object_get(const cson_t object, const char* key){
    return cJSON_GetObjectItem((cJSON*)object, key);
}

cson_type cjson_impl_typeof(cson_t object){
    switch(((cJSON*)object)->type){
        case cJSON_Invalid:
        case cJSON_NULL:
            return CSON_NULL;
        case cJSON_False:
            return CSON_FALSE;
        case cJSON_True:
            return CSON_TRUE;
        case cJSON_Number:
            return CSON_REAL;
        case cJSON_String:
        case cJSON_Raw:
            return CSON_STRING;
        case cJSON_Array:
            return CSON_ARRAY;
        case cJSON_Object:
            return CSON_OBJECT;
        default:
            return CSON_NULL;
    }
}

cson_t cjson_impl_loadb(const char *buffer, size_t buflen){
    cson_t ret = NULL;
    ret = cJSON_Parse(buffer);
    if(!ret){
        printf("parse stop with:%s\n", cJSON_GetErrorPtr());
    }
    return ret;
}

void cjson_impl_decref(cson_t object){
    cJSON_Delete((cJSON*)object);
}

const char *cjson_impl_string_value(const cson_t object){
    return cJSON_GetStringValue((cJSON*)object);
}

size_t cjson_impl_string_length(const cson_t object){
    return strlen(cJSON_GetStringValue((cJSON*)object));
}

long long cjson_impl_integer_value(const cson_t object){
    return ((cJSON*)object)->valueint;
}

double cjson_impl_real_value(const cson_t object){
    return ((cJSON*)object)->valuedouble;
}

char cjson_impl_bool_value(const cson_t object){
    return ((cJSON*)object)->type == cJSON_True;
}

size_t cjson_impl_array_size(const cson_t object){
    return cJSON_GetArraySize((cJSON*)object);
}

cson_t cjson_impl_array_get(const cson_t object, size_t index){
    return cJSON_GetArrayItem((cJSON*)object, index);
}

cson_t cjson_impl_new(){
    return cJSON_CreateObject();
}

char* cjson_impl_to_string(cson_t object){
    return cJSON_PrintUnformatted((cJSON*)object);
}

cson_t cjson_impl_integer(long long val){
    cJSON* tmp = cJSON_CreateNumber(0);
    cJSON_SetNumberValue(tmp, val);
    return tmp;
}

cson_t cjson_impl_string(const char* val){
    return cJSON_CreateString(val);
}

cson_t cjson_impl_bool(char val){
    return cJSON_CreateBool(val);
}
cson_t cjson_impl_real(double val){
    return cJSON_CreateNumber(val);
}

cson_t cjson_impl_array(){
    return cJSON_CreateArray();
}

int cjson_impl_array_add(cson_t array, cson_t obj){
    cJSON_AddItemToArray((cJSON*)array, (cJSON*)obj);
    return 0;
}

int cjson_impl_object_set_new(cson_t rootObj, const char* field, cson_t obj){
    cJSON_AddItemToObject((cJSON*)rootObj, field, (cJSON*)obj);
    return 0;
}

cson_interface csomImpl = {
    cjson_impl_object_get,
    cjson_impl_typeof,
    cjson_impl_loadb,
    cjson_impl_decref,
    cjson_impl_string_value,
    cjson_impl_string_length,
    cjson_impl_integer_value,
    cjson_impl_real_value,
    cjson_impl_bool_value,
    cjson_impl_array_size,
    cjson_impl_array_get,
    cjson_impl_new,
    cjson_impl_to_string,
    cjson_impl_integer,
    cjson_impl_string,
    cjson_impl_bool,
    cjson_impl_real,
    cjson_impl_array,
    cjson_impl_array_add,
    cjson_impl_object_set_new
};

cson.c

#include "cson.h"
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <limits.h>
#include <string.h>

extern cson_interface csomImpl;

#define cson_object_get csomImpl.cson_object_get
#define cson_typeof csomImpl.cson_typeof
#define cson_loadb csomImpl.cson_loadb
#define cson_decref csomImpl.cson_decref
#define cson_string_value csomImpl.cson_string_value
#define cson_string_length csomImpl.cson_string_length
#define cson_integer_value csomImpl.cson_integer_value
#define cson_real_value csomImpl.cson_real_value
#define cson_bool_value csomImpl.cson_bool_value
#define cson_array_size csomImpl.cson_array_size
#define cson_array_get csomImpl.cson_array_get
#define cson_object csomImpl.cson_object
#define cson_to_string csomImpl.cson_to_string
#define cson_integer csomImpl.cson_integer
#define cson_string csomImpl.cson_string
#define cson_bool csomImpl.cson_bool
#define cson_real csomImpl.cson_real
#define cson_array csomImpl.cson_array
#define cson_array_add csomImpl.cson_array_add
#define cson_object_set_new csomImpl.cson_object_set_new
#define cson_is_number(type) (type == CSON_REAL || type == CSON_INTEGER)
#define cson_is_bool(type)    (type == CSON_TRUE || type == CSON_FALSE)

const reflect_item_t integerReflectTbl[] = {
    {"0Integer", 0, sizeof(int), CSON_INTEGER, NULL, 0, NULL, 1},
    {}
};

const reflect_item_t stringReflectTbl[] = {
    {"0String", 0, sizeof(char*), CSON_STRING, NULL, 0, NULL, 1},
    {}
};

const reflect_item_t realReflectTbl[] = {
    {"0Real", 0, sizeof(double), CSON_REAL, NULL, 0, NULL, 1},
    {}
};

const reflect_item_t boolReflectTbl[] = {
    {"0Bool", 0, sizeof(int), CSON_TRUE, NULL, 0, NULL, 1},
    {}
};

/*
 *  reflecter functions
 */
static const reflect_item_t* getReflexItem(const char* field, const reflect_item_t* tbl, int* pIndex);
static void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl, int* pIndex);
static void csonSetProperty(void* obj, const char* field, void* data, const reflect_item_t* tbl);
static void csonSetPropertyFast(void* obj, const void* data, const reflect_item_t* tbl);

/*
 *  integer util functions
 */
typedef union {
    char c;
    short s;
    int i;
    long long l;
} integer_val_t;

static long long getIntegerValueFromPointer(void* ptr, int size);
static int getIntegerValue(cson_t jo_tmp, int size, integer_val_t* i);
static int convertInteger(long long val, int size, integer_val_t* i);
static int checkInteger(long long val, int size);

/*
 * packer functions
 */
typedef int (*json_pack_proc)(void* input, const reflect_item_t* tbl, int index, cson_t* obj);

static int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
static int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
static int getJsonString(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
static int getJsonInteger(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
static int getJsonReal(void* input, const reflect_item_t* tbl, int index, cson_t* obj);
static int getJsonBool(void* input, const reflect_item_t* tbl, int index, cson_t* obj);

json_pack_proc jsonPackTbl[] = {
    getJsonObject,
    getJsonArray,
    getJsonString,
    getJsonInteger,
    getJsonReal,
    getJsonBool,
    getJsonBool,
    NULL
};

static int csonStruct2JsonObj(cson_t obj, void* input, const reflect_item_t* tbl);

/*
 * parser functions
 */
typedef int (*json_obj_proc)(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);

static int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
static int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
static int parseJsonString(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
static int parseJsonInteger(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
static int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
static int parseJsonBool(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);

json_obj_proc jsonObjProcTbl[] = {
    parseJsonObject,
    parseJsonArray,
    parseJsonString,
    parseJsonInteger,
    parseJsonReal,
    parseJsonBool,
    parseJsonBool,
    NULL
};

static int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
static int parseJsonArrayDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
static int parseJsonStringDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
static int parseJsonIntegerDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);
static int parseJsonRealDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index);

json_obj_proc jsonObjDefaultTbl[] = {
    parseJsonObjectDefault,
    parseJsonArrayDefault,
    parseJsonStringDefault,
    parseJsonIntegerDefault,
    parseJsonRealDefault,
    parseJsonIntegerDefault,
    parseJsonIntegerDefault,
    NULL
};

static int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl);

int csonStruct2JsonStr(char** jstr, void* input, const reflect_item_t* tbl)
{
    cson_t jsonPack = cson_object();

    if (!jsonPack) return ERR_MEMORY;

    int ret = csonStruct2JsonObj(jsonPack, input, tbl);

    if (ret == ERR_NONE) {
        char* dumpStr = cson_to_string(jsonPack);
        if (dumpStr == NULL) {
            ret = ERR_MEMORY;
        } else {
            *jstr = dumpStr;
        }
    }

    cson_decref(jsonPack);
    return ret;
}

int csonStruct2JsonObj(cson_t obj, void* input, const reflect_item_t* tbl)
{
    int i = 0;
    int ret = ERR_NONE;

    if (!obj || !input || !tbl) return ERR_ARGS;

    while (1) {
        if (tbl[i].field == NULL) break;

        if(tbl[i].exArgs & _ex_args_exclude_encode){
            i++;
            continue;
        }

        cson_t joTmp = NULL;
        int jsonType = tbl[i].type;

        if (jsonPackTbl[jsonType] != NULL) {
            ret = jsonPackTbl[jsonType](input, tbl, i, &joTmp);
        }

        if (ret != ERR_NONE ) {
            printf("!!!!pack error on field:%s, cod=%d!!!!\n", tbl[i].field, ret);
            if (!(tbl[i].exArgs & _ex_args_nullable)) return ret;
        } else {
            cson_object_set_new(obj, tbl[i].field, joTmp);
        }

        i++;
    }

    return ERR_NONE;
}

int getJsonInteger(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
{
    if (tbl[index].size != sizeof(char) &&
        tbl[index].size != sizeof(short) &&
        tbl[index].size != sizeof(int) &&
        tbl[index].size != sizeof(long long)) {
        printf("Unsupported size(=%ld) of integer.\n", tbl[index].size);
        printf("Please check if the type of field %s in char/short/int/long long!\n", tbl[index].field);
        return ERR_OVERFLOW;
    }

    void* pSrc = (void*)((char*)input + tbl[index].offset);

    long long val = getIntegerValueFromPointer(pSrc, tbl[index].size);

    *obj = cson_integer(val);

    return ERR_NONE;
}

int getJsonString(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
{
    void* pSrc = (void*)((char*)input + tbl[index].offset);

    if (*((char**)pSrc) == NULL) return ERR_MISSING_FIELD;

    *obj = cson_string(*((char**)pSrc));
    return ERR_NONE;
}

int getJsonObject(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
{
    void* pSrc = (void*)((char*)input + tbl[index].offset);
    cson_t jotmp = cson_object();
    int ret = csonStruct2JsonObj(jotmp, pSrc, tbl[index].reflect_tbl);

    if (ret == ERR_NONE) {
        *obj = jotmp;
    } else {
        cson_decref(jotmp);
    }

    return ret;
}

int getJsonArray(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
{
    int ret = ERR_NONE;
    int countIndex = -1;
    char* pSrc = (*(char**)((char*)input + tbl[index].offset));

    if (pSrc == NULL) return ERR_MISSING_FIELD;

    void* ptr = csonGetProperty(input, tbl[index].arrayCountField, tbl, &countIndex);

    if (ptr == NULL || countIndex == -1) {
        return ERR_MISSING_FIELD;
    }
    long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size);

    cson_t joArray = cson_array();

    long long successCount = 0;

    for (long long i = 0; i < size; i++) {
        cson_t jotmp;

        if (tbl[index].reflect_tbl[0].field[0] == '0') {    /* field start with '0' mean basic types. */
            ret = jsonPackTbl[tbl[index].reflect_tbl[0].type](pSrc + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0, &jotmp);
        } else {
            jotmp = cson_object();
            ret = csonStruct2JsonObj(jotmp, pSrc + (i * tbl[index].arrayItemSize), tbl[index].reflect_tbl);
        }

        if (ret == ERR_NONE) {
            successCount++;
            cson_array_add(joArray, jotmp);
        } else {
            printf("create array item faild.\n");
            cson_decref(jotmp);
        }
    }

    if (successCount == 0) {
        cson_decref(joArray);
        return ERR_MISSING_FIELD;
    } else {
        *obj = joArray;
        return ERR_NONE;
    }

    return ret;
}

int getJsonReal(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
{
    if (tbl[index].size != sizeof(double)) {
        printf("Unsupported size(=%ld) of real.\n", tbl[index].size);
        printf("Please check if the type of field %s is double!\n", tbl[index].field);
        return ERR_OVERFLOW;
    }

    void* pSrc = (void*)((char*)input + tbl[index].offset);
    *obj = cson_real(*((double*)pSrc));
    return ERR_NONE;
}

int getJsonBool(void* input, const reflect_item_t* tbl, int index, cson_t* obj)
{
    if (tbl[index].size != sizeof(char) &&
        tbl[index].size != sizeof(short) &&
        tbl[index].size != sizeof(int) &&
        tbl[index].size != sizeof(long long)) {
        printf("Unsupported size(=%ld) of bool.\n", tbl[index].size);
        printf("Please check if the type of field %s in char/short/int/long long!\n", tbl[index].field);
        return ERR_OVERFLOW;
    }

    void* pSrc = (void*)((char*)input + tbl[index].offset);

    if (tbl[index].size == sizeof(char)) {
        *obj = cson_bool(*((char*)pSrc));
    } else if (tbl[index].size == sizeof(short)) {
        *obj = cson_bool(*((short*)pSrc));
    } else if (tbl[index].size == sizeof(int)) {
        *obj = cson_bool(*((int*)pSrc));
    } else {
        *obj = cson_bool(*((long long*)pSrc));
    }

    return ERR_NONE;
}


int csonJsonStr2Struct(const char* jstr, void* output, const reflect_item_t* tbl)
{
    /* load json string */
    cson_t jo = cson_loadb(jstr, strlen(jstr));

    if (!jo) return ERR_FORMAT;

    int ret = csonJsonObj2Struct(jo, output, tbl);
    cson_decref(jo);

    return ret;
}

int csonJsonObj2Struct(cson_t jo, void* output, const reflect_item_t* tbl)
{
    if (!jo || !output || !tbl) return ERR_ARGS;

    for (int i = 0;; i++) {
        int ret = ERR_NONE;
        if (tbl[i].field == NULL) break;
        
        if(tbl[i].exArgs & _ex_args_exclude_decode){
            continue;
        }

        cson_t jo_tmp = cson_object_get(jo, tbl[i].field);

        if (jo_tmp == NULL) {
            ret = ERR_MISSING_FIELD;
        } else {

            int jsonType = cson_typeof(jo_tmp);

            if (jsonType == tbl[i].type ||
                (cson_is_number(cson_typeof(jo_tmp)) && cson_is_number(tbl[i].type)) ||
                (cson_is_bool(cson_typeof(jo_tmp)) && cson_is_bool(tbl[i].type))) {
                if (jsonObjProcTbl[tbl[i].type] != NULL) {
                    ret = jsonObjProcTbl[tbl[i].type](jo_tmp, output, tbl, i);
                }
            } else {
                ret = ERR_TYPE;
            }
        }

        if (ret != ERR_NONE ) {
            printf("!!!!parse error on field:%s, cod=%d!!!!\n", tbl[i].field, ret);
            jsonObjDefaultTbl[tbl[i].type](NULL, output, tbl, i);
            if (!(tbl[i].exArgs & _ex_args_nullable)) return ret;
        }
    }

    return ERR_NONE;
}

int parseJsonString(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    const char* tempstr = cson_string_value(jo_tmp);
    if (NULL != tempstr) {
        char* pDst = (char*)malloc(strlen(tempstr) + 1);
        if (pDst == NULL) {
            return ERR_MEMORY;
        }
        strcpy(pDst, tempstr);
        csonSetPropertyFast(output, &pDst, tbl + index);

        return ERR_NONE;
    }

    return ERR_MISSING_FIELD;
}

int parseJsonInteger(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    int ret;
    integer_val_t value;
    ret = getIntegerValue(jo_tmp, tbl[index].size, &value);

    if (ret != ERR_NONE) {
        printf("Get integer failed!field:%s,errno:%d.\n", tbl[index].field, ret);
    } else {
        csonSetPropertyFast(output, &value, tbl + index);
    }

    return ret;
}

int parseJsonObject(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    return csonJsonObj2Struct(jo_tmp, (char*)output + tbl[index].offset, tbl[index].reflect_tbl);
}

int parseJsonArray(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    size_t arraySize = cson_array_size(jo_tmp);

    if (arraySize == 0) {
        csonSetProperty(output, tbl[index].arrayCountField, &arraySize, tbl);
        return ERR_NONE;
    }

    int countIndex = -1;
    csonGetProperty(output, tbl[index].arrayCountField, tbl, &countIndex);

    if (countIndex == -1) {
        return ERR_MISSING_FIELD;
    }

    char* pMem = (char*)malloc(arraySize * tbl[index].arrayItemSize);
    if (pMem == NULL) return ERR_MEMORY;

    memset(pMem, 0, arraySize * tbl[index].arrayItemSize);

    long long successCount = 0;
    for (size_t j = 0; j < arraySize; j++) {
        cson_t item = cson_array_get(jo_tmp, j);
        if (item != NULL) {
            int ret;

            if (tbl[index].reflect_tbl[0].field[0] == '0') {    /* field start with '0' mean basic types. */
                ret = jsonObjProcTbl[tbl[index].reflect_tbl[0].type](item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl, 0);
            } else {
                ret = csonJsonObj2Struct(item, pMem + (successCount * tbl[index].arrayItemSize), tbl[index].reflect_tbl);
            }

            if (ret == ERR_NONE) {
                successCount++;
            }
        }
    }

    integer_val_t val;
    if (convertInteger(successCount, tbl[countIndex].size, &val) != ERR_NONE) {
        successCount = 0;
    }

    if (successCount == 0) {
        csonSetPropertyFast(output, &successCount, tbl + countIndex);
        free(pMem);
        pMem = NULL;
        csonSetPropertyFast(output, &pMem, tbl + index);
        return ERR_MISSING_FIELD;
    } else {
        csonSetPropertyFast(output, &val, tbl + countIndex);
        csonSetPropertyFast(output, &pMem, tbl + index);
        return ERR_NONE;
    }
}

int parseJsonReal(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    if (tbl[index].size != sizeof(double)) {
        printf("Unsupported size(=%ld) of real.\n", tbl[index].size);
        printf("Please check if the type of field %s is double!\n", tbl[index].field);
        return ERR_OVERFLOW;
    }

    double temp;
    if (cson_typeof(jo_tmp) == CSON_REAL) {
        temp = cson_real_value(jo_tmp);
    } else {
        temp = cson_integer_value(jo_tmp);
    }

    csonSetPropertyFast(output, &temp, tbl + index);
    return ERR_NONE;
}

int parseJsonBool(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    int ret;
    integer_val_t value;
    ret = getIntegerValue(jo_tmp, tbl[index].size, &value);
    if (ret != ERR_NONE) {
        printf("Get integer failed!field:%s,errno:%d.\n", tbl[index].field, ret);
    } else {
        csonSetPropertyFast(output, &value, tbl + index);
    }
    return ret;
}

int parseJsonObjectDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    int i = 0;
    while (1) {
        if (tbl[i].reflect_tbl[i].field == NULL) break;
        
        if(tbl[i].exArgs & _ex_args_exclude_decode){
            i++;
            continue;
        }

        jsonObjDefaultTbl[tbl[index].reflect_tbl[i].type](NULL, output, tbl[index].reflect_tbl, i);
        i++;
    };
    return ERR_NONE;
}

int parseJsonArrayDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    void* temp = NULL;
    csonSetPropertyFast(output, &temp, tbl + index);
    return ERR_NONE;
}

int parseJsonStringDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    char* temp = NULL;
    csonSetPropertyFast(output, &temp, tbl + index);
    return ERR_NONE;
}

int parseJsonIntegerDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    long long temp = 0;

    if (tbl[index].size != sizeof(char) &&
        tbl[index].size != sizeof(short) &&
        tbl[index].size != sizeof(int) &&
        tbl[index].size != sizeof(long long)) {
        printf("Unsupported size(=%ld) of bool.\n", tbl[index].size);
        printf("Please check if the type of field %s in char/short/int/long long!\n", tbl[index].field);
        return ERR_OVERFLOW;
    }

    integer_val_t ret;
    convertInteger(temp, tbl[index].size, &ret);

    csonSetPropertyFast(output, &ret, tbl + index);
    return ERR_NONE;
}

int parseJsonRealDefault(cson_t jo_tmp, void* output, const reflect_item_t* tbl, int index)
{
    if (tbl[index].size != sizeof(double)) {
        printf("Unsupported size(=%ld) of bool.\n", tbl[index].size);
        printf("Please check if the type of field %s is double!\n", tbl[index].field);
        return ERR_OVERFLOW;
    }

    double temp = 0.0;
    csonSetPropertyFast(output, &temp, tbl + index);
    return ERR_NONE;
}


int getIntegerValue(cson_t jo_tmp, int size, integer_val_t* i)
{
    long long temp;

    if (cson_typeof(jo_tmp) == CSON_INTEGER) {
        temp = cson_integer_value(jo_tmp);
    } else if (cson_typeof(jo_tmp) == CSON_TRUE) {
        temp = 1;
    } else if (cson_typeof(jo_tmp) == CSON_FALSE) {
        temp = 0;
    } else if (cson_typeof(jo_tmp) == CSON_REAL) {
        double tempDouble = cson_real_value(jo_tmp);
        if (tempDouble > LLONG_MAX || tempDouble < LLONG_MIN) {
            return ERR_OVERFLOW;
        } else {
            temp = tempDouble;
        }
    } else {
        return ERR_ARGS;
    }

    return convertInteger(temp, size, i);
}

int convertInteger(long long val, int size, integer_val_t* i)
{
    int ret = checkInteger(val, size);

    if (ret != ERR_NONE) return ret;

    /* avoid error on big endian */
    if (size == sizeof(char)) {
        i->c = val;
    } else if (size == sizeof(short)) {
        i->s = val;
    } else if (size == sizeof(int)) {
        i->i = val;
    } else {
        i->l = val;
    }

    return ERR_NONE;
}

int checkInteger(long long val, int size)
{
    if (size != sizeof(char) &&
        size != sizeof(short) &&
        size != sizeof(int) &&
        size != sizeof(long long)) {
        return ERR_OVERFLOW;
    }

    if (size == sizeof(char) && (val > CHAR_MAX || val < CHAR_MIN)) {
        return ERR_OVERFLOW;
    } else if (size == sizeof(short) && (val > SHRT_MAX || val < SHRT_MIN)) {
        return ERR_OVERFLOW;
    } else if (size == sizeof(int)  && (val > INT_MAX || val < INT_MIN)) {
        return ERR_OVERFLOW;
    } else {
    }

    return ERR_NONE;
}

long long getIntegerValueFromPointer(void* ptr, int size)
{
    long long ret = 0;

    if (!ptr) return 0;

    if (size == sizeof(char)) {
        ret = *((char*)ptr);
    } else if (size == sizeof(short)) {
        ret = *((short*)ptr);
    } else if (size == sizeof(int)) {
        ret = *((int*)ptr);
    } else if (size == sizeof(long long)) {
        ret = *((long long*)ptr);
    } else {
        printf("Unsupported size(=%d) of integer.\n", size);
    }

    return ret;
}

/* reflect */
const reflect_item_t* getReflexItem(const char* field, const reflect_item_t* tbl, int* pIndex)
{
    const reflect_item_t* ret = NULL;

    for (int i = 0;; i++) {
        if (!(tbl[i].field)) break;
        if (strcmp(field, tbl[i].field) == 0) {
            ret = &(tbl[i]);

            if (pIndex) *pIndex = i;
            break;
        }
    }

    if (!ret) printf("Can not find field:%s.", field);

    return ret;
}

void* csonGetProperty(void* obj, const char* field, const reflect_item_t* tbl, int* pIndex)
{
    if (!(obj && field && tbl)) return NULL;
    const reflect_item_t* ret = getReflexItem(field, tbl, pIndex);

    if (!ret) return NULL;

    return (void*)((char*)obj + ret->offset);
}

void csonSetProperty(void* obj, const char* field, void* data, const reflect_item_t* tbl)
{
    if (!(obj && field && data && tbl)) return;

    const reflect_item_t* ret = getReflexItem(field, tbl, NULL);

    if (!ret) return;

    void* pDst = (void*)((char*)obj + ret->offset);
    memcpy(pDst, data, ret->size);
    return;
}

void csonSetPropertyFast(void* obj, const void* data, const reflect_item_t* tbl)
{
    if (!(obj && data && tbl)) return;

    void* pDst = (void*)((char*)obj + tbl->offset);
    memcpy(pDst, data, tbl->size);
    return;
}

void csonLoopProperty(void* pData, const reflect_item_t* tbl, loop_func_t func)
{
    int i = 0;
    while (1) {
        if (!tbl[i].field) break;

        char* pProperty = (char*)pData + tbl[i].offset;
        if (tbl[i].type == CSON_ARRAY) {
            int countIndex = -1;
            void* ptr = csonGetProperty(pData, tbl[i].arrayCountField, tbl, &countIndex);

            if (ptr == NULL || countIndex == -1) {
                continue;
            }
            long long size = getIntegerValueFromPointer(ptr, tbl[countIndex].size);

            for (long long j = 0; j < size; j++) {
                csonLoopProperty(*((char**)pProperty) + j * tbl[i].arrayItemSize, tbl[i].reflect_tbl, func);
            }
        } else if (tbl[i].type == CSON_OBJECT) {
            csonLoopProperty(pProperty, tbl[i].reflect_tbl, func);
        }

        func(pProperty, tbl + i);

        i++;
    }
}

static void* printPropertySub(void* pData, const reflect_item_t* tbl)
{
    if (tbl->type == CSON_ARRAY || tbl->type == CSON_OBJECT) return NULL;

    if (tbl->type == CSON_INTEGER || tbl->type == CSON_TRUE || tbl->type == CSON_FALSE) printf("%s:%d\n", tbl->field, *(int*)pData);

    if (tbl->type == CSON_REAL) printf("%s:%f\n", tbl->field, *(double*)pData);

    if (tbl->type == CSON_STRING) printf("%s:%s\n", tbl->field, *((char**)pData));

    return NULL;
}

static void* freePointerSub(void* pData, const reflect_item_t* tbl)
{
    if (tbl->type == CSON_ARRAY || tbl->type == CSON_STRING) {
        //printf("free field %s.\n", tbl->field);
        free(*(void**)pData);
        *(void**)pData = NULL;
    }
    return NULL;
}

void csonPrintProperty(void* pData, const reflect_item_t* tbl)
{
    /* 调用loopProperty迭代结构体中的属性,完成迭代输出属性值 */
    csonLoopProperty(pData, tbl, printPropertySub);
}

void csonFreePointer(void* list, const reflect_item_t* tbl)
{
    /* 调用loopProperty迭代结构体中的属性,释放字符串和数组申请的内存空间 */
    csonLoopProperty(list, tbl, freePointerSub);
}

cson.h

#ifndef _CSON_H_
#define _CSON_H_

#include <stddef.h>

/**
 * @brief error code of parser.
 */
#define     ERR_NONE            (0)     /**< success */
#define     ERR_MEMORY          (-1)    /**< malloc failed */
#define     ERR_TYPE            (-2)    /**< type matching error */
#define     ERR_MISSING_FIELD   (-3)    /**< field not found */
#define     ERR_FORMAT          (-4)    /**< input json string format error */
#define     ERR_ARGS            (-5)    /**< args error */
#define     ERR_OVERFLOW        (-6)    /**< value overflow */

/**
 * @brief the type of json object.
 */
typedef enum {
    CSON_OBJECT,
    CSON_ARRAY,
    CSON_STRING,
    CSON_INTEGER,
    CSON_REAL,
    CSON_TRUE,
    CSON_FALSE,
    CSON_NULL
} cson_type;

typedef void*   cson_t;

/**
 * @brief define the function type of json parse/pack function group
 */
typedef cson_t      (*func_cson_object_get)(const cson_t object, const char* key);
typedef cson_type   (*func_cson_typeof)(cson_t object);
typedef cson_t      (*func_cson_loadb)(const char *buffer, size_t buflen);
typedef void        (*func_cson_decref)(cson_t object);
typedef const char* (*func_cson_string_value)(const cson_t object);
typedef size_t      (*func_cson_string_length)(const cson_t object);
typedef long long   (*func_cson_integer_value)(const cson_t object);
typedef double      (*func_cson_real_value)(const cson_t object);
typedef char        (*func_cson_bool_value)(const cson_t object);
typedef size_t      (*func_cson_array_size)(const cson_t object);
typedef cson_t      (*func_cson_array_get)(const cson_t object, size_t index);
typedef cson_t      (*func_cson_new)();
typedef char*       (*func_cson_to_string)(cson_t object);
typedef cson_t      (*func_cson_integer)(long long val);
typedef cson_t      (*func_cson_string)(const char* val);
typedef cson_t      (*func_cson_bool)(char val);
typedef cson_t      (*func_cson_real)(double val);
typedef cson_t      (*func_cson_array)();
typedef int         (*func_cson_array_add)(cson_t array, cson_t obj);
typedef int         (*func_cson_object_set_new)(cson_t rootObj, const char* field, cson_t obj);

/**
 * @brief define the cson interface
 */
typedef struct {
    func_cson_object_get cson_object_get;
    func_cson_typeof cson_typeof;
    func_cson_loadb cson_loadb;
    func_cson_decref cson_decref;
    func_cson_string_value cson_string_value;
    func_cson_string_length cson_string_length;
    func_cson_integer_value cson_integer_value;
    func_cson_real_value cson_real_value;
    func_cson_bool_value cson_bool_value;
    func_cson_array_size cson_array_size;
    func_cson_array_get cson_array_get;
    func_cson_new cson_object;
    func_cson_to_string cson_to_string;
    func_cson_integer cson_integer;
    func_cson_string cson_string;
    func_cson_bool cson_bool;
    func_cson_real cson_real;
    func_cson_array cson_array;
    func_cson_array_add cson_array_add;
    func_cson_object_set_new cson_object_set_new;
} cson_interface;

/**
 * @brief the description of property in struct.
 *
 * @TODO: Try to simplify the struct
 */
typedef struct reflect_item_t {
    const char*             field;                  /**< field */
    size_t                  offset;                 /**< offset of property */
    size_t                  size;                   /**< size of property */
    cson_type               type;                   /**< corresponding json type */
    const struct reflect_item_t*  reflect_tbl;      /**< must be specified when type is object or array */
    size_t                  arrayItemSize;          /**< size of per array item. must be specified when type is array */
    const char*             arrayCountField;        /**< field saving array size */
    int                     exArgs;                 /**< paser return failure when the field is not found and nullable equals to 0 */
} reflect_item_t;

extern const reflect_item_t integerReflectTbl[];
extern const reflect_item_t stringReflectTbl[];
extern const reflect_item_t boolReflectTbl[];
extern const reflect_item_t realReflectTbl[];

#define _ex_args_nullable       (0x01)
#define _ex_args_exclude_decode (0x02)
#define _ex_args_exclude_encode (0x04)
#define _ex_args_all            (_ex_args_nullable | _ex_args_exclude_decode | _ex_args_exclude_encode)

#define _offset(type, field)                                                (size_t)(&(((type*)0)->field))
#define _size(type, field)                                                  (sizeof(((type*)0)->field))
#define _property(type, field, jtype, tbl, nullable)                        {#field, _offset(type, field), _size(type, field), jtype, tbl, 0, NULL, nullable}
#define _property_end()                                                     {NULL, 0, 0, CSON_NULL, NULL, 0, NULL, 1}

/**
 * @brief Declaring integer properties.
 *
 * @param type: type of struct
 * @param field: field name of properties
 *
 */
#define _property_int(type, field)                                          _property(type, field, CSON_INTEGER, integerReflectTbl, _ex_args_nullable)

/**
 * @brief Declaring real properties.
 *
 * @param type: type of struct
 * @param field: field name of properties
 *
 */
#define _property_real(type, field)                                         _property(type, field, CSON_REAL, realReflectTbl, _ex_args_nullable)

/**
 * @brief Declaring bool properties.
 *
 * @param type: type of struct
 * @param field: field name of properties
 *
 */
#define _property_bool(type, field)                                         _property(type, field, CSON_TRUE, boolReflectTbl, _ex_args_nullable)

/**
 * @brief Declaring string properties.
 *
 * @param type: type of struct
 * @param field: field name of properties
 *
 */
#define _property_string(type, field)                                       _property(type, field, CSON_STRING, stringReflectTbl, _ex_args_nullable)

/**
 * @brief Declaring struct properties.
 *
 * @param type: type of struct
 * @param field: field name of properties
 * @param tbl: property description table of sub-struct
 *
 */
#define _property_obj(type, field, tbl)                                     _property(type, field, CSON_OBJECT, tbl, _ex_args_nullable)

/**
 * @brief Declaring array properties.
 *
 * @param type: type of struct
 * @param field: field name of properties
 * @param tbl: property description table of type of array
 * @param subType: type of array
 * @param count: property to save the array size
 *
 */
#define _property_array(type, field, tbl, subType, count)                   {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, _ex_args_nullable}
#define _property_array_object(type, field, tbl, subType, count)            _property_array(type, field, tbl, subType, count)
#define _property_array_int(type, field, subType, count)                    _property_array(type, field, integerReflectTbl, subType, count)
#define _property_array_string(type, field, subType, count)                 _property_array(type, field, stringReflectTbl, subType, count)
#define _property_array_real(type, field, subType, count)                   _property_array(type, field, realReflectTbl, subType, count)
#define _property_array_bool(type, field, subType, count)                   _property_array(type, field, boolReflectTbl, subType, count)

/**
 * @brief nonull definitions. parser will stop and return error code when field not found which declared whit it.
 *
 * @param refer to comment of nullable definition
 */
#define _property_int_nonull(type, field)                                   _property(type, field, CSON_INTEGER, NULL, 0)
#define _property_real_nonull(type, field)                                  _property(type, field, CSON_REAL, NULL, 0)
#define _property_bool_nonull(type, field)                                  _property(type, field, CSON_TRUE, NULL, 0)
#define _property_string_nonull(type, field)                                _property(type, field, CSON_STRING, NULL, 0)
#define _property_obj_nonull(type, field, tbl)                              _property(type, field, CSON_OBJECT, tbl, 0)
#define _property_array_nonull(type, field, tbl, subType, count)            {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, 0}
#define _property_array_object_nonull(type, field, tbl, subType, count)     _property_array_nonull(type, field, tbl, subType, count)
#define _property_array_int_nonull(type, field, subType, count)             _property_array_nonull(type, field, integerReflectTbl, subType, count)
#define _property_array_string_nonull(type, field, subType, count)          _property_array_nonull(type, field, stringReflectTbl, subType, count)
#define _property_array_real_nonull(type, field, subType, count)            _property_array_nonull(type, field, realReflectTbl, subType, count)
#define _property_array_bool_nonull(type, field, subType, count)            _property_array_nonull(type, field, boolReflectTbl, subType, count)

/**
 * @brief nonull definitions. parser will stop and return error code when field not found which declared whit it.
 *
 * @param refer to comment of nullable definition
 * @param args opptional with _ex_args_nullable(0x01) _ex_args_exclude_decode(0x02) _ex_args_exclude_encode(0x04)
 */
#define _property_int_ex(type, field, args)                                 _property(type, field, CSON_INTEGER, NULL, args)
#define _property_real_ex(type, field, args)                                _property(type, field, CSON_REAL, NULL, args)
#define _property_bool_ex(type, field, args)                                _property(type, field, CSON_TRUE, NULL, args)
#define _property_string_ex(type, field, args)                              _property(type, field, CSON_STRING, NULL, args)
#define _property_obj_ex(type, field, tbl, args)                            _property(type, field, CSON_OBJECT, tbl, args)
#define _property_array_ex(type, field, tbl, subType, count, args)          {#field, _offset(type, field), _size(type, field), CSON_ARRAY, tbl, sizeof(subType), #count, args}
#define _property_array_object_ex(type, field, tbl, subType, count, args)   _property_array_ex(type, field, tbl, subType, count)
#define _property_array_int_ex(type, field, subType, count, args)           _property_array_ex(type, field, integerReflectTbl, subType, count)
#define _property_array_string_ex(type, field, subType, count, args)        _property_array_ex(type, field, stringReflectTbl, subType, count)
#define _property_array_real_ex(type, field, subType, count, args)          _property_array_ex(type, field, realReflectTbl, subType, count)
#define _property_array_bool_ex(type, field, subType, count, args)          _property_array_ex(type, field, boolReflectTbl, subType, count)

/**
 * @brief function type of csonLoopProperty.
 *
 * @param obj: pointer of property.
 * @param tbl: property of field.
 *
 * @return void*(reserved).
 */
typedef void* (*loop_func_t)(void* pData, const reflect_item_t* tbl);

/**
 * @brief loop all property and process property by @func
 *
 * @param obj: object to be operated.
 * @param tbl: property of field.
 * @param func: callback
 *
 * @return void.
 */
void    csonLoopProperty(void* obj, const reflect_item_t* tbl, loop_func_t func);

/**
 * @brief convert json string to struct object.
 *
 * @param jstr: json string
 * @param output: target object
 * @param tbl: property table of output.
 *
 * @return ERR_NONE on success, otherwise failed.
 */
int csonJsonStr2Struct(const char* jstr, void* output, const reflect_item_t* tbl);

/**
 * @brief convert struct object to json string.
 *
 * @param jstr: output json string
 * @param output: input struct object
 * @param tbl: property table of input.
 *
 * @return ERR_NONE on success, otherwise failed.
 */
int csonStruct2JsonStr(char** jstr, void* input, const reflect_item_t* tbl);

/**
 * @brief Iterative output properties of data
 *
 * @param pData: struct object
 * @param tbl: property table of input.
 *
 * @return void.
 */
void csonPrintProperty(void* pData, const reflect_item_t* tbl);

/**
 * @brief Iterative free pointer of data
 *
 * @param pData: struct object
 * @param tbl: property table of input.
 *
 * @return void.
 */
void csonFreePointer(void* list, const reflect_item_t* tbl);

#endif

model_appliance_home_list_get.c

#include "model_appliance_home_list_get.h"
#include "midea_http_manager.h"
#include "cson.h"

// 定义数据结构的反射表
// appliance_ability_item
reflect_item_t appliance_ability_ref_tbl[] = {
    _property_string(appliance_ability_item, isBluetoothControl),
    _property_int(appliance_ability_item, supportBleDataTransfers),
    _property_end(),
};

// appliance_applianceList_item
reflect_item_t applianceList_ref_tbl[] = {
    _property_string(appliance_applianceList_item, applianceCode),
    _property_string(appliance_applianceList_item, sn),
    _property_string(appliance_applianceList_item, onlineStatus),
    _property_string(appliance_applianceList_item, type),
    _property_string(appliance_applianceList_item, modelNumber),
    _property_string(appliance_applianceList_item, name),
    _property_string(appliance_applianceList_item, enterpriseCode),
    _property_string(appliance_applianceList_item, btToken),
    _property_string(appliance_applianceList_item, sn8),
    _property_int(appliance_applianceList_item, bindType),
    _property_obj(appliance_applianceList_item, ability, appliance_ability_ref_tbl),
    _property_end(),
};

// appliance_roomList_item
reflect_item_t appliance_roomList_ref_tbl[] = {
    _property_string(appliance_roomList_item, roomId),
    _property_string(appliance_roomList_item, name),
    _property_string(appliance_roomList_item, des),
    _property_string(appliance_roomList_item, icon),
    _property_string(appliance_roomList_item, isDefault),
    _property_int_ex(appliance_roomList_item, applianceListNum, _ex_args_all),
    _property_array_object(appliance_roomList_item, applianceList, applianceList_ref_tbl, appliance_applianceList_item, applianceListNum),
    _property_end(),
};

// appliance_home_list_item
reflect_item_t appliance_homeList_ref_tbl[] = {
    _property_string(appliance_home_list_item, homegroupId),
    _property_string(appliance_home_list_item, number),
    _property_string(appliance_home_list_item, roleId),
    _property_string(appliance_home_list_item, isDefault),
    _property_string(appliance_home_list_item, name),
    _property_string(appliance_home_list_item, nickname),
    _property_string(appliance_home_list_item, address),
    _property_string(appliance_home_list_item, des),
    _property_string(appliance_home_list_item, coordinate),
    _property_string(appliance_home_list_item, areaid),
    _property_string(appliance_home_list_item, createUserUid),
    _property_string(appliance_home_list_item, createTime),
    _property_string(appliance_home_list_item, profilePicUrl),
    _property_string(appliance_home_list_item, cardOrder),
    _property_int_ex(appliance_home_list_item, roomListNum, _ex_args_all),
    _property_array_object(appliance_home_list_item, roomList, appliance_roomList_ref_tbl, appliance_roomList_item, roomListNum),
    _property_end(),
};

// appliance_home_list_data_item
reflect_item_t appliance_homeList_data_ref_tbl[] = {
    _property_int_ex(appliance_home_list_data_item, homeListNum, _ex_args_all),
    _property_array_object(appliance_home_list_data_item, homeList, appliance_homeList_ref_tbl, appliance_home_list_item, homeListNum),
    _property_end(),
};

// appliance_home_list_model
reflect_item_t appliance_homeList_model_ref_tbl[] = {
    _property_string(appliance_home_list_model, msg),
    _property_int(appliance_home_list_model, code),
    _property_obj(appliance_home_list_model, data, appliance_homeList_data_ref_tbl),
    _property_end(),
};

void appliance_home_list_get_request(appliance_home_list_model *model)
{
    cJSON *root;
    int ret = mss_http_get_base_body(&root);
    // 转字符串
    char *load_device_json = cJSON_Print(root);
    cJSON_Delete(root);

    char *load_device_response_json_str;
    mss_http_request("/v1/appliance/home/list/get", load_device_json, &load_device_response_json_str);
    if (load_device_response_json_str == NULL)
    {
        printf("/v1/appliance/home/list/get fail \n");
        return;
    }

    appliance_home_list_model test_model; // json转model
    csonJsonStr2Struct(load_device_response_json_str, &test_model, appliance_homeList_model_ref_tbl);
    *model = test_model;
    //   free(load_device_json);
}

// void appliance_home_list_model_free(appliance_home_list_model * model){
//     if (model != NULL)
//     {
//         csonFreePointer(model, appliance_homeList_model_ref_tbl);
//     }
// }

model_appliance_home_list_get.h

#ifndef model_appliance_home_list_get_H
#define model_appliance_home_list_get_H

//定义与返回json相对应的数据结构
/**设备支持的能力*/
typedef struct
{
    char * isBluetoothControl;
    char supportBleDataTransfers;

}appliance_ability_item;
/**设备信息*/
typedef struct
{
    char *applianceCode;
    char *sn;
    char *onlineStatus;
    char *type;
    char *modelNumber;
    char *name;
    char * enterpriseCode;
    char * btToken;
    int bindType;
    char * sn8;
    appliance_ability_item ability;
} appliance_applianceList_item;

/**房间信息*/
typedef struct
{
    char *roomId;
    char *name;
    char *des;
    char *icon;
    char *isDefault;
    char        applianceListNum;
    appliance_applianceList_item * applianceList;
} appliance_roomList_item;
/**家庭信息*/
typedef struct
{
    char *homegroupId;
    char *number;
    char *roleId;
    char *isDefault;
    char *name;
    char *nickname;
    char *address;
    char *des;
    char *coordinate;
    char *areaid;
    char *createUserUid;
    char *createTime;
    char * profilePicUrl;
    char * cardOrder;
    char        roomListNum;
    appliance_roomList_item * roomList;
} appliance_home_list_item;

typedef struct
{
    char homeListNum;
    appliance_home_list_item *homeList;
} appliance_home_list_data_item;

typedef struct
{
    int code;
    char *msg;
    appliance_home_list_data_item data;

} appliance_home_list_model;

/**获取用户所有家庭的家电列表*/
void appliance_home_list_get_request(appliance_home_list_model * model);

#endif /*model_appliance_home_list_get_H*/

model_mj_user_auto_login.c

//
//  model_mj_user_auto_login.c
//  meiju-linux
//
//  Created by huocy on 2022/1/3.
//  Copyright © 2022 com.midea. All rights reserved.
//

#include "model_mj_user_auto_login.h"
#include "cson.h"
#include "cJSON/cJSON.h"
#include "osal/midea_osal_url_define.h"
#include "midea_http_manager.h"
#include "midea_data_types.h"
#include "midea_data_center.h"

static midea_system_file_data_t midea_sys_data;

reflect_item_t mj_user_auto_login_item_ref_tbl[] = {
    _property_string(mj_user_auto_login_item, expired),
    _property_string(mj_user_auto_login_item, accessToken),
    _property_end(),
};

reflect_item_t mj_user_auto_login_ref_tbl[] = {
    _property_string(mj_user_auto_login_model, msg),
    _property_int(mj_user_auto_login_model, code),
    _property_obj(mj_user_auto_login_model, data, mj_user_auto_login_item_ref_tbl),
    _property_end(),
};

void request_mj_user_auto_login_model(mj_user_auto_login_model * model){

  //1 to do file read localdata
  //m_hal_storage_read("file",  (char*)(&midea_sys_data), sizeof(midea_sys_data));
   
  //2.setting request params
   cJSON *root;
   int ret = mss_http_get_base_body(&root);
   cJSON *data = cJSON_CreateObject();
    ///todo 待确定tokenpwd来源
   cJSON_AddItemToObject(data,"tokenpwd",cJSON_CreateString(""));
   cJSON_AddItemToObject(data,"uid",cJSON_CreateString(""));
   cJSON_AddItemToObject(data,"rule",cJSON_CreateNumber(1));
   cJSON_AddItemToObject(data,"iotAppId",cJSON_CreateString("900"));
   ///todo 待确定设备ID
   cJSON_AddItemToObject(data,"deviceId",cJSON_CreateString("00000000000000000"));
   cJSON_AddItemToObject(data,"platform",cJSON_CreateNumber(1));
   cJSON_AddItemToObject(root,"data",data);
   
   cJSON *body = cJSON_Print(root);
   char *response_json;

   mss_http_request("/mj/user/autoLogin",body,&response_json);
   printf("刷新token respons_json == %s",response_json);
   
   if (response_json == NULL)
   {
     return;
   }
   

   cJSON *response_json_obj = cJSON_Parse(response_json);
   cJSON *data_c = cJSON_GetObjectItem(response_json_obj, "data");
   
   cJSON *access_token = cJSON_GetObjectItem(data_c, "accessToken");
   cJSON *expired = cJSON_GetObjectItem(data_c, "expired");

   char *at = cJSON_GetStringValue(access_token);
   long long expired_c = cJSON_GetNumberValue(expired);
   printf("刷新后 access_token == %s  expired = %lld\n",at,expired_c);
   mj_user_auto_login_model refresh_model;//json转model
   csonJsonStr2Struct(response_json, &refresh_model, mj_user_auto_login_ref_tbl);
   *model = refresh_model;
}


/// @brief refresh token
/// @param uid 
/// @param tokenpwd 
static int midea_refresh_token(char *uid,char *tokenpwd){  
  
   return 0;
}

model_mj_user_auto_login.h

//
//  model_mj_user_auto_login.h
//  meiju-linux
//
//  Created by huocy on 2022/1/3.
//  Copyright © 2022 com.midea. All rights reserved.
//

#ifndef model_mj_user_auto_login_H
#define model_mj_user_auto_login_H
#include <stdlib.h> 
#include <stdio.h> 
        
typedef struct 
{
    char *expired;
    char *accessToken;

}mj_user_auto_login_item;


 typedef struct
{
    int code;
    char * msg;
    mj_user_auto_login_item  data;

}mj_user_auto_login_model;

#endif /*model_mj_user_auto_login_H*/

model_mj_user_login.c

#include "model_mj_user_login.h"
#include "midea_http_manager.h"
#include "midea_data_types.h"
#include "midea_data_center.h"
#include "midea_utils.h"
#include "midea_security_util.h"
#include "cson.h"

// 定义数据结构的反射表
// user_login_userInfo_item
reflect_item_t userInfo_ref_tbl[] = {
    _property_string(user_login_userInfo_item, birthday),
    _property_string(user_login_userInfo_item, mail),
    _property_string(user_login_userInfo_item, homeName),
    _property_string(user_login_userInfo_item, uid),
    _property_string(user_login_userInfo_item, homeCode),
    _property_string(user_login_userInfo_item, isWeixin),
    _property_string(user_login_userInfo_item, cardid),
    _property_string(user_login_userInfo_item, isQq),
    _property_string(user_login_userInfo_item, brand),
    _property_string(user_login_userInfo_item, isApple),
    _property_string(user_login_userInfo_item, registerTime),
    _property_string(user_login_userInfo_item, nickName),
    _property_string(user_login_userInfo_item, sex),
    _property_string(user_login_userInfo_item, mobile),
    _property_string(user_login_userInfo_item, userId),
    _property_string(user_login_userInfo_item, headImgUrl),
    _property_string(user_login_userInfo_item, isUpdateCacheTime),
    _property_end(),
};
// user_login_mdata_item
reflect_item_t loginMdata_ref_tbl[] = {
    _property_string(user_login_mdata_item, accessToken),
    _property_end(),
};

// mj_user_login_data_item
reflect_item_t loginData_ref_tbl[] = {
    _property_string(mj_user_login_data_item, uid),
    _property_string(mj_user_login_data_item, iotUserId),
    _property_string(mj_user_login_data_item, key),
    _property_int(mj_user_login_data_item, clusterId),
    _property_obj(mj_user_login_data_item, userInfo, userInfo_ref_tbl),
    _property_obj(mj_user_login_data_item, mdata, loginMdata_ref_tbl),
    _property_end(),
};

// mj_user_login_model
reflect_item_t userLoginRequest_ref_tbl[] = {
    _property_string(mj_user_login_model, msg),
    _property_int(mj_user_login_model, code),
    _property_obj(mj_user_login_model, data, loginData_ref_tbl),
    _property_end(),
};

/**
 * @brief 登录接口
 *
 * @param loginId 用户账户(手机号)获取的loginId
 * @param password 用户密码
 * @param model 返回数据模型指针的地址
 * @return int 返回错误码
 */

void mj_user_login_request(char *account, char *loginId, char *password, mj_user_login_model *model)
{

  // 密码两次md5加密
  char *out1;
  mss_md5_encrypt_to_lc_hex((unsigned char *)password, strlen(password), &out1);

  char *out2;
  mss_md5_encrypt_to_lc_hex((unsigned char *)out1, strlen(out1), &out2);
  free(out1);

  // 密码sha256
  uint8_t *password_sha256_out;
  size_t password_sha256_out_size;
  mss_sha256((uint8_t *)password, strlen(password), &password_sha256_out, &password_sha256_out_size);

  char *password_sha256_out_hex;
  midea_bytes_to_lc_hex_string(password_sha256_out, password_sha256_out_size, &password_sha256_out_hex);
  free(password_sha256_out);

  printf("password_sha256_out_hex:%s \n", password_sha256_out_hex);

  printf("login_id_str:%s \n", loginId);
  char *app_key = mss_share_instance()->ms_config->app_key;
  printf("app_key:%s \n", app_key);
  int total_len = strlen(loginId) + 64 + strlen(app_key);
  char *total = calloc(total_len, sizeof(char));

  strcpy(total, loginId);
  strcat(total, password_sha256_out_hex);
  strcat(total, app_key);

  mss_sha256((uint8_t *)total, total_len, &password_sha256_out, &password_sha256_out_size);
  char *password_sha256_out_hex2;
  midea_bytes_to_lc_hex_string(password_sha256_out, password_sha256_out_size, &password_sha256_out_hex2);
  free(password_sha256_out_hex);
  free(password_sha256_out);
  printf("password_sha256_out_hex2:%s \n", password_sha256_out_hex2);

  cJSON *root;
  mss_http_get_base_body(&root);

  cJSON *iot_data = cJSON_CreateObject();
  cJSON_AddItemToObject(root, "iotData", iot_data);

  cJSON_AddItemToObject(iot_data, "iotAppId", cJSON_CreateString(mss_share_instance()->ms_config->app_id));
  cJSON_AddItemToObject(iot_data, "loginAccount", cJSON_CreateString(account));
  cJSON_AddItemToObject(iot_data, "password", cJSON_CreateString(password_sha256_out_hex2));
  cJSON_AddItemToObject(iot_data, "iampwd", cJSON_CreateString(out2));
  cJSON_AddItemToObject(iot_data, "reqId", cJSON_CreateString("out2"));
  cJSON_AddItemToObject(iot_data, "clientType", cJSON_CreateNumber(1));
  cJSON_AddItemToObject(iot_data, "loginId", cJSON_CreateString(loginId));

  cJSON *data2 = cJSON_CreateObject();
  cJSON_AddItemToObject(root, "data", data2);
  cJSON_AddItemToObject(data2, "appKey", cJSON_CreateString("123456"));
  cJSON_AddItemToObject(data2, "appVersion", cJSON_CreateString("1.0.0"));
  cJSON_AddItemToObject(data2, "deviceId", cJSON_CreateString("12121212121212121212121212121212"));
  cJSON_AddItemToObject(data2, "deviceName", cJSON_CreateString("deviceName"));
  cJSON_AddItemToObject(data2, "osVersion", cJSON_CreateString("osVersion"));
  cJSON_AddItemToObject(data2, "platform", cJSON_CreateNumber(1));

  char *login_body_json = cJSON_Print(root);
  cJSON_Delete(root);
  free(out2);
  free(password_sha256_out_hex2);

  printf("login_body_json : %s \n", login_body_json);
  char *login_response_json_str;
  mss_http_request("/mj/user/login", login_body_json, &login_response_json_str);
  free(login_body_json);

  if (login_response_json_str == NULL)
  {
    printf("/mj/user/login fail \n");
    return;
  }
  // 解析用户登录结果
  mj_user_login_model test_model; // json转模型
  csonJsonStr2Struct(login_response_json_str, &test_model, userLoginRequest_ref_tbl);
  *model = test_model;
  free(login_response_json_str);
  if (model->code == 0)
  {
    printf("The encode_data_key = %s", model->data.key);
    printf("The access_token:%s\n", model->data.mdata.accessToken);
    printf("登录成功\n");
  }
}

// /**
//  * @brief  释放model
//  *
//  * @return int
//  */
// int mj_user_login_model_free(mj_user_login_model *model)
// {
//   if (model != NULL)
//   {
//      csonFreePointer(model, userLoginRequest_ref_tbl);
//   }

// }

model_mj_user_login.h

#ifndef model_mj_user_login_H
#define model_mj_user_login_H

//定义与返回json相对应的数据结构
/**用户账户信息*/
typedef struct 
{
    char * birthday;
    char * mail;
    char * homeName;
    char * uid;
    char * homeCode;
    char * isWeixin;
    char * cardid;
    char * isQq;
    char * brand;
    char * isApple;
    char * registerTime;
    char * nickName;
    char * sex;
    char * mobile;
    char * userId;
    char * headImgUrl;
    int isUpdateCacheTime;
}user_login_userInfo_item;

typedef struct 
{
   char *accessToken;

}user_login_mdata_item;


typedef struct
{
    char *uid;
    char * iotUserId;
    int clusterId;
    char * key;
    user_login_userInfo_item userInfo;
    user_login_mdata_item mdata;

}mj_user_login_data_item;
 
 typedef struct
{
    int code;
    char * msg;
    mj_user_login_data_item  data;

}mj_user_login_model;

 /**
  * @brief 登录接口,需要先获取登陆 id
  * 
  * @param loginId 用户账户(手机号)获取的loginId
  * @param password 用户密码
  * @param model 返回数据模型指针的地址
  * @return int 返回错误码
  */

void mj_user_login_request(char* account,char *loginId,char * password,mj_user_login_model * model);

#endif

model_user_login_id_get.c

#include "model_user_login_id_get.h"
#include "midea_http_manager.h"
#include "cson.h"

// 定义数据结构的反射表
// login_id_data_item
reflect_item_t loginId_ref_tbl[] = {
    _property_string(login_id_data_item, loginId),
    _property_end(),
};
// login_id_get_model
reflect_item_t loginIdRequest_ref_tbl[] = {
    _property_string(login_id_get_model, msg),
    _property_int(login_id_get_model, code),
    _property_obj(login_id_get_model, data, loginId_ref_tbl),
    _property_end(),
};

/**
 * @brief 云端请求获取loginId
 *
 * @param loginAccount 用户账户(手机号)
 * @param model 返回数据模型指针的地址
 */
void login_id_get_request(char *loginAccount, login_id_get_model *model)
{

    cJSON *base; // 需要释放
    int ret = mss_http_get_base_body(&base);

    cJSON_AddItemToObject(base, "loginAccount", cJSON_CreateString(loginAccount));

    char *bodyStr = cJSON_Print(base);
    cJSON_Delete(base);

    char *response_json_str; // 需要释放
    mss_http_request("/v1/user/login/id/get", bodyStr, &response_json_str);
    free(bodyStr);
    if (response_json_str == NULL)
    {
        printf("/v1/user/login/id/get fail \n");
        return;
    }
    printf("response_json_str suc:%s\n", response_json_str);

    login_id_get_model test_model; // json转模型
    csonJsonStr2Struct(response_json_str, &test_model, loginIdRequest_ref_tbl);
    *model = test_model;
    free(response_json_str);
}

// // 释放
// int login_id_get_model_free(login_id_get_model *model)
// {
//     if (model != NULL)
//     {
//         csonFreePointer(model, loginIdRequest_ref_tbl);
//     }
// }

model_user_login_id_get.h

#ifndef model_user_login_id_get_H
#define model_user_login_id_get_H

//定义与返回json相对应的数据结构
typedef struct
{
    char *loginId;
}login_id_data_item;
 
 typedef struct
{
    int code;
    char * msg;
    login_id_data_item  data;

}login_id_get_model;

 /**
  * @brief 云端请求获取loginId
  * 
  * @param loginAccount 用户账户(手机号)
  * @param model 返回数据模型指针的地址
  * @return int 返回错误码
  */

void login_id_get_request(char *loginAccount,login_id_get_model * model);

#endif
posted on 2024-11-21 15:52  AtlasLapetos  阅读(9)  评论(0)    收藏  举报