Merge pull request #8191 from lioncash/ini
Common/IniFile: Use std::string_view where applicable
This commit is contained in:
commit
973bba7c1e
|
@ -5,16 +5,13 @@
|
|||
#include "Common/IniFile.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
|
@ -54,32 +51,34 @@ void IniFile::Section::Set(const std::string& key, std::string new_value)
|
|||
keys_order.push_back(key);
|
||||
}
|
||||
|
||||
bool IniFile::Section::Get(const std::string& key, std::string* value,
|
||||
const std::string& defaultValue) const
|
||||
bool IniFile::Section::Get(std::string_view key, std::string* value,
|
||||
const std::string& default_value) const
|
||||
{
|
||||
auto it = values.find(key);
|
||||
const auto it = values.find(key);
|
||||
|
||||
if (it != values.end())
|
||||
{
|
||||
*value = it->second;
|
||||
return true;
|
||||
}
|
||||
else if (&defaultValue != &NULL_STRING)
|
||||
|
||||
if (&default_value != &NULL_STRING)
|
||||
{
|
||||
*value = defaultValue;
|
||||
*value = default_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IniFile::Section::Exists(const std::string& key) const
|
||||
bool IniFile::Section::Exists(std::string_view key) const
|
||||
{
|
||||
return values.find(key) != values.end();
|
||||
}
|
||||
|
||||
bool IniFile::Section::Delete(const std::string& key)
|
||||
bool IniFile::Section::Delete(std::string_view key)
|
||||
{
|
||||
auto it = values.find(key);
|
||||
const auto it = values.find(key);
|
||||
if (it == values.end())
|
||||
return false;
|
||||
|
||||
|
@ -125,38 +124,45 @@ IniFile::IniFile() = default;
|
|||
|
||||
IniFile::~IniFile() = default;
|
||||
|
||||
const IniFile::Section* IniFile::GetSection(const std::string& sectionName) const
|
||||
const IniFile::Section* IniFile::GetSection(std::string_view section_name) const
|
||||
{
|
||||
for (const Section& sect : sections)
|
||||
if (!strcasecmp(sect.name.c_str(), sectionName.c_str()))
|
||||
return (&(sect));
|
||||
{
|
||||
if (CaseInsensitiveStringCompare::IsEqual(sect.name, section_name))
|
||||
return §
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IniFile::Section* IniFile::GetSection(const std::string& sectionName)
|
||||
IniFile::Section* IniFile::GetSection(std::string_view section_name)
|
||||
{
|
||||
for (Section& sect : sections)
|
||||
if (!strcasecmp(sect.name.c_str(), sectionName.c_str()))
|
||||
return (&(sect));
|
||||
{
|
||||
if (CaseInsensitiveStringCompare::IsEqual(sect.name, section_name))
|
||||
return §
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IniFile::Section* IniFile::GetOrCreateSection(const std::string& sectionName)
|
||||
IniFile::Section* IniFile::GetOrCreateSection(std::string_view section_name)
|
||||
{
|
||||
Section* section = GetSection(sectionName);
|
||||
Section* section = GetSection(section_name);
|
||||
if (!section)
|
||||
{
|
||||
sections.emplace_back(sectionName);
|
||||
sections.emplace_back(std::string(section_name));
|
||||
section = §ions.back();
|
||||
}
|
||||
return section;
|
||||
}
|
||||
|
||||
bool IniFile::DeleteSection(const std::string& sectionName)
|
||||
bool IniFile::DeleteSection(std::string_view section_name)
|
||||
{
|
||||
Section* s = GetSection(sectionName);
|
||||
Section* s = GetSection(section_name);
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
for (auto iter = sections.begin(); iter != sections.end(); ++iter)
|
||||
{
|
||||
if (&(*iter) == s)
|
||||
|
@ -165,41 +171,43 @@ bool IniFile::DeleteSection(const std::string& sectionName)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IniFile::Exists(const std::string& sectionName, const std::string& key) const
|
||||
bool IniFile::Exists(std::string_view section_name, std::string_view key) const
|
||||
{
|
||||
const Section* section = GetSection(sectionName);
|
||||
const Section* section = GetSection(section_name);
|
||||
if (!section)
|
||||
return false;
|
||||
|
||||
return section->Exists(key);
|
||||
}
|
||||
|
||||
void IniFile::SetLines(const std::string& sectionName, const std::vector<std::string>& lines)
|
||||
void IniFile::SetLines(std::string_view section_name, const std::vector<std::string>& lines)
|
||||
{
|
||||
Section* section = GetOrCreateSection(sectionName);
|
||||
Section* section = GetOrCreateSection(section_name);
|
||||
section->SetLines(lines);
|
||||
}
|
||||
|
||||
void IniFile::SetLines(const std::string& section_name, std::vector<std::string>&& lines)
|
||||
void IniFile::SetLines(std::string_view section_name, std::vector<std::string>&& lines)
|
||||
{
|
||||
Section* section = GetOrCreateSection(section_name);
|
||||
section->SetLines(std::move(lines));
|
||||
}
|
||||
|
||||
bool IniFile::DeleteKey(const std::string& sectionName, const std::string& key)
|
||||
bool IniFile::DeleteKey(std::string_view section_name, std::string_view key)
|
||||
{
|
||||
Section* section = GetSection(sectionName);
|
||||
Section* section = GetSection(section_name);
|
||||
if (!section)
|
||||
return false;
|
||||
return section->Delete(key);
|
||||
}
|
||||
|
||||
// Return a list of all keys in a section
|
||||
bool IniFile::GetKeys(const std::string& sectionName, std::vector<std::string>* keys) const
|
||||
bool IniFile::GetKeys(std::string_view section_name, std::vector<std::string>* keys) const
|
||||
{
|
||||
const Section* section = GetSection(sectionName);
|
||||
const Section* section = GetSection(section_name);
|
||||
if (!section)
|
||||
{
|
||||
return false;
|
||||
|
@ -209,12 +217,12 @@ bool IniFile::GetKeys(const std::string& sectionName, std::vector<std::string>*
|
|||
}
|
||||
|
||||
// Return a list of all lines in a section
|
||||
bool IniFile::GetLines(const std::string& sectionName, std::vector<std::string>* lines,
|
||||
bool IniFile::GetLines(std::string_view section_name, std::vector<std::string>* lines,
|
||||
const bool remove_comments) const
|
||||
{
|
||||
lines->clear();
|
||||
|
||||
const Section* section = GetSection(sectionName);
|
||||
const Section* section = GetSection(section_name);
|
||||
if (!section)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -4,21 +4,38 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
struct CaseInsensitiveStringCompare
|
||||
{
|
||||
bool operator()(const std::string& a, const std::string& b) const
|
||||
// Allow heterogenous lookup.
|
||||
using is_transparent = void;
|
||||
|
||||
bool operator()(std::string_view a, std::string_view b) const
|
||||
{
|
||||
return strcasecmp(a.c_str(), b.c_str()) < 0;
|
||||
return std::lexicographical_compare(
|
||||
a.begin(), a.end(), b.begin(), b.end(), [](char lhs, char rhs) {
|
||||
return std::tolower(static_cast<u8>(lhs)) < std::tolower(static_cast<u8>(rhs));
|
||||
});
|
||||
}
|
||||
|
||||
static bool IsEqual(std::string_view a, std::string_view b)
|
||||
{
|
||||
if (a.size() != b.size())
|
||||
return false;
|
||||
|
||||
return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char lhs, char rhs) {
|
||||
return std::tolower(static_cast<u8>(lhs)) == std::tolower(static_cast<u8>(rhs));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -32,8 +49,8 @@ public:
|
|||
public:
|
||||
Section();
|
||||
explicit Section(std::string name_);
|
||||
bool Exists(const std::string& key) const;
|
||||
bool Delete(const std::string& key);
|
||||
bool Exists(std::string_view key) const;
|
||||
bool Delete(std::string_view key);
|
||||
|
||||
void Set(const std::string& key, std::string new_value);
|
||||
|
||||
|
@ -52,12 +69,11 @@ public:
|
|||
Delete(key);
|
||||
}
|
||||
|
||||
bool Get(const std::string& key, std::string* value,
|
||||
bool Get(std::string_view key, std::string* value,
|
||||
const std::string& default_value = NULL_STRING) const;
|
||||
|
||||
template <typename T>
|
||||
bool Get(const std::string& key, T* value,
|
||||
const std::common_type_t<T>& default_value = {}) const
|
||||
bool Get(std::string_view key, T* value, const std::common_type_t<T>& default_value = {}) const
|
||||
{
|
||||
std::string temp;
|
||||
bool retval = Get(key, &temp);
|
||||
|
@ -104,41 +120,40 @@ public:
|
|||
bool Save(const std::string& filename);
|
||||
|
||||
// Returns true if key exists in section
|
||||
bool Exists(const std::string& sectionName, const std::string& key) const;
|
||||
bool Exists(std::string_view section_name, std::string_view key) const;
|
||||
|
||||
template <typename T>
|
||||
bool GetIfExists(const std::string& sectionName, const std::string& key, T* value)
|
||||
bool GetIfExists(std::string_view section_name, std::string_view key, T* value)
|
||||
{
|
||||
if (Exists(sectionName, key))
|
||||
return GetOrCreateSection(sectionName)->Get(key, value);
|
||||
if (Exists(section_name, key))
|
||||
return GetOrCreateSection(section_name)->Get(key, value);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool GetIfExists(const std::string& sectionName, const std::string& key, T* value, T defaultValue)
|
||||
bool GetIfExists(std::string_view section_name, std::string_view key, T* value, T default_value)
|
||||
{
|
||||
if (Exists(sectionName, key))
|
||||
return GetOrCreateSection(sectionName)->Get(key, value, defaultValue);
|
||||
else
|
||||
*value = defaultValue;
|
||||
if (Exists(section_name, key))
|
||||
return GetOrCreateSection(section_name)->Get(key, value, default_value);
|
||||
|
||||
*value = default_value;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetKeys(const std::string& sectionName, std::vector<std::string>* keys) const;
|
||||
bool GetKeys(std::string_view section_name, std::vector<std::string>* keys) const;
|
||||
|
||||
void SetLines(const std::string& sectionName, const std::vector<std::string>& lines);
|
||||
void SetLines(const std::string& section_name, std::vector<std::string>&& lines);
|
||||
bool GetLines(const std::string& sectionName, std::vector<std::string>* lines,
|
||||
const bool remove_comments = true) const;
|
||||
void SetLines(std::string_view section_name, const std::vector<std::string>& lines);
|
||||
void SetLines(std::string_view section_name, std::vector<std::string>&& lines);
|
||||
bool GetLines(std::string_view section_name, std::vector<std::string>* lines,
|
||||
bool remove_comments = true) const;
|
||||
|
||||
bool DeleteKey(const std::string& sectionName, const std::string& key);
|
||||
bool DeleteSection(const std::string& sectionName);
|
||||
bool DeleteKey(std::string_view section_name, std::string_view key);
|
||||
bool DeleteSection(std::string_view section_name);
|
||||
|
||||
void SortSections();
|
||||
|
||||
Section* GetOrCreateSection(const std::string& section);
|
||||
Section* GetOrCreateSection(std::string_view section_name);
|
||||
|
||||
// This function is related to parsing data from lines of INI files
|
||||
// It's used outside of IniFile, which is why it is exposed publicly
|
||||
|
@ -150,8 +165,8 @@ public:
|
|||
private:
|
||||
std::list<Section> sections;
|
||||
|
||||
const Section* GetSection(const std::string& section) const;
|
||||
Section* GetSection(const std::string& section);
|
||||
const Section* GetSection(std::string_view section_name) const;
|
||||
Section* GetSection(std::string_view section_name);
|
||||
|
||||
static const std::string& NULL_STRING;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue