Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix gcc-14 build #346

Merged
merged 2 commits into from
Apr 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 31 additions & 30 deletions src/core/include/URI.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,9 @@ class URI {
: _str(src) { parseURI(); }
explicit URI(std::string &&src)
: _str(std::move(src)) { parseURI(); }
URI(const URI &other)
noexcept { *this = other; }
URI(const URI &&other)
noexcept { *this = std::move(other); }
~URI() = default;
URI(const URI &other) noexcept { *this = other; }
URI(const URI &&other) noexcept { *this = std::move(other); }
~URI() = default;

URI &operator=(const URI &other) noexcept {
if (this == &other) {
Expand Down Expand Up @@ -195,18 +193,21 @@ class URI {
using namespace fmt::literals;
if (_path.empty() && _query.empty() && _fragment.empty()) return {};
return fmt::format("{opt_path_slash}{path}{qMark}{query}{hashMark}{fragment}",
"opt_path_slash"_a = (_path.empty() || _path.starts_with('/')) ? "" : "/", "path"_a = _path, // path
"qMark"_a = (_query.empty() || _query.starts_with('?')) ? "" : "?", "query"_a = _query, // query
"hashMark"_a = (_fragment.empty() || _fragment.starts_with('#')) ? "" : "#", "fragment"_a = encode(_fragment)); // fragment
fmt::arg("opt_path_slash", _path.empty() || _path.starts_with('/') ? "" : "/"),
fmt::arg("path", _path), // path
fmt::arg("qMark", (_query.empty() || _query.starts_with('?')) ? "" : "?"),
fmt::arg("query", _query), // query
fmt::arg("hashMark", (_fragment.empty() || _fragment.starts_with('#')) ? "" : "#"),
fmt::arg("fragment", encode(_fragment))); // fragment
}
inline std::optional<std::string> relativeRefNoFragment() const noexcept { // path + query
using namespace fmt::literals;
if (_path.empty() && _query.empty()) return {};
return fmt::format("{opt_path_slash}{path}{qMark}{query}",
"opt_path_slash"_a = (_path.empty() || _path.starts_with('/')) ? "" : "/", "path"_a = _path, // path
"qMark"_a = (_query.empty() || _query.starts_with('?')) ? "" : "?", "query"_a = _query); // query
fmt::arg("opt_path_slash", (_path.empty() || _path.starts_with('/')) ? "" : "/"), fmt::arg("path", _path), // path
fmt::arg("qMark", (_query.empty() || _query.starts_with('?')) ? "" : "?"), fmt::arg("query", _query)); // query
}
// clang-format om
// clang-format on

// decompose map
inline const std::unordered_map<std::string, std::optional<std::string>> &queryParamMap() const {
Expand Down Expand Up @@ -242,7 +243,7 @@ class URI {
continue;
}
const auto value = decode(_query.substr(readPos, _query.length() - readPos));
_queryMap[key] = value.empty() ? std::nullopt : std::optional(value);
_queryMap[key] = value.empty() ? std::nullopt : std::optional(value);
break;
} else {
auto key = std::string(_query.substr(readPos, _query.length() - readPos));
Expand All @@ -256,7 +257,7 @@ class URI {

// comparison operators
auto operator<=>(const URI &other) const noexcept { return _str <=> other.str(); }
bool operator==(const URI &other) const noexcept { return _str == other.str(); }
bool operator==(const URI &other) const noexcept { return _str == other.str(); }

class UriFactory {
mutable std::string _authority;
Expand All @@ -272,11 +273,11 @@ class URI {
std::unordered_map<std::string, std::optional<std::string>> _queryMap;

public:
UriFactory() = default;
UriFactory(const UriFactory &) = default;
UriFactory& operator=(const UriFactory &) = default;
UriFactory() = default;
UriFactory(const UriFactory &) = default;
UriFactory &operator=(const UriFactory &) = default;

UriFactory copy() const {
UriFactory copy() const {
return UriFactory(*this);
}

Expand Down Expand Up @@ -309,25 +310,25 @@ class URI {
std::string toString() const {
using namespace fmt::literals;
if (_authority.empty()) {
_authority = fmt::format("{user}{opt_colon1}{pwd}{at}{host}{opt_colon2}{port}", //
"user"_a = _userName, "opt_colon1"_a = (_pwd.empty() || _userName.empty()) ? "" : ":", /* user:pwd colon separator */
"pwd"_a = _userName.empty() ? "" : _pwd, "at"_a = _userName.empty() ? "" : "@", // 'user:pwd@' separator
"host"_a = _host, "opt_colon2"_a = _port ? ":" : "", "port"_a = _port ? std::to_string(_port.value()) : "");
_authority = fmt::format("{user}{opt_colon1}{pwd}{at}{host}{opt_colon2}{port}", //
fmt::arg("user", _userName), fmt::arg("opt_colon1", (_pwd.empty() || _userName.empty()) ? "" : ":"), /* user:pwd colon separator */
fmt::arg("pwd", _userName.empty() ? "" : _pwd), fmt::arg("at", _userName.empty() ? "" : "@"), // 'user:pwd@' separator
fmt::arg("host", _host), fmt::arg("opt_colon2", _port ? ":" : ""), fmt::arg("port", _port ? std::to_string(_port.value()) : ""));
}

// TODO: Calling toString multiple times appends parameters over and over again
for (const auto &[key, value] : _queryMap) {
_query += fmt::format("{opt_ampersand}{key}{opt_equal}{value}", // N.B. 'key=value' percent-encoding according to RFC 3986
"opt_ampersand"_a = _query.empty() ? "" : "&", "key"_a = encode(key), //
"opt_equal"_a = value ? "=" : "", "value"_a = value ? encode(value.value()) : "");
_query += fmt::format("{opt_ampersand}{key}{opt_equal}{value}", // N.B. 'key=value' percent-encoding according to RFC 3986
fmt::arg("opt_ampersand", _query.empty() ? "" : "&"), fmt::arg("key", encode(key)), //
fmt::arg("opt_equal", value ? "=" : ""), fmt::arg("value", value ? encode(value.value()) : ""));
}

return fmt::format("{scheme}{colon}{opt_auth_slash}{authority}{opt_path_slash}{path}{qMark}{query}{hashMark}{fragment}", //
"scheme"_a = _scheme, "colon"_a = _scheme.empty() ? "" : ":", // scheme
"opt_auth_slash"_a = (_authority.empty() || _authority.starts_with("//")) ? "" : "//", "authority"_a = _authority, // authority
"opt_path_slash"_a = (_path.empty() || _path.starts_with('/') || _authority.empty()) ? "" : "/", "path"_a = _path, // path
"qMark"_a = (_query.empty() || _query.starts_with('?')) ? "" : "?", "query"_a = _query, // query
"hashMark"_a = (_fragment.empty() || _fragment.starts_with('#')) ? "" : "#", "fragment"_a = encode(_fragment)); // fragment
return fmt::format("{scheme}{colon}{opt_auth_slash}{authority}{opt_path_slash}{path}{qMark}{query}{hashMark}{fragment}", //
fmt::arg("scheme", _scheme), fmt::arg("colon", _scheme.empty() ? "" : ":"), // scheme
fmt::arg("opt_auth_slash", (_authority.empty() || _authority.starts_with("//")) ? "" : "//"), fmt::arg("authority", _authority), // authority
fmt::arg("opt_path_slash", (_path.empty() || _path.starts_with('/') || _authority.empty()) ? "" : "/"), fmt::arg("path", _path), // path
fmt::arg("qMark", (_query.empty() || _query.starts_with('?')) ? "" : "?"), fmt::arg("query", _query), // query
fmt::arg("hashMark", (_fragment.empty() || _fragment.starts_with('#')) ? "" : "#"), fmt::arg("fragment", encode(_fragment))); // fragment
}

URI build() {
Expand Down
Loading