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 + -
显示快捷键?