• 配置信息读取代码(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> struct UID{};
    
    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 int int_value;
    }type_mask;
    
    template<class TBase>
    class XConfigContainer
    {
    public:
        typedef void* (*def_func)();
        typedef bool  (*deep_copy)(void* dest, const void* src, unsigned int size);
    
        typedef struct tagConfigItem
        {
            unsigned int offset;
            unsigned int size;
            unsigned int type_mask_;
            const char*  itemname;
            def_func     default_func;
            deep_copy    deep_copy_func;
        }ConfigItem;
    
        typedef struct tagConfigItemLink
        {
            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 int first_item_;   
    public: 
        class_name() { 
            memset(&first_item_, 0, sizeof( class_name ) - (unsigned int)(size_t)&(((class_name *)0)-> first_item_ )); 
        }; 
        ~class_name() {} 
        static unsigned int x_config_item_count; 
        static const ConfigItemLink* GetConfigItem(); 
    public: 
        template<int N> struct ConfigItemSeq{  static ConfigItemLink 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 }; return val.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>) {return get_default_func;}; 
        static deep_copy    get_deep_copy_func(UID<__property_##item_name##_idx>) {return copy_func;}; 
    public: 
        property_##item_name##_t& get_##item_name () {return x_##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) 
    unsigned int 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; 
        return class_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 int x_config_item_count; 
        static const ConfigItemLink* GetConfigItem(); 
    public: 
        template<int N> struct ConfigItemSeq{  static ConfigItemLink 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 }; return val.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>) {return get_default_func;}; 
        static deep_copy    get_deep_copy_func(UID<__property_##item_name##_idx>) {return copy_func;}; 
    public: 
        property_##item_name##_t& get_##item_name () {return item_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) 
    unsigned int 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; 
        return class_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;
        return val1.t1_val2;
    }
    
    #define DEFALUT_VALUE_FLOAT_DECL(value)   []() -> void* {return  union_cast<void*>(value);}
    
    #endif

    使用办法:

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

    typedef struct config_param_t {
        unsigned short param_version;   
        unsigned short aaa;                     
        float  bbb;
        float  ccc;
    } 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 int size){
        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>
    unsigned int 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>
    unsigned int 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>
    unsigned int 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(unsigned char* dest,  unsigned int size){
        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>
    unsigned int 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>
    unsigned int 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 int size){
        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>
    unsigned int 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>
    unsigned int 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(unsigned char* dest,  unsigned int size){
        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>
    unsigned int 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>
    unsigned int 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_ = new CSimpleIniA();
        if(SI_OK != ini_file_stream_ptr_->LoadFile(szConfigIni)){
            return ;
        }
    
        x_config_param.load(ini_file_stream_ptr_, DEFAULT);
  • 相关阅读:
    2021/3/12
    2021/3/11
    2021/3/10
    2021/3/9
    2021/3/8
    2021/3/5
    2021/3/4
    2021/3/3
    2021/3/2
    2021/3/1
  • 原文地址:https://www.cnblogs.com/eaglexmw/p/14784760.html
Copyright © 2020-2023  润新知