15 Star 92 Fork 50

cot软件包 / cotParam

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
cot_param.c 38.18 KB
一键复制 编辑 原始数据 按行查看 历史
大橙子疯 提交于 2024-02-03 15:32 . fix: 删除多余内存占用
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489
/**
**********************************************************************************************************************
* @file cot_param.c
* @brief 该文件提供参数管理框架功能
* @author const_zpc any question please send mail to const_zpc@163.com
* @version V2.1
* @date 2024-1-31
*
* @details 功能详细说明:
* + 参数修改和重置管理
* + 参数序列化和反序列化
* 数据序列化格式:
* | 支持数目(1) | 数据1的长度和ID(0.5+0.5) | 数据1(n) | 数据2的长度和ID(1) | 数据2(n) | 数据3的长度和ID(1) | 数据3(n) |
* | 支持数目(1) | 数据1的长度和ID(1.0+1.0) | 数据1(n) | 数据2的长度和ID(2) | 数据2(n) | 数据3的长度和ID(2) | 数据3(n) |
* | 支持数目(1) | 数据1的长度和ID(1.5+1.5) | 数据1(n) | 数据2的长度和ID(3) | 数据2(n) | 数据3的长度和ID(3) | 数据3(n) |
*
**********************************************************************************************************************
* 源码路径:https://gitee.com/cot_package/cot_param.git 具体问题及建议可在该网址填写 Issue
*
*
**********************************************************************************************************************
*/
/* Includes ----------------------------------------------------------------------------------------------------------*/
#include "cot_param.h"
#include <string.h>
#include <stdio.h>
typedef union
{
uint64_t u64val;
int64_t s64val;
double fVal;
#if COT_PARAM_USE_STRING_TYPE
char str[COT_PARAM_STRING_MAX_LENGTH];
#endif
} Value_u;
static cotParamCheckRet_e ValidateRangeByVoid(const cotParamInfo_t *pParam, const void *pval);
static uint8_t *SerializeUint(uint8_t *ptr, uint64_t value, uint8_t len)
{
for (int i = 0; i < len; i++)
{
*ptr++ = value >> (i * 8);
}
return ptr;
}
static uint8_t *SerializeInt(uint8_t *ptr, int64_t value, uint8_t len)
{
for (int i = 0; i < len; i++)
{
*ptr++ = value >> (i * 8);
}
return ptr;
}
static uint8_t *SerializeFloat(uint8_t *ptr, float value)
{
uint32_t ivalue = *((uint32_t *)&value);
for (int i = 0; i < sizeof(ivalue); i++)
{
*ptr++ = ivalue >> (i * 8);
}
return ptr;
}
static uint8_t *SerializeDouble(uint8_t *ptr, double value)
{
uint64_t ivalue = *((uint64_t *)&value);
for (int i = 0; i < sizeof(ivalue); i++)
{
*ptr++ = ivalue >> (i * 8);
}
return ptr;
}
static uint8_t *UnSerializeUint(const uint8_t *ptr, uint64_t *value, uint8_t len)
{
*value = 0;
for (int i = 0; i < len; i++)
{
*value |= (uint64_t)(*ptr++) << (i * 8);
}
return (uint8_t *)ptr;
}
static uint8_t *UnSerializeInt(const uint8_t *ptr, int64_t *value, uint8_t len)
{
*value = 0;
for (int i = 0; i < len; i++)
{
*value |= (int64_t)(*ptr++) << (i * 8);
}
return (uint8_t *)ptr;
}
static uint8_t *UnSerializeFloat(const uint8_t *ptr, float *value)
{
uint32_t ivalue = 0;
for (int i = 0; i < sizeof(ivalue); i++)
{
ivalue |= (uint32_t)(*ptr++) << (i * 8);
}
*value = *((float *)&ivalue);
return (uint8_t *)ptr;
}
static uint8_t *UnSerializeDouble(const uint8_t *ptr, double *value)
{
uint64_t ivalue = 0;
for (int i = 0; i < sizeof(ivalue); i++)
{
ivalue |= (uint64_t)(*ptr++) << (i * 8);
}
*value = *((double *)&ivalue);
return (uint8_t *)ptr;
}
static bool ResetParamValue(const cotParamInfo_t *pParam)
{
if (pParam != NULL && (pParam->attr & COT_PARAM_ATTR_RESET))
{
#if COT_PARAM_USE_STRING_TYPE
if (pParam->type != COT_PARAM_STRING)
{
memcpy(pParam->unCurValuePtr.pVoid, pParam->unDefValuePtr.pVoid, pParam->length);
}
else
{
strcpy(pParam->unCurValuePtr.pString, pParam->unDefValuePtr.pString);
}
#else
memcpy(pParam->unCurValuePtr.pVoid, pParam->unDefValuePtr.pVoid, pParam->length);
#endif
return true;
}
return false;
}
static bool ResetParamMinValue(const cotParamInfo_t *pParam)
{
if (pParam != NULL && (pParam->attr & COT_PARAM_ATTR_RANGE))
{
#if COT_PARAM_USE_STRING_TYPE
if (pParam->type != COT_PARAM_STRING)
#endif
{
memcpy(pParam->unCurValuePtr.pVoid, pParam->unMinValuePtr.pVoid, pParam->length);
}
return true;
}
return false;
}
static bool ResetParamMaxValue(const cotParamInfo_t *pParam)
{
if (pParam != NULL && (pParam->attr & COT_PARAM_ATTR_RANGE))
{
#if COT_PARAM_USE_STRING_TYPE
if (pParam->type == COT_PARAM_STRING)
{
pParam->unCurValuePtr.pString[*pParam->unMaxValuePtr.pStringLength] = 0;
}
else
#endif
{
memcpy(pParam->unCurValuePtr.pVoid, pParam->unMaxValuePtr.pVoid, pParam->length);
}
return true;
}
return false;
}
/**
* @brief 参数表初始化
*
* @param pManager 参数表管理句柄
* @param pParamTable 参数表
* @param count 参数表元素数目, 可以通过宏 COT_PARAM_TABLE_SIZE 获取
* @return 0,成功; -1,失败
*/
int cotParam_Init(cotParamManager_t *pManager, cotParamInfo_t *pParamTable, uint16_t count)
{
if (pManager == NULL || pParamTable == NULL)
{
return -1;
}
for (uint16_t i = 0; i < count; i++)
{
if (pParamTable[i].unMaxValuePtr.pVoid == NULL || pParamTable[i].unMinValuePtr.pVoid == NULL)
{
pParamTable[i].attr &= ~COT_PARAM_ATTR_RANGE;
}
if (!(pParamTable[i].attr & COT_PARAM_ATTR_READ))
{
pParamTable[i].attr &= ~COT_PARAM_ATTR_WRITE;
}
if (pParamTable[i].unDefValuePtr.pVoid == NULL)
{
pParamTable[i].attr &= ~COT_PARAM_ATTR_RESET;
}
if (pParamTable[i].unCurValuePtr.pVoid == NULL)
{
return -1;
}
}
pManager->pParamTable = pParamTable;
pManager->count = count;
return 0;
}
/**
* @brief 重置所有参数,恢复为缺省值
*
* @attention 无可重置权限的参数不能恢复为缺省值
* @param pManager 参数表管理句柄
* @return 0,成功; -1,失败
*/
int cotParam_ResetDefault(const cotParamManager_t *pManager)
{
if (pManager == NULL)
{
return -1;
}
for (uint16_t i = 0; i < pManager->count; ++i)
{
ResetParamValue(&pManager->pParamTable[i]);
}
return 0;
}
/**
* @brief 检查所有参数当前值的范围并对超出范围时进行处理
*
* @attention 如果参数有自定义校验方式,则只有满足范围校验成功的前提下才会执行自定义校验
* @param param 参数信息
* @param pfnCheckError 参数超出范围时的处理函数
* @return 0,成功; -1,失败
*/
int cotParam_Check(const cotParamManager_t* pManager, cotParamError_f pfnCheckError)
{
cotParamCheckRet_e eCheckResult;
if (pManager == NULL)
{
return -1;
}
for (int id = 0; id < pManager->count; id++)
{
eCheckResult = ValidateRangeByVoid(&pManager->pParamTable[id], pManager->pParamTable[id].unCurValuePtr.pVoid);
if (COT_PARAM_CHECK_OK != eCheckResult)
{
if (pfnCheckError != NULL)
{
pfnCheckError(&pManager->pParamTable[id], eCheckResult);
}
}
else
{
#if COT_PARAM_USE_CUSTOM_CHECK
if (pManager->pParamTable[id].pfnParamCheck != NULL)
{
if (pManager->pParamTable[id].pfnParamCheck(pManager->pParamTable[id].unCurValuePtr.pVoid) != 0)
{
if (pfnCheckError != NULL)
{
pfnCheckError(&pManager->pParamTable[id], COT_PARAM_CHECK_OTHER_ERR);
}
}
}
#endif
}
}
return 0;
}
static cotParamInfo_t *FindParamByParamPtr(const cotParamManager_t *pManager, const void *curParamPtr)
{
for (uint16_t i = 0; i < pManager->count; ++i)
{
if (pManager->pParamTable[i].unCurValuePtr.pVoid == curParamPtr)
{
return &pManager->pParamTable[i];
}
}
return NULL;
}
/**
* @brief 参数列表迭代器
*
* @attention 无读取权限的参数会自动跳过
* @param pManager 参数表管理句柄
* @param psIdx 参数表起始索引
* @return 参数信息
*/
cotParamInfo_t *cotParam_IterateList(const cotParamManager_t *pManager, size_t *psIdx)
{
cotParamInfo_t *p = NULL;
if (pManager == NULL || psIdx == NULL || *psIdx > pManager->count)
{
return NULL;
}
while (*psIdx < pManager->count)
{
if (pManager->pParamTable[*psIdx].attr & COT_PARAM_ATTR_READ)
{
p = &pManager->pParamTable[*psIdx];
(*psIdx)++;
break;
}
(*psIdx)++;
}
return p;
}
#if ( COT_PARAM_NAME_MAX_LENGTH > 1)
static cotParamInfo_t *FindParamByName(const cotParamManager_t *pManager, const char *pszName)
{
for (uint16_t i = 0; i < pManager->count; ++i)
{
if (strcmp(pManager->pParamTable[i].pszName, pszName) == 0)
{
return &pManager->pParamTable[i];
}
}
return NULL;
}
#endif
/**
* @brief 根据参数名称查找参数信息
*
* @attention 无可读权限时会查找失败
* @param pManager 参数表管理句柄
* @param pszName 参数名称
* @return 参数信息
*/
const cotParamInfo_t *cotParam_FindParamByName(const cotParamManager_t *pManager, const char *pszName)
{
#if ( COT_PARAM_NAME_MAX_LENGTH > 1)
cotParamInfo_t *pInfo;
if (pManager != NULL)
{
pInfo = FindParamByName(pManager, pszName);
if (pInfo->attr & COT_PARAM_ATTR_READ)
{
return pInfo;
}
}
#endif
return NULL;
}
static cotParamInfo_t *FindParamByID(const cotParamManager_t *pManager, uint16_t id)
{
for (uint16_t i = 0; i < pManager->count; ++i)
{
if (pManager->pParamTable[i].id == id)
{
return &pManager->pParamTable[i];
}
}
return NULL;
}
/**
* @brief 根据参数ID查找参数信息
*
* @attention 无可读权限时会查找失败
* @param pManager 参数表管理句柄
* @param id 参数ID
* @return 参数信息
*/
const cotParamInfo_t *cotParam_FindParamByID(const cotParamManager_t *pManager, uint16_t id)
{
cotParamInfo_t *pInfo;
if (pManager != NULL)
{
pInfo = FindParamByID(pManager, id);
if (pInfo->attr & COT_PARAM_ATTR_READ)
{
return pInfo;
}
}
return NULL;
}
/**
* @brief 根据当前参数数据地址指针查找参数信息
*
* @attention 无可读权限时会查找失败
* @param pManager 参数表管理句柄
* @param pCurParam 当前参数数据指针
* @return 参数信息
*/
const cotParamInfo_t *cotParam_FindParamByParamPtr(const cotParamManager_t *pManager, const void *pCurParam)
{
cotParamInfo_t *pInfo;
if (pManager != NULL || pCurParam != NULL)
{
pInfo = FindParamByParamPtr(pManager, pCurParam);
if (pInfo->attr & COT_PARAM_ATTR_READ)
{
return pInfo;
}
}
return NULL;
}
// 验证参数是否在指定范围内
static cotParamCheckRet_e ValidateRange(const cotParamInfo_t *pParam, const Value_u *pval)
{
if (!(pParam->attr & COT_PARAM_ATTR_RANGE))
{
return COT_PARAM_CHECK_OK;
}
switch (pParam->type)
{
case COT_PARAM_INT8:
if (pval->s64val < *pParam->unMinValuePtr.pInt8)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (pval->s64val > *pParam->unMaxValuePtr.pInt8)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
case COT_PARAM_INT16:
if (pval->s64val < *pParam->unMinValuePtr.pInt16)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (pval->s64val > *pParam->unMaxValuePtr.pInt16)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
case COT_PARAM_INT32:
if (pval->s64val < *pParam->unMinValuePtr.pInt32)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (pval->s64val > *pParam->unMaxValuePtr.pInt32)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_INT64:
if (pval->s64val < *pParam->unMinValuePtr.pInt64)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (pval->s64val > *pParam->unMaxValuePtr.pInt64)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
#endif
case COT_PARAM_UINT8:
if (pval->u64val < *pParam->unMinValuePtr.pUint8)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (pval->u64val > *pParam->unMaxValuePtr.pUint8)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
case COT_PARAM_UINT16:
if (pval->u64val < *pParam->unMinValuePtr.pUint16)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (pval->u64val > *pParam->unMaxValuePtr.pUint16)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
case COT_PARAM_UINT32:
if (pval->u64val < *pParam->unMinValuePtr.pUint32)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (pval->u64val > *pParam->unMaxValuePtr.pUint32)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_UINT64:
if (pval->u64val < *pParam->unMinValuePtr.pUint64)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (pval->u64val > *pParam->unMaxValuePtr.pUint64)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
#endif
case COT_PARAM_FLOAT:
if (pval->fVal < *pParam->unMinValuePtr.pFloat)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (pval->fVal > *pParam->unMaxValuePtr.pFloat)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_DOUBLE:
if (pval->fVal < *pParam->unMinValuePtr.pDouble)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (pval->fVal > *pParam->unMaxValuePtr.pDouble)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
#endif
#if COT_PARAM_USE_STRING_TYPE
case COT_PARAM_STRING:
if (strlen(pval->str) < *pParam->unMinValuePtr.pStringLength)
{
return COT_PARAM_CHECK_OVER_MIN;
}
else if (strlen(pval->str) > *pParam->unMaxValuePtr.pStringLength)
{
return COT_PARAM_CHECK_OVER_MAX;
}
break;
#endif
default:
break;
}
return COT_PARAM_CHECK_OK;
}
static cotParamCheckRet_e ValidateRangeByVoid(const cotParamInfo_t *pParam, const void *pval)
{
Value_u uValue;
memset(&uValue, 0, sizeof(uValue));
switch (pParam->type)
{
case COT_PARAM_INT8:
uValue.s64val = *(COT_PARAM_INT8_T *)pval;
break;
case COT_PARAM_INT16:
uValue.s64val = *(COT_PARAM_INT16_T *)pval;
break;
case COT_PARAM_INT32:
uValue.s64val = *(COT_PARAM_INT32_T *)pval;
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_INT64:
uValue.s64val = *(COT_PARAM_INT64_T *)pval;
break;
#endif
case COT_PARAM_UINT8:
uValue.s64val = *(COT_PARAM_UINT8_T *)pval;
break;
case COT_PARAM_UINT16:
uValue.s64val = *(COT_PARAM_UINT16_T *)pval;
break;
case COT_PARAM_UINT32:
uValue.s64val = *(COT_PARAM_UINT32_T *)pval;
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_UINT64:
uValue.s64val = *(COT_PARAM_UINT64_T *)pval;
break;
#endif
case COT_PARAM_FLOAT:
uValue.fVal = *(COT_PARAM_FLOAT_T *)pval;
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_DOUBLE:
uValue.fVal = *(COT_PARAM_DOUBLE_T *)pval;
break;
#endif
#if COT_PARAM_USE_STRING_TYPE
case COT_PARAM_STRING:
memcpy(uValue.str, pval, strlen(pval) >= COT_PARAM_STRING_MAX_LENGTH ? COT_PARAM_STRING_MAX_LENGTH - 1 : strlen(pval));
break;
#endif
default:
return COT_PARAM_CHECK_OK;
}
return ValidateRange(pParam, &uValue);
}
/**
* @brief 校验当前参数值并进行处理
*
* @attention 字符串类型参数若设置了最长的长度,超长则会进行截断,但是小于最小长度时则不做处理
* @attention 该函数不会执行自定义校验
* @param pParam 参数信息
* @param eResetOpt 参数值超出范围的处理选项 @enum cotParamResetOpt_e
* @return 0,成功; -1,失败
*/
int cotParam_SingleParamCheckProcess(const cotParamInfo_t *pParam, cotParamResetOpt_e eResetOpt)
{
cotParamCheckRet_e eCheckResult;
if (pParam == NULL)
{
return -1;
}
eCheckResult = ValidateRangeByVoid(pParam, pParam->unCurValuePtr.pVoid);
if (eCheckResult != COT_PARAM_CHECK_OK)
{
if (eResetOpt == COT_PARAM_RESET_DEF)
{
ResetParamValue(pParam);
}
else if (eResetOpt == COT_PARAM_RESET_MIN || (eResetOpt == COT_PARAM_RESET_MIN_MAX && eCheckResult == COT_PARAM_CHECK_OVER_MIN))
{
ResetParamMinValue(pParam);
}
else if (eResetOpt == COT_PARAM_RESET_MAX || (eResetOpt == COT_PARAM_RESET_MIN_MAX && eCheckResult == COT_PARAM_CHECK_OVER_MAX))
{
ResetParamMaxValue(pParam);
}
}
return 0;
}
/**
* @brief 更新参数值同时进行校验处理
*
* @attention 该函数不会执行自定义校验
* @param pParam 参数信息
* @param pNewValue 新的参数值
* @param eResetOpt 新的参数值超出范围的处理选项 @enum cotParamResetOpt_e
* @return 0,成功; -1,失败
*/
int cotParam_SingleParamUpdate(const cotParamInfo_t *pParam, const void *pNewValue, cotParamResetOpt_e eResetOpt)
{
cotParamCheckRet_e eCheckResult;
if (pParam == NULL)
{
return -1;
}
eCheckResult = ValidateRangeByVoid(pParam, pNewValue);
if (eCheckResult != COT_PARAM_CHECK_OK)
{
if (eResetOpt == COT_PARAM_RESET_DEF)
{
ResetParamValue(pParam);
}
else if (eResetOpt == COT_PARAM_RESET_MIN || (eResetOpt == COT_PARAM_RESET_MIN_MAX && eCheckResult == COT_PARAM_CHECK_OVER_MIN))
{
ResetParamMinValue(pParam);
}
else if (eResetOpt == COT_PARAM_RESET_MAX || (eResetOpt == COT_PARAM_RESET_MIN_MAX && eCheckResult == COT_PARAM_CHECK_OVER_MAX))
{
ResetParamMaxValue(pParam);
}
}
else
{
#if COT_PARAM_USE_STRING_TYPE
if (pParam->type != COT_PARAM_STRING)
{
memcpy(pParam->unCurValuePtr.pVoid, pNewValue, pParam->length);
}
else
{
strcpy(pParam->unCurValuePtr.pString, pNewValue);
}
#else
memcpy(pParam->unCurValuePtr.pVoid, pNewValue, pParam->length);
#endif
}
return 0;
}
/**
* @brief 根据参数信息校验输入的值
*
* @attention 如果参数有自定义校验方式,则只有满足范围校验成功的前提下才会执行自定义校验
* @param[in] pParam 参数信息
* @param[in] pValue 输入的参数值,该变量的类型需要和该参数的类型保持一致
* @param[out] peCheckResult 校验结果
* @return 0,成功; -1,失败
*/
int cotParam_SingleParamCheckInput(const cotParamInfo_t *pParam, const void *pValue, cotParamCheckRet_e *peCheckResult)
{
if (pParam == NULL || pValue == NULL || peCheckResult == NULL)
{
return -1;
}
*peCheckResult = ValidateRangeByVoid(pParam, pValue);
#if COT_PARAM_USE_CUSTOM_CHECK
if (*peCheckResult == COT_PARAM_CHECK_OK)
{
if (pParam->pfnParamCheck != NULL)
{
if (pParam->pfnParamCheck(pValue) != 0)
{
*peCheckResult = COT_PARAM_CHECK_OTHER_ERR;
}
}
}
#endif
return 0;
}
/**
* @brief 校验当前参数值
*
* @attention 如果参数有自定义校验方式,则只有满足范围校验成功的前提下才会执行自定义校验
* @param[in] pParam 参数信息
* @param[out] peCheckResult 校验结果
* @return 0,成功; -1,失败
*/
int cotParam_SingleParamSelfCheck(const cotParamInfo_t *pParam, cotParamCheckRet_e *peCheckResult)
{
return cotParam_SingleParamCheckInput(pParam, pParam->unCurValuePtr.pVoid, peCheckResult);
}
/**
* @brief 重置参数为缺省值
*
* @attention 无缺省值的参数会失败
* @param pParam 参数信息
* @return 0,成功; -1,失败
*/
int cotParam_SingleParamResetDefValue(const cotParamInfo_t *pParam)
{
if (pParam == NULL)
{
return -1;
}
if (!ResetParamValue(pParam))
{
return -1;
}
return 0;
}
/**
* @brief 重置参数为最小值
*
* @attention 字符串类型参数该功能无效, 无最大最小值的参数也会失败
* @param pParam 参数信息
* @return 0,成功; -1,失败
*/
int cotParam_SingleParamResetMinValue(const cotParamInfo_t *pParam)
{
if (pParam == NULL)
{
return -1;
}
if (!ResetParamMinValue(pParam))
{
return -1;
}
return 0;
}
/**
* @brief 重置参数为最大值
*
* @attention 字符串类型参数该功能无效, 无最大最小值的参数也会失败
* @param pParam 参数信息
* @return 0,成功; -1,失败
*/
int cotParam_SingleParamResetMaxValue(const cotParamInfo_t *pParam)
{
if (pParam == NULL)
{
return -1;
}
if (!ResetParamMaxValue(pParam))
{
return -1;
}
return 0;
}
static uint16_t ParamInfoFormStream(cotParamInfo_t *pParam, const uint8_t *pbuf)
{
switch (pParam->type)
{
case COT_PARAM_INT8:
{
int64_t val = 0;
pbuf = UnSerializeInt(pbuf, &val, pParam->length);
*pParam->unCurValuePtr.pInt8 = (COT_PARAM_INT8_T)val;
}
break;
case COT_PARAM_INT16:
{
int64_t val = 0;
pbuf = UnSerializeInt(pbuf, &val, pParam->length);
*pParam->unCurValuePtr.pInt16 = (COT_PARAM_INT16_T)val;
}
break;
case COT_PARAM_INT32:
{
int64_t val = 0;
pbuf = UnSerializeInt(pbuf, &val, pParam->length);
*pParam->unCurValuePtr.pInt32 = (COT_PARAM_INT32_T)val;
}
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_INT64:
{
int64_t val = 0;
pbuf = UnSerializeInt(pbuf, &val, pParam->length);
*pParam->unCurValuePtr.pInt64 = (COT_PARAM_INT64_T)val;
}
break;
#endif
case COT_PARAM_UINT8:
{
uint64_t val = 0;
pbuf = UnSerializeUint(pbuf, &val, pParam->length);
*pParam->unCurValuePtr.pUint8 = (COT_PARAM_UINT8_T)val;
}
break;
case COT_PARAM_UINT16:
{
uint64_t val = 0;
pbuf = UnSerializeUint(pbuf, &val, pParam->length);
*pParam->unCurValuePtr.pUint16 = (COT_PARAM_UINT16_T)val;
}
break;
case COT_PARAM_UINT32:
{
uint64_t val = 0;
pbuf = UnSerializeUint(pbuf, &val, pParam->length);
*pParam->unCurValuePtr.pUint32= (COT_PARAM_UINT32_T)val;
}
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_UINT64:
{
uint64_t val = 0;
pbuf = UnSerializeUint(pbuf, &val, pParam->length);
*pParam->unCurValuePtr.pUint64 = (COT_PARAM_UINT64_T)val;
}
break;
#endif
case COT_PARAM_FLOAT:
pbuf = UnSerializeFloat(pbuf, pParam->unCurValuePtr.pFloat);
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_DOUBLE:
pbuf = UnSerializeDouble(pbuf, pParam->unCurValuePtr.pDouble);
break;
#endif
#if COT_PARAM_USE_STRING_TYPE
case COT_PARAM_STRING:
memcpy(pParam->unCurValuePtr.pString, &pbuf[0], pParam->length);
break;
#endif
default:
return 0; // 不支持的参数类型
}
return pParam->length;
}
static uint8_t *MoveBufToBase(uint8_t *pbuf, uint32_t length)
{
memmove(pbuf - length, pbuf, length);
return (pbuf - length);
}
/**
* @brief 加载数据
*
* @param pManager 参数表管理句柄
* @param pfnLoadCallback 加载回调函数
* @return 0,成功; -1,失败; -2,加载回调函数返回失败
*/
int cotParam_Load(const cotParamManager_t *pManager, cotParamLoad_f pfnLoadCallback)
{
#if COT_PARAM_USE_STRING_TYPE
uint8_t buf[sizeof(cotParamInfo_t) + COT_PARAM_STRING_MAX_LENGTH];
#else
uint8_t buf[sizeof(cotParamInfo_t)];
#endif
uint8_t *ptr = buf;
if (pManager == NULL || pfnLoadCallback == NULL)
{
return -1;
}
uint16_t length = 0;
uint16_t paramLength = 0;
uint16_t id = 0;
cotParamInfo_t *pParamInfo;
uint8_t keyLength = 0;
#if COT_PARAM_USE_KEY_VALUE
uint64_t key = 0;
#endif
do
{
length = sizeof(buf) - (ptr - buf);
if (pfnLoadCallback(ptr, length, &length) != 0)
{
return -2;
}
if (length == 0)
{
break;
}
length += (ptr - buf);
ptr = buf;
#if COT_PARAM_USE_KEY_VALUE
if (keyLength == 0)
{
keyLength = ptr[0];
ptr++;
length -= 1;
}
while (length > keyLength)
{
UnSerializeUint(ptr, &key, keyLength);
#if COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_16
id = (key >> 4) & 0x0F;
paramLength = key & 0x0F;
#elif COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_256
id = (key >> 8) & 0xFF;
paramLength = key & 0xFF;
#elif COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_4096
id = (key >> 12) & 0xFFF;
paramLength = key & 0xFFF;
#endif
if (length < (paramLength + keyLength))
{
break;
}
ptr += keyLength;
length -= keyLength;
pParamInfo = (cotParamInfo_t *)FindParamByID(pManager, id);
if (pParamInfo == NULL || paramLength != pParamInfo->length)
{
ptr += paramLength;
length -= paramLength;
continue;
}
ParamInfoFormStream(pParamInfo, ptr);
ptr += paramLength;
length -= paramLength;
}
#else
while (length >= 1)
{
pParamInfo = &pManager->pParamTable[id];
if (length < pParamInfo->length)
{
break;
}
ParamInfoFormStream(pParamInfo, ptr);
ptr += pParamInfo->length;
length -= pParamInfo->length;
id++;
}
#endif
ptr = MoveBufToBase(ptr, ptr - buf);
ptr += length;
} while (1);
return 0;
}
static uint16_t ParamInfoToStream(uint8_t *pbuf, cotParamInfo_t *pParam)
{
switch (pParam->type)
{
case COT_PARAM_INT8:
pbuf = SerializeInt(pbuf, *(COT_PARAM_INT8_T *)pParam->unCurValuePtr.pVoid, pParam->length);
break;
case COT_PARAM_INT16:
pbuf = SerializeInt(pbuf, *(COT_PARAM_INT16_T *)pParam->unCurValuePtr.pVoid, pParam->length);
break;
case COT_PARAM_INT32:
pbuf = SerializeInt(pbuf, *(COT_PARAM_INT32_T *)pParam->unCurValuePtr.pVoid, pParam->length);
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_INT64:
pbuf = SerializeInt(pbuf, *(COT_PARAM_INT64_T *)pParam->unCurValuePtr.pVoid, pParam->length);
break;
#endif
case COT_PARAM_UINT8:
pbuf = SerializeUint(pbuf, *(COT_PARAM_UINT8_T *)pParam->unCurValuePtr.pVoid, pParam->length);
break;
case COT_PARAM_UINT16:
pbuf = SerializeUint(pbuf, *(COT_PARAM_UINT16_T *)pParam->unCurValuePtr.pVoid, pParam->length);
break;
case COT_PARAM_UINT32:
pbuf = SerializeUint(pbuf, *(COT_PARAM_UINT32_T *)pParam->unCurValuePtr.pVoid, pParam->length);
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_UINT64:
pbuf = SerializeUint(pbuf, *(COT_PARAM_UINT64_T *)pParam->unCurValuePtr.pVoid, pParam->length);
break;
#endif
case COT_PARAM_FLOAT:
pbuf = SerializeFloat(pbuf, *(COT_PARAM_FLOAT_T *)pParam->unCurValuePtr.pVoid);
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_DOUBLE:
pbuf = SerializeDouble(pbuf, *(COT_PARAM_DOUBLE_T *)pParam->unCurValuePtr.pVoid);
break;
#endif
#if COT_PARAM_USE_STRING_TYPE
case COT_PARAM_STRING:
memcpy(&pbuf[0], pParam->unCurValuePtr.pString, pParam->length);
break;
#endif
default:
return 0; // 不支持的参数类型
}
return pParam->length;
}
/**
* @brief 保存数据
*
* @param pManager 参数表管理句柄
* @param pfnSaveCallback 保存回调函数
* @return 0,成功; -1,失败; -2,保存回调函数返回失败
*/
int cotParam_Save(const cotParamManager_t *pManager, cotParamSave_f pfnSaveCallback)
{
#if COT_PARAM_USE_STRING_TYPE
uint8_t buf[sizeof(cotParamInfo_t) + COT_PARAM_STRING_MAX_LENGTH];
#else
uint8_t buf[sizeof(cotParamInfo_t)];
#endif
uint8_t *ptr = buf;
uint16_t length = 0;
#if COT_PARAM_USE_KEY_VALUE
uint64_t key = 0;
#endif
if (pManager == NULL || pfnSaveCallback == NULL)
{
return -1;
}
#if COT_PARAM_USE_KEY_VALUE
buf[0] = COT_PARAM_SUPPORT_NUM;
if (pfnSaveCallback(buf, 1) != 0)
{
return -2;
}
#endif
for (int i = 0; i < pManager->count; i++)
{
ptr = buf;
length = 0;
#if COT_PARAM_USE_KEY_VALUE
#if COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_16
key = (pManager->pParamTable[i].id << 4) | (pManager->pParamTable[i].length & 0x0F);
#elif COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_256
key = (pManager->pParamTable[i].id << 8) | (pManager->pParamTable[i].length & 0xFF);
#elif COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_4096
key = (pManager->pParamTable[i].id << 12) | (pManager->pParamTable[i].length & 0xFFF);
#endif
ptr = SerializeUint(ptr, key, COT_PARAM_SUPPORT_NUM);
length += COT_PARAM_SUPPORT_NUM;
#endif
length = ParamInfoToStream(&buf[length], &pManager->pParamTable[i]);
ptr += length;
if (pfnSaveCallback(buf, (ptr - buf)) != 0)
{
return -2;
}
}
if (pfnSaveCallback(buf, 0) != 0)
{
return -2;
}
return 0;
}
/**
* @brief 获取参数序列化所需要的内存大小
*
* @param[in] pManager 参数表管理句柄
* @return 参数序列化所需要的内存大小
*/
uint32_t cotParam_GetSerializeSize(const cotParamManager_t* pManager)
{
uint32_t length = 1;
uint16_t idx = 0;
if (pManager == NULL)
{
return 0;
}
while (idx < pManager->count)
{
#if COT_PARAM_USE_KEY_VALUE
length += (pManager->pParamTable[idx++].length + COT_PARAM_SUPPORT_NUM);
#else
length += pManager->pParamTable[idx++].length;
#endif
}
return length;
}
/**
* @brief 获取参数序列化后的数据
*
* @param[in] pManager 参数表管理句柄
* @param[out] pbuf 存参数序列化后的数据
* @return 0,成功; -1,失败
*/
uint32_t cotParam_Serialize(const cotParamManager_t* pManager, uint8_t *pbuf)
{
if (pManager == NULL)
{
return 0;
}
uint8_t *ptr = pbuf;
#if COT_PARAM_USE_KEY_VALUE
uint64_t key = 0;
#endif
#if COT_PARAM_USE_KEY_VALUE
*ptr = COT_PARAM_SUPPORT_NUM;
ptr++;
#endif
for (int i = 0; i < pManager->count; i++)
{
#if COT_PARAM_USE_KEY_VALUE
#if COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_16
key = (pManager->pParamTable[i].id << 4) | (pManager->pParamTable[i].length & 0x0F);
#elif COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_256
key = (pManager->pParamTable[i].id << 8) | (pManager->pParamTable[i].length & 0xFF);
#elif COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_4096
key = (pManager->pParamTable[i].id << 12) | (pManager->pParamTable[i].length & 0xFFF);
#endif
ptr = SerializeUint(ptr, key, COT_PARAM_SUPPORT_NUM);
#endif
ptr += ParamInfoToStream(ptr, &pManager->pParamTable[i]);
}
return ptr - pbuf;
}
/**
* @brief 参数反序列化
*
* @param[in] pManager 参数表管理句柄
* @param[in] pbuf 参数需要反序列化的数据
* @param[in] length 反序列化的数据长度
* @return 0,成功; -1,失败
*/
int cotParam_Deserialization(const cotParamManager_t* pManager, const uint8_t *pbuf, uint32_t length)
{
if (pManager == NULL)
{
return -1;
}
const uint8_t *ptr = pbuf;
uint16_t id = 0;
cotParamInfo_t *pParamInfo;
#if COT_PARAM_USE_KEY_VALUE
uint8_t keyLength = 0;
uint16_t paramLength = 0;
uint64_t key = 0;
#endif
#if COT_PARAM_USE_KEY_VALUE
if (keyLength == 0)
{
keyLength = ptr[0];
ptr++;
length -= 1;
}
while (length > keyLength)
{
ptr = UnSerializeUint(ptr, &key, keyLength);
#if COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_16
id = (key >> 4) & 0x0F;
paramLength = key & 0x0F;
#elif COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_256
id = (key >> 8) & 0xFF;
paramLength = key & 0xFF;
#elif COT_PARAM_SUPPORT_NUM == COT_PARAM_SUPPORT_4096
id = (key >> 12) & 0xFFF;
paramLength = key & 0xFFF;
#endif
if (length < (paramLength + keyLength))
{
break;
}
length -= (keyLength + paramLength);
pParamInfo = (cotParamInfo_t *)FindParamByID(pManager, id);
if (pParamInfo == NULL || paramLength != pParamInfo->length)
{
ptr += paramLength;
continue;
}
ParamInfoFormStream(pParamInfo, ptr);
ptr += paramLength;
}
#else
while (length >= 1)
{
pParamInfo = &pManager->pParamTable[id];
if (length < pParamInfo->length)
{
break;
}
ParamInfoFormStream(pParamInfo, ptr);
ptr += pParamInfo->length;
length -= pParamInfo->length;
id++;
}
#endif
return 0;
}
/**
* @brief 修改参数值,新值校验不通过则不修改
*
* @note 该函数主要是方便进行二次函数封装,隐藏参数表管理句柄入参,可参考 cotParam_SingleParamChange 的实现
* @param pManager 参数表管理句柄
* @param pCurParam 当前参数数据指针
* @param paramList 可变参数列表
* @return 0,成功; -1,失败;
*/
int cotParam_SingleParamChangeImpl(const cotParamManager_t* pManager, const void *pCurParam, va_list paramList)
{
const cotParamInfo_t *pParam = cotParam_FindParamByParamPtr(pManager, pCurParam);
if (pParam == NULL)
{
return -1;
}
switch (pParam->type)
{
case COT_PARAM_INT8:
{
COT_PARAM_INT8_T val = (COT_PARAM_INT8_T)va_arg(paramList, COT_PARAM_INT32_T);
cotParam_SingleParamUpdate(pParam, &val, COT_PARAM_RESET_NONE);
}
break;
case COT_PARAM_INT16:
{
COT_PARAM_INT16_T val = (COT_PARAM_INT16_T)va_arg(paramList, COT_PARAM_INT32_T);
cotParam_SingleParamUpdate(pParam, &val, COT_PARAM_RESET_NONE);
}
break;
case COT_PARAM_INT32:
{
COT_PARAM_INT32_T val = (COT_PARAM_INT32_T)va_arg(paramList, COT_PARAM_INT32_T);
cotParam_SingleParamUpdate(pParam, &val, COT_PARAM_RESET_NONE);
}
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_INT64:
{
COT_PARAM_INT64_T val = (COT_PARAM_INT64_T)va_arg(paramList, COT_PARAM_INT64_T);
cotParam_SingleParamUpdate(pParam, &val, COT_PARAM_RESET_NONE);
}
break;
#endif
case COT_PARAM_UINT8:
{
COT_PARAM_UINT8_T val = (COT_PARAM_UINT8_T)va_arg(paramList, COT_PARAM_UINT32_T);
cotParam_SingleParamUpdate(pParam, &val, COT_PARAM_RESET_NONE);
}
break;
case COT_PARAM_UINT16:
{
COT_PARAM_UINT16_T val = (COT_PARAM_UINT16_T)va_arg(paramList, COT_PARAM_UINT32_T);
cotParam_SingleParamUpdate(pParam, &val, COT_PARAM_RESET_NONE);
}
break;
case COT_PARAM_UINT32:
{
COT_PARAM_UINT32_T val = (COT_PARAM_UINT32_T)va_arg(paramList, COT_PARAM_UINT32_T);
cotParam_SingleParamUpdate(pParam, &val, COT_PARAM_RESET_NONE);
}
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_UINT64:
{
COT_PARAM_UINT64_T val = (COT_PARAM_UINT64_T)va_arg(paramList, COT_PARAM_UINT64_T);
cotParam_SingleParamUpdate(pParam, &val, COT_PARAM_RESET_NONE);
}
break;
#endif
case COT_PARAM_FLOAT:
{
COT_PARAM_FLOAT_T val = (COT_PARAM_FLOAT_T)va_arg(paramList, COT_PARAM_DOUBLE_T);
cotParam_SingleParamUpdate(pParam, &val, COT_PARAM_RESET_NONE);
}
break;
#if COT_PARAM_USE_64_BIT_LENGTH
case COT_PARAM_DOUBLE:
{
COT_PARAM_DOUBLE_T val = (COT_PARAM_DOUBLE_T)va_arg(paramList, COT_PARAM_DOUBLE_T);
cotParam_SingleParamUpdate(pParam, &val, COT_PARAM_RESET_NONE);
}
break;
#endif
#if COT_PARAM_USE_STRING_TYPE
case COT_PARAM_STRING:
{
char *pszString = (char *)va_arg(paramList, char *);
char szString[COT_PARAM_STRING_MAX_LENGTH] = {0};
memcpy(szString, pszString, strlen(pszString) >= COT_PARAM_STRING_MAX_LENGTH ?
(COT_PARAM_STRING_MAX_LENGTH - 1) : strlen(pszString));
cotParam_SingleParamUpdate(pParam, szString, COT_PARAM_RESET_NONE);
}
break;
#endif
default:
return -1;
}
return 0;
}
/**
* @brief 修改参数值,新值校验不通过则不修改
*
* @code 如:cotParam_SingleParamChange(&sg_tParamManager, &g_test_u16, 60)
* @param pManager 参数表管理句柄
* @param pCurParam 当前参数数据指针
* @param ... 新值(只有一个参数)
* @return 0,成功; -1,失败;
*/
int cotParam_SingleParamChange(const cotParamManager_t* pManager, const void *pCurParam, ...)
{
int ret = 0;
va_list paramList;
va_start(paramList, pCurParam);
ret = cotParam_SingleParamChangeImpl(pManager, pCurParam, paramList);
va_end(paramList);
return ret;
}
C
1
https://gitee.com/cot_package/cot_param.git
git@gitee.com:cot_package/cot_param.git
cot_package
cot_param
cotParam
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891