做设备端应用编程时,常常需要通过保存配置的方式来保存系统参数,而通常的方式是写xml文件或者ini文件,本文封装ini文件的读写,方便配置文件的读写!
一、编译使用iniparser库。
iniparser库很小,若不使用库的方式,也可以放入工程直接进行编译!本文使用的Linux gcc编译iniparser库。
请参考一下链接:
http://www.cnblogs.com/dyllove98/archive/2013/07/28/3221732.html
二、封装类
-
/*
-
* ConfigBaseClass.h
-
*
-
* Created on: Jan 8, 2015
-
* Author: need
-
*/
-
-
#ifndef CONFIGBASECLASS_H_
-
#define CONFIGBASECLASS_H_
-
-
/*******************************************************************************
-
* AmConfig class provides methods to retrieve and store configurations
-
* of Vin, Vout, Image and Stream, DO NOT use this class directly,
-
* use the inherited class instead
-
******************************************************************************/
-
#include <stdlib.h>
-
#include <errno.h>
-
#include <unistd.h>
-
#include <string>
-
#include <sstream>
-
#include <cstdio>
-
#ifdef __cplusplus
-
extern "C" {
-
#endif
-
#include <iniparser.h>
-
#ifdef __cplusplus
-
}
-
#endif
-
-
#define TOSTR(str) (char*)#str
-
#define CONFIG_GET_PROPERTY_BOOLEAN(property) property=getBoolean(TOSTR(property), property)
-
#define CONFIG_SET_PROPERTY_BOOLEAN(property) setBoolean(TOSTR(property), property)
-
#define CONFIG_GET_PROPERTY_INT(property) property=getInt(TOSTR(property), property)
-
#define CONFIG_SET_PROPERTY_INT(property) setInt(TOSTR(property), property)
-
#define CONFIG_GET_PROPERTY_UINT(property) property=getUInt(TOSTR(property), property)
-
#define CONFIG_SET_PROPERTY_UINT(property) setUInt(TOSTR(property), property)
-
#define CONFIG_GET_PROPERTY_STRING(property) property=getString(TOSTR(property), property.c_str())
-
#define CONFIG_SET_PROPERTY_STRING(property) setString(TOSTR(property), property.c_str())
-
#define CONFIG_GET_PROPERTY_DOUBLE(property) property=getDouble(TOSTR(property), property)
-
#define CONFIG_SET_PROPERTY_DOUBLE(property) setDouble(TOSTR(property), property)
-
using std::string;
-
using std::stringstream;
-
-
/**
-
* ini格式配置文件的读写工具类。。
-
* 该类中的所有方法由ConfigBaseClass对象调用调用。
-
*/
-
class ConfigFileRWUtil
-
{
-
public:
-
ConfigFileRWUtil(const char *configFileName);
-
virtual ~ConfigFileRWUtil();
-
-
public:
-
bool saveConfig();
-
void dumpIniFile() { /* Dump INI file to stdout: debug only*/
-
iniparser_dump(mDictionary, stdout);
-
}
-
-
-
bool init();
-
-
int getSectionNumber() {
-
return iniparser_getnsec(mDictionary);
-
}
-
-
char* getSectionName(int n) {
-
return iniparser_getsecname(mDictionary, n);
-
}
-
-
char* getString(const char *key, const char *defValue) {
-
return iniparser_getstring(mDictionary, (char *)key, (char *)defValue);
-
}
-
-
int getInt(const char *key, int defValue) {
-
return iniparser_getint(mDictionary, (char *)key, defValue);
-
}
-
-
double getDouble(const char *key, double defValue) {
-
return iniparser_getdouble(mDictionary, (char *)key, defValue);
-
}
-
-
bool getBoolean(const char *key, bool defValue) {
-
return (iniparser_getboolean(mDictionary,
-
(char *)key,
-
(defValue ? 1 : 0)) ? true : false);
-
}
-
-
bool setString(const char *entry, const char *value) {
-
return (iniparser_set(mDictionary, (char *)entry, (char *)value)
-
== 0 ? true : false);
-
}
-
-
bool setInt(const char *entry, int value) {
-
char tmpValue[32] = {0};
-
int ret = sprintf(tmpValue, "%d", value);
-
tmpValue[ret] = '\0';
-
return setString(entry, tmpValue);
-
}
-
-
bool setUint(const char *entry, int value) {
-
char tmpValue[32] = {0};
-
int ret = sprintf(tmpValue, "%u", value);
-
tmpValue[ret] = '\0';
-
return setString(entry, tmpValue);
-
}
-
-
bool setDouble(const char *entry, double value) {
-
char tmpValue[32] = {0};
-
int ret = sprintf(tmpValue, "%f", value);
-
tmpValue[ret] = '\0';
-
return setString(entry, tmpValue);
-
}
-
-
void deleteEntry(char *entry) {
-
iniparser_unset(mDictionary, entry);
-
}
-
-
protected:
-
char *mConfigFile;
-
dictionary *mDictionary;
-
};
-
-
/**
-
* ConfigBaseClass类
-
* 实现ini配置文件和class的相互转换。
-
* 需要存取ini配置文件的类需要继承ConfigBaseClass,然后重写下面两个虚函数
-
* virtual bool loadConfigDetail() = 0;
-
* virtual bool saveConfigDetail() = 0;
-
* 例子:
-
*
-
#include "ConfigBaseClass.h"
-
#define CONFIG_EVENT_FILENAME "/mnt/config/test.conf"
-
#define TEST_ARR_SIZE 2
-
-
typedef enum{
-
ENMU1,
-
ENMU2
-
}TestEnum;
-
-
class Test1: public ConfigBaseClass
-
{
-
public:
-
uint8_t numMember;
-
string stringMember;
-
bool boolMember;
-
TestEnum enumMember;
-
uint8_t arrMember[TEST_ARR_SIZE][TEST_ARR_SIZE];
-
-
public:
-
Test1()
-
:numMember(0),boolMember(0),enumMember(ENMU1){
-
-
}
-
virtual ~Test1(){
-
-
}
-
virtual bool loadConfigDetail(){
-
CONFIG_GET_PROPERTY_UINT(numMember);
-
CONFIG_GET_PROPERTY_STRING(stringMember);
-
CONFIG_GET_PROPERTY_BOOLEAN(boolMember);
-
//
-
enumMember=(TestEnum)getUInt(TOSTR(enumMember), enumMember);
-
-
char str[32] = {0};
-
int i=0,j=0;
-
for(i=0; i<TEST_ARR_SIZE; i++){
-
for(j=0; j<TEST_ARR_SIZE; j++) {
-
memset(str, 0, 32);//数据元素,需要自己根据下表生成对应的属性名
-
sprintf(str, "arrMember_%u_%u", i, j);
-
arrMember[i][j]=getUInt(str, 0);
-
}
-
}
-
return true;
-
}
-
-
virtual bool saveConfigDetail(){
-
CONFIG_SET_PROPERTY_UINT(numMember);
-
CONFIG_SET_PROPERTY_STRING(stringMember);
-
CONFIG_SET_PROPERTY_BOOLEAN(boolMember);
-
CONFIG_SET_PROPERTY_UINT(enumMember);
-
-
char str[32] = {0};
-
int i=0,j=0;
-
for(i=0; i<TEST_ARR_SIZE; i++){
-
for(j=0; j<TEST_ARR_SIZE; j++) {
-
memset(str, 0, 32);//数据元素,需要自己根据下表生成对应的属性名
-
sprintf(str, "arrMember_%u_%u", i, j);
-
setUInt(str, arrMember[i][j]);
-
}
-
}
-
return true;
-
}
-
} ;
-
-
class Test: public ConfigBaseClass
-
{
-
public:
-
-
Test1 structMember;
-
Test1 structArr[TEST_ARR_SIZE];
-
-
public:
-
Test(){
-
-
}
-
virtual ~Test(){
-
-
}
-
-
virtual bool loadConfigDetail(){
-
structMember.loadConfig(configRWUtil, sectionName, TOSTR(structMember));
-
for(int i=0;i<TEST_ARR_SIZE;i++){
-
structArr[i].loadConfig(configRWUtil, sectionName, TOSTR(structArr), false, i);
-
}
-
return true;
-
}
-
-
virtual bool saveConfigDetail(){
-
structMember.saveConfig();
-
for(int i=0;i<TEST_ARR_SIZE;i++){
-
structArr[i].saveConfig();
-
}
-
return true;
-
}
-
} ;
-
-
-
int main() {
-
ConfigFileRWUtil* fileRWUtil = new ConfigFileRWUtil(CONFIG_EVENT_FILENAME);
-
Test test;
-
test.loadConfig(fileRWUtil, "", TOSTR(test), true);
-
-
printf("%s, %d \n", test.structMember.stringMember.c_str(), test.structArr[0].numMember);
-
test.structMember.stringMember="abcd";
-
test.structArr[0].numMember=123;
-
test.saveConfig();
-
return 0;
-
}
-
* }
-
*/
-
-
class ConfigBaseClass {
-
public:
-
ConfigBaseClass();
-
virtual ~ConfigBaseClass();
-
-
/**
-
* 从ini配置文件中加载数据
-
* 参数configRWUtil, ini文件的读写类。
-
* 参数parentSectionName,如果是最顶层配置类,使用空字符串,如果是属性配置类,填父亲配置类的sectionName。
-
* 参数mySectionName, 当前配置类的sectionName
-
* 参数isRootConfigClass 是否是根配置类。默认值 不是。
-
* 参数index 如果是数组元素,标识数组下表。如果不是 -1. 默认值 -1
-
*/
-
bool loadConfig(ConfigFileRWUtil *configRWUtil, string parentSectionName, string mySectionName, bool isRootConfigClass=false, int index=-1);
-
-
bool saveConfig();
-
-
string getString(char* propertyName, const char *defValue) {
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
-
return defValue;
-
}
-
return configRWUtil->getString(orginagekey(propertyName).c_str(), defValue);
-
}
-
-
int getInt(char* propertyName, int defValue) {
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
-
return defValue;
-
}
-
return configRWUtil->getInt(orginagekey(propertyName).c_str(),defValue);
-
}
-
-
double getDouble(char* propertyName, double defValue) {
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
-
return defValue;
-
}
-
return configRWUtil->getDouble(orginagekey(propertyName).c_str(),defValue);
-
}
-
-
int getUInt(char* propertyName, int defValue) {
-
return getInt(propertyName, defValue);
-
}
-
-
bool getBoolean(char* propertyName, bool defValue) {
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
-
return false;
-
}
-
return configRWUtil->getBoolean(orginagekey(propertyName).c_str(),defValue);
-
}
-
-
bool setString(char* propertyName, const char *value) {
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
-
return false;
-
}
-
return configRWUtil->setString(orginagekey(propertyName).c_str(),value);
-
}
-
-
-
bool setInt(char* propertyName, int value) {
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
-
return false;
-
}
-
return configRWUtil->setInt(orginagekey(propertyName).c_str(),value);
-
}
-
-
bool setBoolean(char* propertyName, bool value) {
-
return setInt(propertyName, value);
-
}
-
-
bool setUInt(char* propertyName, int value) {
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
-
return false;
-
}
-
return configRWUtil->setUint(orginagekey(propertyName).c_str(), value);
-
}
-
int setDouble(char* propertyName, double value) {
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
-
return value;
-
}
-
return configRWUtil->setDouble(orginagekey(propertyName).c_str(), value);
-
}
-
-
protected:
-
virtual bool loadConfigDetail() = 0;
-
virtual bool saveConfigDetail() = 0;
-
-
-
private:
-
string orginagekey(char* property) {
-
stringstream str1;
-
str1 << sectionName<<":"<<property;
-
return str1.str();
-
};
-
bool setSection() {
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
-
return false;
-
}else {
-
// fprintf(stderr,"setSection! %s\n", sectionName.c_str());
-
}
-
return configRWUtil->setString(sectionName.c_str(),"");
-
}
-
-
protected:
-
ConfigFileRWUtil *configRWUtil;
-
string sectionName;
-
int index;
-
bool isRootConfigClass;
-
};
-
-
#endif /* CONFIGBASECLASS_H_ */
实现:
-
/*
-
* ConfigBaseClass.cpp
-
*
-
* Created on: Jan 8, 2015
-
* Author: need
-
*/
-
-
#include "ConfigBaseClass.h"
-
/*******************************************************************************
-
* ConfigFileRWUtil
-
******************************************************************************/
-
-
ConfigFileRWUtil::ConfigFileRWUtil(const char *configFileName)
-
: mConfigFile(NULL),
-
mDictionary(NULL)
-
{
-
if (configFileName) {
-
mConfigFile = strdup(configFileName);
-
}
-
}
-
-
ConfigFileRWUtil::~ConfigFileRWUtil()
-
{
-
delete[] mConfigFile;
-
if (mDictionary) {
-
iniparser_freedict(mDictionary);
-
}
-
fprintf(stderr,"~ConfigFileRWUtil \n");
-
}
-
-
bool ConfigFileRWUtil::init()
-
{
-
/* Unload old dictonary everytime to keep config file updated */
-
-
if(access(mConfigFile, R_OK&W_OK)<0) {
-
fprintf(stderr,"%s not exist! create one! \n", mConfigFile);
-
FILE *tmp = fopen(mConfigFile, "a");
-
fclose(tmp);
-
if(tmp == NULL){
-
fprintf(stderr,"%s create error! \n", mConfigFile);
-
return false;
-
}
-
}
-
-
if (mDictionary) {
-
iniparser_freedict(mDictionary);
-
mDictionary = NULL;
-
}
-
mDictionary = iniparser_load(mConfigFile);
-
mDictionary != NULL ? fprintf(stderr,"%s is loaded! \n", mConfigFile) :
-
fprintf(stderr,"Failed loading config file: %s \n", mConfigFile);
-
-
return (mDictionary != NULL);
-
}
-
-
bool ConfigFileRWUtil::saveConfig()
-
{
-
bool ret = false;
-
-
if (mDictionary && mConfigFile) {
-
FILE *filePointer = fopen(mConfigFile, "w+");
-
if (NULL == filePointer) {
-
fprintf(stderr,"%s\n", strerror(errno));
-
} else {
-
iniparser_dump_ini(mDictionary, filePointer);
-
fclose(filePointer);
-
ret = true;
-
}
-
} else {
-
fprintf(stderr,"Please load config file before save it!");
-
}
-
-
return ret;
-
}
-
-
ConfigBaseClass::ConfigBaseClass()
-
:configRWUtil(NULL), index(-1), isRootConfigClass(false){
-
// TODO Auto-generated constructor stub
-
-
}
-
-
ConfigBaseClass::~ConfigBaseClass() {
-
// TODO Auto-generated destructor stub
-
}
-
-
bool ConfigBaseClass::loadConfig(ConfigFileRWUtil *configRWUtil, string parentSectionName, string mySectionName, bool isRootConfigClass, int index) {
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"loadConfig error! configRWUtil is null! \n");
-
return false;
-
}
-
this->configRWUtil = configRWUtil;
-
if(mySectionName.empty()) {
-
fprintf(stderr,"loadConfig error! mySectionName is null! \n");
-
return false;
-
}
-
-
stringstream str1;
-
if(!parentSectionName.empty()){
-
str1<<parentSectionName<<"_";
-
}
-
str1<<mySectionName;
-
if(index>=0){
-
str1 <<"_"<<index;
-
}
-
this->sectionName = str1.str();
-
-
if(!isRootConfigClass || index>0) {
-
this->isRootConfigClass = false;
-
}else{
-
fprintf(stderr,"isRootConfigClass true call configRWUtil->init! %s \n", this->sectionName.c_str());
-
configRWUtil->init();
-
configRWUtil->dumpIniFile();
-
this->isRootConfigClass = true;
-
}
-
this->index = index;
-
return loadConfigDetail();
-
}
-
-
bool ConfigBaseClass::saveConfig() {
-
fprintf(stderr,"%s %d start save config!", sectionName.c_str(), isRootConfigClass);
-
if(configRWUtil == NULL) {
-
fprintf(stderr,"Please loadConfig before use it! %s", __FUNCTION__);
-
return false;
-
}
-
setSection();
-
saveConfigDetail();
-
if(isRootConfigClass) {
-
// fprintf(stderr,"isRootConfigClass true saveConfig! \n");
-
configRWUtil->saveConfig();
-
}else {
-
// fprintf(stderr,fprintf(stderr,"isRootConfigClass false! \n");
-
}
-
return true;
-
}
三、使用
-
#include "ConfigBaseClass.h"
-
-
#define CONFIG_FILENAME "/home/hisi/nfs/config_filename.ini"
-
-
class SubProfile:public ConfigBaseClass{
-
public:
-
int test1;
-
SubProfile(){}
-
virtual ~SubProfile(){}
-
-
virtual bool loadConfigDetail(){
-
CONFIG_GET_PROPERTY_INT(test1);
-
return true;
-
}
-
virtual bool saveConfigDetail(){
-
CONFIG_SET_PROPERTY_INT(test1);
-
return true;
-
}
-
SubProfile &operator=(const SubProfile &subprofile) {
-
test1 = subprofile.test1;
-
return *this;
-
}
-
};
-
-
class Profile:public ConfigBaseClass{
-
public:
-
int test1;
-
char test2;
-
bool test3;
-
std::string test4;
-
SubProfile test5;
-
-
public:
-
Profile(){}
-
virtual ~Profile(){}
-
-
virtual bool loadConfigDetail(){
-
CONFIG_GET_PROPERTY_INT(test1);
-
CONFIG_GET_PROPERTY_UINT(test2);
-
CONFIG_GET_PROPERTY_BOOLEAN(test3);
-
CONFIG_GET_PROPERTY_STRING(test4);
-
test5.loadConfig(configRWUtil, sectionName, TOSTR(test5));
-
return true;
-
}
-
virtual bool saveConfigDetail(){
-
CONFIG_SET_PROPERTY_INT(test1);
-
CONFIG_SET_PROPERTY_UINT(test2);
-
CONFIG_SET_PROPERTY_BOOLEAN(test3);
-
CONFIG_SET_PROPERTY_STRING(test4);
-
test5.saveConfig();
-
return true;
-
}
-
Profile &operator=(const Profile &profile) {
-
test1 = profile.test1;
-
test2 = profile.test2;
-
test3 = profile.test3;
-
test4 = profile.test4;
-
test5 = profile.test5;
-
return *this;
-
}
-
};
-
-
int main(int argc, char* argv[])
-
{
-
//
-
ConfigFileRWUtil* ConfigRWUtil = new ConfigFileRWUtil(CONFIG_FILENAME);
-
-
Profile prifile;
-
prifile.test1 = 1;
-
prifile.test2 = 'c';
-
prifile.test3 = false;
-
prifile.test4 = "test4";
-
prifile.test5.test1 = 4;
-
-
prifile.loadConfig(ConfigRWUtil, "", TOSTR(prifile), true);
-
prifile.saveConfig();
-
-
if(ConfigRWUtil != NULL){
-
delete ConfigRWUtil;
-
ConfigRWUtil = NULL;
-
}
-
return 0;
-
}
在包含字符串的情况下,本例使用的是std:string!
本文所有:Devile May Cry J QQ:384668960
阅读(982) | 评论(0) | 转发(0) |