📄 kurl.cpp
字号:
uint len = _url.length(); QChar* buf = new QChar[ len + 1 ]; QChar* orig = buf; memcpy( buf, _url.unicode(), len * sizeof( QChar ) ); uint pos = 0; // Node 1: Accept alpha or slash QChar x = buf[pos++]; if ( x == '/' ) 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( (isalpha((int)buf[pos]) || isdigit((int)buf[pos]) || buf[pos] == '+' || buf[pos] == '-') && pos < len ) pos++; if ( pos == len - 1 ) // Need to always compare length()-1 otherwise KURL passes "http:" as legal!!! (DA) goto NodeErr; if (buf[pos] == ':' && buf[pos+1] == '/' && buf[pos+2] == '/' ) { m_strProtocol = QString( orig, pos ).lower(); pos += 3; } else if (buf[pos] == ':' && buf[pos+1] == '/' ) { m_strProtocol = QString( orig, pos ).lower(); pos++; start = pos; goto Node9; } else if ( buf[pos] == ':' ) { m_strProtocol = QString( orig, pos ).lower(); pos++; goto Node11; } else goto NodeErr; //Node 3: We need at least one character here if ( pos == len ) // goto NodeOk; Wrong!!! As the above comment states at least one character is required here!!! goto NodeErr;#if 0 start = pos++;#else start = pos;#endif // Node 4: Accept any amount of characters. // Terminate or / or @ while( buf[pos] != ':' && buf[pos] != '@' && buf[pos] != '/' && pos < len ) pos++; if ( pos == len ) { m_strHost = decode(QString( buf + start, pos - start ), 0, encoding_hint); goto NodeOk; } x = buf[pos]; if ( x == '@' ) { m_strUser = decode(QString( buf + start, pos - start ), 0, encoding_hint); pos++; goto Node7; } /* else if ( x == ':' ) { m_strHost = decode(QString( buf + start, pos - start ), 0, encoding_hint); pos++; goto Node8a; } */ else if ( x == '/' ) { m_strHost = decode(QString( buf + start, pos - start ), 0, encoding_hint); start = pos++; goto Node9; } else if ( x != ':' ) goto NodeErr; m_strUser = decode(QString( buf + start, pos - start ), 0, encoding_hint); pos++; // Node 5: We need at least one character if ( pos == len ) goto NodeErr; start = pos++; // Node 6: Read everything until @ while( buf[pos] != '@' && pos < len ) pos++; if ( pos == len ) { // Ok the : was used to separate host and port m_strHost = 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); start = pos++; goto Node9; } m_strPass = decode(QString( buf + start, pos - start), 0, encoding_hint); pos++; // Node 7: We need at least one character Node7: if ( pos == len ) goto NodeErr; start = pos++; // Node 8: Read everything until / : or terminate while( buf[pos] != '/' && buf[pos] != ':' && pos < len ) pos++; if ( pos == len ) { m_strHost = decode(QString( buf + start, pos - start ), 0, encoding_hint); goto NodeOk; } x = buf[pos]; m_strHost = decode(QString( buf + start, pos - start ), 0, encoding_hint); if ( x == '/' ) { start = pos++; goto Node9; } else if ( x != ':' ) goto NodeErr; pos++; // Node 8a: Accept at least one digit if ( pos == len ) goto NodeErr; start = pos; if ( !isdigit( buf[pos++] ) ) goto NodeErr; // Node 8b: Accept any amount of digits while( isdigit( buf[pos] ) && pos < len ) pos++; port = QString( buf + start, pos - start ); m_iPort = port.toUShort(); if ( pos == len ) goto NodeOk; start = pos++; // Node 9: Accept any character and # or terminate Node9: while( buf[pos] != '#' && pos < len ) pos++; if ( pos == len ) { QString tmp( buf + start, len - start ); setEncodedPathAndQuery( tmp, encoding_hint ); // setEncodedPathAndQuery( QString( buf + start, pos - start ) ); goto NodeOk; } else if ( buf[pos] != '#' ) goto NodeErr; setEncodedPathAndQuery( QString( buf + start, pos - start ), encoding_hint ); pos++; // Node 10: Accept all the rest m_strRef_encoded = QString( buf + pos, len - pos ); goto NodeOk; // Node 11 We need at least one character Node11: start = pos; if ( pos++ == len ) goto NodeOk; // Wrong, but since a fix was applied up top it is a non-issue here!!!! // Just for the record an opaque URL such as "mailto:" is always required // to have at least one more character other than a '/' following the colon. // Node 12: Accept the res setEncodedPathAndQuery( QString( buf + start, len - start ), encoding_hint ); goto NodeOk; NodeOk: delete []orig; m_bIsMalformed = false; // Valid URL if (m_strProtocol.isEmpty()) m_strProtocol = "file"; //debug("Prot=%s\nUser=%s\nPass=%s\nHost=%s\nPath=%s\nQuery=%s\nRef=%s\nPort=%i\n", //m_strProtocol.ascii(), m_strUser.ascii(), m_strPass.ascii(), //m_strHost.ascii(), m_strPath.ascii(), m_strQuery_encoded.ascii(), //m_strRef_encoded.ascii(), m_iPort ); if (m_strProtocol == "file") { if (!m_strHost.isEmpty()) { // File-protocol has a host name..... hmm? if (m_strHost.lower() == "localhost") { m_strHost = QString::null; // We can ignore localhost } else { // Pass the hostname as part of the path. Perhaps system calls // just handle it. m_strPath = "//"+m_strHost+m_strPath; m_strPath_encoded = QString::null; m_strHost = QString::null; } } } return; NodeErr: //kdDebug(126) << "KURL couldn't parse URL \"" << _url << "\"" << endl; delete []orig; reset(); m_strProtocol = _url;}KURL& KURL::operator=( const QString& _url ){ reset(); parse( _url ); return *this;}KURL& KURL::operator=( const char * _url ){ reset(); parse( QString::fromLatin1(_url) ); return *this;}KURL& KURL::operator=( const QUrl & u ){ m_strProtocol = u.protocol(); 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;}KURL& 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; return *this;}bool KURL::operator==( const KURL& _u ) const{ if ( isMalformed() || _u.isMalformed() ) 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{ if ( isMalformed() || _u.isMalformed() ) 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; } return ( *this == _u );}bool KURL::isParentOf( const KURL& _u ) const{ if ( isMalformed() || _u.isMalformed() ) 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 ) { QString p1( QDir::cleanDirPath( path() )+'/' ); QString p2( QDir::cleanDirPath( _u.path() )+'/' ); ////kdDebug(126) << "p1=" << p1 << endl; ////kdDebug(126) << "p2=" << p2 << endl; ////kdDebug(126) << "p1.length()=" << p1.length() << endl; ////kdDebug(126) << "p2.left(!$)=" << p2.left( p1.length() ) << endl; return p2.startsWith( p1 ); } return false;}void KURL::setFileName( const QString& _txt ){ m_strRef_encoded = QString::null; int i = 0; while( _txt[i] == '/' ) ++i; QString tmp; if ( i ) tmp = _txt.mid( i ); else tmp = _txt; QString path = m_strPath; if ( path.isEmpty() ) path = "/"; else { int lastSlash = path.findRev( '/' ); if ( lastSlash == -1) { // The first character is not a '/' ??? // This looks strange ... path = "/"; } else if ( path.right(1) != "/" ) path.truncate( lastSlash+1 ); // keep the "/" } path += tmp; setPath( path ); cleanPath();}static QString cleanpath(const QString &path){ if (path.isEmpty()) return QString::null; // Did we have a trailing '/' int len = path.length(); bool slash = false; if ( len > 0 && path.right(1)[0] == '/' ) slash = true; QString result = QDir::cleanDirPath( path ); // Restore the trailing '/' len = result.length(); if ( len > 0 && result.right(1)[0] != '/' && slash ) result += "/"; return result;}void KURL::cleanPath() // taken from the old KURL{ m_strPath = cleanpath(m_strPath); // WABA: Is this safe when "/../" is encoded with %? m_strPath_encoded = cleanpath(m_strPath_encoded);}static QString trailingSlash( int _trailing, const QString &path ){ QString result = path; if ( _trailing == 0 ) return result; else if ( _trailing == 1 ) { int len = result.length(); if ( len == 0 ) result = QString::null; else if ( result[ len - 1 ] != '/' ) result += "/"; return result; } else if ( _trailing == -1 ) { if ( result == "/" ) return result; int len = result.length(); if ( len != 0 && result[ len - 1 ] == '/' ) result.truncate( len - 1 ); return result; } else { assert( 0 ); return QString::null; }}QString KURL::encodedPathAndQuery( int _trailing, bool _no_empty_path, int encoding_hint ) const{ QString tmp; if (!m_strPath_encoded.isEmpty() && encoding_hint == 0) { tmp = trailingSlash( _trailing, m_strPath_encoded ); } else { tmp = path( _trailing ); if ( _no_empty_path && tmp.isEmpty() ) tmp = "/"; tmp = encode( tmp, false, encoding_hint ); } // TODO apply encoding_hint to the query tmp += m_strQuery_encoded; return tmp;}void KURL::setEncodedPathAndQuery( const QString& _txt, int encoding_hint ){ int pos = _txt.find( '?' ); if ( pos == -1 ) { m_strPath_encoded = _txt; m_strQuery_encoded = QString::null; } else { m_strPath_encoded = _txt.left( pos ); m_strQuery_encoded = _txt.right(_txt.length() - pos); } bool keepEncoded; m_strPath = decode( m_strPath_encoded, &keepEncoded, encoding_hint );// WABA: Always keep the original encoding. There are a lot of// braindead web-servers out there you know.// if (!keepEncoded)// m_strPath_encoded = QString::null;}QString KURL::path( int _trailing ) const{ return trailingSlash( _trailing, path() );}bool KURL::isLocalFile() const{#if 0 static const QString & fileProt = KGlobal::staticQString( "file" );#else static const char* fileProt = "file";#endif return ( ( m_strProtocol == fileProt ) && ( m_strHost.isEmpty()) );}bool KURL::hasSubURL() const{ if ( m_strProtocol.isEmpty() || m_bIsMalformed ) return false; if (m_strRef_encoded.isEmpty()) return false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -