Replace the internal representation of IniFile with ParsedIniLine.

This commit is contained in:
Henrik Rydgård 2023-09-25 19:35:46 +02:00
parent daa1bc3c6e
commit 41f4c08d17
2 changed files with 53 additions and 132 deletions

View file

@ -197,30 +197,20 @@ void ParsedIniLine::Reconstruct(std::string *output) const {
}
void Section::Clear() {
lines.clear();
lines_.clear();
}
std::string* Section::GetLine(const char* key, std::string* valueOut, std::string* commentOut)
{
for (std::vector<std::string>::iterator iter = lines.begin(); iter != lines.end(); ++iter)
{
std::string& line = *iter;
std::string lineKey;
ParseLine(line, &lineKey, valueOut, commentOut);
if (!strcasecmp(lineKey.c_str(), key))
ParsedIniLine *Section::GetLine(const char *key) {
for (auto &line : lines_) {
if (!strvcasecmp(line.Key(), key))
return &line;
}
return nullptr;
}
const std::string* Section::GetLine(const char* key, std::string* valueOut, std::string* commentOut) const
{
for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
{
const std::string& line = *iter;
std::string lineKey;
ParseLine(line, &lineKey, valueOut, commentOut);
if (!strcasecmp(lineKey.c_str(), key))
const ParsedIniLine *Section::GetLine(const char* key) const {
for (auto &line : lines_) {
if (!strvcasecmp(line.Key(), key))
return &line;
}
return nullptr;
@ -246,19 +236,13 @@ void Section::Set(const char* key, int newValue) {
Set(key, StringFromInt(newValue).c_str());
}
void Section::Set(const char* key, const char* newValue)
{
std::string value, commented;
std::string* line = GetLine(key, &value, &commented);
if (line)
{
// Change the value - keep the key and comment
*line = StripSpaces(key) + " = " + EscapeHash(newValue) + commented;
}
else
{
void Section::Set(const char* key, const char* newValue) {
ParsedIniLine *line = GetLine(key);
if (line) {
line->SetValue(newValue);
} else {
// The key did not already exist in this section - let's add it.
lines.emplace_back(std::string(key) + " = " + EscapeHash(newValue));
lines_.emplace_back(ParsedIniLine(key, newValue));
}
}
@ -270,16 +254,15 @@ void Section::Set(const char* key, const std::string& newValue, const std::strin
Delete(key);
}
bool Section::Get(const char* key, std::string* value, const char* defaultValue) const
{
const std::string* line = GetLine(key, value, 0);
if (!line)
{
if (defaultValue)
{
bool Section::Get(const char* key, std::string* value, const char* defaultValue) const {
const ParsedIniLine *line = GetLine(key);
if (!line) {
if (defaultValue) {
*value = defaultValue;
}
return false;
} else {
*value = line->Value();
}
return true;
}
@ -324,7 +307,7 @@ void Section::Set(const char* key, const std::vector<std::string>& newValues)
}
void Section::AddComment(const std::string &comment) {
lines.emplace_back("# " + comment);
lines_.emplace_back(ParsedIniLine::CommentOnly("# " + comment));
}
bool Section::Get(const char* key, std::vector<std::string>& values) const
@ -415,39 +398,29 @@ bool Section::Get(const char* key, double* value, double defaultValue) const
return false;
}
bool Section::Exists(const char *key) const
{
for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
{
std::string lineKey;
ParseLine(*iter, &lineKey, NULL, NULL);
if (!strcasecmp(lineKey.c_str(), key))
bool Section::Exists(const char *key) const {
for (auto &line : lines_) {
if (!strvcasecmp(key, line.Key()))
return true;
}
return false;
}
std::map<std::string, std::string> Section::ToMap() const
{
std::map<std::string, std::string> Section::ToMap() const {
std::map<std::string, std::string> outMap;
for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
{
std::string lineKey, lineValue;
if (ParseLine(*iter, &lineKey, &lineValue, NULL)) {
outMap[lineKey] = lineValue;
for (auto &line : lines_) {
if (!line.Key().empty()) {
outMap[std::string(line.Key())] = line.Value();
}
}
return outMap;
}
bool Section::Delete(const char *key)
{
std::string* line = GetLine(key, 0, 0);
for (std::vector<std::string>::iterator liter = lines.begin(); liter != lines.end(); ++liter)
{
if (line == &*liter)
{
lines.erase(liter);
bool Section::Delete(const char *key) {
ParsedIniLine *line = GetLine(key);
for (auto liter = lines_.begin(); liter != lines_.end(); ++liter) {
if (line == &*liter) {
lines_.erase(liter);
return true;
}
}
@ -500,27 +473,14 @@ bool IniFile::Exists(const char* sectionName, const char* key) const {
return section->Exists(key);
}
void IniFile::SetLines(const char* sectionName, const std::vector<std::string> &lines)
{
Section* section = GetOrCreateSection(sectionName);
section->lines.clear();
for (std::vector<std::string>::const_iterator iter = lines.begin(); iter != lines.end(); ++iter)
{
section->lines.push_back(*iter);
}
}
bool IniFile::DeleteKey(const char* sectionName, const char* key)
{
bool IniFile::DeleteKey(const char* sectionName, const char* key) {
Section* section = GetSection(sectionName);
if (!section)
return false;
std::string* line = section->GetLine(key, 0, 0);
for (std::vector<std::string>::iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter)
{
if (line == &(*liter))
{
section->lines.erase(liter);
ParsedIniLine *line = section->GetLine(key);
for (auto liter = section->lines_.begin(); liter != section->lines_.end(); ++liter) {
if (line == &(*liter)) {
section->lines_.erase(liter);
return true;
}
}
@ -528,55 +488,18 @@ bool IniFile::DeleteKey(const char* sectionName, const char* key)
}
// Return a list of all keys in a section
bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys) const
{
const Section* section = GetSection(sectionName);
bool IniFile::GetKeys(const char* sectionName, std::vector<std::string>& keys) const {
const Section *section = GetSection(sectionName);
if (!section)
return false;
keys.clear();
for (std::vector<std::string>::const_iterator liter = section->lines.begin(); liter != section->lines.end(); ++liter)
{
std::string key;
ParseLine(*liter, &key, 0, 0);
if (!key.empty())
keys.push_back(key);
for (auto liter = section->lines_.begin(); liter != section->lines_.end(); ++liter) {
if (!liter->Key().empty())
keys.push_back(std::string(liter->Key()));
}
return true;
}
// Return a list of all lines in a section
bool IniFile::GetLines(const char* sectionName, std::vector<std::string>& lines, const bool remove_comments) const
{
const Section* section = GetSection(sectionName);
if (!section)
return false;
lines.clear();
for (std::vector<std::string>::const_iterator iter = section->lines.begin(); iter != section->lines.end(); ++iter)
{
std::string line = StripSpaces(*iter);
if (remove_comments)
{
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);
}
return true;
}
void IniFile::SortSections()
{
std::sort(sections.begin(), sections.end());
@ -650,7 +573,9 @@ bool IniFile::Load(std::istream &in) {
if (sections.empty()) {
sections.push_back(std::unique_ptr<Section>(new Section("")));
}
sections.back()->lines.push_back(line);
ParsedIniLine parsedLine;
parsedLine.ParseFrom(line);
sections.back()->lines_.push_back(parsedLine);
}
}
}
@ -671,12 +596,13 @@ bool IniFile::Save(const Path &filename)
fprintf(file, "\xEF\xBB\xBF");
for (const auto &section : sections) {
if (!section->name().empty() && (!section->lines.empty() || !section->comment.empty())) {
if (!section->name().empty() && (!section->lines_.empty() || !section->comment.empty())) {
fprintf(file, "[%s]%s\n", section->name().c_str(), section->comment.c_str());
}
for (const std::string &s : section->lines) {
fprintf(file, "%s\n", s.c_str());
for (const auto &line : section->lines_) {
std::string buffer;
line.Reconstruct(&buffer);
fprintf(file, "%s\n", buffer.c_str());
}
}

View file

@ -63,8 +63,8 @@ public:
std::map<std::string, std::string> ToMap() const;
std::string *GetLine(const char* key, std::string* valueOut, std::string* commentOut);
const std::string *GetLine(const char* key, std::string* valueOut, std::string* commentOut) const;
ParsedIniLine *GetLine(const char *key);
const ParsedIniLine *GetLine(const char *key) const;
void Set(const char* key, const char* newValue);
void Set(const char* key, const std::string& newValue, const std::string& defaultValue);
@ -114,7 +114,7 @@ public:
}
protected:
std::vector<std::string> lines;
std::vector<ParsedIniLine> lines_;
std::string name_;
std::string comment;
};
@ -122,12 +122,10 @@ protected:
class IniFile {
public:
bool Load(const Path &path);
bool Load(const std::string &filename) { return Load(Path(filename)); }
bool Load(std::istream &istream);
bool LoadFromVFS(VFSInterface &vfs, const std::string &filename);
bool Save(const Path &path);
bool Save(const std::string &filename) { return Save(Path(filename)); }
// Returns true if key exists in section
bool Exists(const char* sectionName, const char* key) const;
@ -172,9 +170,6 @@ public:
bool GetKeys(const char* sectionName, std::vector<std::string>& keys) const;
void SetLines(const char* sectionName, const std::vector<std::string> &lines);
bool GetLines(const char* sectionName, std::vector<std::string>& lines, const bool remove_comments = true) const;
bool DeleteKey(const char* sectionName, const char* key);
bool DeleteSection(const char* sectionName);