配置信息读取代码(VS2012编译通过,使用了C++11特性)
配置文件的读取重复代码极多,且容易漏掉、出错,如下一段配置信息读取代码,可以简化编程。
主体类定义:
#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;
};
unsignedintint_value;
}type_mask;
template<class TBase> classXConfigContainer
{public:
typedefvoid* (*def_func)();
typedefbool (*deep_copy)(void* dest, const void* src, unsigned intsize);
typedefstructtagConfigItem
{
unsignedintoffset;
unsignedintsize;
unsignedinttype_mask_;const char*itemname;
def_func default_func;
deep_copy deep_copy_func;
}ConfigItem;
typedefstructtagConfigItemLink
{
ConfigItem cfg_item;struct tagConfigItemLink*lpnext;
}ConfigItemLink;public:
XConfigContainer() {}~XConfigContainer() {}
unsignedint init(void*user_param);
unsignedint load(void* config_pesist, void*user_param);
unsignedint load_detla(void* config_pesist, void*user_param);
unsignedint save(void* config_pesist, void* user_param) const;
unsignedint save_to_struct(void* config_struct, void* user_param) const;
};#define BEGIN_CONFIG_CONTAINER(class_name) \ class class_name : public XConfigContainer<class_name>\
{ \private: \
unsignedintfirst_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 {
unsignedshortparam_version;
unsignedshortaaa;floatbbb;floatccc;
} config_param;
2.声明相应的结构信息说明:
#include "ConfigContainer.h"BEGIN_CONFIG2_CONTAINER(ConfigParam, config_param);
CONFIG2_ITEM(unsignedshort, param_version, DEFALUT_VALUE_DECL(57920), NULL);
CONFIG2_ITEM(unsignedshort, 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_) {
signedint 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{
unsignedint 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_) {
signedint def_val = (signed int)((*def_func_)());
copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}else{
unsignedint 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_) {
signedint def_val = c_item->valueint;
copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}else{
unsignedint 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_) {
signedint def_val = c_item->valueint;
copy_value(&(((unsigned char*)(TBase*)this)[lpItem->cfg_item.offset]), &def_val, lpItem->cfg_item.size);
}else{
unsignedint 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_) {
signedint 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{
unsignedint 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);