util/UriRelative: use std::string_view internally
This commit is contained in:
parent
c5f037fa64
commit
9976665cc7
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2021 Max Kellermann <max.kellermann@gmail.com>
|
* Copyright 2008-2022 Max Kellermann <max.kellermann@gmail.com>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -31,13 +31,14 @@
|
|||||||
#include "UriExtract.hxx"
|
#include "UriExtract.hxx"
|
||||||
#include "StringAPI.hxx"
|
#include "StringAPI.hxx"
|
||||||
#include "StringCompare.hxx"
|
#include "StringCompare.hxx"
|
||||||
#include "StringView.hxx"
|
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
using std::string_view_literals::operator""sv;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
uri_is_child(const char *parent, const char *child) noexcept
|
uri_is_child(const char *parent, const char *child) noexcept
|
||||||
{
|
{
|
||||||
@ -90,50 +91,51 @@ uri_apply_base(std::string_view uri, std::string_view base) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ClearFilename(StringView &path) noexcept
|
ClearFilename(std::string_view &path) noexcept
|
||||||
{
|
{
|
||||||
const char *slash = path.FindLast('/');
|
const auto slash = path.rfind('/');
|
||||||
if (slash != nullptr)
|
if (slash != path.npos)
|
||||||
path.SetEnd(slash + 1);
|
path = path.substr(0, slash + 1);
|
||||||
else
|
else
|
||||||
path.size = 0;
|
path = path.substr(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
StripLeadingSlashes(StringView &s) noexcept
|
StripLeadingSlashes(std::string_view &s) noexcept
|
||||||
{
|
{
|
||||||
while (!s.empty() && s.front() == '/')
|
while (s.starts_with('/'))
|
||||||
s.pop_front();
|
s.remove_prefix(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ConsumeLastSegment(StringView &path) noexcept
|
ConsumeLastSegment(std::string_view &path) noexcept
|
||||||
{
|
{
|
||||||
assert(!path.empty());
|
assert(!path.empty());
|
||||||
assert(path.back() == '/');
|
assert(path.back() == '/');
|
||||||
|
|
||||||
path.pop_back();
|
path.remove_suffix(1);
|
||||||
const char *slash = path.FindLast('/');
|
|
||||||
if (slash == nullptr)
|
const auto slash = path.rfind('/');
|
||||||
|
if (slash == path.npos)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
path.SetEnd(slash + 1);
|
path = path.substr(0, slash + 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ConsumeSpecial(StringView &relative_path, StringView &base_path) noexcept
|
ConsumeSpecial(std::string_view &relative_path, std::string_view &base_path) noexcept
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
if (relative_path.SkipPrefix("./")) {
|
if (SkipPrefix(relative_path, "./"sv)) {
|
||||||
StripLeadingSlashes(relative_path);
|
StripLeadingSlashes(relative_path);
|
||||||
} else if (relative_path.SkipPrefix("../")) {
|
} else if (SkipPrefix(relative_path, "../"sv)) {
|
||||||
StripLeadingSlashes(relative_path);
|
StripLeadingSlashes(relative_path);
|
||||||
|
|
||||||
if (!ConsumeLastSegment(base_path))
|
if (!ConsumeLastSegment(base_path))
|
||||||
return false;
|
return false;
|
||||||
} else if (relative_path.Equals(".")) {
|
} else if (relative_path == "."sv) {
|
||||||
relative_path.pop_front();
|
relative_path.remove_prefix(1);
|
||||||
return true;
|
return true;
|
||||||
} else
|
} else
|
||||||
return true;
|
return true;
|
||||||
@ -170,29 +172,29 @@ uri_apply_relative(std::string_view relative_uri,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringView relative_path{relative_uri};
|
std::string_view relative_path{relative_uri};
|
||||||
|
|
||||||
const auto _base_path = uri_get_path(base_uri);
|
const auto _base_path = uri_get_path(base_uri);
|
||||||
if (_base_path.data() == nullptr) {
|
if (_base_path.data() == nullptr) {
|
||||||
std::string result(base_uri);
|
std::string result(base_uri);
|
||||||
if (relative_path.front() != '/')
|
if (relative_path.front() != '/')
|
||||||
result.push_back('/');
|
result.push_back('/');
|
||||||
while (relative_path.SkipPrefix("./")) {}
|
while (SkipPrefix(relative_path, "./"sv)) {}
|
||||||
if (relative_path.StartsWith("../"))
|
if (relative_path.starts_with("../"sv))
|
||||||
return {};
|
return {};
|
||||||
if (!relative_path.Equals("."))
|
if (relative_path != "."sv)
|
||||||
result += relative_path;
|
result += relative_path;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringView base_path(_base_path);
|
std::string_view base_path(_base_path);
|
||||||
ClearFilename(base_path);
|
ClearFilename(base_path);
|
||||||
|
|
||||||
if (!ConsumeSpecial(relative_path, base_path))
|
if (!ConsumeSpecial(relative_path, base_path))
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
std::string result(base_uri.data(), _base_path.data());
|
std::string result(base_uri.data(), _base_path.data());
|
||||||
result.append(base_path.data, base_path.size);
|
result.append(base_path);
|
||||||
result.append(relative_path);
|
result.append(relative_path);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2008-2021 Max Kellermann <max.kellermann@gmail.com>
|
* Copyright 2008-2022 Max Kellermann <max.kellermann@gmail.com>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@ -27,8 +27,7 @@
|
|||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef URI_RELATIVE_HXX
|
#pragma once
|
||||||
#define URI_RELATIVE_HXX
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@ -58,5 +57,3 @@ uri_apply_base(std::string_view uri, std::string_view base) noexcept;
|
|||||||
std::string
|
std::string
|
||||||
uri_apply_relative(std::string_view relative_uri,
|
uri_apply_relative(std::string_view relative_uri,
|
||||||
std::string_view base_uri) noexcept;
|
std::string_view base_uri) noexcept;
|
||||||
|
|
||||||
#endif
|
|
||||||
|
Loading…
Reference in New Issue
Block a user