#ifndef URLUtils_h
#define URLUtils_h
#include "SecurityOrigin.h"
namespace WebCore {
template <typename T>
class URLUtils {
public:
URL href() const { return static_cast<const T*>(this)->href(); }
void setHref(const String& url) { static_cast<T*>(this)->setHref(url); }
String toString() const;
String origin() const;
String protocol() const;
void setProtocol(const String&);
String username() const;
void setUsername(const String&);
String password() const;
void setPassword(const String&);
String host() const;
void setHost(const String&);
String hostname() const;
void setHostname(const String&);
String port() const;
void setPort(const String&);
String pathname() const;
void setPathname(const String&);
String search() const;
void setSearch(const String&);
String hash() const;
void setHash(const String&);
};
template <typename T>
String URLUtils<T>::toString() const
{
return href().string();
}
template <typename T>
String URLUtils<T>::origin() const
{
RefPtr<SecurityOrigin> origin = SecurityOrigin::create(href());
return origin->toString();
}
template <typename T>
String URLUtils<T>::protocol() const
{
return href().protocol() + ':';
}
template <typename T>
void URLUtils<T>::setProtocol(const String& value)
{
URL url = href();
url.setProtocol(value);
setHref(url.string());
}
template <typename T>
String URLUtils<T>::username() const
{
return href().user();
}
template <typename T>
void URLUtils<T>::setUsername(const String& user)
{
URL url = href();
url.setUser(user);
setHref(url);
}
template <typename T>
String URLUtils<T>::password() const
{
return href().pass();
}
template <typename T>
void URLUtils<T>::setPassword(const String& pass)
{
URL url = href();
url.setPass(pass);
setHref(url);
}
template <typename T>
String URLUtils<T>::host() const
{
const URL& url = href();
if (url.hostEnd() == url.pathStart())
return url.host();
if (isDefaultPortForProtocol(url.port(), url.protocol()))
return url.host();
return url.host() + ':' + String::number(url.port());
}
static inline unsigned parsePortFromStringPosition(const String& value, unsigned portStart, unsigned& portEnd)
{
portEnd = portStart;
while (isASCIIDigit(value[portEnd]))
++portEnd;
return value.substring(portStart, portEnd - portStart).toUInt();
}
template <typename T>
void URLUtils<T>::setHost(const String& value)
{
if (value.isEmpty())
return;
URL url = href();
if (!url.canSetHostOrPort())
return;
size_t separator = value.find(':');
if (!separator)
return;
if (separator == notFound)
url.setHostAndPort(value);
else {
unsigned portEnd;
unsigned port = parsePortFromStringPosition(value, separator + 1, portEnd);
if (!port) {
url.setHostAndPort(value.substring(0, separator + 1) + '0');
} else {
if (isDefaultPortForProtocol(port, url.protocol()))
url.setHostAndPort(value.substring(0, separator));
else
url.setHostAndPort(value.substring(0, portEnd));
}
}
setHref(url.string());
}
template <typename T>
String URLUtils<T>::hostname() const
{
return href().host();
}
template <typename T>
void URLUtils<T>::setHostname(const String& value)
{
unsigned i = 0;
unsigned hostLength = value.length();
while (value[i] == '/')
i++;
if (i == hostLength)
return;
URL url = href();
if (!url.canSetHostOrPort())
return;
url.setHost(value.substring(i));
setHref(url.string());
}
template <typename T>
String URLUtils<T>::port() const
{
if (href().hasPort())
return String::number(href().port());
return emptyString();
}
template <typename T>
void URLUtils<T>::setPort(const String& value)
{
URL url = href();
if (!url.canSetHostOrPort())
return;
unsigned port = value.toUInt();
if (isDefaultPortForProtocol(port, url.protocol()))
url.removePort();
else
url.setPort(port);
setHref(url.string());
}
template <typename T>
String URLUtils<T>::pathname() const
{
return href().path();
}
template <typename T>
void URLUtils<T>::setPathname(const String& value)
{
URL url = href();
if (!url.canSetPathname())
return;
if (value[0] == '/')
url.setPath(value);
else
url.setPath("/" + value);
setHref(url.string());
}
template <typename T>
String URLUtils<T>::search() const
{
String query = href().query();
return query.isEmpty() ? emptyString() : "?" + query;
}
template <typename T>
void URLUtils<T>::setSearch(const String& value)
{
URL url = href();
String newSearch = (value[0] == '?') ? value.substring(1) : value;
url.setQuery(newSearch.replaceWithLiteral('#', "%23"));
setHref(url.string());
}
template <typename T>
String URLUtils<T>::hash() const
{
String fragmentIdentifier = href().fragmentIdentifier();
if (fragmentIdentifier.isEmpty())
return emptyString();
return AtomicString(String("#" + fragmentIdentifier));
}
template <typename T>
void URLUtils<T>::setHash(const String& value)
{
URL url = href();
if (value[0] == '#')
url.setFragmentIdentifier(value.substring(1));
else
url.setFragmentIdentifier(value);
setHref(url.string());
}
}
#endif // URLUtils_h