配置文件的读取重复代码极多,且容易漏掉、出错,如下一段配置信息读取代码,可以简化编程。

主体类定义:

#ifndef _CONFIG_CONTAINER_H_#define _CONFIG_CONTAINER_H_#include<stdio.h>#include<stdlib.h>#include<memory.h>#include<vector>#include<string>#include<type_traits>template<unsigned int> structUID{};

typedef union type_mask_t
{
struct{bool is_int_ : 1;bool is_enum_ : 1;bool is_float_ : 1;bool is_signed_ : 1;bool is_class_ : 1;
};
unsigned
intint_value;
}type_mask;

template
<class TBase> classXConfigContainer
{
public:
typedef
void* (*def_func)();
typedef
bool (*deep_copy)(void* dest, const void* src, unsigned intsize);

typedef
structtagConfigItem
{
unsigned
intoffset;
unsigned
intsize;
unsigned
inttype_mask_;const char*itemname;
def_func default_func;
deep_copy deep_copy_func;
}ConfigItem;

typedef
structtagConfigItemLink
{
ConfigItem cfg_item;
struct tagConfigItemLink*lpnext;
}ConfigItemLink;
public:
XConfigContainer() {}
~XConfigContainer() {}

unsigned
int init(void*user_param);
unsigned
int load(void* config_pesist, void*user_param);
unsigned
int load_detla(void* config_pesist, void*user_param);
unsigned
int save(void* config_pesist, void* user_param) const;
unsigned
int save_to_struct(void* config_struct, void* user_param) const;
};
#define BEGIN_CONFIG_CONTAINER(class_name) \ class class_name : public XConfigContainer<class_name>\
{ \
private: \
unsigned
intfirst_item_; \public: \
class_name() { \
memset(
&first_item_, 0, sizeof( class_name ) - (unsigned int)(size_t)&(((class_name *)0)->first_item_ )); \
}; \
~class_name() {} \static unsigned intx_config_item_count; \static const ConfigItemLink*GetConfigItem(); \public: \
template
<int N> struct ConfigItemSeq{ staticConfigItemLink config_item_seq; }; \private: \
typedef class_name thisClass; \
enum {__property_first_idx =__COUNTER__}; \#define CONFIG_ITEM(type_name, item_name, get_default_func, copy_func) \ public: \
typedef type_name property_##item_name##_t; \
private: \enum {__property_##item_name##_idx = __COUNTER__ - __property_first_idx - 1}; \static unsigned int get_offset(UID<__property_##item_name##_idx>) {return (unsigned int)(size_t)&(((thisClass *)0)->x_##item_name##_ );}; \static unsigned int get_size(UID<__property_##item_name##_idx>) {return sizeof(property_##item_name##_t); }; \static unsigned int get_type_mask(UID<__property_##item_name##_idx>) {static type_mask val =\
{std::is_integral
<property_##item_name##_t>::value, \
std::is_enum
<property_##item_name##_t>::value, \
std::is_floating_point
<property_##item_name##_t>::value, \
std::is_signed
<property_##item_name##_t>::value, \
std::is_class
<property_##item_name##_t>::value }; returnval.int_value; }; \static const char* get_item_name(UID<__property_##item_name##_idx>) {return#item_name;}; \static def_func get_default_value(UID<__property_##item_name##_idx>) {returnget_default_func;}; \static deep_copy get_deep_copy_func(UID<__property_##item_name##_idx>) {returncopy_func;}; \public: \
property_##item_name##_t
& get_##item_name () {returnx_##item_name##_;} \protected: \
property_##item_name##_t x_##item_name##_;
#define END_CONFIG_CONTAINER() \ private: \enum {__property_last_idx = __COUNTER__ - __property_first_idx - 1}; \public: \static const unsigned int get_config_count() {return__property_last_idx;}; \
};
#define CONFIG_CONTAINER_IMPL(class_name) \unsignedint class_name :: x_config_item_count =class_name :: __property_last_idx; \
template
<int N> class_name::ConfigItemLink class_name ::ConfigItemSeq<N>::config_item_seq = { {get_offset(UID<N>() ), get_size(UID<N>() ), get_type_mask(UID<N>() ), get_item_name(UID<N>()), get_default_value(UID<N>()), get_deep_copy_func(UID<N>()) }, & ConfigItemSeq<N-1>::config_item_seq }; \
template
<> class_name::ConfigItemLink class_name ::ConfigItemSeq<0>::config_item_seq = { {get_offset(UID<0>() ), get_size(UID<0>() ), get_type_mask(UID<0>() ), get_item_name(UID<0>()), get_default_value(UID<0>()), get_deep_copy_func(UID<0>()) }, 0}; \const class_name::ConfigItemLink*class_name ::GetConfigItem() \
{ \
static class_name::ConfigItemLink* class_name##ItemArray = & ConfigItemSeq<__property_last_idx - 1>::config_item_seq; \returnclass_name##ItemArray;\
}
#define BEGIN_CONFIG2_CONTAINER(class_name, struct_name) \ class class_name : public struct_name, public XConfigContainer< class_name>\
{ \
public: \
class_name() { \
memset((struct_name
*)this, 0, sizeof( struct_name )); \
}; \
~class_name() {} \static unsigned intx_config_item_count; \static const ConfigItemLink*GetConfigItem(); \public: \
template
<int N> struct ConfigItemSeq{ staticConfigItemLink config_item_seq; }; \private: \
typedef class_name thisClass; \
typedef struct_name thisStruct; \
enum {__property_first_idx =__COUNTER__}; \#define CONFIG2_ITEM(type_name, item_name, get_default_func, copy_func) \ public: \
typedef type_name property_##item_name##_t; \
private: \enum {__property_##item_name##_idx = __COUNTER__ - __property_first_idx - 1}; \static unsigned int get_offset(UID<__property_##item_name##_idx>) {return (unsigned int)(size_t)&(((thisClass *)0)->item_name );}; \static unsigned int get_size(UID<__property_##item_name##_idx>) {return sizeof(property_##item_name##_t); }; \static unsigned int get_type_mask(UID<__property_##item_name##_idx>) {static type_mask val =\
{std::is_integral
<property_##item_name##_t>::value, \
std::is_enum
<property_##item_name##_t>::value, \
std::is_floating_point
<property_##item_name##_t>::value, \
std::is_signed
<property_##item_name##_t>::value, \
std::is_class
<property_##item_name##_t>::value }; returnval.int_value; }; \static const char* get_item_name(UID<__property_##item_name##_idx>) {return#item_name;}; \static def_func get_default_value(UID<__property_##item_name##_idx>) {returnget_default_func;}; \static deep_copy get_deep_copy_func(UID<__property_##item_name##_idx>) {returncopy_func;}; \public: \
property_##item_name##_t
& get_##item_name () {returnitem_name;} \#define END_CONFIG2_CONTAINER() \ private: \enum {__property_last_idx = __COUNTER__ - __property_first_idx - 1}; \public: \static const unsigned int get_config_count() {return__property_last_idx;}; \
};
#define CONFIG2_CONTAINER_IMPL(class_name) \unsignedint class_name :: x_config_item_count =class_name :: __property_last_idx; \
template
<int N> class_name::ConfigItemLink class_name ::ConfigItemSeq<N>::config_item_seq = { {get_offset(UID<N>() ), get_size(UID<N>() ), get_type_mask(UID<N>() ), get_item_name(UID<N>()), get_default_value(UID<N>()), get_deep_copy_func(UID<N>()) }, & ConfigItemSeq<N-1>::config_item_seq }; \
template
<> class_name::ConfigItemLink class_name ::ConfigItemSeq<0>::config_item_seq = { {get_offset(UID<0>() ), get_size(UID<0>() ), get_type_mask(UID<0>() ), get_item_name(UID<0>()), get_default_value(UID<0>()), get_deep_copy_func(UID<0>()) }, 0}; \const class_name::ConfigItemLink*class_name ::GetConfigItem() \
{ \
static class_name::ConfigItemLink* class_name##ItemArray = & ConfigItemSeq<__property_last_idx - 1>::config_item_seq; \returnclass_name##ItemArray;\
}
#define DEFALUT_VALUE_DECL(value) []() -> void* {return (void*)(value);}template<class T1, class T2>T1 union_cast(T2 val){
union value_type{
T2 t2_val1;
T1 t1_val2;
} val1;
val1.t2_val1
=val;returnval1.t1_val2;
}
#define DEFALUT_VALUE_FLOAT_DECL(value) []() -> void* {return union_cast<void*>(value);} #endif

使用办法:

1.预先定义好的配置信息结构体

typedef structconfig_param_t {
unsigned
shortparam_version;
unsigned
shortaaa;floatbbb;floatccc;
} config_param;

2.声明相应的结构信息说明:

#include "ConfigContainer.h"BEGIN_CONFIG2_CONTAINER(ConfigParam, config_param);
CONFIG2_ITEM(unsigned
short, param_version, DEFALUT_VALUE_DECL(57920), NULL);
CONFIG2_ITEM(unsigned
short, aaa, DEFALUT_VALUE_DECL(0), NULL);
CONFIG2_ITEM(
float, bbb, DEFALUT_VALUE_FLOAT_DECL(0.5f), NULL); //,默认值为0.5 CONFIG2_ITEM(float, ccc, DEFALUT_VALUE_FLOAT_DECL(0.5f), NULL); //,默认值为0.6 END_CONFIG2_CONTAINER();

3.实现结构信息说明:

#include "config_param.h"CONFIG2_CONTAINER_IMPL(ConfigParam);

 

4-1.使用Ini来读取配置文件,相应代码:

#include <SimpleIni.h>#include"ConfigContainer.h"template<class T>
void copy_value(unsigned char* dest, T* src, unsigned intsize){switch(size)
{
case sizeof(unsigned char):if (std::is_signed<T>::value)*(char*)dest = *(char*)src;else *(unsigned char*)dest = *(unsigned char*)src;return;case sizeof(unsigned short):if (std::is_signed<T>::value)*(short*)dest = *(short*)src;else *(unsigned short*)dest = *(unsigned short*)src;return;case sizeof(unsigned int):if (std::is_floating_point<T>::value){*(float*)dest = *(float*)src;
}
else{if (std::is_signed<T>::value)*(int*)dest = *(int*)src;else *(unsigned int*)dest = *(unsigned int*)src;
}
return;
}
//其他情况,使用memcpy memcpy(dest, src, size);
}

template
<class TBase>unsignedint XConfigContainer<TBase>::init(void*user_param)
{
//依次读取配置项 type_mask temp_type_mask;const ConfigItemLink* lpItem =TBase::GetConfigItem();while(lpItem !=nullptr) {
temp_type_mask.int_value
= lpItem->cfg_item.type_mask_;//保存在内部变量中:如果是整数 def_func def_func_ = lpItem->cfg_item.default_func;if(temp_type_mask.is_int_) {if(temp_type_mask.is_signed_) {//signed int def_val = (signed int)((*def_func_)()); signed int signed_val = union_cast<signed int>((*def_func_)());
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &signed_val, lpItem->cfg_item.size);
}
else{//unsigned int def_unsigned_val = (unsigned int)((*def_func_)()); unsigned int unsigned_val = union_cast<unsigned int>((*def_func_)());
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &unsigned_val, lpItem->cfg_item.size);
}
}
else if (temp_type_mask.is_float_){ //浮点数 float float_val = union_cast<float>((*def_func_)());
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &float_val, lpItem->cfg_item.size);
}
else { //其他,默认是字符串//char* strDef = (char*)((*def_func_)()); char* strValue = (char*)((*def_func_)());//如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) {
(
*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strValue, lpItem->cfg_item.size);
}
else{
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strValue, lpItem->cfg_item.size);
}
}

lpItem
= lpItem->lpnext;
}
return 0;
}

template
<class TBase>unsignedint XConfigContainer<TBase>::load(void* config_pesist, void*user_param)
{
//内部对象 CSimpleIniA * c_ini = (CSimpleIniA *)(config_pesist);if (0 ==c_ini) {return 1;
}
//依次读取配置项 type_mask temp_type_mask;const ConfigItemLink* lpItem =TBase::GetConfigItem();while(lpItem !=nullptr) {
temp_type_mask.int_value
= lpItem->cfg_item.type_mask_;//保存在内部变量中:如果是整数 def_func def_func_ = lpItem->cfg_item.default_func;if(temp_type_mask.is_int_) {if(temp_type_mask.is_signed_) {//signed int def_val = (signed int)((*def_func_)()); signed int signed_val = (signed int)c_ini->GetLongValue((const char*)user_param, lpItem->cfg_item.itemname, union_cast<signed int>((*def_func_)()));
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &signed_val, lpItem->cfg_item.size);
}
else{//unsigned int def_unsigned_val = (unsigned int)((*def_func_)()); unsigned int unsigned_val = (signed int)c_ini->GetLongValue((const char*)user_param, lpItem->cfg_item.itemname, union_cast<unsigned int>((*def_func_)()));
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &unsigned_val, lpItem->cfg_item.size);
}
}
else if (temp_type_mask.is_float_){ //浮点数//float def_float_val = union_cast<float>((*def_func_)()); float float_val = (float)c_ini->GetDoubleValue((const char*)user_param, lpItem->cfg_item.itemname, union_cast<float>((*def_func_)()));
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &float_val, lpItem->cfg_item.size);
}
else { //其他,默认是字符串//char* strDef = (char*)((*def_func_)()); char* strValue = (char*)c_ini->GetValue((const char*)user_param, lpItem->cfg_item.itemname, (char*)((*def_func_)()));//如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) {
(
*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strValue, lpItem->cfg_item.size);
}
else{
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strValue, lpItem->cfg_item.size);
}
}

lpItem
= lpItem->lpnext;
}
return 0;
}

template
<class TBase>unsignedint XConfigContainer<TBase>::load_detla(void* config_pesist, void*user_param)
{
//内部对象 CSimpleIniA * c_ini = (CSimpleIniA *)(config_pesist);if (0 ==c_ini) {return 1;
}
//依次读取配置项 type_mask temp_type_mask;//cJSON * c_item = NULL; const ConfigItemLink* lpItem =TBase::GetConfigItem();while(lpItem !=nullptr) {
temp_type_mask.int_value
= lpItem->cfg_item.type_mask_;lpItem= lpItem->lpnext;
}
return 0;
}

template
<class T>T read_value(unsignedchar* dest, unsigned intsize){switch(size)
{
case sizeof(unsigned char):if (std::is_signed<T>::value)return (T)*(char*)dest;else return (T)*(unsigned char*)dest;case sizeof(unsigned short):if (std::is_signed<T>::value)return (T)*(short*)dest;else return (T)*(unsigned short*)dest;case sizeof(unsigned int):if (std::is_floating_point<T>::value){return (T)*(float*)dest;
}
else{if (std::is_signed<T>::value)return (T)*(int*)dest;else return (T)*(unsigned int*)dest;
}
case sizeof(double):return *(T*)dest;default:return *(T*)dest;
}
return 0;
}

