linux ini文件写入,内存解析Ini文件(Linux解析解析ini文件)

#include "IniMemory.h"

#include "IniMemoryPrivate.h"

#include

#include

#include

#include

IniMemory::IniMemory():my(new IniMemoryPrivate(this))

{

strIniBuffer = nullptr;

my->listSection.clear();

}

IniMemory::IniMemory(char* strIni): my(new IniMemoryPrivate(this)), strIniBuffer(nullptr)

{

//将最后一个字符设置为换行

strIniBuffer = strIni;

//初始化失败,直接异常中断处理

if(!ReProcessIni()){

delete my;

my = nullptr;

throw "初始化失败,请检查ini内容是否合法。";

}

}

IniMemory::IniMemory(IniMemory& iniMemory): my(new IniMemoryPrivate(this)), strIniBuffer(nullptr)

{

//完全拷贝

this->strIniBuffer = iniMemory.strIniBuffer;

my->listSection = iniMemory.my->listSection;

}

IniMemory::~IniMemory()

{

if(my){

delete my;

my = nullptr;

}

}

IniMemory& IniMemory::operator=(char * buffer)

{

//如果空间不够,那么释放空间

if(nullptr == my){

my = new IniMemoryPrivate(this);

}

this->strIniBuffer = buffer;

//初始化失败,直接异常中断处理

if(!ReProcessIni()){

if(strIniBuffer){

strIniBuffer = nullptr;

}

my->listSection.clear();

}

return *this;

}

IniMemory& IniMemory::operator=(const IniMemory& iniMem)

{

if(&iniMem == this){

return *this;

}

if(nullptr == my){

my = new IniMemoryPrivate(this);

}

strIniBuffer = iniMem.strIniBuffer;

my->listSection = iniMem.my->listSection;

return *this;

}

bool IniMemory::SetBuffer(char *strIni)

{

this->strIniBuffer = strIni;

if(nullptr == my){

my = new IniMemoryPrivate(this);

}

//初始化失败,直接异常中断处理

if(!ReProcessIni()){

if(strIniBuffer){

strIniBuffer = nullptr;

}

my->listSection.clear();

}

return true;

}

std::string IniMemory::GetIniString(const std::string &strApp, const std::string &strKey, const std::string &strDefault)

{

if(my->listSection.empty()){

return strDefault;

}

//将strAppName转换成小写

std::string strAppName = strApp;

std::transform(strAppName.begin(), strAppName.end(), strAppName.begin(), ::tolower);

for (auto itIndex = my->listSection.begin(); itIndex != my->listSection.end(); itIndex++){

if(strAppName == itIndex->strSectionName){//找到了这个段

//继续查找属性

std::string strKeyName = strKey;

std::transform(strKeyName.begin(), strKeyName.end(), strKeyName.begin(), ::tolower);

for (auto itSubIndex = itIndex->listVarPair.begin(); itSubIndex != itIndex->listVarPair.end(); itSubIndex++){

//如果找到了这个属性,那么返回对应的值

if(strKeyName == itSubIndex->first){

return itSubIndex->second;

}

}

}

}

//如果没有找到对应的属性,那么直接返回默认值

return strDefault;

}

int IniMemory::GetIniInt(const std::string &strApp, const std::string &strKey, const int &nDefault)

{

if(my->listSection.empty()){

return nDefault;

}

//将strAppName转换成小写

std::string strAppName = strApp;

std::transform(strAppName.begin(), strAppName.end(), strAppName.begin(), ::tolower);

for (auto itIndex = my->listSection.begin(); itIndex != my->listSection.end(); itIndex++){

if(strAppName == itIndex->strSectionName){//找到了这个段

//继续查找属性

std::string strKeyName = strKey;

std::transform(strKeyName.begin(), strKeyName.end(), strKeyName.begin(), ::tolower);

for (auto itSubIndex = itIndex->listVarPair.begin(); itSubIndex != itIndex->listVarPair.end(); itSubIndex++){

//如果找到了这个属性,那么返回对应的值,将这个值转换成int类型返回

if(strKeyName == itSubIndex->first){

return ::atoi(itSubIndex->second.c_str());

}

}

}

}

//如果没有找到对应的属性,那么直接返回默认值

return nDefault;

}

bool IniMemory::WriteIniString(const std::string &strApp, const std::string &strKey, const std::string &strString)

