util/UriExtract: uri_get_path() returns std::string_view

This commit is contained in:
Max Kellermann 2020-03-13 18:15:21 +01:00
parent 9a164668f2
commit 332f480ec3
4 changed files with 40 additions and 31 deletions

View File

@ -456,11 +456,11 @@ CurlStorage::GetInfo(const char *uri_utf8, gcc_unused bool follow)
} }
gcc_pure gcc_pure
static const char * static std::string_view
UriPathOrSlash(const char *uri) noexcept UriPathOrSlash(const char *uri) noexcept
{ {
const char *path = uri_get_path(uri); auto path = uri_get_path(uri);
if (path == nullptr) if (path.data() == nullptr)
path = "/"; path = "/";
return path; return path;
} }
@ -495,7 +495,7 @@ private:
*/ */
gcc_pure gcc_pure
StringView HrefToEscapedName(const char *href) const noexcept { StringView HrefToEscapedName(const char *href) const noexcept {
const char *path = uri_get_path(href); StringView path = uri_get_path(href);
if (path == nullptr) if (path == nullptr)
return nullptr; return nullptr;
@ -504,16 +504,16 @@ private:
case in hex digits in escaped characters; TODO: case in hex digits in escaped characters; TODO:
implement properly */ implement properly */
path = StringAfterPrefixIgnoreCase(path, base_path.c_str()); path = StringAfterPrefixIgnoreCase(path, base_path.c_str());
if (path == nullptr || *path == 0) if (path == nullptr || path.empty())
return nullptr; return nullptr;
const char *slash = strchr(path, '/'); const char *slash = path.Find('/');
if (slash == nullptr) if (slash == nullptr)
/* regular file */ /* regular file */
return path; return path;
else if (slash[1] == 0) else if (slash == &path.back())
/* trailing slash: collection; strip the slash */ /* trailing slash: collection; strip the slash */
return {path, slash}; return {path.data, slash};
else else
/* strange, better ignore it */ /* strange, better ignore it */
return nullptr; return nullptr;

View File

@ -48,12 +48,12 @@ IsValidSchemeChar(char ch)
gcc_pure gcc_pure
static bool static bool
IsValidScheme(StringView p) noexcept IsValidScheme(std::string_view p) noexcept
{ {
if (p.empty() || !IsValidSchemeStart(p.front())) if (p.empty() || !IsValidSchemeStart(p.front()))
return false; return false;
for (size_t i = 1; i < p.size; ++i) for (size_t i = 1; i < p.size(); ++i)
if (!IsValidSchemeChar(p[i])) if (!IsValidSchemeChar(p[i]))
return false; return false;
@ -65,18 +65,23 @@ IsValidScheme(StringView p) noexcept
* double slash). * double slash).
*/ */
gcc_pure gcc_pure
static const char * static std::string_view
uri_after_scheme(const char *uri) noexcept uri_after_scheme(std::string_view uri) noexcept
{ {
if (uri[0] == '/' && uri[1] == '/' && uri[2] != '/') if (uri.length() > 2 &&
return uri + 2; uri[0] == '/' && uri[1] == '/' && uri[2] != '/')
return uri.substr(2);
const char *colon = strchr(uri, ':'); auto colon = uri.find(':');
return colon != nullptr && if (colon == std::string_view::npos ||
IsValidScheme({uri, colon}) && !IsValidScheme(uri.substr(0, colon)))
colon[1] == '/' && colon[2] == '/' return {};
? colon + 3
: nullptr; uri = uri.substr(colon + 1);
if (uri[0] != '/' || uri[1] != '/')
return {};
return uri.substr(2);
} }
bool bool
@ -101,12 +106,16 @@ uri_is_relative_path(const char *uri) noexcept
return !uri_has_scheme(uri) && *uri != '/'; return !uri_has_scheme(uri) && *uri != '/';
} }
const char * std::string_view
uri_get_path(const char *uri) noexcept uri_get_path(std::string_view uri) noexcept
{ {
const char *ap = uri_after_scheme(uri); auto ap = uri_after_scheme(uri);
if (ap != nullptr) if (ap.data() != nullptr) {
return strchr(ap, '/'); auto slash = ap.find('/');
if (slash == std::string_view::npos)
return {};
return ap.substr(slash);
}
return uri; return uri;
} }

View File

@ -57,9 +57,9 @@ uri_is_relative_path(const char *uri) noexcept;
* Returns the URI path (including the query string) or nullptr if the * Returns the URI path (including the query string) or nullptr if the
* given URI has no path. * given URI has no path.
*/ */
gcc_pure gcc_nonnull_all gcc_pure
const char * std::string_view
uri_get_path(const char *uri) noexcept; uri_get_path(std::string_view uri) noexcept;
gcc_pure gcc_pure
const char * const char *

View File

@ -163,8 +163,8 @@ uri_apply_relative(const std::string &relative_uri,
return base_uri.substr(0, i) + relative_uri; return base_uri.substr(0, i) + relative_uri;
} }
const char *_base_path = uri_get_path(base_uri.c_str()); const auto _base_path = uri_get_path(base_uri);
if (_base_path == nullptr) { if (_base_path.data() == nullptr) {
std::string result(base_uri); std::string result(base_uri);
if (relative_uri.front() != '/') if (relative_uri.front() != '/')
result.push_back('/'); result.push_back('/');
@ -183,7 +183,7 @@ uri_apply_relative(const std::string &relative_uri,
if (!ConsumeSpecial(relative_path, base_path)) if (!ConsumeSpecial(relative_path, base_path))
return {}; return {};
std::string result(base_uri.c_str(), _base_path); std::string result(base_uri.data(), _base_path.data());
result.append(base_path.data, base_path.size); result.append(base_path.data, base_path.size);
result.append(relative_path); result.append(relative_path);
return result; return result;