#ifndef PKMNLIB_ANGELSCRIPTMETADATA_HPP #define PKMNLIB_ANGELSCRIPTMETADATA_HPP #include #include #include class AngelscriptMetadata { public: explicit AngelscriptMetadata(const std::string& metadataString) { Parse(metadataString); } inline const ArbUt::StringView& GetIdentifier() const noexcept { return _identifier; } inline const std::string& GetParameter(const ArbUt::StringView& name) const noexcept { return _parameters.Get(name); } private: ArbUt::StringView _identifier; ArbUt::Dictionary _parameters; size_t ReadUpToOrEnd(const std::string& s, const char symbol, size_t start) { for (size_t i = start; i < s.length(); ++i) { if (s.at(i) == symbol) { return i; } } return s.length(); } size_t FindNextNonSpace(const std::string& s, size_t start) { for (size_t i = start; i < s.length(); ++i) { if (s.at(i) != ' ') { return i; } } return s.length(); } void Parse(const std::string& metadataString) { auto idEnd = ReadUpToOrEnd(metadataString, ' ', 0); _identifier = ArbUt::StringView(metadataString.substr(0, idEnd).c_str(), idEnd); auto current = idEnd; while (true) { current = FindNextNonSpace(metadataString, current); if (current >= metadataString.length()) { break; } ParseParameter(metadataString, current); } } void ParseParameter(const std::string& metadataString, size_t& current) { auto start = current; current = ReadUpToOrEnd(metadataString, '=', current); auto name = ArbUt::StringView(metadataString.substr(start, current - start).c_str(), current - start); current++; start = current; auto isQuoted = metadataString[current] == '"'; if (isQuoted) { current++; start++; current = ReadUpToOrEnd(metadataString, '"', current); } else { current = ReadUpToOrEnd(metadataString, ' ', current); } auto value = metadataString.substr(start, current - start); _parameters.Insert(name, value); if (isQuoted) { current += 1; } } }; #endif // PKMNLIB_ANGELSCRIPTMETADATA_HPP