5#ifndef ADA_URL_AGGREGATOR_INL_H 
    6#define ADA_URL_AGGREGATOR_INL_H 
   22inline void url_aggregator::update_base_authority(
 
   23    std::string_view base_buffer, 
const ada::url_components &base) {
 
   24  std::string_view input = base_buffer.substr(
 
   26  ada_log(
"url_aggregator::update_base_authority ", input);
 
   28  bool input_starts_with_dash = input.starts_with(
"//");
 
   29  uint32_t diff = components.host_start - components.protocol_end;
 
   31  buffer.erase(components.protocol_end,
 
   32               components.host_start - components.protocol_end);
 
   33  components.username_end = components.protocol_end;
 
   35  if (input_starts_with_dash) {
 
   36    input.remove_prefix(2);
 
   38    buffer.insert(components.protocol_end, 
"//");
 
   39    components.username_end += 2;
 
   42  size_t password_delimiter = input.find(
':');
 
   46  if (password_delimiter != std::string_view::npos) {
 
   48    std::string_view username = input.substr(0, password_delimiter);
 
   49    std::string_view password = input.substr(password_delimiter + 1);
 
   51    buffer.insert(components.protocol_end + diff, username);
 
   52    diff += uint32_t(username.size());
 
   53    buffer.insert(components.protocol_end + diff, 
":");
 
   54    components.username_end = components.protocol_end + diff;
 
   55    buffer.insert(components.protocol_end + diff + 1, password);
 
   56    diff += uint32_t(password.size()) + 1;
 
   57  } 
else if (!input.empty()) {
 
   59    buffer.insert(components.protocol_end + diff, input);
 
   60    components.username_end =
 
   61        components.protocol_end + diff + uint32_t(input.size());
 
   62    diff += uint32_t(input.size());
 
   65  components.host_start += diff;
 
   67  if (buffer.size() > 
base.host_start && buffer[
base.host_start] != 
'@') {
 
   68    buffer.insert(components.host_start, 
"@");
 
   71  components.host_end += diff;
 
   72  components.pathname_start += diff;
 
   74    components.search_start += diff;
 
   77    components.hash_start += diff;
 
   81inline void url_aggregator::update_unencoded_base_hash(std::string_view input) {
 
   82  ada_log(
"url_aggregator::update_unencoded_base_hash ", input, 
" [",
 
   83          input.size(), 
" bytes], buffer is '", buffer, 
"' [", buffer.size(),
 
   84          " bytes] components.hash_start = ", components.hash_start);
 
   88    buffer.resize(components.hash_start);
 
   90  components.hash_start = uint32_t(buffer.size());
 
   92  bool encoding_required = unicode::percent_encode<true>(
 
   96  if (!encoding_required) {
 
   99  ada_log(
"url_aggregator::update_unencoded_base_hash final buffer is '",
 
  100          buffer, 
"' [", buffer.size(), 
" bytes]");
 
  105    uint32_t start, uint32_t end, std::string_view input) {
 
  106  uint32_t current_length = end - start;
 
  107  uint32_t input_size = uint32_t(input.size());
 
  108  uint32_t new_difference = input_size - current_length;
 
  110  if (current_length == 0) {
 
  111    buffer.insert(start, input);
 
  112  } 
else if (input_size == current_length) {
 
  113    buffer.replace(start, input_size, input);
 
  114  } 
else if (input_size < current_length) {
 
  115    buffer.erase(start, current_length - input_size);
 
  116    buffer.replace(start, input_size, input);
 
  118    buffer.replace(start, current_length, input.substr(0, current_length));
 
  119    buffer.insert(start + current_length, input.substr(current_length));
 
  122  return new_difference;
 
  125inline void url_aggregator::update_base_hostname(
const std::string_view input) {
 
  126  ada_log(
"url_aggregator::update_base_hostname ", input, 
" [", input.size(),
 
  127          " bytes], buffer is '", buffer, 
"' [", buffer.size(), 
" bytes]");
 
  132  add_authority_slashes_if_needed();
 
  134  bool has_credentials = components.protocol_end + 2 < components.host_start;
 
  135  uint32_t new_difference =
 
  136      replace_and_resize(components.host_start, components.host_end, input);
 
  139    buffer.insert(components.host_start, 
"@");
 
  142  components.host_end += new_difference;
 
  143  components.pathname_start += new_difference;
 
  145    components.search_start += new_difference;
 
  148    components.hash_start += new_difference;
 
  155  ada_log(
"url_aggregator::get_pathname_length");
 
  156  uint32_t ending_index = uint32_t(buffer.size());
 
  158    ending_index = components.search_start;
 
  160    ending_index = components.hash_start;
 
  162  return ending_index - components.pathname_start;
 
 
  170inline void url_aggregator::update_base_search(std::string_view input) {
 
  171  ada_log(
"url_aggregator::update_base_search ", input);
 
  179  if (input[0] == 
'?') {
 
  180    input.remove_prefix(1);
 
  185      components.search_start = uint32_t(buffer.size());
 
  188      buffer.resize(components.search_start + 1);
 
  191    buffer.append(input);
 
  194      components.search_start = components.hash_start;
 
  196      buffer.erase(components.search_start,
 
  197                   components.hash_start - components.search_start);
 
  198      components.hash_start = components.search_start;
 
  201    buffer.insert(components.search_start, 
"?");
 
  202    buffer.insert(components.search_start + 1, input);
 
  203    components.hash_start += uint32_t(input.size() + 1);  
 
  209inline void url_aggregator::update_base_search(
 
  210    std::string_view input, 
const uint8_t query_percent_encode_set[]) {
 
  211  ada_log(
"url_aggregator::update_base_search ", input,
 
  218      components.search_start = uint32_t(buffer.size());
 
  221      buffer.resize(components.search_start + 1);
 
  224    bool encoding_required =
 
  225        unicode::percent_encode<true>(input, query_percent_encode_set, buffer);
 
  228    if (!encoding_required) {
 
  229      buffer.append(input);
 
  233      components.search_start = components.hash_start;
 
  235      buffer.erase(components.search_start,
 
  236                   components.hash_start - components.search_start);
 
  237      components.hash_start = components.search_start;
 
  240    buffer.insert(components.search_start, 
"?");
 
  243    if (idx == input.size()) {
 
  244      buffer.insert(components.search_start + 1, input);
 
  245      components.hash_start += uint32_t(input.size() + 1);  
 
  247      buffer.insert(components.search_start + 1, input, 0, idx);
 
  248      input.remove_prefix(idx);
 
  251      std::string encoded =
 
  252          ada::unicode::percent_encode(input, query_percent_encode_set);
 
  253      buffer.insert(components.search_start + idx + 1, encoded);
 
  254      components.hash_start +=
 
  255          uint32_t(encoded.size() + idx + 1);  
 
  262inline void url_aggregator::update_base_pathname(
const std::string_view input) {
 
  263  ada_log(
"url_aggregator::update_base_pathname '", input, 
"' [", input.size(),
 
  268  const bool begins_with_dashdash = input.starts_with(
"//");
 
  269  if (!begins_with_dashdash && has_dash_dot()) {
 
  279    buffer.insert(components.pathname_start, 
"/.");
 
  280    components.pathname_start += 2;
 
  283  uint32_t difference = replace_and_resize(
 
  284      components.pathname_start,
 
  287    components.search_start += difference;
 
  290    components.hash_start += difference;
 
  295inline void url_aggregator::append_base_pathname(
const std::string_view input) {
 
  296  ada_log(
"url_aggregator::append_base_pathname ", input, 
" ", 
to_string(),
 
  300#if ADA_DEVELOPMENT_CHECKS 
  303  path_expected.append(input);
 
  305  uint32_t ending_index = uint32_t(buffer.size());
 
  307    ending_index = components.search_start;
 
  309    ending_index = components.hash_start;
 
  311  buffer.insert(ending_index, input);
 
  314    components.search_start += uint32_t(input.size());
 
  317    components.hash_start += uint32_t(input.size());
 
  319#if ADA_DEVELOPMENT_CHECKS 
  322      path_expected, path_after,
 
  323      "append_base_pathname problem after inserting " + std::string(input));
 
  328inline void url_aggregator::update_base_username(
const std::string_view input) {
 
  329  ada_log(
"url_aggregator::update_base_username '", input, 
"' ", 
to_string(),
 
  334  add_authority_slashes_if_needed();
 
  337  bool host_starts_with_at = buffer.size() > components.host_start &&
 
  338                             buffer[components.host_start] == 
'@';
 
  339  uint32_t diff = replace_and_resize(components.protocol_end + 2,
 
  340                                     components.username_end, input);
 
  342  components.username_end += diff;
 
  343  components.host_start += diff;
 
  345  if (!input.empty() && !host_starts_with_at) {
 
  346    buffer.insert(components.host_start, 
"@");
 
  348  } 
else if (input.empty() && host_starts_with_at && !
has_password) {
 
  351    buffer.erase(components.host_start, 1);
 
  355  components.host_end += diff;
 
  356  components.pathname_start += diff;
 
  358    components.search_start += diff;
 
  361    components.hash_start += diff;
 
  366inline void url_aggregator::append_base_username(
const std::string_view input) {
 
  367  ada_log(
"url_aggregator::append_base_username ", input);
 
  370#if ADA_DEVELOPMENT_CHECKS 
  373  username_expected.append(input);
 
  375  add_authority_slashes_if_needed();
 
  382  uint32_t difference = uint32_t(input.size());
 
  383  buffer.insert(components.username_end, input);
 
  384  components.username_end += difference;
 
  385  components.host_start += difference;
 
  387  if (buffer[components.host_start] != 
'@' &&
 
  388      components.host_start != components.host_end) {
 
  389    buffer.insert(components.host_start, 
"@");
 
  393  components.host_end += difference;
 
  394  components.pathname_start += difference;
 
  396    components.search_start += difference;
 
  399    components.hash_start += difference;
 
  401#if ADA_DEVELOPMENT_CHECKS 
  404      username_expected, username_after,
 
  405      "append_base_username problem after inserting " + std::string(input));
 
  410constexpr void url_aggregator::clear_password() {
 
  411  ada_log(
"url_aggregator::clear_password ", 
to_string());
 
  417  uint32_t diff = components.host_start - components.username_end;
 
  418  buffer.erase(components.username_end, diff);
 
  419  components.host_start -= diff;
 
  420  components.host_end -= diff;
 
  421  components.pathname_start -= diff;
 
  423    components.search_start -= diff;
 
  426    components.hash_start -= diff;
 
  430inline void url_aggregator::update_base_password(
const std::string_view input) {
 
  431  ada_log(
"url_aggregator::update_base_password ", input);
 
  435  add_authority_slashes_if_needed();
 
  443      update_base_username(
"");
 
  450  uint32_t difference = uint32_t(input.size());
 
  452  if (password_exists) {
 
  453    uint32_t current_length =
 
  454        components.host_start - components.username_end - 1;
 
  455    buffer.erase(components.username_end + 1, current_length);
 
  456    difference -= current_length;
 
  458    buffer.insert(components.username_end, 
":");
 
  462  buffer.insert(components.username_end + 1, input);
 
  463  components.host_start += difference;
 
  468  if (buffer[components.host_start] != 
'@') {
 
  469    buffer.insert(components.host_start, 
"@");
 
  473  components.host_end += difference;
 
  474  components.pathname_start += difference;
 
  476    components.search_start += difference;
 
  479    components.hash_start += difference;
 
  484inline void url_aggregator::append_base_password(
const std::string_view input) {
 
  485  ada_log(
"url_aggregator::append_base_password ", input, 
" ", 
to_string(),
 
  489#if ADA_DEVELOPMENT_CHECKS 
  491  std::string password_expected = std::string(
get_password());
 
  492  password_expected.append(input);
 
  494  add_authority_slashes_if_needed();
 
  501  uint32_t difference = uint32_t(input.size());
 
  503    buffer.insert(components.host_start, input);
 
  506    buffer.insert(components.username_end, 
":");
 
  507    buffer.insert(components.username_end + 1, input);
 
  509  components.host_start += difference;
 
  514  if (buffer[components.host_start] != 
'@') {
 
  515    buffer.insert(components.host_start, 
"@");
 
  519  components.host_end += difference;
 
  520  components.pathname_start += difference;
 
  522    components.search_start += difference;
 
  525    components.hash_start += difference;
 
  527#if ADA_DEVELOPMENT_CHECKS 
  530      password_expected, password_after,
 
  531      "append_base_password problem after inserting " + std::string(input));
 
  536inline void url_aggregator::update_base_port(uint32_t input) {
 
  537  ada_log(
"url_aggregator::update_base_port");
 
  545  std::string value = helpers::concat(
":", std::to_string(input));
 
  546  uint32_t difference = uint32_t(value.size());
 
  549    difference -= components.pathname_start - components.host_end;
 
  550    buffer.erase(components.host_end,
 
  551                 components.pathname_start - components.host_end);
 
  554  buffer.insert(components.host_end, value);
 
  555  components.pathname_start += difference;
 
  557    components.search_start += difference;
 
  560    components.hash_start += difference;
 
  562  components.port = input;
 
  567  ada_log(
"url_aggregator::clear_port");
 
  572  uint32_t length = components.pathname_start - components.host_end;
 
  573  buffer.erase(components.host_end, length);
 
  574  components.pathname_start -= length;
 
  576    components.search_start -= length;
 
  579    components.hash_start -= length;
 
 
  585[[nodiscard]] 
inline uint32_t url_aggregator::retrieve_base_port()
 const {
 
  586  ada_log(
"url_aggregator::retrieve_base_port");
 
  587  return components.
port;
 
  591  ada_log(
"url_aggregator::clear_search");
 
  598    buffer.resize(components.search_start);
 
  600    buffer.erase(components.search_start,
 
  601                 components.hash_start - components.search_start);
 
  602    components.hash_start = components.search_start;
 
  607#if ADA_DEVELOPMENT_CHECKS 
  609                   "search should have been cleared on buffer=" + buffer +
 
  610                       " with " + components.to_string() + 
"\n" + 
to_diagram());
 
 
  616  ada_log(
"url_aggregator::clear_hash");
 
  621  buffer.resize(components.hash_start);
 
  624#if ADA_DEVELOPMENT_CHECKS 
  626                   "hash should have been cleared on buffer=" + buffer +
 
  627                       " with " + components.to_string() + 
"\n" + 
to_diagram());
 
 
  632constexpr void url_aggregator::clear_pathname() {
 
  633  ada_log(
"url_aggregator::clear_pathname");
 
  635  uint32_t ending_index = uint32_t(buffer.size());
 
  641  uint32_t pathname_length = ending_index - components.pathname_start;
 
  642  buffer.erase(components.pathname_start, pathname_length);
 
  643  uint32_t difference = pathname_length;
 
  644  if (components.pathname_start == components.host_end + 2 &&
 
  645      buffer[components.host_end] == 
'/' &&
 
  646      buffer[components.host_end + 1] == 
'.') {
 
  647    components.pathname_start -= 2;
 
  648    buffer.erase(components.host_end, 2);
 
  652    components.search_start -= difference;
 
  655    components.hash_start -= difference;
 
  657  ada_log(
"url_aggregator::clear_pathname completed, running checks...");
 
  658#if ADA_DEVELOPMENT_CHECKS 
  660                   "pathname should have been cleared on buffer=" + buffer +
 
  661                       " with " + components.to_string() + 
"\n" + 
to_diagram());
 
  664  ada_log(
"url_aggregator::clear_pathname completed, running checks... ok");
 
  667constexpr void url_aggregator::clear_hostname() {
 
  668  ada_log(
"url_aggregator::clear_hostname");
 
  670  if (!has_authority()) {
 
  675  uint32_t hostname_length = components.host_end - components.host_start;
 
  676  uint32_t start = components.host_start;
 
  679  if (hostname_length > 0 && buffer[start] == 
'@') {
 
  683  buffer.erase(start, hostname_length);
 
  684  components.host_end = start;
 
  685  components.pathname_start -= hostname_length;
 
  687    components.search_start -= hostname_length;
 
  690    components.hash_start -= hostname_length;
 
  692#if ADA_DEVELOPMENT_CHECKS 
  694                   "hostname should have been cleared on buffer=" + buffer +
 
  695                       " with " + components.to_string() + 
"\n" + 
to_diagram());
 
  699                   "hostname should have been cleared on buffer=" + buffer +
 
  700                       " with " + components.to_string() + 
"\n" + 
to_diagram());
 
  705  ada_log(
"url_aggregator::has_hash");
 
 
  710  ada_log(
"url_aggregator::has_search");
 
 
  715  ada_log(
"url_aggregator::has_credentials");
 
 
  719constexpr bool url_aggregator::cannot_have_credentials_or_port()
 const {
 
  720  ada_log(
"url_aggregator::cannot_have_credentials_or_port");
 
  730[[nodiscard]] 
constexpr bool ada::url_aggregator::has_authority()
 
  732  ada_log(
"url_aggregator::has_authority");
 
  735  return components.protocol_end + 2 <= components.host_start &&
 
  736         helpers::substring(buffer, components.protocol_end,
 
  737                            components.protocol_end + 2) == 
"//";
 
  740inline void ada::url_aggregator::add_authority_slashes_if_needed() noexcept {
 
  741  ada_log(
"url_aggregator::add_authority_slashes_if_needed");
 
  746  if (has_authority()) {
 
  752  buffer.insert(components.protocol_end, 
"//");
 
  753  components.username_end += 2;
 
  754  components.host_start += 2;
 
  755  components.host_end += 2;
 
  756  components.pathname_start += 2;
 
  758    components.search_start += 2;
 
  761    components.hash_start += 2;
 
  766constexpr void ada::url_aggregator::reserve(uint32_t capacity) {
 
  767  buffer.reserve(capacity);
 
  771  ada_log(
"url_aggregator::has_non_empty_username");
 
  772  return components.protocol_end + 2 < components.username_end;
 
 
  776  ada_log(
"url_aggregator::has_non_empty_password");
 
  777  return components.host_start - components.username_end > 0;
 
 
  781  ada_log(
"url_aggregator::has_password");
 
  783  return components.host_start > components.username_end &&
 
  784         buffer[components.username_end] == 
':';
 
 
  791  if (components.host_start == components.host_end) {
 
  794  if (components.host_end > components.host_start + 1) {
 
  797  return components.username_end != components.host_start;
 
 
  801  return has_authority();
 
 
  805  ada_log(
"url_aggregator::has_port");
 
  808  return has_hostname() && components.pathname_start != components.host_end;
 
 
  811[[nodiscard]] 
constexpr bool url_aggregator::has_dash_dot() const noexcept {
 
  815  ada_log(
"url_aggregator::has_dash_dot");
 
  816#if ADA_DEVELOPMENT_CHECKS 
  822                     buffer[components.
host_end + 1] == 
'.') ||
 
  823                    (buffer[components.
host_end] == 
':' &&
 
  827      buffer[components.
host_end] == 
'/' &&
 
  828      buffer[components.
host_end + 1] == 
'.') {
 
  838  return components.pathname_start == components.host_end + 2 &&
 
  840         buffer[components.host_end + 1] == 
'.';
 
  845  ada_log(
"url_aggregator::get_href");
 
 
  850    std::string_view view, 
bool check_trailing_content) 
noexcept {
 
  851  ada_log(
"url_aggregator::parse_port('", view, 
"') ", view.size());
 
  852  if (!view.empty() && view[0] == 
'-') {
 
  853    ada_log(
"parse_port: view[0] == '0' && view.size() > 1");
 
  857  uint16_t parsed_port{};
 
  858  auto r = std::from_chars(view.data(), view.data() + view.size(), parsed_port);
 
  859  if (r.ec == std::errc::result_out_of_range) {
 
  860    ada_log(
"parse_port: r.ec == std::errc::result_out_of_range");
 
  864  ada_log(
"parse_port: ", parsed_port);
 
  865  const size_t consumed = size_t(r.ptr - view.data());
 
  866  ada_log(
"parse_port: consumed ", consumed);
 
  867  if (check_trailing_content) {
 
  869        (consumed == view.size() || view[consumed] == 
'/' ||
 
  870         view[consumed] == 
'?' || (is_special() && view[consumed] == 
'\\'));
 
  872  ada_log(
"parse_port: is_valid = ", is_valid);
 
  874    ada_log(
"parse_port", r.ec == std::errc());
 
  876    auto default_port = scheme_default_port();
 
  877    bool is_port_valid = (default_port == 0 && parsed_port == 0) ||
 
  878                         (default_port != parsed_port);
 
  879    if (r.ec == std::errc() && is_port_valid) {
 
  880      update_base_port(parsed_port);
 
  888constexpr void url_aggregator::set_protocol_as_file() {
 
  889  ada_log(
"url_aggregator::set_protocol_as_file ");
 
  894  uint32_t new_difference = 5 - components.protocol_end;
 
  896  if (buffer.empty()) {
 
  897    buffer.append(
"file:");
 
  899    buffer.erase(0, components.protocol_end);
 
  900    buffer.insert(0, 
"file:");
 
  902  components.protocol_end = 5;
 
  905  components.username_end += new_difference;
 
  906  components.host_start += new_difference;
 
  907  components.host_end += new_difference;
 
  908  components.pathname_start += new_difference;
 
  910    components.search_start += new_difference;
 
  913    components.hash_start += new_difference;
 
  922  if (!components.check_offset_consistency()) {
 
  923    ada_log(
"url_aggregator::validate inconsistent components \n",
 
  942    ada_log(
"url_aggregator::validate omitted protocol_end \n", 
to_diagram());
 
  946    ada_log(
"url_aggregator::validate omitted username_end \n", 
to_diagram());
 
  950    ada_log(
"url_aggregator::validate omitted host_start \n", 
to_diagram());
 
  954    ada_log(
"url_aggregator::validate omitted host_end \n", 
to_diagram());
 
  958    ada_log(
"url_aggregator::validate omitted pathname_start \n", 
to_diagram());
 
  962  if (components.protocol_end > buffer.size()) {
 
  963    ada_log(
"url_aggregator::validate protocol_end overflow \n", 
to_diagram());
 
  966  if (components.username_end > buffer.size()) {
 
  967    ada_log(
"url_aggregator::validate username_end overflow \n", 
to_diagram());
 
  970  if (components.host_start > buffer.size()) {
 
  971    ada_log(
"url_aggregator::validate host_start overflow \n", 
to_diagram());
 
  974  if (components.host_end > buffer.size()) {
 
  975    ada_log(
"url_aggregator::validate host_end overflow \n", 
to_diagram());
 
  978  if (components.pathname_start > buffer.size()) {
 
  979    ada_log(
"url_aggregator::validate pathname_start overflow \n",
 
  984  if (components.protocol_end > 0) {
 
  985    if (buffer[components.protocol_end - 1] != 
':') {
 
  987          "url_aggregator::validate missing : at the end of the protocol \n",
 
  993  if (components.username_end != buffer.size() &&
 
  994      components.username_end > components.protocol_end + 2) {
 
  995    if (buffer[components.username_end] != 
':' &&
 
  996        buffer[components.username_end] != 
'@') {
 
  998          "url_aggregator::validate missing : or @ at the end of the username " 
 1005  if (components.host_start != buffer.size()) {
 
 1006    if (components.host_start > components.username_end) {
 
 1007      if (buffer[components.host_start] != 
'@') {
 
 1009            "url_aggregator::validate missing @ at the end of the password \n",
 
 1013    } 
else if (components.host_start == components.username_end &&
 
 1014               components.host_end > components.host_start) {
 
 1015      if (components.host_start == components.protocol_end + 2) {
 
 1016        if (buffer[components.protocol_end] != 
'/' ||
 
 1017            buffer[components.protocol_end + 1] != 
'/') {
 
 1019              "url_aggregator::validate missing // between protocol and host " 
 1025        if (components.host_start > components.protocol_end &&
 
 1026            buffer[components.host_start] != 
'@') {
 
 1028              "url_aggregator::validate missing @ at the end of the username " 
 1035      if (components.host_end != components.host_start) {
 
 1036        ada_log(
"url_aggregator::validate expected omitted host \n",
 
 1042  if (components.host_end != buffer.size() &&
 
 1043      components.pathname_start > components.host_end) {
 
 1044    if (components.pathname_start == components.host_end + 2 &&
 
 1045        buffer[components.host_end] == 
'/' &&
 
 1046        buffer[components.host_end + 1] == 
'.') {
 
 1047      if (components.pathname_start + 1 >= buffer.size() ||
 
 1048          buffer[components.pathname_start] != 
'/' ||
 
 1049          buffer[components.pathname_start + 1] != 
'/') {
 
 1051            "url_aggregator::validate expected the path to begin with // \n",
 
 1055    } 
else if (buffer[components.host_end] != 
':') {
 
 1056      ada_log(
"url_aggregator::validate missing : at the port \n",
 
 1061  if (components.pathname_start != buffer.size() &&
 
 1062      components.pathname_start < components.search_start &&
 
 1063      components.pathname_start < components.hash_start && !
has_opaque_path) {
 
 1064    if (buffer[components.pathname_start] != 
'/') {
 
 1065      ada_log(
"url_aggregator::validate missing / at the path \n",
 
 1071    if (buffer[components.search_start] != 
'?') {
 
 1072      ada_log(
"url_aggregator::validate missing ? at the search \n",
 
 1078    if (buffer[components.hash_start] != 
'#') {
 
 1079      ada_log(
"url_aggregator::validate missing # at the hash \n",
 
 
 1090  ada_log(
"url_aggregator::get_pathname pathname_start = ",
 
 1091          components.pathname_start, 
" buffer.size() = ", buffer.size(),
 
 1092          " components.search_start = ", components.search_start,
 
 1093          " components.hash_start = ", components.hash_start);
 
 1094  auto ending_index = uint32_t(buffer.size());
 
 1096    ending_index = components.search_start;
 
 1098    ending_index = components.hash_start;
 
 1100  return helpers::substring(buffer, components.pathname_start, ending_index);
 
 
 1108void url_aggregator::update_host_to_base_host(
 
 1109    const std::string_view input) 
noexcept {
 
 1110  ada_log(
"url_aggregator::update_host_to_base_host ", input);
 
 1115    if (input.empty() && !is_special()) {
 
 1116      if (has_hostname()) {
 
 1118      } 
else if (has_dash_dot()) {
 
 1119        add_authority_slashes_if_needed();
 
 1125  update_base_hostname(input);
 
Definitions of the character sets used by unicode functions.
 
#define ADA_ASSERT_TRUE(COND)
 
#define ada_lifetime_bound
 
#define ADA_ASSERT_EQUAL(LHS, RHS, MESSAGE)
 
#define ada_really_inline
 
Definitions for helper functions used within Ada.
 
constexpr uint8_t FRAGMENT_PERCENT_ENCODE[32]
 
constexpr bool is_digit(char x) noexcept
 
ada_really_inline size_t percent_encode_index(const std::string_view input, const uint8_t character_set[])
 
std::ostream & operator<<(std::ostream &out, const ada::url &u)
 
Declarations for the URL scheme.
 
ada_really_inline const url_components & get_components() const noexcept
 
constexpr bool has_non_empty_password() const noexcept
 
constexpr bool validate() const noexcept
 
void clear_search() override
 
std::string_view get_hostname() const noexcept ada_lifetime_bound
 
std::string to_string() const override
 
std::string_view get_hash() const noexcept ada_lifetime_bound
 
std::string to_diagram() const
 
constexpr bool has_hostname() const noexcept
 
constexpr bool has_search() const noexcept override
 
constexpr std::string_view get_href() const noexcept ada_lifetime_bound
 
constexpr bool has_empty_hostname() const noexcept
 
constexpr bool has_password() const noexcept
 
std::string_view get_search() const noexcept ada_lifetime_bound
 
ada_really_inline uint32_t get_pathname_length() const noexcept
 
constexpr std::string_view get_pathname() const noexcept ada_lifetime_bound
 
std::string_view get_password() const noexcept ada_lifetime_bound
 
constexpr bool has_hash() const noexcept override
 
constexpr bool has_port() const noexcept
 
ada_really_inline constexpr bool has_credentials() const noexcept
 
constexpr bool has_non_empty_username() const noexcept
 
std::string_view get_username() const noexcept ada_lifetime_bound
 
URL Component representations using offsets.
 
static constexpr uint32_t omitted
 
Definitions for unicode operations.
 
Declaration for the basic URL definitions.
 
Declaration for the URL Components.