📄 q3url.cpp
字号:
/*! Returns true if the URL contains a hostname; otherwise returns false. \sa setHost()*/bool Q3Url::hasHost() const{ return !d->host.isEmpty();}/*! Returns the port of the URL or -1 if no port has been set. \sa setPort()*/int Q3Url::port() const{ return d->port;}/*! Sets the port of the URL to \a port. \sa port()*/void Q3Url::setPort( int port ){ d->port = port;}/*! Returns true if the URL contains a port; otherwise returns false. \sa setPort()*/bool Q3Url::hasPort() const{ return d->port >= 0;}/*! Sets the path of the URL to \a path. \sa path() hasPath()*/void Q3Url::setPath( const QString& path ){ d->path = path; slashify( d->path ); d->cleanPathDirty = true; d->isValid = true;}/*! Returns true if the URL contains a path; otherwise returns false. \sa path() setPath()*/bool Q3Url::hasPath() const{ return !d->path.isEmpty();}/*! Sets the query of the URL to \a txt. \a txt must be encoded. \sa query() encode()*/void Q3Url::setQuery( const QString& txt ){ d->queryEncoded = txt;}/*! Returns the (encoded) query of the URL. \sa setQuery() decode()*/QString Q3Url::query() const{ return d->queryEncoded;}/*! Returns the (encoded) reference of the URL. \sa setRef() hasRef() decode()*/QString Q3Url::ref() const{ return d->refEncoded;}/*! Sets the reference of the URL to \a txt. \a txt must be encoded. \sa ref() hasRef() encode()*/void Q3Url::setRef( const QString& txt ){ d->refEncoded = txt;}/*! Returns true if the URL has a reference; otherwise returns false. \sa setRef()*/bool Q3Url::hasRef() const{ return !d->refEncoded.isEmpty();}/*! Returns true if the URL is valid; otherwise returns false. A URL is invalid if it cannot be parsed, for example.*/bool Q3Url::isValid() const{ return d->isValid;}/*! Resets all parts of the URL to their default values and invalidates it.*/void Q3Url::reset(){ d->protocol = QLatin1String("file"); d->user = QLatin1String(""); d->pass = QLatin1String(""); d->host = QLatin1String(""); d->path = QLatin1String(""); d->queryEncoded = QLatin1String(""); d->refEncoded = QLatin1String(""); d->isValid = true; d->port = -1; d->cleanPathDirty = true;}/*! Parses the \a url. Returns true on success; otherwise returns false.*/bool Q3Url::parse( const QString& url ){ QString url_( url ); slashify( url_ ); if ( url_.isEmpty() ) { d->isValid = false; return false; } d->cleanPathDirty = true; d->isValid = true; QString oldProtocol = d->protocol; d->protocol.clear(); const int Init = 0; const int Protocol = 1; const int Separator1= 2; // : const int Separator2= 3; // :/ const int Separator3= 4; // :// or more slashes const int User = 5; const int Pass = 6; const int Host = 7; const int Path = 8; const int Ref = 9; const int Query = 10; const int Port = 11; const int Done = 12; const int InputAlpha= 1; const int InputDigit= 2; const int InputSlash= 3; const int InputColon= 4; const int InputAt = 5; const int InputHash = 6; const int InputQuery= 7; static uchar table[ 12 ][ 8 ] = { /* None InputAlpha InputDigit InputSlash InputColon InputAt InputHash InputQuery */ { 0, Protocol, 0, Path, 0, 0, 0, 0, }, // Init { 0, Protocol, Protocol, 0, Separator1, 0, 0, 0, }, // Protocol { 0, Path, Path, Separator2, 0, 0, 0, 0, }, // Separator1 { 0, Path, Path, Separator3, 0, 0, 0, 0, }, // Separator2 { 0, User, User, Separator3, Pass, Host, 0, 0, }, // Separator3 { 0, User, User, User, Pass, Host, User, User, }, // User { 0, Pass, Pass, Pass, Pass, Host, Pass, Pass, }, // Pass { 0, Host, Host, Path, Port, Host, Ref, Query, }, // Host { 0, Path, Path, Path, Path, Path, Ref, Query, }, // Path { 0, Ref, Ref, Ref, Ref, Ref, Ref, Query, }, // Ref { 0, Query, Query, Query, Query, Query, Query, Query, }, // Query { 0, 0, Port, Path, 0, 0, 0, 0, } // Port }; bool relPath = false; relPath = false; bool forceRel = false; // If ':' is at pos 1, we have only one letter // before that separator => that's a drive letter! if ( url_.length() >= 2 && url_[1] == QLatin1Char(':') ) relPath = forceRel = true; int hasNoHost = -1; int cs = url_.find( QLatin1String(":/") ); if ( cs != -1 ) // if a protocol is there, find out if there is a host or directly the path after it hasNoHost = url_.find( QLatin1String("///"), cs ); table[ 4 ][ 1 ] = User; table[ 4 ][ 2 ] = User; if ( cs == -1 || forceRel ) { // we have a relative file if ( url.find( QLatin1Char(':') ) == -1 || forceRel ) { table[ 0 ][ 1 ] = Path; // Filenames may also begin with a digit table[ 0 ][ 2 ] = Path; } else { table[ 0 ][ 1 ] = Protocol; } relPath = true; } else { // some checking table[ 0 ][ 1 ] = Protocol; // find the part between the protocol and the path as the meaning // of that part is dependent on some chars ++cs; while ( url_[ cs ] == QLatin1Char('/') ) ++cs; int slash = url_.find( QLatin1String("/"), cs ); if ( slash == -1 ) slash = url_.length() - 1; QString tmp = url_.mid( cs, slash - cs + 1 ); if ( !tmp.isEmpty() ) { // if this part exists // look for the @ in this part int at = tmp.find( QLatin1String("@") ); if ( at != -1 ) at += cs; // we have no @, which means host[:port], so directly // after the protocol the host starts, or if the protocol // is file or there were more than 2 slashes, it is the // path if ( at == -1 ) { if ( url_.left( 4 ) == QLatin1String("file") || hasNoHost != -1 ) table[ 4 ][ 1 ] = Path; else table[ 4 ][ 1 ] = Host; table[ 4 ][ 2 ] = table[ 4 ][ 1 ]; } } } int state = Init; // parse state int input; // input token QChar c = url_[ 0 ]; int i = 0; QString port; for ( ;; ) { switch ( c.latin1() ) { case '?': input = InputQuery; break; case '#': input = InputHash; break; case '@': input = InputAt; break; case ':': input = InputColon; break; case '/': input = InputSlash; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0': input = InputDigit; break; default: input = InputAlpha; } state = table[ state ][ input ]; switch ( state ) { case Protocol: d->protocol += c; break; case User: d->user += c; break; case Pass: d->pass += c; break; case Host: d->host += c; break; case Path: d->path += c; break; case Ref: d->refEncoded += c; break; case Query: d->queryEncoded += c; break; case Port: port += c; break; default: break; } ++i; if ( i > (int)url_.length() - 1 || state == Done || state == 0 ) break; c = url_[ i ]; } if ( !port.isEmpty() ) { port.remove( (uint)0, 1 ); d->port = port.toInt(); } // error if ( i < (int)url_.length() - 1 ) { d->isValid = false; return false; } if ( d->protocol.isEmpty() ) d->protocol = oldProtocol; if ( d->path.isEmpty() ) d->path = QLatin1String("/"); // hack for windows if ( d->path.length() == 2 && d->path[ 1 ] == QLatin1Char(':') ) d->path += QLatin1String("/"); // #### do some corrections, should be done nicer too if ( !d->pass.isEmpty() ) { if ( d->pass[ 0 ] == QLatin1Char(':') ) d->pass.remove( (uint)0, 1 ); decode( d->pass ); } if ( !d->user.isEmpty() ) { decode( d->user ); } if ( !d->path.isEmpty() ) { if ( d->path[ 0 ] == QLatin1Char('@') || d->path[ 0 ] == QLatin1Char(':') ) d->path.remove( (uint)0, 1 ); if ( d->path[ 0 ] != QLatin1Char('/') && !relPath && d->path[ 1 ] != QLatin1Char(':') ) d->path.prepend( QLatin1String("/") ); } if ( !d->refEncoded.isEmpty() && d->refEncoded[ 0 ] == QLatin1Char('#') ) d->refEncoded.remove( (uint)0, 1 ); if ( !d->queryEncoded.isEmpty() && d->queryEncoded[ 0 ] == QLatin1Char('?') ) d->queryEncoded.remove( (uint)0, 1 ); if ( !d->host.isEmpty() && d->host[ 0 ] == QLatin1Char('@') ) d->host.remove( (uint)0, 1 );#if defined(Q_OS_WIN32) // hack for windows file://machine/path syntax if ( d->protocol == QLatin1String("file") ) { if ( url.left( 7 ) == QLatin1String("file://") && d->path.length() > 1 && d->path[ 1 ] != QLatin1Char(':') ) d->path.prepend( QLatin1String("/") ); }#endif decode( d->path ); d->cleanPathDirty = true;#if 0 qDebug( "URL: %s", url.latin1() ); qDebug( "protocol: %s", d->protocol.latin1() ); qDebug( "user: %s", d->user.latin1() ); qDebug( "pass: %s", d->pass.latin1() ); qDebug( "host: %s", d->host.latin1() ); qDebug( "path: %s", path().latin1() ); qDebug( "ref: %s", d->refEncoded.latin1() ); qDebug( "query: %s", d->queryEncoded.latin1() ); qDebug( "port: %d\n\n----------------------------\n\n", d->port );#endif return true;}/*! \overload Parses \a url and assigns the resulting data to this class. If you pass a string like "/home/qt" the "file" protocol will be assumed.*/Q3Url& Q3Url::operator=( const QString& url ){ reset(); parse( url ); return *this;}/*! Assigns the data of \a url to this class.*/Q3Url& Q3Url::operator=( const Q3Url& url ){ *d = *url.d; return *this;}/*! Compares this URL with \a url and returns true if they are equal; otherwise returns false.*/bool Q3Url::operator==( const Q3Url& url ) const{ if ( !isValid() || !url.isValid() )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -