diff options
author | edo9300 | 2019-02-13 23:32:22 +0100 |
---|---|---|
committer | edo9300 | 2019-02-13 23:32:22 +0100 |
commit | 7a0dc2ef4b8c70c75ee258057539941296dbe062 (patch) | |
tree | 8aac8a1907b78166517dbdb4026504b4da00e0a6 | |
parent | 82eda30cfd49a850da43ad7cd3806514f51db49d (diff) |
Create new ini handling class using cpp stuff
-rw-r--r-- | arm9/source/inifile.cpp | 343 | ||||
-rw-r--r-- | arm9/source/inifile.h | 68 | ||||
-rw-r--r-- | arm9/source/inihandler.cpp | 97 | ||||
-rw-r--r-- | arm9/source/inihandler.h | 78 | ||||
-rw-r--r-- | arm9/source/main.cpp | 20 |
5 files changed, 185 insertions, 421 deletions
diff --git a/arm9/source/inifile.cpp b/arm9/source/inifile.cpp deleted file mode 100644 index c806ba3..0000000 --- a/arm9/source/inifile.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/>. -*/ - -#include <cstdio> -#include <cstdlib> -#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) < str.length()) str = str.substr(first, last - first + 1); - } -} - -CIniFile::CIniFile() { - m_bLastResult = false; - m_bModified = false; - m_bReadOnly = false; -} - -CIniFile::CIniFile(const std::string& filename) { - m_sFileName = filename; - m_bLastResult = false; - m_bModified = false; - m_bReadOnly = false; - m_bHasHandle = false; - LoadIniFile(m_sFileName); -} - -CIniFile::~CIniFile() { - if(m_FileContainer.size() > 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<std::string>& strings, char delimiter) { - std::string strValue; - for(size_t ii = 0; ii < strings.size(); ++ii) { - if(ii) strValue += delimiter; - strValue += strings[ii]; - } - SetString(Section, Item, strValue); -} - -/*int CIniFile::GetInt(const std::string& Section,const std::string& Item) -{ - std::string value=GetFileString(Section,Item); - if(value.size()>2&&'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; - - m_bHasHandle = true; - - //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::HasFileHandle() { - return m_bHasHandle; -} - -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; ii < m_FileContainer.size(); ii++) { - std::string& strline = m_FileContainer[ii]; - size_t notSpace = strline.find_first_not_of(' '); - strline = strline.substr(notSpace); - if(strline.find('[') == 0 && ii > 0) { - 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(ii < iFileLines) { - strline = m_FileContainer[ii++]; - - size_t rBracketPos = 0; - if('[' == strline[0]) rBracketPos = strline.find(']'); - if(rBracketPos > 0 && 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(ii < iFileLines) { - strline = m_FileContainer[ii++]; - size_t equalsignPos = strline.find('='); - if(equalsignPos != strline.npos) { - size_t last = equalsignPos ? strline.find_last_not_of(" \t", equalsignPos - 1) : strline.npos; - if(last == strline.npos) strItem = ""; - else strItem = strline.substr(0, last + 1); - - if(strItem == Item) { - size_t first = strline.find_first_not_of(" \t", equalsignPos + 1); - if(first == strline.npos) strValue = ""; - else strValue = strline.substr(first); - m_bLastResult = true; - return strValue; - } - } else if('[' == strline[0]) { - break; - } - } - break; - } - } - } - } - return std::string(""); -} - -void CIniFile::SetFileString(const std::string& Section, const std::string& Item, const std::string& Value) { - std::string strline; - std::string strSection; - std::string strItem; - - if(m_bReadOnly) return; - - size_t ii = 0; - size_t iFileLines = m_FileContainer.size(); - - while(ii < iFileLines) { - strline = m_FileContainer[ii++]; - - size_t rBracketPos = 0; - if('[' == strline[0]) rBracketPos = strline.find(']'); - if(rBracketPos > 0 && rBracketPos != std::string::npos) { - strSection = strline.substr(1, rBracketPos - 1); - if(strSection == Section) { - while(ii < iFileLines) { - strline = m_FileContainer[ii++]; - size_t equalsignPos = strline.find('='); - if(equalsignPos != strline.npos) { - size_t last = equalsignPos ? strline.find_last_not_of(" \t", equalsignPos - 1) : strline.npos; - if(last == strline.npos) strItem = ""; - else strItem = strline.substr(0, last + 1); - - if(Item == strItem) { - ReplaceLine(ii - 1, Item + " = " + Value); - return; - } - } else if('[' == strline[0]) { - InsertLine(ii - 1, Item + " = " + Value); - return; - } - } - InsertLine(ii, Item + " = " + Value); - return; - } - } - } - - InsertLine(ii, "[" + Section + "]"); - InsertLine(ii + 1, Item + " = " + Value); - return; -} - - - -bool CIniFile::InsertLine(size_t line, const std::string& str) { - m_FileContainer.insert(m_FileContainer.begin() + line, str); - return true; -} - -bool CIniFile::ReplaceLine(size_t line, const std::string& str) { - m_FileContainer[line] = str; - return true; -} diff --git a/arm9/source/inifile.h b/arm9/source/inifile.h deleted file mode 100644 index cbf6e2c..0000000 --- a/arm9/source/inifile.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - inifile.h - Copyright (C) 2007 Acekard, www.acekard.com - Copyright (C) 2007-2009 somebody - Copyright (C) 2009-2010 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 <http://www.gnu.org/licenses/>. -*/ - -#ifndef _INIFILE_H_ -#define _INIFILE_H_ - -#include <string> -#include <vector> -#include <map> - -class CIniFile { -public: - CIniFile(); - CIniFile(const std::string& filename); - virtual ~CIniFile(); - -public: - bool LoadIniFile(const std::string& FileName); - bool SaveIniFile(const std::string& FileName); - bool SaveIniFileModified(const std::string& FileName); - bool HasFileHandle(); - - std::string GetString(const std::string& Section, const std::string& Item, const std::string& DefaultValue); - void SetString(const std::string& Section, const std::string& Item, const std::string& Value); - int GetInt(const std::string& Section, const std::string& Item, int DefaultValue); - void SetInt(const std::string& Section, const std::string& Item, int Value); - void GetStringVector(const std::string& Section, const std::string& Item, std::vector<std::string>& strings, char delimiter = ','); - void SetStringVector(const std::string& Section, const std::string& Item, std::vector<std::string>& strings, char delimiter = ','); -protected: - std::string m_sFileName; - typedef std::vector<std::string> cStringArray; - cStringArray m_FileContainer; - bool m_bLastResult; - bool m_bModified; - bool m_bReadOnly; - bool m_bHasHandle; - typedef std::map<std::string, size_t> cSectionCache; - cSectionCache m_Cache; - - bool InsertLine(size_t line, const std::string& str); - bool ReplaceLine(size_t line, const std::string& str); - - void SetFileString(const std::string& Section, const std::string& Item, const std::string& Value); - std::string GetFileString(const std::string& Section, const std::string& Item); - - std::string GetString(const std::string& Section, const std::string& Item); - int GetInt(const std::string& Section, const std::string& Item); -}; - -#endif // _INIFILE_H_ - diff --git a/arm9/source/inihandler.cpp b/arm9/source/inihandler.cpp new file mode 100644 index 0000000..ec2432d --- /dev/null +++ b/arm9/source/inihandler.cpp @@ -0,0 +1,97 @@ +/* + inihandler.cpp + Copyright (C) 2019 edo9300 + + 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 <http://www.gnu.org/licenses/>. +*/ + +#include "inihandler.h" +#include <fstream> + +bool IniFile::LoadFile(const std::string & filename) { + std::ifstream inifile(filename, std::ifstream::in); + if(!inifile.is_open()) + return false; + is_from_file = true; + cur_filename = filename; + std::string cur_str; + std::string cur_field(""); + auto remove_trailing_space = [](const std::string& str) { + auto pos = str.find_last_of(" "); + if(pos != std::string::npos) + return str.substr(0, pos); + return str; + + }; + auto remove_leading_space = [](const std::string& str) { + auto pos = str.find_first_of(" "); + if(pos != std::string::npos) + return str.substr(pos + 1); + return str; + + }; + while(std::getline(inifile, cur_str)) { + auto pos = cur_str.find_first_of("\n\r"); + if(cur_str.size() && pos != std::string::npos) + cur_str = cur_str.substr(0, pos); + pos = cur_str.find('['); + if(pos != std::string::npos) { + auto endpos = cur_str.find(']'); + cur_field = cur_str.substr(pos + 1, endpos - pos - 1); + continue; + } + if(cur_field == "") + continue; + pos = cur_str.find('='); + if(pos == std::string::npos) + continue; + auto key = remove_trailing_space(cur_str.substr(0, pos)); + auto val = remove_leading_space(cur_str.substr(pos + 1, cur_str.size() - pos)); + contents[cur_field].Set(key, val); + } + return true; +} + +bool IniFile::SaveFile(const std::string & filename) { + if(filename != "") + cur_filename = filename; + std::ofstream inifile(cur_filename, std::ofstream::out); + if(!inifile.is_open()) + return false; + modified = false; + for(auto& content : contents) { + inifile << "[" << content.first << "]\n"; + for(auto& obj : content.second.GetHandle()) { + inifile << obj.first << " = " << obj.second << "\n"; + } + } + return true; +} + +void IniFile::SetValue(const std::string& field, const std::string& key, const std::string& _val) { + modified = true; + contents[field].Set(key, _val); +} + +std::string IniFile::GetValueString(const std::string & field, const std::string & key, const std::string & _default) { + if(contents.find(key) != contents.end()) + return contents[field].GetValString(key); + return _default; +} + +int IniFile::GetValueInt(const std::string & field, const std::string & key, int _default) { + if(contents.find(key) != contents.end()) + return contents[field].GetValInt(key); + return _default; +} diff --git a/arm9/source/inihandler.h b/arm9/source/inihandler.h new file mode 100644 index 0000000..636c52b --- /dev/null +++ b/arm9/source/inihandler.h @@ -0,0 +1,78 @@ +/* + inihandler.h + Copyright (C) 2019 edo9300 + + 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 <http://www.gnu.org/licenses/>. +*/ + +#ifndef _BETTER_INIFILE_H_ +#define _BETTER_INIFILE_H_ +#include <string> +#include <map> +#include <functional> + +class IniObj { +public: + IniObj(){}; + void Set(const std::string& _key, const std::string& _val) { + val[_key] = _val; + } + void Set(const std::string& _key, int _val) { + val[_key] = std::to_string(_val); + } + std::string GetValString(const std::string& _key) { + if(val.find(_key) != val.end()) + return val[_key]; + return ""; + } + int GetValInt(const std::string& _key) { + if(val.find(_key) != val.end()) + return std::stoi(val[_key]); + return 0; + } + std::map<std::string, std::string>& GetHandle() { + return std::ref(val); + } +private: + std::map<std::string /*key*/, std::string /*val*/> val; +}; + +class IniFile { +public: + IniFile():is_from_file(false), modified(false){}; + IniFile(const std::string& filename) :is_from_file(false), modified(false) { + LoadFile(filename); + }; + bool LoadFile(const std::string& filename); + bool SaveFile(const std::string& filename = ""); + bool SaveFileIfModified(const std::string& filename = "") { + return modified ? SaveFile(filename) : true; + }; + void SetValue(const std::string& field, const std::string& key, const std::string& _val); + void SetValue(const std::string& field, const std::string& key, int _val) { + SetValue(field, key, std::to_string(_val)); + }; + std::string GetValueString(const std::string& field, const std::string& key, const std::string& _default = ""); + int GetValueInt(const std::string& field, const std::string& key, int _default = 0); + bool HasFileHandle() { + return is_from_file; + }; +private: + std::map<std::string/*field*/, IniObj> contents; + std::string cur_filename; + bool is_from_file; + bool modified; +}; + +#endif
\ No newline at end of file diff --git a/arm9/source/main.cpp b/arm9/source/main.cpp index 15d7d4c..b344fe6 100644 --- a/arm9/source/main.cpp +++ b/arm9/source/main.cpp @@ -14,11 +14,11 @@ #include "headers.h" #include "utils.h" #include "menu.h" -#include "inifile.h" +#include "inihandler.h" #include "apppatch.h" -CIniFile bootsrtapconfig; -CIniFile bootstrap_template; +IniFile bootsrtapconfig; +IniFile bootstrap_template; PrintConsole upperScreen; PrintConsole lowerScreen; @@ -203,11 +203,11 @@ void CreateForwarder() { Movefile("sd:/MakeForwarder/banner.nds", folderpath + "/content/00000000.app"); Movefile("sd:/MakeForwarder/title.tmd", folderpath + "/content/title.tmd"); if(bootstrap_template.HasFileHandle()) { - bootsrtapconfig.SaveIniFile((folderpath + "/data/config.ini").c_str()); - bootstrap_template.SetString("NDS-BOOTSTRAP", "NDS_PATH", file.c_str()); + bootsrtapconfig.SaveFile(folderpath + "/data/config.ini"); + bootstrap_template.SetValue("NDS-BOOTSTRAP", "NDS_PATH", file.c_str()); std::string savePath = ReplaceAll(file, ".nds", ".sav"); - bootstrap_template.SetString("NDS-BOOTSTRAP", "SAV_PATH", savePath.c_str()); - bootstrap_template.SaveIniFile((folderpath + "/data/bootstrap.ini").c_str()); + bootstrap_template.SetValue("NDS-BOOTSTRAP", "SAV_PATH", savePath.c_str()); + bootstrap_template.SaveFile(folderpath + "/data/bootstrap.ini"); } } } @@ -224,10 +224,10 @@ void SetBootstrap() { std::string bootstrappath = file.substr(0, found + 1); std::string bootstrapversion = file.substr(found + 1); - bootsrtapconfig.SetString("NDS-FORWARDER", "BOOTSTRAP_PATH", bootstrappath.c_str()); - bootsrtapconfig.SetString("NDS-FORWARDER", "BOOTSTRAP_VERSION", bootstrapversion.c_str()); + bootsrtapconfig.SetValue("NDS-FORWARDER", "BOOTSTRAP_PATH", bootstrappath.c_str()); + bootsrtapconfig.SetValue("NDS-FORWARDER", "BOOTSTRAP_VERSION", bootstrapversion.c_str()); - bootstrap_template.LoadIniFile((bootstrappath + "nds-bootstrap.ini").c_str()); + bootstrap_template.LoadFile(bootstrappath + "nds-bootstrap.ini"); } void CheckResources() { |