diff --git a/Common/Data/Format/IniFile.cpp b/Common/Data/Format/IniFile.cpp index 2b63ff86cc..b4bb21e811 100644 --- a/Common/Data/Format/IniFile.cpp +++ b/Common/Data/Format/IniFile.cpp @@ -37,7 +37,8 @@ bool StringViewEqualCaseInsensitive(const std::string_view lhs, const std::strin } // This unescapes # signs. -static bool ParseLineKey(const std::string &line, size_t &pos, std::string *keyOut) { +// NOTE: These parse functions can make better use of the string_view - the pos argument should not be needed, for example. +static bool ParseLineKey(std::string_view line, size_t &pos, std::string *keyOut) { std::string key = ""; while (pos < line.size()) { @@ -52,7 +53,8 @@ static bool ParseLineKey(const std::string &line, size_t &pos, std::string *keyO } // Escaped. - key += line.substr(pos, next - pos - 1) + "#"; + key += line.substr(pos, next - pos - 1); + key.push_back('#'); pos = next + 1; } else if (line[next] == '=') { // Hurray, done. @@ -68,11 +70,11 @@ static bool ParseLineKey(const std::string &line, size_t &pos, std::string *keyO return true; } -static bool ParseLineValue(const std::string &line, size_t &pos, std::string *valueOut) { +static bool ParseLineValue(std::string_view line, size_t &pos, std::string *valueOut) { std::string value = ""; - std::string strippedLine = StripSpaces(line.substr(pos)); - if (strippedLine[0] == '"' && strippedLine[strippedLine.size()-1] == '"') { + std::string_view strippedLine = StripSpaces(line.substr(pos)); + if (strippedLine.size() >= 2 && strippedLine[0] == '"' && strippedLine[strippedLine.size() - 1] == '"') { // Don't remove comment if is surrounded by " " value += line.substr(pos); pos = line.npos; // Won't enter the while below @@ -92,7 +94,8 @@ static bool ParseLineValue(const std::string &line, size_t &pos, std::string *va break; } else { // Escaped. - value += line.substr(pos, next - pos - 1) + "#"; + value += line.substr(pos, next - pos - 1); + value.push_back('#'); pos = next + 1; } } @@ -104,7 +107,7 @@ static bool ParseLineValue(const std::string &line, size_t &pos, std::string *va return true; } -static bool ParseLineComment(const std::string& line, size_t &pos, std::string *commentOut) { +static bool ParseLineComment(std::string_view line, size_t &pos, std::string *commentOut) { // Don't bother with anything if we don't need the comment data. if (commentOut) { // Include any whitespace/formatting in the comment. @@ -125,8 +128,7 @@ static bool ParseLineComment(const std::string& line, size_t &pos, std::string * return true; } -// Ugh, this is ugly. -static bool ParseLine(const std::string& line, std::string* keyOut, std::string* valueOut, std::string* commentOut) +static bool ParseLine(std::string_view line, std::string* keyOut, std::string* valueOut, std::string* commentOut) { // Rules: // 1. A line starting with ; is commented out. @@ -150,7 +152,7 @@ static bool ParseLine(const std::string& line, std::string* keyOut, std::string* return true; } -static std::string EscapeHash(const std::string &value) { +static std::string EscapeHash(std::string_view value) { std::string result = ""; for (size_t pos = 0; pos < value.size(); ) { @@ -159,7 +161,8 @@ static std::string EscapeHash(const std::string &value) { result += value.substr(pos); pos = value.npos; } else { - result += value.substr(pos, next - pos) + "\\#"; + result += value.substr(pos, next - pos); + result += "\\#"; pos = next + 1; } } @@ -167,9 +170,13 @@ static std::string EscapeHash(const std::string &value) { return result; } -void ParsedIniLine::ParseFrom(const std::string &line) { - // TODO: Skip whitespace. - if (line[0] == '#') { +void ParsedIniLine::ParseFrom(std::string_view line) { + line = StripSpaces(line); + if (line.empty()) { + key.clear(); + value.clear(); + comment.clear(); + } else if (line[0] == '#') { key.clear(); value.clear(); comment = line; diff --git a/Common/Data/Format/IniFile.h b/Common/Data/Format/IniFile.h index 9146c0a086..b0e42c5ed3 100644 --- a/Common/Data/Format/IniFile.h +++ b/Common/Data/Format/IniFile.h @@ -33,7 +33,7 @@ public: } // Comments only come from "ParseFrom". - void ParseFrom(const std::string &line); + void ParseFrom(std::string_view line); void Reconstruct(std::string *output) const; // Having these as views allows a more efficient internal representation, like one joint string. diff --git a/Common/StringUtils.cpp b/Common/StringUtils.cpp index 3fea930ad2..5a21febb8f 100644 --- a/Common/StringUtils.cpp +++ b/Common/StringUtils.cpp @@ -239,18 +239,15 @@ std::string StringFromFormat(const char* format, ...) return temp; } -std::string StringFromInt(int value) -{ +std::string StringFromInt(int value) { char temp[16]; snprintf(temp, sizeof(temp), "%d", value); return temp; } // Turns " hej " into "hej". Also handles tabs. -std::string StripSpaces(const std::string &str) -{ +std::string StripSpaces(const std::string &str) { const size_t s = str.find_first_not_of(" \t\r\n"); - if (str.npos != s) return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); else @@ -268,6 +265,25 @@ std::string StripQuotes(const std::string& s) return s; } +// Turns " hej " into "hej". Also handles tabs. +std::string_view StripSpaces(std::string_view str) { + const size_t s = str.find_first_not_of(" \t\r\n"); + if (str.npos != s) + return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1); + else + return ""; +} + +// "\"hello\"" is turned to "hello" +// This one assumes that the string has already been space stripped in both +// ends, as done by StripSpaces above, for example. +std::string_view StripQuotes(std::string_view s) { + if (s.size() && '\"' == s[0] && '\"' == *s.rbegin()) + return s.substr(1, s.size() - 2); + else + return s; +} + void SplitString(const std::string& str, const char delim, std::vector& output) { size_t next = 0; diff --git a/Common/StringUtils.h b/Common/StringUtils.h index 49e8610457..75b5fc6db1 100644 --- a/Common/StringUtils.h +++ b/Common/StringUtils.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #ifdef _MSC_VER @@ -83,6 +84,9 @@ std::string StringFromInt(int value); std::string StripSpaces(const std::string &s); std::string StripQuotes(const std::string &s); +std::string_view StripSpaces(std::string_view s); +std::string_view StripQuotes(std::string_view s); + void SplitString(const std::string& str, const char delim, std::vector& output); void GetQuotedStrings(const std::string& str, std::vector& output);