📄 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) { free(strBuffer); } 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[2048]; char *buffer; size_t bufferLength = base.pathEndPos + strlen(str) + 1; if (bufferLength > sizeof(staticBuffer)) { buffer = (char *)malloc(bufferLength); } 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) { free(buffer); } break; } } } if (strBuffer) { free(strBuffer); }}bool KURL::hasPath() const{ return m_isValid && pathEndPos != portEndPos;}QString KURL::protocol() const{ if (!m_isValid) { return QString(); } return urlString.left(schemeEndPos);}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() 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; } 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(); } return 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_STRINGQString 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);}#endifvoid 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);}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(hostEndPos); 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); }}void KURL::setPath(const QString &s){ if (m_isValid) { QString newURL = urlString.left(portEndPos) + encode_string(s) + urlString.mid(pathEndPos); parse(newURL.ascii(), &newURL); }}QString KURL::canonicalURL() const{#ifdef CONSTRUCT_CANONICAL_STRING bool hadPrePathComponent = false; QString canonicalURL; if (!protocol().isEmpty()) { canonicalURL += protocol(); canonicalURL += "://"; hadPrePathComponent = true; } if (!_user().isEmpty()) { canonicalURL += _user(); if (!_pass().isEmpty()){ canonicalURL += ":"; canonicalURL += _pass(); } canonicalURL += "@"; hadPrePathComponent = true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -