📄 kwqkurl.cpp
字号:
} else {
// workaround for sites that put leading whitespace on relative URLs
while (*str == ' ') {
str++;
}
// if the base is invalid, just append the relative
// portion. The RFC does not specify what to do in this case.
if (!base.m_isValid) {
QString newURL = base.urlString + str;
parse(newURL.ascii(), &newURL);
if (strBuffer) {
#ifndef __OOM__
free(strBuffer);
#else
MemoryManager::Free( strBuffer );
#endif
}
return;
}
switch(str[0]) {
case '\0':
// the reference must be empty - the RFC says this is a
// reference to the same document
{
*this = base;
break;
}
case '#':
// must be fragment-only reference
{
QString newURL = base.urlString.left(base.queryEndPos) + str;
parse(newURL.ascii(), &newURL);
break;
}
case '?':
// query-only reference, special case needed for non-URL results
{
QString newURL = base.urlString.left(base.pathEndPos) + str;
parse(newURL.ascii(), &newURL);
break;
}
case '/':
// must be net-path or absolute-path reference
{
if (str[1] == '/') {
// net-path
QString newURL = base.urlString.left(base.schemeEndPos + 1) + str;
parse(newURL.ascii(), &newURL);
} else {
// abs-path
QString newURL = base.urlString.left(base.portEndPos) + str;
parse(newURL.ascii(), &newURL);
}
break;
}
default:
{
// must be relative-path reference
char staticBuffer[256];
char *buffer;
size_t bufferLength = base.pathEndPos + strlen(str) + 1;
if (bufferLength > sizeof(staticBuffer)) {
#ifndef __OOM__
buffer = (char *)malloc(bufferLength);
#else
buffer = (char *)MemoryManager::Alloc(bufferLength);
#endif
} else {
buffer = staticBuffer;
}
char *bufferPos = buffer;
// first copy everything before the path from the base
const char *baseString = base.urlString.ascii();
const char *baseStringStart = baseString;
const char *pathStart = baseStringStart + base.portEndPos;
while (baseStringStart < pathStart) {
*bufferPos++ = *baseStringStart++;
}
char *bufferPathStart = bufferPos;
// now copy the base path
const char *baseStringEnd = baseString + base.pathEndPos;
// go back to the last slash
while (baseStringEnd > baseStringStart && baseStringEnd[-1] != '/') {
baseStringEnd--;
}
bufferPos += copyPathRemovingDots(bufferPos, baseStringStart, 0, baseStringEnd - baseStringStart);
const char *relStringStart = str;
const char *relStringPos = relStringStart;
while (*relStringPos != '\0' && *relStringPos != '?' && *relStringPos != '#') {
if (relStringPos[0] == '.' && bufferPos[-1] == '/') {
if (isPathSegmentEndChar(relStringPos[1])) {
// skip over "." segment
relStringPos += 1;
if (relStringPos[0] == '/') {
relStringPos++;
}
continue;
} else if (relStringPos[1] == '.' && isPathSegmentEndChar(relStringPos[2])) {
// skip over ".." segment and rewind the last segment
// the RFC leaves it up to the app to decide what to do with excess
// ".." segments - we choose to drop them since some web content
// relies on this.
relStringPos += 2;
if (relStringPos[0] == '/') {
relStringPos++;
}
if (bufferPos > bufferPathStart + 1) {
bufferPos--;
}
while (bufferPos > bufferPathStart + 1 && bufferPos[-1] != '/') {
bufferPos--;
}
continue;
}
}
*bufferPos = *relStringPos;
relStringPos++;
bufferPos++;
}
// all done with the path work, now copy any remainder
// of the relative reference; this will also add a null terminator
strcpy(bufferPos, relStringPos);
parse(buffer, NULL);
ASSERT(strlen(buffer) + 1 <= bufferLength);
if (buffer != staticBuffer) {
#ifndef __OOM__
free(buffer);
#else
MemoryManager::Free( buffer );
#endif
}
break;
}
}
}
if (strBuffer) {
#ifndef __OOM__
free(strBuffer);
#else
MemoryManager::Free( strBuffer );
#endif
}
}
bool KURL::hasPath() const
{
return m_isValid && pathEndPos != portEndPos;
}
QString KURL::protocol() const
{
if (!m_isValid) {
return QString();
}
return urlString.left(schemeEndPos);
}
// returns the host part not including the port part
QString KURL::host() const
{
if (!m_isValid) {
return QString();
}
int start = (passwordEndPos == userStartPos) ? passwordEndPos : passwordEndPos + 1;
return decode_string(urlString.mid(start, hostEndPos - start));
}
unsigned short int KURL::port(bool defaultPort) const
{
if (!m_isValid) {
return 0;
}
if (hostEndPos != portEndPos) {
bool ok;
unsigned short result = urlString.mid(hostEndPos + 1, portEndPos - hostEndPos - 1).toUShort(&ok);
if (!ok) {
result = 0;
}
return result;
}
// include default port for protocol if the port is not specified
if(defaultPort){
if (protocol() == "https")
return 443;
else if (protocol() == "http")
return 80;
}
return 0;
}
QString KURL::pass() const
{
if (!m_isValid) {
return QString();
}
if (passwordEndPos == userEndPos) {
return QString();
}
return decode_string(urlString.mid(userEndPos + 1, passwordEndPos - userEndPos - 1));
}
QString KURL::user() const
{
if (!m_isValid) {
return QString();
}
return decode_string(urlString.mid(userStartPos, userEndPos - userStartPos));
}
QString KURL::ref() const
{
if (!m_isValid || fragmentEndPos == queryEndPos) {
return QString();
}
return urlString.mid(queryEndPos + 1, fragmentEndPos - (queryEndPos + 1 ) );
}
bool KURL::hasRef() const
{
return m_isValid && fragmentEndPos != queryEndPos;
}
QString KURL::query() const
{
if (!m_isValid) {
return QString();
}
// if question mark is the only char in query string, return empty string
if (queryEndPos - pathEndPos == 1)
{
return QString();
}
return decode_string(urlString.mid(pathEndPos, queryEndPos - pathEndPos));
}
QString KURL::path() const
{
if (!m_isValid) {
return QString();
}
return decode_string(urlString.mid(portEndPos, pathEndPos - portEndPos));
}
#ifdef CONSTRUCT_CANONICAL_STRING
QString KURL::_path() const
{
if (!m_isValid) {
return QString();
}
return urlString.mid(portEndPos, pathEndPos - portEndPos);
}
QString KURL::_user() const
{
if (!m_isValid) {
return QString();
}
return urlString.mid(userStartPos, userEndPos - userStartPos);
}
QString KURL::_pass() const
{
if (!m_isValid) {
return QString();
}
if (passwordEndPos == userEndPos) {
return QString();
}
return urlString.mid(userEndPos + 1, passwordEndPos - userEndPos - 1);
}
QString KURL::_host() const
{
if (!m_isValid) {
return QString();
}
int start = (passwordEndPos == userStartPos) ? passwordEndPos : passwordEndPos + 1;
return urlString.mid(start, hostEndPos - start);
}
#endif
void KURL::setProtocol(const QString &s)
{
if (!m_isValid) {
QString newURL = s + ":" + urlString;
parse(newURL.ascii(), &newURL);
return;
}
QString newURL = s + urlString.mid(schemeEndPos);
parse(newURL.ascii(), &newURL);
}
// set only host part not including the port part.
void KURL::setHostName(const QString &s)
{
if (m_isValid) {
bool slashSlashNeeded = userStartPos == schemeEndPos + 1;
int hostStart = (passwordEndPos == userStartPos) ? passwordEndPos : passwordEndPos + 1;
QString newURL = urlString.left(hostStart) + (slashSlashNeeded ? "//" : QString()) + s + urlString.mid(hostEndPos);
parse(newURL.ascii(), &newURL);
}
}
// set both host part and port part.
void KURL::setHost(const QString &s)
{
if (m_isValid) {
bool slashSlashNeeded = userStartPos == schemeEndPos + 1;
int hostStart = (passwordEndPos == userStartPos) ? passwordEndPos : passwordEndPos + 1;
QString newURL = urlString.left(hostStart) + (slashSlashNeeded ? "//" : QString()) + s + urlString.mid(portEndPos);
parse(newURL.ascii(), &newURL);
}
}
void KURL::setPort(unsigned short i)
{
if (m_isValid) {
bool colonNeeded = portEndPos == hostEndPos;
int portStart = (colonNeeded ? hostEndPos : hostEndPos + 1);
QString newURL = urlString.left(portStart) + (colonNeeded ? ":" : QString()) + QString::number(i) + urlString.mid(portEndPos);
parse(newURL.ascii(), &newURL);
}
}
void KURL::setUser(const QString &user)
{
if (m_isValid) {
QString u;
int end = userEndPos;
if (!user.isEmpty()) {
// Untested code, but this is never used.
ASSERT_NOT_REACHED();
#if 0
u = user;
if (userStartPos == schemeEndPos + 1) {
u = "//" + u;
}
// Add '@' if we didn't have one before.
if (end == hostEndPos || (end == passwordEndPos && urlString[end] != '@')) {
u += '@';
}
#endif
} else {
// Remove '@' if we now have neither user nor password.
if (userEndPos == passwordEndPos && end != hostEndPos && urlString[end] == '@') {
end += 1;
}
}
const QString newURL = urlString.left(userStartPos) + u + urlString.mid(end);
parse(newURL.ascii(), &newURL);
}
}
void KURL::setPass(const QString &password)
{
if (m_isValid) {
QString p;
int end = passwordEndPos;
if (!password.isEmpty()) {
// Untested code, but this is never used.
ASSERT_NOT_REACHED();
#if 0
p = ':' + password + '@';
if (userEndPos == schemeEndPos + 1) {
p = "//" + p;
}
// Eat the existing '@' since we are going to add our own.
if (end != hostEndPos && urlString[end] == '@') {
end += 1;
}
#endif
} else {
// Remove '@' if we now have neither user nor password.
if (userStartPos == userEndPos && end != hostEndPos && urlString[end] == '@') {
end += 1;
}
}
const QString newURL = urlString.left(userEndPos) + p + urlString.mid(end);
parse(newURL.ascii(), &newURL);
}
}
void KURL::setRef(const QString &s)
{
if (m_isValid) {
QString newURL = urlString.left(queryEndPos) + (s.isEmpty() ? QString() : "#" + s);
parse(newURL.ascii(), &newURL);
}
}
void KURL::setQuery(const QString &query)
{
if (m_isValid) {
QString q;
if (!query.isEmpty() && query[0] != '?') {
q = "?" + query;
} else {
q = query;
}
QString newURL = urlString.left(pathEndPos) + q + urlString.mid(queryEndPos);
parse(newURL.ascii(), &newURL);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -