/********************************************************************
created: 2008/07/28
filename: config.h
author: Lichuang
purpose: 封装读取ini格式的配置文件操作
*********************************************************************/
#include "config.h"
#include "comdef.h"
#include <stdio.h>
#include <iostream>
CConfig::CConfig()
{
}
CConfig::CConfig(const char* pFile)
: m_strFileName(pFile)
{
}
CConfig::CConfig(const string& strFile)
: m_strFileName(strFile)
{
}
CConfig::~CConfig()
{
}
int CConfig::Init(const char* pFileName)
{
m_strFileName = pFileName;
return LoadFile();
}
int CConfig::Init(const string& strFileName)
{
m_strFileName = strFileName;
return LoadFile();
}
int CConfig::Init()
{
return LoadFile();
}
int CConfig::Dump()
{
map<string, ConfigType>::iterator tSecIter1 = m_mSec2Config.begin(), tSecIter2 = m_mSec2Config.end();
ConfigType::iterator tConfigTypeIter1, tConfigTypeIter2;
while (tSecIter1 != tSecIter2)
{
cout << "[" << tSecIter1->first << "]" << endl;
tConfigTypeIter1 = tSecIter1->second.begin(), tConfigTypeIter2 = tSecIter1->second.end();
while (tConfigTypeIter1 != tConfigTypeIter2)
{
cout << tConfigTypeIter1->first << "=" << tConfigTypeIter1->second << endl;
++tConfigTypeIter1;
}
cout << endl;
++tSecIter1;
}
return 0;
}
int CConfig::ReadItem(const string& strSection, const string& strKey, string& strValue)
{
if (!m_mSec2Config.count(strSection))
{
return -1;
}
ConfigType& tConfigType = m_mSec2Config[strSection];
strValue = tConfigType[strKey];
return (strValue.empty()) ? -1 : 0;
}
int CConfig::WriteItem(const string& strSection, const string& strKey, const string& strValue)
{
ConfigType& tConfigType = m_mSec2Config[strSection];
if (tConfigType.count(strKey))
{
return -1;
}
tConfigType[strKey] = strValue;
return WriteFile();
}
int CConfig::LoadFile()
{
FILE* pFile;
if (NULL == (pFile = ::fopen(m_strFileName.c_str(), "r")))
{
return -1;
}
string strLine, strSection;
string strKey, strValue;
size_t nPos, nEndPos;
ConfigType tConfigType;
while (0 == ReadLine(pFile, strLine))
{
if (string::npos != (nPos = strLine.find_first_of("[")))
{
if (string::npos == (nEndPos = strLine.find_first_of("]")))
{
::fclose(pFile);
return -1;
}
strSection = strLine.substr(nPos + 1, nEndPos - nPos - 1);
if (0 > TrimString(strSection))
{
::fclose(pFile);
return -1;
}
}
else if (string::npos != (nPos = strLine.find_first_of("=")))
{
strKey = strLine.substr(0, nPos);
strValue = strLine.substr(nPos + 1);
if (0 > TrimString(strKey) || 0 > TrimString(strValue) || strSection.empty())
{
::fclose(pFile);
return -1;
}
m_mSec2Config[strSection][strKey] = strValue;
}
}
return ::fclose(pFile);
}
int CConfig::WriteFile()
{
FILE* pFile;
if (NULL == (pFile = ::fopen(m_strFileName.c_str(), "w")))
{
return -1;
}
map<string, ConfigType>::iterator tSecIter1 = m_mSec2Config.begin(), tSecIter2 = m_mSec2Config.end();
ConfigType::iterator tConfigTypeIter1, tConfigTypeIter2;
string strSection, strConfig;
while (tSecIter1 != tSecIter2)
{
strSection = string("[") + tSecIter1->first + string("]\n");
::fwrite(strSection.c_str(), sizeof(char), strSection.length(), pFile);
tConfigTypeIter1 = tSecIter1->second.begin(), tConfigTypeIter2 = tSecIter1->second.end();
while (tConfigTypeIter1 != tConfigTypeIter2)
{
strConfig = tConfigTypeIter1->first + string("=") + tConfigTypeIter1->second + string("\n");
::fwrite(strConfig.c_str(), sizeof(char), strConfig.length(), pFile);
++tConfigTypeIter1;
}
::fwrite("\n", sizeof(char), 1, pFile);
++tSecIter1;
}
return ::fclose(pFile);
}
int CConfig::ReadLine(FILE* pFile, string& strLine)
{
char szBuff[BUFFER_LEN];
int nLen;
do
{
if (NULL == ::fgets(szBuff, BUFFER_LEN, pFile))
{
return -1;
}
if (0 < (nLen = ::strlen(szBuff)))
{
break;
}
} while (true);
szBuff[nLen - 1] = '\0';
strLine = szBuff;
return 0;
}
int CConfig::TrimString(string& strToken)
{
if (strToken.empty())
{
return -1;
}
size_t nPos = strToken.find_first_not_of(" \t");
size_t nEndPos = strToken.find_last_not_of(" \t");
strToken = strToken.substr(nPos, nEndPos - nPos + 1);
return (strToken.empty()) ? -1 : 0;
}
//实现主要采用STL, 实现了ini格式文件的读,写,已经打印文件信息等功能,暂时觉得这些功能已经够用了,以后有需要再进行添加.应该还少了一个宏BUFFER_LEN的定义,这个宏在一个公用的头文件//中定义,如果你想试用这个类,可以自行进行定义,我默认定义为1024字节大小.