{

//将strAppName转换成小写

std::string strAppName = strApp;

std::transform(strAppName.begin(), strAppName.end(), strAppName.begin(), ::tolower);

for (auto itIndex = my->listSection.begin(); itIndex != my->listSection.end(); itIndex++){

if(strAppName == itIndex->strSectionName){//找到了这个段

//继续查找属性

std::string strKeyName = strKey;

std::transform(strKeyName.begin(), strKeyName.end(), strKeyName.begin(), ::tolower);

for (auto itSubIndex = itIndex->listVarPair.begin(); itSubIndex != itIndex->listVarPair.end(); itSubIndex++){

//如果找到了这个属性,那么返回对应的值,将这个值转换成int类型返回

if(strKeyName == itSubIndex->first){

itSubIndex->second = strString;

//刷新缓冲区数据

return true;

}

}

itIndex->listVarPair.push_back(std::make_pair(std::string(strKeyName),std::string(strString)));

return true;

}

}

//插入一个新的段

IniMemoryPrivate::stSection section;

section.strSectionName = strApp;

my->listSection.push_back(section);

my->listSection.rbegin()->listVarPair.push_back(std::make_pair(std::string(strKey),std::string(strString)));

return true;

//如果没有找到对应的属性,那么直接返回默认值

}

bool IniMemory::WriteIniStringToNewBuffer(char *newBuffer, size_t nBufferSize, const std::string &strApp, const std::string &strKey, const std::string &strString)

{

//将strAppName转换成小写

std::string strAppName = strApp;

std::transform(strAppName.begin(), strAppName.end(), strAppName.begin(), ::tolower);

for (auto itIndex = my->listSection.begin(); itIndex != my->listSection.end(); itIndex++){

if(strAppName == itIndex->strSectionName){//找到了这个段

//继续查找属性

std::string strKeyName = strKey;

std::transform(strKeyName.begin(), strKeyName.end(), strKeyName.begin(), ::tolower);

for (auto itSubIndex = itIndex->listVarPair.begin(); itSubIndex != itIndex->listVarPair.end(); itSubIndex++){

//如果找到了这个属性,那么返回对应的值,将这个值转换成int类型返回

if(strKeyName == itSubIndex->first){

//保存这个值

std::string strTmp = itSubIndex->second;

//设置值

itSubIndex->second = strString;

//刷新缓冲区数据

bool bRes = FlushBuffer(newBuffer, nBufferSize);

//还原值

itSubIndex->second = strTmp;

return bRes;

}

}

itIndex->listVarPair.push_back(std::make_pair(std::string(strKeyName),std::string(strString)));

bool bRes = FlushBuffer(newBuffer, nBufferSize);

itIndex->listVarPair.pop_back();

return bRes;

}

}

//没有找到对应的段

IniMemoryPrivate::stSection section;

section.strSectionName = strApp;

my->listSection.push_back(section);

my->listSection.rbegin()->listVarPair.push_back(std::make_pair(std::string(strKey),std::string(strString)));

bool bRes = FlushBuffer(newBuffer, nBufferSize);

my->listSection.pop_back();

return bRes;

}

bool IniMemory::GetIniSection(std::list &strReturnedString)

{

if(my->listSection.empty()){

return false;

}

for (auto itIndex = my->listSection.begin(); itIndex != my->listSection.end(); itIndex++){

strReturnedString.push_back(itIndex->strSectionName);

}

return true;

}

bool IniMemory::GetIniSectionProperties(const std::string &strApp, std::list &strReturnedStringList)

{

if(my->listSection.empty()){

return false;

}

//查找这个块,找到了就将这个块里所有的变量全部放到这list里面

//将strAppName转换成小写

std::string strAppName = strApp;

std::transform(strAppName.begin(), strAppName.end(), strAppName.begin(), ::tolower);

for (auto itIndex = my->listSection.begin(); itIndex != my->listSection.end(); itIndex++){

if(strAppName == itIndex->strSectionName){//找到了这个段

for (auto itSubIndex = itIndex->listVarPair.begin(); itSubIndex != itIndex->listVarPair.end(); itSubIndex++){

//将所有属性放入list中

strReturnedStringList.push_back(itSubIndex->first);

}

return true;

}

}

//没有找到这个块

return false;

}

//重新解析

bool IniMemory::ReProcessIni()

