/* inifile.cpp Copyright (C) 2007 Acekard, www.acekard.com Copyright (C) 2007-2009 somebody Copyright (C) 2009 yellow wood goblin This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "inifile.h" #include "stringtool.h" static bool freadLine(FILE* f,std::string& str) { str.clear(); __read: char p=0; size_t readed=fread(&p,1,1,f); if(0==readed) { str=""; return false; } if('\n'==p||'\r'==p) { str=""; return true; } while(p!='\n'&&p!='\r'&&readed) { str+=p; readed=fread(&p,1,1,f); } if(str.empty()||""==str) { goto __read; } return true; } static void trimString(std::string& str) { size_t first=str.find_first_not_of(" \t"),last; if(first==str.npos) { str=""; } else { last=str.find_last_not_of(" \t"); if(first>0||(last+1)0) { m_FileContainer.clear(); } } void CIniFile::SetString(const std::string& Section,const std::string& Item,const std::string& Value) { if(GetFileString(Section,Item)!=Value) { SetFileString(Section,Item,Value); m_bModified=true; } } void CIniFile::SetInt(const std::string& Section,const std::string& Item,int Value) { std::string strtemp=formatString("%d",Value); if(GetFileString(Section,Item)!=strtemp) { SetFileString(Section,Item,strtemp); m_bModified=true; } } std::string CIniFile::GetString(const std::string& Section,const std::string& Item) { return GetFileString(Section,Item); } std::string CIniFile::GetString(const std::string& Section,const std::string& Item,const std::string& DefaultValue) { std::string temp=GetString(Section,Item); if(!m_bLastResult) { SetString(Section,Item,DefaultValue); temp=DefaultValue; } return temp; } void CIniFile::GetStringVector(const std::string& Section,const std::string& Item,std::vector< std::string >& strings,char delimiter) { std::string strValue=GetFileString(Section,Item); strings.clear(); size_t pos; while((pos=strValue.find(delimiter),strValue.npos!=pos)) { const std::string string=strValue.substr(0,pos); if(string.length()) { strings.push_back(string); } strValue=strValue.substr(pos+1,strValue.npos); } if(strValue.length()) { strings.push_back(strValue); } } void CIniFile::SetStringVector(const std::string& Section,const std::string& Item,std::vector& strings,char delimiter) { std::string strValue; for(size_t ii=0;ii2&&'0'==value[0]&&('x'==value[1]||'X'==value[1])) return strtol(value.c_str(),NULL,16); else return strtol(value.c_str(),NULL,10); } int CIniFile::GetInt(const std::string& Section,const std::string& Item,int DefaultValue) { int temp; temp=GetInt(Section,Item); if(!m_bLastResult) { SetInt(Section,Item,DefaultValue); temp=DefaultValue; } return temp; } bool CIniFile::LoadIniFile(const std::string& FileName) { //dbg_printf("load %s\n",FileName.c_str()); if(FileName!="") m_sFileName=FileName; FILE* f=fopen(FileName.c_str(),"rb"); if(NULL==f) return false; //check for utf8 bom. char bom[3]; if(fread(bom,3,1,f)==1&&bom[0]==0xef&&bom[1]==0xbb&&bom[2]==0xbf) ; else fseek(f,0,SEEK_SET); std::string strline(""); m_FileContainer.clear(); while(freadLine(f,strline)) { trimString(strline); if(strline!=""&&';'!=strline[0]&&'/'!=strline[0]&&'!'!=strline[0]) m_FileContainer.push_back(strline); } fclose(f); m_bLastResult=false; m_bModified=false; return true; } bool CIniFile::SaveIniFileModified(const std::string& FileName) { if(m_bModified==true) { return SaveIniFile(FileName); } return true; } bool CIniFile::SaveIniFile(const std::string& FileName) { if(FileName!="") m_sFileName=FileName; FILE* f=fopen(m_sFileName.c_str(),"wb"); if(NULL==f) { return false; } for(size_t ii=0;ii0) { if(!m_FileContainer[ii-1].empty()&&m_FileContainer[ii-1]!="") fwrite("\r\n",1,2,f); } if(!strline.empty()&&strline!="") { fwrite(strline.c_str(),1,strline.length(),f); fwrite("\r\n",1,2,f); } } fclose(f); m_bModified=false; return true; } std::string CIniFile::GetFileString(const std::string& Section,const std::string& Item) { std::string strline; std::string strSection; std::string strItem; std::string strValue; size_t ii=0; size_t iFileLines=m_FileContainer.size(); if(m_bReadOnly) { cSectionCache::iterator it=m_Cache.find(Section); if((it!=m_Cache.end())) ii=it->second; } m_bLastResult=false; if(iFileLines>=0) { while(ii0&&rBracketPos!=std::string::npos) { strSection=strline.substr(1,rBracketPos-1); if(m_bReadOnly) m_Cache.insert(std::make_pair(strSection,ii-1)); if(strSection==Section) { while(ii0&&rBracketPos!=std::string::npos) { strSection=strline.substr(1,rBracketPos-1); if(strSection==Section) { while(ii