#include "url/url_canon.h"
#include "url/url_canon_internal.h"
namespace url {
namespace {
template <typename CHAR, typename UCHAR>
void DoCanonicalizePathComponent(
std::optional<std::basic_string_view<CHAR>> source,
char separator,
CanonOutput* output,
Component* new_component) {
if (source.has_value()) {
auto& source_value = *source;
if (separator)
output->push_back(separator);
new_component->begin = output->length();
for (size_t i = 0; i < source_value.size(); i++) {
UCHAR uch = static_cast<UCHAR>(source_value[i]);
if (IsInC0ControlPercentEncodeSet(uch)) {
AppendUtf8EscapedChar(source_value, &i, output);
} else {
output->push_back(static_cast<char>(uch));
}
}
new_component->len = output->length() - new_component->begin;
} else {
new_component->reset();
}
}
template <typename CHAR, typename UCHAR>
bool DoCanonicalizePathUrl(const Replacements<CHAR>& source,
CanonOutput* output,
Parsed* new_parsed) {
bool success =
CanonicalizeScheme(source.MaybeScheme(), output, &new_parsed->scheme);
new_parsed->username.reset();
new_parsed->password.reset();
new_parsed->host.reset();
new_parsed->port.reset();
DoCanonicalizePathComponent<CHAR, UCHAR>(source.MaybePath(), '\0', output,
&new_parsed->path);
CanonicalizeQuery(source.MaybeQuery(), nullptr, output, &new_parsed->query);
CanonicalizeRef(source.MaybeRef(), output, &new_parsed->ref);
return success;
}
}
bool CanonicalizePathUrl(std::string_view spec,
const Parsed& parsed,
CanonOutput* output,
Parsed* new_parsed) {
return DoCanonicalizePathUrl<char, unsigned char>(
Replacements<char>(spec, parsed), output, new_parsed);
}
bool CanonicalizePathUrl(std::u16string_view spec,
const Parsed& parsed,
CanonOutput* output,
Parsed* new_parsed) {
return DoCanonicalizePathUrl<char16_t, char16_t>(
Replacements<char16_t>(spec, parsed), output, new_parsed);
}
void CanonicalizePathUrlPath(std::optional<std::string_view> source,
CanonOutput* output,
Component* new_component) {
DoCanonicalizePathComponent<char, unsigned char>(source, '\0', output,
new_component);
}
void CanonicalizePathUrlPath(std::optional<std::u16string_view> source,
CanonOutput* output,
Component* new_component) {
DoCanonicalizePathComponent<char16_t, char16_t>(source, '\0', output,
new_component);
}
bool ReplacePathUrl(std::string_view base,
const Parsed& base_parsed,
const Replacements<char>& replacements,
CanonOutput* output,
Parsed* new_parsed) {
Replacements<char> overridden(base, base_parsed);
SetupOverrideComponents(replacements, overridden);
return DoCanonicalizePathUrl<char, unsigned char>(overridden, output,
new_parsed);
}
bool ReplacePathUrl(std::string_view base,
const Parsed& base_parsed,
const Replacements<char16_t>& replacements,
CanonOutput* output,
Parsed* new_parsed) {
RawCanonOutput<1024> utf8;
Replacements<char> overridden(base, base_parsed);
SetupUtf16OverrideComponents(replacements, utf8, overridden);
return DoCanonicalizePathUrl<char, unsigned char>(overridden, output,
new_parsed);
}
}