Chinaunix首页 | 论坛 | 博客
  • 博客访问: 16337
  • 博文数量: 7
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2017-04-10 19:30
文章分类

全部博文(7)

文章存档

2015年(7)

我的朋友

分类: LINUX

2015-02-13 09:34:17

做设备端应用编程时,常常需要通过保存配置的方式来保存系统参数,而通常的方式是写xml文件或者ini文件,本文封装ini文件的读写,方便配置文件的读写!

一、编译使用iniparser库。
    iniparser库很小,若不使用库的方式,也可以放入工程直接进行编译!本文使用的Linux gcc编译iniparser库。
    请参考一下链接:
    http://www.cnblogs.com/dyllove98/archive/2013/07/28/3221732.html

二、封装类
    

点击(此处)折叠或打开

  1. /*
  2.  * ConfigBaseClass.h
  3.  *
  4.  * Created on: Jan 8, 2015
  5.  * Author: need
  6.  */

  7. #ifndef CONFIGBASECLASS_H_
  8. #define CONFIGBASECLASS_H_

  9. /*******************************************************************************
  10.  * AmConfig class provides methods to retrieve and store configurations
  11.  * of Vin, Vout, Image and Stream, DO NOT use this class directly,
  12.  * use the inherited class instead
  13.  ******************************************************************************/
  14. #include <stdlib.h>
  15. #include <errno.h>
  16. #include <unistd.h>
  17. #include <string>
  18. #include <sstream>
  19. #include <cstdio>
  20. #ifdef __cplusplus
  21. extern "C" {
  22. #endif
  23. #include <iniparser.h>
  24. #ifdef __cplusplus
  25. }
  26. #endif

  27. #define TOSTR(str) (char*)#str
  28. #define CONFIG_GET_PROPERTY_BOOLEAN(property) property=getBoolean(TOSTR(property), property)
  29. #define CONFIG_SET_PROPERTY_BOOLEAN(property) setBoolean(TOSTR(property), property)
  30. #define CONFIG_GET_PROPERTY_INT(property) property=getInt(TOSTR(property), property)
  31. #define CONFIG_SET_PROPERTY_INT(property) setInt(TOSTR(property), property)
  32. #define CONFIG_GET_PROPERTY_UINT(property) property=getUInt(TOSTR(property), property)
  33. #define CONFIG_SET_PROPERTY_UINT(property) setUInt(TOSTR(property), property)
  34. #define CONFIG_GET_PROPERTY_STRING(property) property=getString(TOSTR(property), property.c_str())
  35. #define CONFIG_SET_PROPERTY_STRING(property) setString(TOSTR(property), property.c_str())
  36. #define CONFIG_GET_PROPERTY_DOUBLE(property) property=getDouble(TOSTR(property), property)
  37. #define CONFIG_SET_PROPERTY_DOUBLE(property) setDouble(TOSTR(property), property)
  38. using std::string;
  39. using std::stringstream;

  40. /**
  41.  *    ini格式配置文件的读写工具类。。
  42.  * 该类中的所有方法由ConfigBaseClass对象调用调用。
  43.  */
  44. class ConfigFileRWUtil
  45. {
  46. public:
  47.     ConfigFileRWUtil(const char *configFileName);
  48.     virtual ~ConfigFileRWUtil();

  49. public:
  50.     bool saveConfig();
  51.     void dumpIniFile() { /* Dump INI file to stdout: debug only*/
  52.         iniparser_dump(mDictionary, stdout);
  53.     }


  54.     bool init();

  55.     int getSectionNumber() {
  56.         return iniparser_getnsec(mDictionary);
  57.     }

  58.     char* getSectionName(int n) {
  59.         return iniparser_getsecname(mDictionary, n);
  60.     }

  61.     char* getString(const char *key, const char *defValue) {
  62.         return iniparser_getstring(mDictionary, (char *)key, (char *)defValue);
  63.     }

  64.     int getInt(const char *key, int defValue) {
  65.         return iniparser_getint(mDictionary, (char *)key, defValue);
  66.     }

  67.     double getDouble(const char *key, double defValue) {
  68.         return iniparser_getdouble(mDictionary, (char *)key, defValue);
  69.     }

  70.     bool getBoolean(const char *key, bool defValue) {
  71.         return (iniparser_getboolean(mDictionary,
  72.                 (char *)key,
  73.                 (defValue ? 1 : 0)) ? true : false);
  74.     }

  75.     bool setString(const char *entry, const char *value) {
  76.         return (iniparser_set(mDictionary, (char *)entry, (char *)value)
  77.                 == 0 ? true : false);
  78.     }

  79.     bool setInt(const char *entry, int value) {
  80.         char tmpValue[32] = {0};
  81.         int ret = sprintf(tmpValue, "%d", value);
  82.         tmpValue[ret] = '\0';
  83.         return setString(entry, tmpValue);
  84.     }

  85.     bool setUint(const char *entry, int value) {
  86.         char tmpValue[32] = {0};
  87.         int ret = sprintf(tmpValue, "%u", value);
  88.         tmpValue[ret] = '\0';
  89.         return setString(entry, tmpValue);
  90.     }

  91.     bool setDouble(const char *entry, double value) {
  92.         char tmpValue[32] = {0};
  93.         int ret = sprintf(tmpValue, "%f", value);
  94.         tmpValue[ret] = '\0';
  95.         return setString(entry, tmpValue);
  96.     }

  97.     void deleteEntry(char *entry) {
  98.         iniparser_unset(mDictionary, entry);
  99.     }

  100. protected:
  101.     char *mConfigFile;
  102.     dictionary *mDictionary;
  103. };

  104. /**
  105.  * ConfigBaseClass类
  106.  * 实现ini配置文件和class的相互转换。
  107.  * 需要存取ini配置文件的类需要继承ConfigBaseClass,然后重写下面两个虚函数
  108.  * virtual bool loadConfigDetail() = 0;
  109.  * virtual bool saveConfigDetail() = 0;
  110.  * 例子:
  111.  *
  112. #include "ConfigBaseClass.h"
  113. #define CONFIG_EVENT_FILENAME    "/mnt/config/test.conf"
  114. #define TEST_ARR_SIZE 2

  115. typedef enum{
  116.     ENMU1,
  117.     ENMU2
  118. }TestEnum;

  119. class Test1: public ConfigBaseClass
  120. {
  121. public:
  122.     uint8_t numMember;
  123.     string stringMember;
  124.     bool boolMember;
  125.     TestEnum enumMember;
  126.     uint8_t arrMember[TEST_ARR_SIZE][TEST_ARR_SIZE];

  127. public:
  128.     Test1()
  129.     :numMember(0),boolMember(0),enumMember(ENMU1){

  130.     }
  131.     virtual ~Test1(){

  132.     }
  133.     virtual bool loadConfigDetail(){
  134.         CONFIG_GET_PROPERTY_UINT(numMember);
  135.         CONFIG_GET_PROPERTY_STRING(stringMember);
  136.         CONFIG_GET_PROPERTY_BOOLEAN(boolMember);
  137.         //
  138.         enumMember=(TestEnum)getUInt(TOSTR(enumMember), enumMember);

  139.         char str[32] = {0};
  140.         int i=0,j=0;
  141.         for(i=0; i<TEST_ARR_SIZE; i++){
  142.             for(j=0; j<TEST_ARR_SIZE; j++) {
  143.                 memset(str, 0, 32);//数据元素,需要自己根据下表生成对应的属性名
  144.                 sprintf(str, "arrMember_%u_%u", i, j);
  145.                 arrMember[i][j]=getUInt(str, 0);
  146.             }
  147.         }
  148.         return true;
  149.     }

  150.     virtual bool saveConfigDetail(){
  151.         CONFIG_SET_PROPERTY_UINT(numMember);
  152.         CONFIG_SET_PROPERTY_STRING(stringMember);
  153.         CONFIG_SET_PROPERTY_BOOLEAN(boolMember);
  154.         CONFIG_SET_PROPERTY_UINT(enumMember);

  155.         char str[32] = {0};
  156.         int i=0,j=0;
  157.         for(i=0; i<TEST_ARR_SIZE; i++){
  158.             for(j=0; j<TEST_ARR_SIZE; j++) {
  159.                 memset(str, 0, 32);//数据元素,需要自己根据下表生成对应的属性名
  160.                 sprintf(str, "arrMember_%u_%u", i, j);
  161.                 setUInt(str, arrMember[i][j]);
  162.             }
  163.         }
  164.         return true;
  165.     }
  166. } ;

  167. class Test: public ConfigBaseClass
  168. {
  169. public:

  170.     Test1 structMember;
  171.     Test1 structArr[TEST_ARR_SIZE];

  172. public:
  173.     Test(){

  174.     }
  175.     virtual ~Test(){

  176.     }

  177.     virtual bool loadConfigDetail(){
  178.         structMember.loadConfig(configRWUtil, sectionName, TOSTR(structMember));
  179.         for(int i=0;i<TEST_ARR_SIZE;i++){
  180.             structArr[i].loadConfig(configRWUtil, sectionName, TOSTR(structArr), false, i);
  181.         }
  182.         return true;
  183.     }

  184.     virtual bool saveConfigDetail(){
  185.         structMember.saveConfig();
  186.         for(int i=0;i<TEST_ARR_SIZE;i++){
  187.             structArr[i].saveConfig();
  188.         }
  189.         return true;
  190.     }
  191. } ;


  192. int main() {
  193.     ConfigFileRWUtil* fileRWUtil = new ConfigFileRWUtil(CONFIG_EVENT_FILENAME);
  194.     Test test;
  195.     test.loadConfig(fileRWUtil, "", TOSTR(test), true);

  196.     printf("%s, %d \n", test.structMember.stringMember.c_str(), test.structArr[0].numMember);
  197.     test.structMember.stringMember="abcd";
  198.     test.structArr[0].numMember=123;
  199.     test.saveConfig();
  200.     return 0;
  201. }
  202.  * }
  203.  */

  204. class ConfigBaseClass {
  205. public:
  206.     ConfigBaseClass();
  207.     virtual ~ConfigBaseClass();

  208.     /**
  209.      * 从ini配置文件中加载数据
  210.      * 参数configRWUtil, ini文件的读写类。
  211.      * 参数parentSectionName,如果是最顶层配置类,使用空字符串,如果是属性配置类,填父亲配置类的sectionName。
  212.      * 参数mySectionName, 当前配置类的sectionName
  213.      * 参数isRootConfigClass 是否是根配置类。默认值 不是。
  214.      * 参数index 如果是数组元素,标识数组下表。如果不是 -1. 默认值 -1
  215.      */
  216.     bool loadConfig(ConfigFileRWUtil *configRWUtil, string parentSectionName, string mySectionName, bool isRootConfigClass=false, int index=-1);

  217.     bool saveConfig();

  218.     string getString(char* propertyName, const char *defValue) {
  219.         if(configRWUtil == NULL) {
  220.             fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
  221.             return defValue;
  222.         }
  223.         return configRWUtil->getString(orginagekey(propertyName).c_str(), defValue);
  224.     }

  225.     int getInt(char* propertyName, int defValue) {
  226.         if(configRWUtil == NULL) {
  227.             fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
  228.             return defValue;
  229.         }
  230.         return configRWUtil->getInt(orginagekey(propertyName).c_str(),defValue);
  231.     }

  232.     double getDouble(char* propertyName, double defValue) {
  233.         if(configRWUtil == NULL) {
  234.             fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
  235.             return defValue;
  236.         }
  237.         return configRWUtil->getDouble(orginagekey(propertyName).c_str(),defValue);
  238.     }

  239.     int getUInt(char* propertyName, int defValue) {
  240.         return getInt(propertyName, defValue);
  241.     }

  242.     bool getBoolean(char* propertyName, bool defValue) {
  243.         if(configRWUtil == NULL) {
  244.             fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
  245.             return false;
  246.         }
  247.         return configRWUtil->getBoolean(orginagekey(propertyName).c_str(),defValue);
  248.     }

  249.     bool setString(char* propertyName, const char *value) {
  250.         if(configRWUtil == NULL) {
  251.             fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
  252.             return false;
  253.         }
  254.         return configRWUtil->setString(orginagekey(propertyName).c_str(),value);
  255.     }


  256.     bool setInt(char* propertyName, int value) {
  257.         if(configRWUtil == NULL) {
  258.             fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
  259.             return false;
  260.         }
  261.         return configRWUtil->setInt(orginagekey(propertyName).c_str(),value);
  262.     }

  263.     bool setBoolean(char* propertyName, bool value) {
  264.         return setInt(propertyName, value);
  265.     }

  266.     bool setUInt(char* propertyName, int value) {
  267.         if(configRWUtil == NULL) {
  268.             fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
  269.             return false;
  270.         }
  271.         return configRWUtil->setUint(orginagekey(propertyName).c_str(), value);
  272.     }
  273.     int setDouble(char* propertyName, double value) {
  274.         if(configRWUtil == NULL) {
  275.             fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
  276.             return value;
  277.         }
  278.         return configRWUtil->setDouble(orginagekey(propertyName).c_str(), value);
  279.     }

  280. protected:
  281.     virtual bool loadConfigDetail() = 0;
  282.     virtual bool saveConfigDetail() = 0;


  283. private:
  284.     string orginagekey(char* property) {
  285.         stringstream str1;
  286.         str1 << sectionName<<":"<<property;
  287.         return str1.str();
  288.     };
  289.     bool setSection() {
  290.         if(configRWUtil == NULL) {
  291.             fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
  292.             return false;
  293.         }else {
  294. //            fprintf(stderr,"setSection! %s\n", sectionName.c_str());
  295.         }
  296.         return configRWUtil->setString(sectionName.c_str(),"");
  297.     }

  298. protected:
  299.     ConfigFileRWUtil *configRWUtil;
  300.     string sectionName;
  301.     int index;
  302.     bool isRootConfigClass;
  303. };

  304. #endif /* CONFIGBASECLASS_H_ */
    实现:

