From 775dc8a9c0c83f7a2f776e97f5b90385c759535a Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sat, 12 Jul 2008 17:40:22 +0000 Subject: Initial megacommit. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/IniFile.cpp | 464 +++++++++++++++++++++++++++++++++++++ 1 file changed, 464 insertions(+) create mode 100644 Source/Core/Common/Src/IniFile.cpp (limited to 'Source/Core/Common/Src/IniFile.cpp') diff --git a/Source/Core/Common/Src/IniFile.cpp b/Source/Core/Common/Src/IniFile.cpp new file mode 100644 index 0000000000..6cfd2a078e --- /dev/null +++ b/Source/Core/Common/Src/IniFile.cpp @@ -0,0 +1,464 @@ +// Copyright (C) 2003-2008 Dolphin Project. + +// 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, version 2.0. + +// 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 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ +// see IniFile.h + +#include +#include + +#include +#include +#include +#include +#include + +#include "StringUtil.h" +#include "IniFile.h" + +IniFile::IniFile() +{} + + +IniFile::~IniFile() +{} + + +Section::Section() + : name(""), comment(""), lines() {} + + +Section::Section(const std::string& _name) + : name(_name), comment(""), lines() {} + + +Section::Section(const Section& other) +{ + name = other.name; + comment = other.comment; + lines = other.lines; +} + + +Section* IniFile::GetSection(const char* sectionName) +{ + for (std::vector
::iterator iter = sections.begin(); iter != sections.end(); ++iter) + { + if (!strcmp(iter->name.c_str(), sectionName)) + { + return(&(*iter)); + } + } + + return(0); +} + + +Section* IniFile::GetOrCreateSection(const char* sectionName) +{ + Section* section = GetSection(sectionName); + + if (!section) + { + sections.push_back(Section(sectionName)); + section = §ions[sections.size() - 1]; + } + + return(section); +} + + +bool IniFile::DeleteSection(const char* sectionName) +{ + Section* s = GetSection(sectionName); + + if (!s) + { + return(false); + } + + for (std::vector
::iterator iter = sections.begin(); iter != sections.end(); ++iter) + { + if (&(*iter) == s) + { + sections.erase(iter); + return(true); + } + } + + return(false); +} + + +void IniFile::ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut) +{ + // allow many types of commenting + // These MUST be signed! Do not change to size_t + int firstEquals = (int)line.find("=", 0); + int firstCommentChar = (int)line.find(";", 0); + + if (firstCommentChar < 0){firstCommentChar = (int)line.find("#", firstEquals > 0 ? firstEquals : 0);} + + if (firstCommentChar < 0){firstCommentChar = (int)line.find("//", firstEquals > 0 ? firstEquals : 0);} + + // allow preserval of spacing before comment + if (firstCommentChar > 0) + { + while (line[firstCommentChar - 1] == ' ' || line[firstCommentChar - 1] == 9) // 9 == tab + { + firstCommentChar--; + } + } + + if ((firstEquals >= 0) && ((firstCommentChar < 0) || (firstEquals < firstCommentChar))) + { + // Yes, a valid line! + *keyOut = StripSpaces(line.substr(0, firstEquals)); + + if (commentOut) + { + *commentOut = firstCommentChar > 0 ? line.substr(firstCommentChar) : std::string(""); + } + + if (valueOut) + { + *valueOut = StripQuotes(StripSpaces(line.substr(firstEquals + 1, firstCommentChar - firstEquals - 1))); + } + } +} + + +std::string* IniFile::GetLine(Section* section, const char* key, std::string* valueOut, std::string* commentOut) +{ + for (std::vector::iterator iter = section->lines.begin(); iter != section->lines.end(); ++iter) + { + std::string& line = *iter; + std::string lineKey; + ParseLine(line, &lineKey, valueOut, commentOut); + + if (!stricmp(lineKey.c_str(), key)) + { + return(&line); + } + } + + return(0); +} + + +void IniFile::Set(const char* sectionName, const char* key, const char* newValue) +{ + Section* section = GetOrCreateSection(sectionName); + std::string value, comment; + std::string* line = GetLine(section, key, &value, &comment); + + if (line) + { + // Change the value - keep the key and comment + *line = StripSpaces(key) + " = " + newValue + comment; + } + else + { + // The key did not already exist in this section - let's add it. + section->lines.push_back(std::string(key) + " = " + newValue); + } +} + + +void IniFile::Set(const char* sectionName, const char* key, u32 newValue) +{ + Set(sectionName, key, StringFromFormat("0x%08x", newValue).c_str()); +} + + +void IniFile::Set(const char* sectionName, const char* key, int newValue) +{ + Set(sectionName, key, StringFromInt(newValue).c_str()); +} + + +void IniFile::Set(const char* sectionName, const char* key, bool newValue) +{ + Set(sectionName, key, StringFromBool(newValue).c_str()); +} + + +bool IniFile::Get(const char* sectionName, const char* key, std::string* value, const char* defaultValue) +{ + Section* section = GetSection(sectionName); + + if (!section) + { + if (defaultValue) + { + *value = defaultValue; + } + + return(false); + } + + std::string* line = GetLine(section, key, value, 0); + + if (!line) + { + if (defaultValue) + { + *value = defaultValue; + } + + return(false); + } + + return(true); +} + + +bool IniFile::Get(const char* sectionName, const char* key, int* value, int defaultValue) +{ + std::string temp; + bool retval = Get(sectionName, key, &temp, 0); + + if (retval && TryParseInt(temp.c_str(), value)) + { + return(true); + } + + *value = defaultValue; + return(false); +} + + +bool IniFile::Get(const char* sectionName, const char* key, u32* value, u32 defaultValue) +{ + std::string temp; + bool retval = Get(sectionName, key, &temp, 0); + + if (retval && TryParseUInt(temp.c_str(), value)) + { + return(true); + } + + *value = defaultValue; + return(false); +} + + +bool IniFile::Get(const char* sectionName, const char* key, bool* value, bool defaultValue) +{ + std::string temp; + bool retval = Get(sectionName, key, &temp, 0); + + if (retval && TryParseBool(temp.c_str(), value)) + { + return(true); + } + + *value = defaultValue; + return(false); +} + + +bool IniFile::DeleteKey(const char* sectionName, const char* key) +{ + Section* section = GetSection(sectionName); + + if (!section) + { + return(false); + } + + std::string* line = GetLine(section, key, 0, 0); + + for (std::vector::iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter) + { + if (line == &(*liter)) + { + section->lines.erase(liter); + return(true); + } + } + + return(false); //shouldn't happen +} + + +bool IniFile::Load(const char* filename) +{ + sections.clear(); + sections.push_back(Section("")); + //first section consists of the comments before the first real section + + std::ifstream in; + in.open(filename, std::ios::in); + + if (in.fail()) + { + return(false); + } + + while (!in.eof()) + { + char templine[512]; + in.getline(templine, 512); + std::string line = templine; + + if (in.eof()) + { + break; + } + + if (line.size() > 0) + { + if (line[0] == '[') + { + int endpos = (int)line.find("]"); + + if (endpos != std::string::npos) + { + // New section! + std::string sub = line.substr(1, endpos - 1); + sections.push_back(Section(sub)); + + if (endpos + 1 < line.size()) + { + sections[sections.size() - 1].comment = line.substr(endpos + 1); + } + } + } + else + { + sections[sections.size() - 1].lines.push_back(line); + } + } + } + + in.close(); + return(true); +} + + +bool IniFile::Save(const char* filename) +{ + std::ofstream out; + out.open(filename, std::ios::out); + + if (out.fail()) + { + return(false); + } + + for (std::vector
::const_iterator iter = sections.begin(); iter != sections.end(); ++iter) + { + const Section& section = *iter; + + if (section.name != "") + { + out << "[" << section.name << "]" << section.comment << std::endl; + } + + for (std::vector::const_iterator liter = section.lines.begin(); liter != section.lines.end(); ++liter) + { + std::string s = *liter; + out << s << std::endl; + } + } + + out.close(); + return(true); +} + + +bool IniFile::GetKeys(const char* sectionName, std::vector& keys) +{ + Section* section = GetSection(sectionName); + + if (!section) + { + return(false); + } + + keys.clear(); + + for (std::vector::const_iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter) + { + std::string key; + ParseLine(*liter, &key, 0, 0); + keys.push_back(key); + } + + return(true); +} + + +bool IniFile::GetLines(const char* sectionName, std::vector& lines) +{ + Section* section = GetSection(sectionName); + + if (!section) + { + return(false); + } + + lines.clear(); + + for (std::vector::const_iterator iter = section->lines.begin(); iter != section->lines.end(); ++iter) + { + std::string line = StripSpaces(*iter); + int commentPos = (int)line.find('#'); + + if (commentPos == 0) + { + continue; + } + + if (commentPos != (int)std::string::npos) + { + line = StripSpaces(line.substr(0, commentPos)); + } + + lines.push_back(line); + } + + lines = section->lines; + return(true); +} + + +void IniFile::SortSections() +{ + std::sort(sections.begin(), sections.end()); +} + + +/* + int main() + { + IniFile ini; + ini.Load("my.ini"); + ini.Set("Hej", "A", "amaskdfl"); + ini.Set("Mossa", "A", "amaskdfl"); + ini.Set("Aissa", "A", "amaskdfl"); + //ini.Read("my.ini"); + std::string x; + ini.Get("Hej", "B", &x, "boo"); + ini.DeleteKey("Mossa", "A"); + ini.DeleteSection("Mossa"); + ini.SortSections(); + ini.Save("my.ini"); + //UpdateVars(ini); + return 0; + } + */ + -- cgit v1.2.3