10 #include <wordring/whatwg/url/infra.hpp>
11 #include <wordring/whatwg/url/url_defs.hpp>
13 #include <wordring/whatwg/encoding/encoding.hpp>
14 #include <wordring/whatwg/infra/infra.hpp>
15 #include <wordring/whatwg/infra/unicode.hpp>
34 enum class host_type_name : std::uint32_t
49 domain_base(std::u32string
const& val) : m_value(val) {}
51 std::u32string m_value;
72 std::u32string m_value;
88 using value_type = std::variant<
96 template <
typename Value>
97 host_base(Value
const& val) : m_value(val) {}
99 template <
typename Value>
100 host_base(Value&& val) : m_value(std::move(val)) {}
102 host_type_name type()
104 switch (m_value.index())
106 case 0:
return host_type_name::Domain;
107 case 1:
return host_type_name::Ipv4Address;
108 case 2:
return host_type_name::Ipv6Address;
109 case 3:
return host_type_name::OpaqueHost;
110 case 4:
return host_type_name::EmptyHost;
114 return static_cast<host_type_name
>(0);
189 std::u32string
domain_to_ascii(std::u32string
const& s,
bool beStrict, std::error_code& ec);
191 inline std::u32string
domain_to_ascii(std::u32string
const& s, std::error_code& ec)
225 if (s.size() < 3 || s.front() != U
'[' || s.back() != U
']')
return false;
265 std::optional<host_base>
parse_ipv4(std::u32string
const& in, std::error_code& ec);
266 std::optional<host_base>
parse_ipv6(std::u32string
const& in, std::error_code& ec);
267 std::optional<host_base>
parse_opaque_host(std::u32string
const& in, std::error_code& ec);
269 std::pair<std::optional<std::uint32_t>,
bool> parse_ipv4_number(std::u32string s);
279 std::u32string
const& in,
bool isNotSpecial, std::error_code& ec)
282 if (!in.empty() && in.front() == U
'[')
284 if (in.back() != U
']')
287 return std::optional<host_base>();
289 return parse_ipv6(std::u32string(++in.begin(), --in.end()), ec);
301 std::u32string domain;
306 if (ec)
return std::optional<host_base>();
311 return std::optional<host_base>();
314 std::optional<host_base> ipv4 =
parse_ipv4(asciiDomain, ec);
316 if(ec)
return std::optional<host_base>();
318 return std::optional<host_base>();
321 inline std::optional<host_base>
parse_host(std::u32string
const& in, std::error_code& ec)
330 inline std::optional<host_base>
parse_ipv4(std::u32string
const& in, std::error_code& ec)
333 bool validationError =
false;
335 std::vector<std::u32string> parts;
338 if (!parts.empty() && parts.back().empty())
340 validationError =
true;
341 if (1 < parts.size()) parts.erase(--parts.end());
346 return std::optional<host_base>();
349 inline std::pair<std::optional<std::uint32_t>,
bool> parse_ipv4_number(std::u32string s)
352 bool validationError =
false;
354 std::uint32_t R = 10;
356 if (2 <= s.size() && s.front() == U
'0' && (s.at(1) == U
'x' || s.at(1) == U
'X'))
358 validationError =
true;
363 else if (2 <= s.size() && s.front() == U
'0')
365 validationError =
true;
370 if (s.empty())
return std::make_pair(std::optional<std::uint32_t>(), validationError);
372 std::u32string_view sv = R == 8 ? U
"012345678" : (R == 10 ? U
"0123456789" : U
"0123456789abcdefABCDEF");
373 for (char32_t cp : s)
if (std::find(sv.begin(), sv.end(), cp) == sv.end())
375 return std::make_pair(std::optional<std::uint32_t>(), validationError);
379 std::copy(s.begin(), s.end(), std::back_inserter(tmp));
381 std::from_chars(tmp.data(), tmp.data() + tmp.length(), i, R);
383 return std::make_pair(std::optional<std::uint32_t>(i), validationError);
390 inline std::optional<host_base>
parse_ipv6(std::u32string
const& in, std::error_code& ec)
392 return std::optional<host_base>();
400 inline std::optional<host_base>
parse_opaque_host(std::u32string
const& in, std::error_code& ec)
402 return std::optional<host_base>();