kurl.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 2,357 行 · 第 1/4 页
CPP
2,357 行
m_strPath_encoded += '/'; } } else { if ( m_strPath.isEmpty() ) m_strPath = '/'; } KURL tmp( url() + rUrl, encoding_hint); *this = tmp; cleanPath(false); } else { KURL tmp( rUrl, encoding_hint); *this = tmp; // Preserve userinfo if applicable. if (!_u.m_strUser.isEmpty() && m_strUser.isEmpty() && (_u.m_strHost == m_strHost) && (_u.m_strProtocol == m_strProtocol)) { m_strUser = _u.m_strUser; m_strPass = _u.m_strPass; } cleanPath(false); }}void KURL::reset(){ m_strProtocol = QString::null; m_strUser = QString::null; m_strPass = QString::null; m_strHost = QString::null; m_strPath = QString::null; m_strPath_encoded = QString::null; m_strQuery_encoded = QString::null; m_strRef_encoded = QString::null; m_bIsMalformed = true; m_iPort = 0; m_iUriMode = Auto;}bool KURL::isEmpty() const{ return (m_strPath.isEmpty() && m_strProtocol.isEmpty());}void KURL::parse( const QString& _url, int encoding_hint ){ if ( _url.isEmpty() || m_iUriMode == Invalid ) { m_strProtocol = _url; m_iUriMode = Invalid; return; } const QChar* buf = _url.unicode(); const QChar* orig = buf; uint len = _url.length(); uint pos = 0; // Node 1: Accept alpha or slash QChar x = buf[pos++];#ifdef Q_WS_WIN /* win32: accept <letter>: or <letter>:/ or <letter>:\ */ const bool alpha = isalpha((int)x); if (alpha && len<2) goto NodeErr; if (alpha && buf[pos]==':' && (len==2 || (len>2 && (buf[pos+1]=='/' || buf[pos+1]=='\\'))))#else if ( x == '/' )#endif { // A slash means we immediately proceed to parse it as a file URL. m_iUriMode = URL; m_strProtocol = fileProt; parseURL( _url, encoding_hint ); return; } if ( !isalpha( (int)x ) ) goto NodeErr; // Node 2: Accept any amount of (alpha|digit|'+'|'-') // '.' is not currently accepted, because current KURL may be confused. // Proceed with :// :/ or : while( pos < len && (isalpha((int)buf[pos]) || isdigit((int)buf[pos]) || buf[pos] == '+' || buf[pos] == '-')) pos++; if (pos < len && buf[pos] == ':' ) { m_strProtocol = QString( orig, pos ).lower(); if ( m_iUriMode == Auto ) m_iUriMode = uriModeForProtocol( m_strProtocol ); // Proceed to correct parse function. switch ( m_iUriMode ) { case RawURI: parseRawURI( _url ); return; case Mailto: parseMailto( _url ); return; case URL: parseURL( _url, encoding_hint ); return; default: // Unknown URI mode results in an invalid URI. break; } }NodeErr: reset(); m_strProtocol = _url; m_iUriMode = Invalid;}void KURL::parseRawURI( const QString& _url, int encoding_hint ){ uint len = _url.length(); const QChar* buf = _url.unicode(); uint pos = 0; // Accept any amount of (alpha|digit|'+'|'-') // '.' is not currently accepted, because current KURL may be confused. // Proceed with : while( pos < len && (isalpha((int)buf[pos]) || isdigit((int)buf[pos]) || buf[pos] == '+' || buf[pos] == '-')) pos++; // Note that m_strProtocol is already set here, so we just skip over the protocol. if (pos < len && buf[pos] == ':' ) pos++; else { // can't happen, the caller checked all this already reset(); m_strProtocol = _url; m_iUriMode = Invalid; return; } if ( pos == len ) // can't happen, the caller checked this already m_strPath = QString::null; else m_strPath = decode( QString( buf + pos, len - pos ), encoding_hint, true ); m_bIsMalformed = false; return;}void KURL::parseMailto( const QString& _url, int encoding_hint ){ parseURL( _url, encoding_hint); if ( m_bIsMalformed ) return; QRegExp mailre("(.+@)(.+)"); if ( mailre.exactMatch( m_strPath ) ) {#ifndef KDE_QT_ONLY QString host = KIDNA::toUnicode( mailre.cap( 2 ) ); if (host.isEmpty()) host = mailre.cap( 2 ).lower();#else QString host = mailre.cap( 2 ).lower();#endif m_strPath = mailre.cap( 1 ) + host; }}void KURL::parseURL( const QString& _url, int encoding_hint ){ QString port; bool badHostName = false; int start = 0; uint len = _url.length(); const QChar* buf = _url.unicode(); QChar delim; QString tmp; uint pos = 0; // Node 1: Accept alpha or slash QChar x = buf[pos++];#ifdef Q_WS_WIN /* win32: accept <letter>: or <letter>:/ or <letter>:\ */ const bool alpha = isalpha((int)x); if (alpha && len<2) goto NodeErr; if (alpha && buf[pos]==':' && (len==2 || (len>2 && (buf[pos+1]=='/' || buf[pos+1]=='\\'))))#else if ( x == '/' )#endif goto Node9; if ( !isalpha( (int)x ) ) goto NodeErr; // Node 2: Accept any amount of (alpha|digit|'+'|'-') // '.' is not currently accepted, because current KURL may be confused. // Proceed with :// :/ or : while( pos < len && (isalpha((int)buf[pos]) || isdigit((int)buf[pos]) || buf[pos] == '+' || buf[pos] == '-')) pos++; // Note that m_strProtocol is already set here, so we just skip over the protocol. if ( pos+2 < len && buf[pos] == ':' && buf[pos+1] == '/' && buf[pos+2] == '/' ) { pos += 3; } else if (pos+1 < len && buf[pos] == ':' ) // Need to always compare length()-1 otherwise KURL passes "http:" as legal!! { pos++; start = pos; goto Node9; } else goto NodeErr; //Node 3: We need at least one character here if ( pos == len ) goto NodeErr; start = pos; // Node 4: Accept any amount of characters. if (buf[pos] == '[') // An IPv6 host follows. goto Node8; // Terminate on / or @ or ? or # or " or ; or < x = buf[pos]; while( (x != ':') && (x != '@') && (x != '/') && (x != '?') && (x != '#') ) { if ((x == '\"') || (x == ';') || (x == '<')) badHostName = true; if (++pos == len) break; x = buf[pos]; } if ( pos == len ) { if (badHostName) goto NodeErr; setHost(decode(QString( buf + start, pos - start ), encoding_hint)); goto NodeOk; } if ( x == '@' ) { m_strUser = decode(QString( buf + start, pos - start ), encoding_hint); pos++; goto Node7; } else if ( (x == '/') || (x == '?') || (x == '#')) { if (badHostName) goto NodeErr; setHost(decode(QString( buf + start, pos - start ), encoding_hint)); start = pos; goto Node9; } else if ( x != ':' ) goto NodeErr; m_strUser = decode(QString( buf + start, pos - start ), encoding_hint); pos++; // Node 5: We need at least one character if ( pos == len ) goto NodeErr; start = pos++; // Node 6: Read everything until @, /, ? or # while( (pos < len) && (buf[pos] != '@') && (buf[pos] != '/') && (buf[pos] != '?') && (buf[pos] != '#')) pos++; // If we now have a '@' the ':' seperates user and password. // Otherwise it seperates host and port. if ( (pos == len) || (buf[pos] != '@') ) { // Ok the : was used to separate host and port if (badHostName) goto NodeErr; setHost(m_strUser); m_strUser = QString::null; QString tmp( buf + start, pos - start ); char *endptr; m_iPort = (unsigned short int)strtol(tmp.ascii(), &endptr, 10); if ((pos == len) && (strlen(endptr) == 0)) goto NodeOk; // there is more after the digits pos -= strlen(endptr); if ((buf[pos] != '@') && (buf[pos] != '/') && (buf[pos] != '?') && (buf[pos] != '#')) goto NodeErr; start = pos; goto Node9; } m_strPass = decode(QString( buf + start, pos - start), encoding_hint); pos++; // Node 7: We need at least one character Node7: if ( pos == len ) goto NodeErr; Node8: if (buf[pos] == '[') { // IPv6 address start = ++pos; // Skip '[' if (pos == len) { badHostName = true; goto NodeErr; } // Node 8a: Read everything until ] or terminate badHostName = false; x = buf[pos]; while( (x != ']') ) { if ((x == '\"') || (x == ';') || (x == '<')) badHostName = true; if (++pos == len) { badHostName = true; break; } x = buf[pos]; } if (badHostName) goto NodeErr; setHost(decode(QString( buf + start, pos - start ), encoding_hint)); if (pos < len) pos++; // Skip ']' if (pos == len) goto NodeOk; } else { // Non IPv6 address, with a user start = pos; // Node 8b: Read everything until / : or terminate badHostName = false; x = buf[pos]; while( (x != ':') && (x != '@') && (x != '/') && (x != '?') && (x != '#') ) { if ((x == '\"') || (x == ';') || (x == '<')) badHostName = true; if (++pos == len) break; x = buf[pos]; } if (badHostName) goto NodeErr; if ( pos == len ) { setHost(decode(QString( buf + start, pos - start ), encoding_hint)); goto NodeOk; } setHost(decode(QString( buf + start, pos - start ), encoding_hint)); } x = buf[pos]; if ( x == '/' || x == '#' || x == '?' ) { start = pos; goto Node9; } else if ( x != ':' ) goto NodeErr; pos++; // Node 8c: Accept at least one digit if ( pos == len ) goto NodeErr; start = pos; if ( !isdigit( buf[pos++] ) ) goto NodeErr; // Node 8d: Accept any amount of digits while( pos < len && isdigit( buf[pos] ) ) pos++; port = QString( buf + start, pos - start ); m_iPort = port.toUShort(); if ( pos == len ) goto NodeOk; start = pos; Node9: // parse path until query or reference reached while( pos < len && buf[pos] != '#' && buf[pos]!='?' ) pos++; tmp = QString( buf + start, pos - start ); //kdDebug(126)<<" setting encoded path to:"<<tmp<<endl; setEncodedPath( tmp, encoding_hint ); if ( pos == len ) goto NodeOk; //Node10: // parse query or reference depending on what comes first delim = (buf[pos++]=='#'?'?':'#'); start = pos; while(pos < len && buf[pos]!=delim ) pos++; tmp = QString(buf + start, pos - start); if (delim=='#') _setQuery(tmp, encoding_hint); else m_strRef_encoded = tmp; if (pos == len) goto NodeOk; //Node11: // feed the rest into the remaining variable tmp = QString( buf + pos + 1, len - pos - 1); if (delim == '#') m_strRef_encoded = tmp; else _setQuery(tmp, encoding_hint); NodeOk: //kdDebug(126)<<"parsing finished. m_strProtocol="<<m_strProtocol<<" m_strHost="<<m_strHost<<" m_strPath="<<m_strPath<<endl; m_bIsMalformed = false; // Valid URL //kdDebug()<<"Prot="<<m_strProtocol<<"\nUser="<<m_strUser<<"\nPass="<<m_strPass<<"\nHost="<<m_strHost<<"\nPath="<<m_strPath<<"\nQuery="<<m_strQuery_encoded<<"\nRef="<<m_strRef_encoded<<"\nPort="<<m_iPort<<endl; if (m_strProtocol.isEmpty()) { m_iUriMode = URL; m_strProtocol = fileProt; } return; NodeErr:// kdDebug(126) << "KURL couldn't parse URL \"" << _url << "\"" << endl; reset(); m_strProtocol = _url; m_iUriMode = Invalid;}KURL& KURL::operator=( const QString& _url ){ reset(); parse( _url ); return *this;}KURL& KURL::operator=( const char * _url ){ reset(); parse( QString::fromLatin1(_url) ); return *this;}#ifndef QT_NO_NETWORKPROTOCOLKURL& KURL::operator=( const QUrl & u ){ m_strProtocol = u.protocol(); m_iUriMode = Auto; m_strUser = u.user(); m_strPass = u.password(); m_strHost = u.host(); m_strPath = u.path( false ); m_strPath_encoded = QString::null; m_strQuery_encoded = u.query(); m_strRef_encoded = u.ref(); m_bIsMalformed = !u.isValid(); m_iPort = u.port(); return *this;}#endifKURL& KURL::operator=( const KURL& _u ){ m_strProtocol = _u.m_strProtocol; m_strUser = _u.m_strUser; m_strPass = _u.m_strPass; m_strHost = _u.m_strHost; m_strPath = _u.m_strPath; m_strPath_encoded = _u.m_strPath_encoded; m_strQuery_encoded = _u.m_strQuery_encoded; m_strRef_encoded = _u.m_strRef_encoded; m_bIsMalformed = _u.m_bIsMalformed; m_iPort = _u.m_iPort; m_iUriMode = _u.m_iUriMode; return *this;}bool KURL::operator<( const KURL& _u) const{ int i; if (!_u.isValid()) { if (!isValid()) { i = m_strProtocol.compare(_u.m_strProtocol); return (i < 0); } return false; } if (!isValid()) return true; i = m_strProtocol.compare(_u.m_strProtocol); if (i) return (i < 0); i = m_strHost.compare(_u.m_strHost); if (i) return (i < 0); if (m_iPort != _u.m_iPort) return (m_iPort < _u.m_iPort); i = m_strPath.compare(_u.m_strPath); if (i) return (i < 0); i = m_strQuery_encoded.compare(_u.m_strQuery_encoded); if (i) return (i < 0); i = m_strRef_encoded.compare(_u.m_strRef_encoded); if (i) return (i < 0); i = m_strUser.compare(_u.m_strUser); if (i) return (i < 0); i = m_strPass.compare(_u.m_strPass); if (i) return (i < 0); return false;}bool KURL::operator==( const KURL& _u ) const{ if ( !isValid() || !_u.isValid() ) return false; if ( m_strProtocol == _u.m_strProtocol && m_strUser == _u.m_strUser && m_strPass == _u.m_strPass && m_strHost == _u.m_strHost && m_strPath == _u.m_strPath && // The encoded path may be null, but the URLs are still equal (David) ( m_strPath_encoded.isNull() || _u.m_strPath_encoded.isNull() || m_strPath_encoded == _u.m_strPath_encoded ) && m_strQuery_encoded == _u.m_strQuery_encoded && m_strRef_encoded == _u.m_strRef_encoded && m_iPort == _u.m_iPort ) { return true; } return false;}bool KURL::operator==( const QString& _u ) const{ KURL u( _u ); return ( *this == u );}bool KURL::cmp( const KURL &u, bool ignore_trailing ) const{ return equals( u, ignore_trailing );}bool KURL::equals( const KURL &_u, bool ignore_trailing ) const{ if ( !isValid() || !_u.isValid() ) return false; if ( ignore_trailing ) { QString path1 = path(1); QString path2 = _u.path(1); if ( path1 != path2 ) return false; if ( m_strProtocol == _u.m_strProtocol && m_strUser == _u.m_strUser && m_strPass == _u.m_strPass && m_strHost == _u.m_strHost && m_strQuery_encoded == _u.m_strQuery_encoded && m_strRef_encoded == _u.m_strRef_encoded && m_iPort == _u.m_iPort ) return true; return false;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?