mirror of
https://github.com/coderkei/akmenu-next.git
synced 2025-06-18 08:55:46 -04:00
339 lines
10 KiB
C++
339 lines
10 KiB
C++
/*
|
|
inifile.cpp
|
|
Copyright (C) 2007 Acekard, www.acekard.com
|
|
Copyright (C) 2007-2009 somebody
|
|
Copyright (C) 2009 yellow wood goblin
|
|
|
|
SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
#include "inifile.h"
|
|
#include <fat.h>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include "dbgtool.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;
|
|
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;
|
|
|
|
// 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(), "w");
|
|
if (f == NULL) {
|
|
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(' ');
|
|
if (notSpace != std::string::npos) {
|
|
strline = strline.substr(notSpace);
|
|
}
|
|
|
|
if (strline.find('[') == 0 && ii > 0) {
|
|
if (!m_FileContainer[ii - 1].empty())
|
|
fprintf(f, "\n");
|
|
}
|
|
|
|
if (!strline.empty()) {
|
|
fprintf(f, "%s\n", strline.c_str());
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|