20#include <unordered_map>
26namespace hi {
inline namespace v1 {
48 constexpr URL() noexcept = default;
49 constexpr
URL(
URL const&) noexcept = default;
50 constexpr
URL(
URL&&) noexcept = default;
51 constexpr
URL& operator=(
URL const&) noexcept = default;
52 constexpr
URL& operator=(
URL&&) noexcept = default;
69 explicit URL(std::filesystem::path
const&
path) :
URI(make_file_url_string(
path)) {}
78 if (validate_scheme and not(not
scheme() or
scheme() ==
"file")) {
79 throw url_error(
"URL::generic_path() is only valid on a file: scheme URL");
84 hilet first = p.begin();
88 auto has_root_name =
false;
92 if (not server.empty() and server !=
"localhost") {
93 validate_file_server(server);
103 hi_assert(has_root_name ==
false or p.absolute());
105 if (p.double_absolute()) {
109 throw url_error(
"file URL has two server names.");
112 has_root_name =
true;
116 validate_file_server(*it);
122 auto empty_segment =
false;
124 validate_file_segment(*it);
125 empty_segment = it->empty();
127 if (it == first and empty_segment) {
131 }
else if (
auto i = it->find(
':'); i != std::string::npos) {
134 throw url_error(
"file URL contains a device name which is a security issue.");
137 if (has_root_name or p.absolute()) {
140 r += has_root_name ?
'$' :
':';
153 has_root_name =
true;
165 for (; it != last; ++it) {
166 validate_file_segment(*it);
167 empty_segment = it->empty();
172 if (not empty_segment) {
187 if (
auto scheme_ =
scheme()) {
188 if (scheme_ ==
"resource") {
194 throw url_error(std::format(
"Resource {} not found.", *
this));
197 }
else if (scheme_ ==
"file") {
200 throw url_error(
"URL can not be converted to a filesystem path.");
210 operator std::filesystem::path()
const
215 [[nodiscard]]
constexpr friend URL operator/(
URL const& base,
URI const& ref)
noexcept
217 return URL{up_cast<URI const&>(base) / ref};
220 [[nodiscard]]
constexpr friend URL operator/(
URL const& base, std::string_view ref)
noexcept
222 return URL{up_cast<URI const&>(base) / ref};
226 constexpr void static validate_file_segment(std::string_view segment)
228 for (
auto c : segment) {
229 if (c ==
'/' or c ==
'\\') {
230 throw url_error(
"Filename server name may not contain slash or back-slash.");
235 constexpr void static validate_file_server(std::string_view server)
237 for (
auto c : server) {
238 if (c ==
'/' or c ==
'\\') {
239 throw url_error(
"Filename segments may not contain slash or back-slash.");
244 static std::string make_file_url_string(std::filesystem::path
const&
path)
246 auto r = std::u8string{};
248 hilet root_name =
path.root_name().generic_u8string();
249 if (root_name.empty()) {
251 if (not
path.root_directory().empty()) {
253 r += u8
"file:" +
path.root_directory().generic_u8string();
259 }
else if (
hilet i = root_name.find(
':'); i != std::string::npos) {
262 r += u8
"file:///" + root_name +
path.root_directory().generic_u8string();
264 throw url_error(
"Paths containing a device are not allowed to be converted to a URL.");
268 r += u8
"file://" + root_name +
path.root_directory().generic_u8string();
269 if (not
path.root_directory().empty()) {
270 throw url_error(
"Invalid path contains server name without a root directory.");
274 return to_string(r +
path.relative_path().generic_u8string());
288template<
typename CharT>
289struct std::formatter<
hi::URL, CharT> : std::formatter<hi::URI, CharT> {
290 auto format(
hi::URL const& t,
auto& fc)
292 return std::formatter<hi::URI, CharT>::format(t, fc);
Utilities to assert and bound check.
#define hi_assert(expression)
Assert if expression is true.
Definition assert.hpp:86
functions to locate files and directories.
Utilities used by the HikoGUI library itself.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
String conversion functions.
constexpr std::u8string to_u8string(std::u32string_view rhs) noexcept
Conversion from UTF-32 to UTF-8.
Definition to_string.hpp:111
std::optional< std::filesystem::path > find_path(path_location location, std::filesystem::path const &ref) noexcept
Find a path.
Definition path_location.hpp:83
@ resource_dirs
The location of application resources.
@ other
The gui_event does not have associated data.
DOXYGEN BUG.
Definition algorithm.hpp:15
The HikoGUI namespace.
Definition ascii.hpp:19
Definition exception.hpp:108
A Uniform Resource Identifier.
Definition URI.hpp:41
constexpr std::optional< authority_type > const & authority() const noexcept
Get the authority-component of the URI.
Definition URI.hpp:541
constexpr std::optional< std::string > const & scheme() const noexcept
Get the scheme-component of the URI.
Definition URI.hpp:518
Universal Resource Locator.
Definition URL.hpp:44
constexpr URL() noexcept=default
Create an empty URL.
URL(std::filesystem::path const &path)
Convert a filesystem-path to a file-scheme URL.
Definition URL.hpp:69
constexpr URL(URI &&other) noexcept
Convert a URI to an URL.
Definition URL.hpp:60
operator std::filesystem::path() const
Definition URL.hpp:210
std::filesystem::path filesystem_path() const
Create a filesystem path from a file URL.
Definition URL.hpp:185
constexpr std::u8string filesystem_path_generic_u8string(bool validate_scheme=true) const
Return a generic path.
Definition URL.hpp:76