template
<class TBase>unsignedint XConfigContainer<TBase>::save(void* config_pesist, void* user_param) const{//内部对象 CSimpleIniA * c_ini = (CSimpleIniA *)(config_pesist);if (0 ==c_ini) {return 1;
}
//依次读取配置项 type_mask temp_type_mask;//cJSON * c_item = NULL; const ConfigItemLink* lpItem =TBase::GetConfigItem();while(lpItem !=nullptr) {lpItem= lpItem->lpnext;
}
return 0;
}

template
<class TBase>unsignedint XConfigContainer<TBase>::save_to_struct(void* config_struct, void* user_param) const{void* algo_config = (void*)config_struct;if (0 ==algo_config) {return 1;
}

type_mask temp_type_mask;
const ConfigItemLink* lpItem =TBase::GetConfigItem();while(lpItem !=nullptr) {
temp_type_mask.int_value
= lpItem->cfg_item.type_mask_;if(temp_type_mask.is_int_) {if(temp_type_mask.is_signed_) {
signed
int def_val = *(signed int*)&(((unsigned char*)this)[lpItem->cfg_item.offset]);
copy_value(
&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
else{
unsigned
int def_val = *(unsigned int*)&(((unsigned char*)this)[lpItem->cfg_item.offset]);
copy_value(
&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
}
else if (temp_type_mask.is_float_){ //浮点数 float def_val = *(float*)&(((unsigned char*)this)[lpItem->cfg_item.offset]);
copy_value(
&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
else { //其他,默认是字符串 const char* strDef = ((std::string*) &(((unsigned char*)this)[lpItem->cfg_item.offset]))->c_str();//如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) {
(
*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size);
}
else{
copy_value(
&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size);
}
}

lpItem
= lpItem->lpnext;
}
return 0;
}

4-2.如果使用Json,则是如下的转化代码:

#include "ConfigContainer.h"#include"cJSON.h"template<class T>
void copy_value(unsigned char* dest, T* src, unsigned intsize){switch(size)
{
case sizeof(unsigned char):if (std::is_signed<T>::value)*(char*)dest = *(char*)src;else *(unsigned char*)dest = *(unsigned char*)src;return;case sizeof(unsigned short):if (std::is_signed<T>::value)*(short*)dest = *(short*)src;else *(unsigned short*)dest = *(unsigned short*)src;return;case sizeof(unsigned int):if (std::is_floating_point<T>::value){*(float*)dest = *(float*)src;
}
else{if (std::is_signed<T>::value)*(int*)dest = *(int*)src;else *(unsigned int*)dest = *(unsigned int*)src;
}
return;
}
//其他情况,使用memcpy memcpy(dest, src, size);
}

template
<class TBase>unsignedint XConfigContainer<TBase>::load(void* config_pesist, void*user_param)
{
//内部对象 cJSON * c_json = (cJSON *)(config_pesist);if (0 ==c_json) {return 1;
}
//依次读取配置项 type_mask temp_type_mask;
cJSON
* c_item =NULL;const ConfigItemLink* lpItem =TBase::GetConfigItem();while(lpItem !=nullptr) {//从json数据中读取到内容 c_item = cJSON_GetObjectItem(c_json, lpItem->cfg_item.itemname);
temp_type_mask.int_value
= lpItem->cfg_item.type_mask_;if (NULL ==c_item){//保存在内部变量中:如果是整数 def_func def_func_ = lpItem->cfg_item.default_func;if(temp_type_mask.is_int_) {if(temp_type_mask.is_signed_) {
signed
int def_val = (signed int)((*def_func_)());
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
else{
unsigned
int def_val = (unsigned int)((*def_func_)());
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
}
else if (temp_type_mask.is_float_){ //浮点数 float def_val = union_cast<float>((*def_func_)());
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
else { //其他,默认是字符串 char* strDef = (char*)((*def_func_)());//如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) {
(
*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size);
}
else{
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size);
}
}
}
else{if(temp_type_mask.is_int_) {if(temp_type_mask.is_signed_) {
signed
int def_val = c_item->valueint;
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
else{
unsigned
int def_val = c_item->valueint;
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
}
else if (temp_type_mask.is_float_){ //浮点数 float def_val = (float)(c_item->valuedouble);
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
else { //其他,默认是字符串 char* strDef = c_item->valuestring;//如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) {
(
*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size);
}
else{
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size);
}
}
}

lpItem
= lpItem->lpnext;
}
return 0;
}

template
<class TBase>unsignedint XConfigContainer<TBase>::load_detla(void* config_pesist, void*user_param)
{
//内部对象 cJSON * c_json = (cJSON *)(config_pesist);if (0 ==c_json) {return 1;
}
//依次读取配置项 type_mask temp_type_mask;
cJSON
* c_item =NULL;const ConfigItemLink* lpItem =TBase::GetConfigItem();while(lpItem !=nullptr) {//从json数据中读取到内容 c_item = cJSON_GetObjectItem(c_json, lpItem->cfg_item.itemname);
temp_type_mask.int_value
= lpItem->cfg_item.type_mask_;//增量配置,则不考虑不存在的内容 if (NULL !=c_item){if(temp_type_mask.is_int_) {if(temp_type_mask.is_signed_) {
signed
int def_val = c_item->valueint;
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
else{
unsigned
int def_val = c_item->valueint;
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
}
else if (temp_type_mask.is_float_){ //浮点数 float def_val = (float)(c_item->valuedouble);
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
else { //其他,默认是字符串 char* strDef = c_item->valuestring;//如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) {
(
*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size);
}
else{
copy_value(
&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size);
}
}
}

lpItem
= lpItem->lpnext;
}
return 0;
}

template
<class T>T read_value(unsignedchar* dest, unsigned intsize){switch(size)
{
case sizeof(unsigned char):if (std::is_signed<T>::value)return (T)*(char*)dest;else return (T)*(unsigned char*)dest;case sizeof(unsigned short):if (std::is_signed<T>::value)return (T)*(short*)dest;else return (T)*(unsigned short*)dest;case sizeof(unsigned int):if (std::is_floating_point<T>::value){return (T)*(float*)dest;
}
else{if (std::is_signed<T>::value)return (T)*(int*)dest;else return (T)*(unsigned int*)dest;
}
case sizeof(double):return *(T*)dest;default:return *(T*)dest;
}
return 0;
}

template
<class TBase>unsignedint XConfigContainer<TBase>::save(void* config_pesist, void* user_param) const{//内部对象 cJSON * c_json = (cJSON *)(config_pesist);if (0 ==c_json) {return 1;
}
//依次读取配置项 type_mask temp_type_mask;
cJSON
* c_item =NULL;const ConfigItemLink* lpItem =TBase::GetConfigItem();while(lpItem !=nullptr) {
temp_type_mask.int_value
= lpItem->cfg_item.type_mask_;if(temp_type_mask.is_int_) {//暂时还不支持64位大整数 if(temp_type_mask.is_signed_) {
cJSON_AddNumberToObject(c_json, lpItem
->cfg_item.itemname, read_value<signed int>(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), lpItem->cfg_item.size));
}
else{
cJSON_AddNumberToObject(c_json, lpItem
->cfg_item.itemname, read_value<unsigned int>(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), lpItem->cfg_item.size));
}
}
else if (temp_type_mask.is_float_){ //浮点数 if (lpItem->cfg_item.size == sizeof(float)) {
cJSON_AddNumberToObject(c_json, lpItem
->cfg_item.itemname, read_value<float>(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), lpItem->cfg_item.size));
}
else{
cJSON_AddNumberToObject(c_json, lpItem
->cfg_item.itemname, read_value<double>(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), lpItem->cfg_item.size));
}
}
else { //其他,默认是字符串 cJSON_AddStringToObject(c_json, lpItem->cfg_item.itemname, ((std::string*)&((char*)(TBase*)this)[lpItem->cfg_item.offset]) ->c_str());
}

lpItem
= lpItem->lpnext;
}
return 0;
}

template
<class TBase>unsignedint XConfigContainer<TBase>::save_to_struct(void* config_struct, void* user_param) const{void* algo_config = (void*)config_struct;if (0 ==algo_config) {return 1;
}

type_mask temp_type_mask;
const ConfigItemLink* lpItem =TBase::GetConfigItem();while(lpItem !=nullptr) {
temp_type_mask.int_value
= lpItem->cfg_item.type_mask_;if(temp_type_mask.is_int_) {if(temp_type_mask.is_signed_) {
signed
int def_val = *(signed int*)&(((unsigned char*)this)[lpItem->cfg_item.offset]);
copy_value(
&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
else{
unsigned
int def_val = *(unsigned int*)&(((unsigned char*)this)[lpItem->cfg_item.offset]);
copy_value(
&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
}
else if (temp_type_mask.is_float_){ //浮点数 float def_val = *(float*)&(((unsigned char*)this)[lpItem->cfg_item.offset]);
copy_value(
&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}
else { //其他,默认是字符串 const char* strDef = ((std::string*) &(((unsigned char*)this)[lpItem->cfg_item.offset]))->c_str();//如果有深度拷贝,则使用深拷贝函数 if (lpItem->cfg_item.deep_copy_func) {
(
*(lpItem->cfg_item.deep_copy_func))(&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size);
}
else{
copy_value(
&(((unsigned char*)algo_config)[lpItem->cfg_item.offset]), strDef, lpItem->cfg_item.size);
}
}

lpItem
= lpItem->lpnext;
}
return 0;
}

5.使用时

#include "ConfigContainer_ini.h"ConfigParam                 x_config_param;
CSimpleIniA
* ini_file_stream_ptr_ = newCSimpleIniA();if(SI_OK != ini_file_stream_ptr_->LoadFile(szConfigIni)){return;
}

x_config_param.load(ini_file_stream_ptr_, DEFAULT);

 

标签: none

添加新评论