点击(此处)折叠或打开

  1. /*
  2.  * ConfigBaseClass.cpp
  3.  *
  4.  * Created on: Jan 8, 2015
  5.  * Author: need
  6.  */

  7. #include "ConfigBaseClass.h"
  8. /*******************************************************************************
  9.  * ConfigFileRWUtil
  10.  ******************************************************************************/

  11. ConfigFileRWUtil::ConfigFileRWUtil(const char *configFileName)
  12. : mConfigFile(NULL),
  13.   mDictionary(NULL)
  14. {
  15.     if (configFileName) {
  16.         mConfigFile = strdup(configFileName);
  17.     }
  18. }

  19. ConfigFileRWUtil::~ConfigFileRWUtil()
  20. {
  21.     delete[] mConfigFile;
  22.     if (mDictionary) {
  23.         iniparser_freedict(mDictionary);
  24.     }
  25.     fprintf(stderr,"~ConfigFileRWUtil \n");
  26. }

  27. bool ConfigFileRWUtil::init()
  28. {
  29.     /* Unload old dictonary everytime to keep config file updated */

  30.     if(access(mConfigFile, R_OK&W_OK)<0) {
  31.         fprintf(stderr,"%s not exist! create one! \n", mConfigFile);
  32.         FILE *tmp = fopen(mConfigFile, "a");
  33.         fclose(tmp);
  34.         if(tmp == NULL){
  35.             fprintf(stderr,"%s create error! \n", mConfigFile);
  36.             return false;
  37.         }
  38.     }

  39.     if (mDictionary) {
  40.         iniparser_freedict(mDictionary);
  41.         mDictionary = NULL;
  42.     }
  43.     mDictionary = iniparser_load(mConfigFile);
  44.     mDictionary != NULL ? fprintf(stderr,"%s is loaded! \n", mConfigFile) :
  45.             fprintf(stderr,"Failed loading config file: %s \n", mConfigFile);

  46.     return (mDictionary != NULL);
  47. }

  48. bool ConfigFileRWUtil::saveConfig()
  49. {
  50.     bool ret = false;

  51.     if (mDictionary && mConfigFile) {
  52.         FILE *filePointer = fopen(mConfigFile, "w+");
  53.         if (NULL == filePointer) {
  54.             fprintf(stderr,"%s\n", strerror(errno));
  55.         } else {
  56.             iniparser_dump_ini(mDictionary, filePointer);
  57.             fclose(filePointer);
  58.             ret = true;
  59.         }
  60.     } else {
  61.         fprintf(stderr,"Please load config file before save it!");
  62.     }

  63.     return ret;
  64. }

  65. ConfigBaseClass::ConfigBaseClass()
  66. :configRWUtil(NULL), index(-1), isRootConfigClass(false){
  67.     // TODO Auto-generated constructor stub

  68. }

  69. ConfigBaseClass::~ConfigBaseClass() {
  70.     // TODO Auto-generated destructor stub
  71. }

  72. bool ConfigBaseClass::loadConfig(ConfigFileRWUtil *configRWUtil, string parentSectionName, string mySectionName, bool isRootConfigClass, int index) {
  73.     if(configRWUtil == NULL) {
  74.         fprintf(stderr,"loadConfig error! configRWUtil is null! \n");
  75.         return false;
  76.     }
  77.     this->configRWUtil = configRWUtil;
  78.     if(mySectionName.empty()) {
  79.         fprintf(stderr,"loadConfig error! mySectionName is null! \n");
  80.         return false;
  81.     }

  82.     stringstream str1;
  83.     if(!parentSectionName.empty()){
  84.         str1<<parentSectionName<<"_";
  85.     }
  86.     str1<<mySectionName;
  87.     if(index>=0){
  88.         str1 <<"_"<<index;
  89.     }
  90.     this->sectionName = str1.str();

  91.     if(!isRootConfigClass || index>0) {
  92.         this->isRootConfigClass = false;
  93.     }else{
  94.         fprintf(stderr,"isRootConfigClass true call configRWUtil->init! %s \n", this->sectionName.c_str());
  95.         configRWUtil->init();
  96.         configRWUtil->dumpIniFile();
  97.         this->isRootConfigClass = true;
  98.     }
  99.     this->index = index;
  100.     return loadConfigDetail();
  101. }

  102. bool ConfigBaseClass::saveConfig() {
  103.     fprintf(stderr,"%s %d start save config!", sectionName.c_str(), isRootConfigClass);
  104.     if(configRWUtil == NULL) {
  105.         fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
  106.         return false;
  107.     }
  108.     setSection();
  109.     saveConfigDetail();
  110.     if(isRootConfigClass) {
  111. //        fprintf(stderr,"isRootConfigClass true saveConfig! \n");
  112.         configRWUtil->saveConfig();
  113.     }else {
  114. //        fprintf(stderr,fprintf(stderr,"isRootConfigClass false! \n");
  115.     }
  116.     return true;
  117. }

三、使用

点击(此处)折叠或打开

  1. #include "ConfigBaseClass.h"

  2. #define CONFIG_FILENAME "/home/hisi/nfs/config_filename.ini"

  3. class SubProfile:public ConfigBaseClass{
  4. public:
  5.     int test1;
  6.     SubProfile(){}
  7.     virtual ~SubProfile(){}

  8.     virtual bool loadConfigDetail(){
  9.         CONFIG_GET_PROPERTY_INT(test1);
  10.         return true;
  11.     }
  12.     virtual bool saveConfigDetail(){
  13.         CONFIG_SET_PROPERTY_INT(test1);
  14.         return true;
  15.     }
  16.     SubProfile &operator=(const SubProfile &subprofile) {
  17.         test1 = subprofile.test1;
  18.         return *this;
  19.     }
  20. };

  21. class Profile:public ConfigBaseClass{
  22. public:
  23.     int test1;
  24.     char test2;
  25.     bool test3;
  26.     std::string test4;
  27.     SubProfile test5;

  28. public:
  29.     Profile(){}
  30.     virtual ~Profile(){}

  31.     virtual bool loadConfigDetail(){
  32.         CONFIG_GET_PROPERTY_INT(test1);
  33.         CONFIG_GET_PROPERTY_UINT(test2);
  34.         CONFIG_GET_PROPERTY_BOOLEAN(test3);
  35.         CONFIG_GET_PROPERTY_STRING(test4);
  36.         test5.loadConfig(configRWUtil, sectionName, TOSTR(test5));
  37.         return true;
  38.     }
  39.     virtual bool saveConfigDetail(){
  40.         CONFIG_SET_PROPERTY_INT(test1);
  41.         CONFIG_SET_PROPERTY_UINT(test2);
  42.         CONFIG_SET_PROPERTY_BOOLEAN(test3);
  43.         CONFIG_SET_PROPERTY_STRING(test4);
  44.         test5.saveConfig();
  45.         return true;
  46.     }
  47.     Profile &operator=(const Profile &profile) {
  48.         test1 = profile.test1;
  49.         test2 = profile.test2;
  50.         test3 = profile.test3;
  51.         test4 = profile.test4;
  52.         test5 = profile.test5;
  53.         return *this;
  54.     }
  55. };

  56. int main(int argc, char* argv[])
  57. {
  58.     //
  59.     ConfigFileRWUtil* ConfigRWUtil = new ConfigFileRWUtil(CONFIG_FILENAME);

  60.     Profile prifile;
  61.     prifile.test1 = 1;
  62.     prifile.test2 = 'c';
  63.     prifile.test3 = false;
  64.     prifile.test4 = "test4";
  65.     prifile.test5.test1 = 4;

  66.     prifile.loadConfig(ConfigRWUtil, "", TOSTR(prifile), true);
  67.     prifile.saveConfig();

  68.     if(ConfigRWUtil != NULL){
  69.         delete ConfigRWUtil;
  70.         ConfigRWUtil = NULL;
  71.     }
  72.     return 0;
  73. }

在包含字符串的情况下,本例使用的是std:string!


本文所有:Devile May Cry J        QQ:384668960
阅读(982) | 评论(0) | 转发(0) |
0

上一篇:freetype2.3.10操作字库生成bitmap

下一篇:没有了

给主人留下些什么吧!~~