mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-26 23:10:38 +00:00
IniFile: Store sections in unique_ptrs, instead of directly.
This fixes an issue when you create two sections consecutively and retain pointers to them, and then modify them, such as happens in the postshader ini initialization. Previously, one of the section pointers could get invalidated since the section vector got resized. Now, the pointed-to sections don't move around in memory, only the list of them does.
This commit is contained in:
parent
2a74a0b98a
commit
d82ecf1d3e
@ -420,42 +420,36 @@ bool Section::Delete(const char *key)
|
||||
|
||||
// IniFile
|
||||
|
||||
const Section* IniFile::GetSection(const char* sectionName) const
|
||||
{
|
||||
for (std::vector<Section>::const_iterator iter = sections.begin(); iter != sections.end(); ++iter)
|
||||
const Section* IniFile::GetSection(const char* sectionName) const {
|
||||
for (const auto &iter : sections)
|
||||
if (!strcasecmp(iter->name().c_str(), sectionName))
|
||||
return (&(*iter));
|
||||
return iter.get();
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
Section* IniFile::GetSection(const char* sectionName) {
|
||||
for (const auto &iter : sections)
|
||||
if (!strcasecmp(iter->name().c_str(), sectionName))
|
||||
return iter.get();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Section* IniFile::GetSection(const char* sectionName)
|
||||
{
|
||||
for (std::vector<Section>::iterator iter = sections.begin(); iter != sections.end(); ++iter)
|
||||
if (!strcasecmp(iter->name().c_str(), sectionName))
|
||||
return (&(*iter));
|
||||
return 0;
|
||||
}
|
||||
|
||||
Section* IniFile::GetOrCreateSection(const char* sectionName)
|
||||
{
|
||||
Section* IniFile::GetOrCreateSection(const char* sectionName) {
|
||||
Section* section = GetSection(sectionName);
|
||||
if (!section)
|
||||
{
|
||||
sections.push_back(Section(sectionName));
|
||||
section = §ions[sections.size() - 1];
|
||||
if (!section) {
|
||||
sections.push_back(std::unique_ptr<Section>(new Section(sectionName)));
|
||||
section = sections.back().get();
|
||||
}
|
||||
return section;
|
||||
}
|
||||
|
||||
bool IniFile::DeleteSection(const char* sectionName)
|
||||
{
|
||||
bool IniFile::DeleteSection(const char* sectionName) {
|
||||
Section* s = GetSection(sectionName);
|
||||
if (!s)
|
||||
return false;
|
||||
for (std::vector<Section>::iterator iter = sections.begin(); iter != sections.end(); ++iter)
|
||||
{
|
||||
if (&(*iter) == s)
|
||||
{
|
||||
|
||||
for (auto iter = sections.begin(); iter != sections.end(); ++iter) {
|
||||
if (iter->get() == s) {
|
||||
sections.erase(iter);
|
||||
return true;
|
||||
}
|
||||
@ -463,8 +457,7 @@ bool IniFile::DeleteSection(const char* sectionName)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IniFile::Exists(const char* sectionName, const char* key) const
|
||||
{
|
||||
bool IniFile::Exists(const char* sectionName, const char* key) const {
|
||||
const Section* section = GetSection(sectionName);
|
||||
if (!section)
|
||||
return false;
|
||||
@ -556,7 +549,7 @@ void IniFile::SortSections()
|
||||
bool IniFile::Load(const Path &path)
|
||||
{
|
||||
sections.clear();
|
||||
sections.push_back(Section(""));
|
||||
sections.push_back(std::unique_ptr<Section>(new Section("")));
|
||||
// first section consists of the comments before the first real section
|
||||
|
||||
// Open file
|
||||
@ -612,16 +605,16 @@ bool IniFile::Load(std::istream &in) {
|
||||
if (sectionNameEnd != std::string::npos) {
|
||||
// New section!
|
||||
std::string sub = line.substr(1, sectionNameEnd - 1);
|
||||
sections.push_back(Section(sub));
|
||||
sections.push_back(std::unique_ptr<Section>(new Section(sub)));
|
||||
|
||||
if (sectionNameEnd + 1 < line.size()) {
|
||||
sections[sections.size() - 1].comment = line.substr(sectionNameEnd + 1);
|
||||
sections.back()->comment = line.substr(sectionNameEnd + 1);
|
||||
}
|
||||
} else {
|
||||
if (sections.empty()) {
|
||||
sections.push_back(Section(""));
|
||||
sections.push_back(std::unique_ptr<Section>(new Section("")));
|
||||
}
|
||||
sections[sections.size() - 1].lines.push_back(line);
|
||||
sections.back()->lines.push_back(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -641,12 +634,12 @@ bool IniFile::Save(const Path &filename)
|
||||
// TODO: Do we still need this? It's annoying.
|
||||
fprintf(file, "\xEF\xBB\xBF");
|
||||
|
||||
for (const Section §ion : sections) {
|
||||
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 auto §ion : sections) {
|
||||
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) {
|
||||
for (const std::string &s : section->lines) {
|
||||
fprintf(file, "%s\n", s.c_str());
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <istream>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@ -144,14 +145,15 @@ public:
|
||||
bool DeleteSection(const char* sectionName);
|
||||
|
||||
void SortSections();
|
||||
std::vector<Section> &Sections() { return sections; }
|
||||
|
||||
std::vector<std::unique_ptr<Section>> &Sections() { return sections; }
|
||||
|
||||
bool HasSection(const char *section) { return GetSection(section) != 0; }
|
||||
|
||||
Section* GetOrCreateSection(const char* section);
|
||||
|
||||
private:
|
||||
std::vector<Section> sections;
|
||||
std::vector<std::unique_ptr<Section>> sections;
|
||||
|
||||
const Section* GetSection(const char* section) const;
|
||||
Section* GetSection(const char* section);
|
||||
|
@ -140,13 +140,13 @@ bool I18NRepo::LoadIni(const std::string &languageID, const Path &overridePath)
|
||||
|
||||
Clear();
|
||||
|
||||
const std::vector<Section> §ions = ini.Sections();
|
||||
const std::vector<std::unique_ptr<Section>> §ions = ini.Sections();
|
||||
|
||||
std::lock_guard<std::mutex> guard(catsLock_);
|
||||
for (auto §ion : sections) {
|
||||
for (size_t i = 0; i < (size_t)I18NCat::CATEGORY_COUNT; i++) {
|
||||
if (!strcmp(section.name().c_str(), g_categoryNames[i])) {
|
||||
cats_[i].reset(new I18NCategory(section));
|
||||
if (!strcmp(section->name().c_str(), g_categoryNames[i])) {
|
||||
cats_[i].reset(new I18NCategory(*section.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ void LoadPostShaderInfo(Draw::DrawContext *draw, const std::vector<Path> &direct
|
||||
|
||||
// Alright, let's loop through the sections and see if any is a shader.
|
||||
for (size_t i = 0; i < ini.Sections().size(); i++) {
|
||||
Section §ion = ini.Sections()[i];
|
||||
Section §ion = *(ini.Sections()[i].get());
|
||||
std::string shaderType;
|
||||
section.Get("Type", &shaderType, "render");
|
||||
|
||||
|
@ -113,7 +113,7 @@ static void LoadThemeInfo(const std::vector<Path> &directories) {
|
||||
|
||||
// Alright, let's loop through the sections and see if any is a theme.
|
||||
for (size_t i = 0; i < ini.Sections().size(); i++) {
|
||||
Section §ion = ini.Sections()[i];
|
||||
Section §ion = *(ini.Sections()[i].get());
|
||||
ThemeInfo info;
|
||||
section.Get("Name", &info.name, section.name().c_str());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user