{

if(nullptr == strIniBuffer){

return false;

}

my->listSection.clear();

char tmpBuffer[4096];

char* pEnd;

pEnd = strIniBuffer;

int n = 0;

while (*pEnd || 0 != n){

if('\n' == *pEnd || (0 != n && !(*pEnd))){

tmpBuffer[n] = '\0';

//获得了一行的内容,处理这一行

//判断是不是一个空行,注释行,是的话直接跳过

char* pBufferStart = tmpBuffer;

char* pBufferEnd =tmpBuffer + n - 1;

//处理前面的空格

while (' ' == *pBufferStart || '\t' == *pBufferStart){

pBufferStart++;

}

//处理末尾的空格符号

while (' ' == *pBufferEnd || '\r' == *pBufferEnd || '\t' == *pBufferEnd){

*pBufferEnd-- = '\0';

}

//如果是注释行,或者空行,那么直接跳过,处理下一行

if(';' == *pBufferStart || 0 == strlen(pBufferStart)){

;

}else if('[' == *pBufferStart){

pBufferStart++;

char* pos;

//判断是不是段名

//回这里如果找不到配对的],那么直接返false

if((pos = strchr(pBufferStart, ']'))){

char* check = pos+1;

*pos-- = '\0';

//这里我再处理一下空格

while (' ' == *pBufferStart || '\t' == *pBufferStart){

pBufferStart++;

}

while (' ' == *pos || '\t' == *pos){

*pos-- = '\0';

}

if(0 != strlen(pBufferStart)){

//将段名转换成小写

do{

*pos = tolower((int)*pos);

}while (pos-- != pBufferStart);

//得到了一个段名,那么申请一个新的stSection节点,将段名放入

IniMemoryPrivate::stSection section;

section.strSectionName = pBufferStart;

my->listSection.push_back(section);

}

//检查是不是合法的段名

while('\0' != *check){

if(';' == *check){

break;

}

if(' ' != *check && '\t' != *check){

my->listSection.clear();

strIniBuffer = nullptr;

return false;

}

check++;

}

}else{

strIniBuffer = nullptr;

return false;

}

}else{

//否则判断这一行是不是属性

char* pos = nullptr;

if((pos = strchr(pBufferStart, '='))){

//如果是一个变量,那么将该变量放入最后一个段的那个节点的list对中

char* pVarEnd = pos;

pVarEnd--;

//这里只需要把后面的空格去掉,因为前面的空格已经在最开始清除掉了

while (' ' == *pVarEnd || '\t' == *pVarEnd){

*pVarEnd-- = '\0';

}

//将变量名转换成小写

while (pVarEnd != pBufferStart){

*pVarEnd = ::tolower(*pVarEnd);

pVarEnd--;

}

*pVarEnd = ::tolower(*pVarEnd);

*pos++ = '\0';

while (' ' == *pos || '\t' == *pos){

pos++;

}

char* pSubPos = nullptr;

//注释忽略

if((pSubPos = strchr(pos, ';'))){

*pSubPos-- = '\0';

}

while (pSubPos && (' ' == *pSubPos || '\t' == *pSubPos)){

*pSubPos-- = '\0';

}

//设置如果变量名不空,那么放入

if(0 != strlen(pBufferStart)){

//全局的属性

if(0 == my->listSection.size()){

IniMemoryPrivate::stSection section;

section.strSectionName = "";

my->listSection.push_back(section);

}

//将该对值放入list中

my->listSection.rbegin()->listVarPair.push_back(std::make_pair(pBufferStart,pos));

}

}else{//说明不是段名,不是属性,也不是注释,那么要他干嘛,终止解析,game over

strIniBuffer = nullptr;

return false;

}

}

n = 0;

if('\n' == *pEnd){

pEnd++;

}

continue;

}else{

tmpBuffer[n] = *pEnd;

}

n++;

pEnd++;

}

strIniBuffer = nullptr;

return true;

}

size_t IniMemory::BufferSize()

{

//返回Buffer需要的大小

return my->CountNeedBuffer();

}

//将所有内容输出到新的缓冲区中

bool IniMemory::WriteToNewBuffer(char* NewBuffer, size_t nBufferSize)

{

return FlushBuffer(NewBuffer, nBufferSize);

}

//输出到新的缓冲区

bool IniMemory::FlushBuffer(char * newBuffer, size_t nBufferSize)

{

if(nullptr == newBuffer){

return false;

}

size_t Buffersize = my->CountNeedBuffer();

if(nBufferSize < Buffersize){

return false;

}

char* pBufferEnd = newBuffer;

//不去管内存大小够不够,这个问题留给外面去考虑,我只管复制

for (auto itIndex = my->listSection.begin(); itIndex != my->listSection.end(); itIndex++){

if(itIndex != my->listSection.begin() || "" != itIndex ->strSectionName){

*pBufferEnd++ = '[';

strcpy(pBufferEnd, itIndex->strSectionName.c_str());

pBufferEnd += strlen(pBufferEnd);

*pBufferEnd++ = ']';

*pBufferEnd++ = '\n';

}

//添加本段中的所有属性到配置文件中

for (auto itSubIndex = itIndex->listVarPair.begin(); itSubIndex != itIndex->listVarPair.end(); itSubIndex++){

//把变量名复制到相应位置

strcpy(pBufferEnd, itSubIndex->first.c_str());

pBufferEnd += strlen(pBufferEnd);

*pBufferEnd++ = '=';

strcpy(pBufferEnd, itSubIndex->second.c_str());

pBufferEnd += strlen(pBufferEnd);

*pBufferEnd++ = '\n';

}

}

*pBufferEnd = '\0';

return true;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值