src/corelib/io/qurl.cpp
changeset 7 f7bc934e204c
parent 3 41300fa6a67c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
     1 /****************************************************************************
     1 /****************************************************************************
     2 **
     2 **
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     4 ** All rights reserved.
     4 ** All rights reserved.
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
     6 **
     6 **
     7 ** This file is part of the QtCore module of the Qt Toolkit.
     7 ** This file is part of the QtCore module of the Qt Toolkit.
     8 **
     8 **
   348         Normalized = 0x4,
   348         Normalized = 0x4,
   349         HostCanonicalized = 0x8
   349         HostCanonicalized = 0x8
   350     };
   350     };
   351     int stateFlags;
   351     int stateFlags;
   352 
   352 
   353     QByteArray encodedNormalized;
   353     mutable QByteArray encodedNormalized;
   354     const QByteArray & normalized();
   354     const QByteArray & normalized() const;
   355 
   355 
   356     mutable QUrlErrorInfo errorInfo;
   356     mutable QUrlErrorInfo errorInfo;
   357     QString createErrorString();
   357     QString createErrorString();
   358 };
   358 };
   359 
   359 
   435     } 
   435     } 
   436     return false;
   436     return false;
   437 }
   437 }
   438 
   438 
   439 // scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
   439 // scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
   440 static void QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData)
   440 static bool QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData)
   441 {
   441 {
   442     bool first = true;
   442     bool first = true;
       
   443     bool isSchemeValid = true;
   443 
   444 
   444     parseData->scheme = *ptr;
   445     parseData->scheme = *ptr;
   445     for (;;) {
   446     for (;;) {
   446         char ch = **ptr;
   447         char ch = **ptr;
   447         if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
   448         if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
   448             ;
   449             ;
   449         } else if (!first && ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.')) {
   450         } else if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.') {
   450             ;
   451             if (first)
       
   452                 isSchemeValid = false;
   451         } else {
   453         } else {
   452             break;
   454             break;
   453         }
   455         }
   454 
   456 
   455         ++(*ptr);
   457         ++(*ptr);
   456         first = false;
   458         first = false;
   457     }
   459     }
   458 
   460 
   459     if (**ptr != ':') {
   461     if (**ptr != ':') {
       
   462         isSchemeValid = true;
   460         *ptr = parseData->scheme;
   463         *ptr = parseData->scheme;
   461     } else {
   464     } else {
   462         parseData->schemeLength = *ptr - parseData->scheme;
   465         parseData->schemeLength = *ptr - parseData->scheme;
   463         ++(*ptr); // skip ':'
   466         ++(*ptr); // skip ':'
   464     }
   467     }
       
   468 
       
   469     return isSchemeValid;
   465 }
   470 }
   466 
   471 
   467 // IPvFuture  = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
   472 // IPvFuture  = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
   468 static bool QT_FASTCALL _IPvFuture(const char **ptr)
   473 static bool QT_FASTCALL _IPvFuture(const char **ptr)
   469 {
   474 {
  3239     QString aceForm; // this variable is here for caching
  3244     QString aceForm; // this variable is here for caching
  3240 
  3245 
  3241     while (1) {
  3246     while (1) {
  3242         int idx = nextDotDelimiter(domain, lastIdx);
  3247         int idx = nextDotDelimiter(domain, lastIdx);
  3243         int labelLength = idx - lastIdx;
  3248         int labelLength = idx - lastIdx;
  3244         if (labelLength == 0)
  3249         if (labelLength == 0) {
       
  3250             if (idx == domain.length())
       
  3251                 break;
  3245             return QString(); // two delimiters in a row -- empty label not allowed
  3252             return QString(); // two delimiters in a row -- empty label not allowed
       
  3253         }
  3246 
  3254 
  3247         // RFC 3490 says, about the ToASCII operation:
  3255         // RFC 3490 says, about the ToASCII operation:
  3248         //   3. If the UseSTD3ASCIIRules flag is set, then perform these checks:
  3256         //   3. If the UseSTD3ASCIIRules flag is set, then perform these checks:
  3249         //
  3257         //
  3250         //     (a) Verify the absence of non-LDH ASCII code points; that is, the
  3258         //     (a) Verify the absence of non-LDH ASCII code points; that is, the
  3738 #if defined (QURL_DEBUG)
  3746 #if defined (QURL_DEBUG)
  3739     qDebug("QUrlPrivate::parse(), parsing \"%s\"", pptr);
  3747     qDebug("QUrlPrivate::parse(), parsing \"%s\"", pptr);
  3740 #endif
  3748 #endif
  3741 
  3749 
  3742     // optional scheme
  3750     // optional scheme
  3743     _scheme(ptr, &parseData);
  3751     bool isSchemeValid = _scheme(ptr, &parseData);
       
  3752 
       
  3753     if (isSchemeValid == false) {
       
  3754         that->isValid = false;
       
  3755         char ch = *((*ptr)++);
       
  3756         that->errorInfo.setParams(*ptr, QT_TRANSLATE_NOOP(QUrl, "unexpected URL scheme"),
       
  3757                                   0, ch);
       
  3758         QURL_SETFLAG(that->stateFlags, Validated | Parsed);
       
  3759 #if defined (QURL_DEBUG)
       
  3760         qDebug("QUrlPrivate::parse(), unrecognized: %c%s", ch, *ptr);
       
  3761 #endif
       
  3762         return;
       
  3763     }
  3744 
  3764 
  3745     // hierpart
  3765     // hierpart
  3746     _hierPart(ptr, &parseData);
  3766     _hierPart(ptr, &parseData);
  3747 
  3767 
  3748     // optional query
  3768     // optional query
  3848 QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const
  3868 QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const
  3849 {
  3869 {
  3850     if (!QURL_HASFLAG(stateFlags, Parsed)) parse();
  3870     if (!QURL_HASFLAG(stateFlags, Parsed)) parse();
  3851     else ensureEncodedParts();
  3871     else ensureEncodedParts();
  3852 
  3872 
       
  3873     if (options==0x100) // private - see qHash(QUrl)
       
  3874         return normalized();
       
  3875 
  3853     QByteArray url;
  3876     QByteArray url;
  3854 
  3877 
  3855     if (!(options & QUrl::RemoveScheme) && !scheme.isEmpty()) {
  3878     if (!(options & QUrl::RemoveScheme) && !scheme.isEmpty()) {
  3856         url += scheme.toLatin1();
  3879         url += scheme.toLatin1();
  3857         url += ':';
  3880         url += ':';
  3862         if (doFileScheme && !encodedPath.startsWith('/'))
  3885         if (doFileScheme && !encodedPath.startsWith('/'))
  3863             url += '/';
  3886             url += '/';
  3864         url += "//";
  3887         url += "//";
  3865 
  3888 
  3866         if ((options & QUrl::RemoveUserInfo) != QUrl::RemoveUserInfo) {
  3889         if ((options & QUrl::RemoveUserInfo) != QUrl::RemoveUserInfo) {
       
  3890             bool hasUserOrPass = false;
  3867             if (!userName.isEmpty()) {
  3891             if (!userName.isEmpty()) {
  3868                 url += encodedUserName;
  3892                 url += encodedUserName;
  3869                 if (!(options & QUrl::RemovePassword) && !password.isEmpty()) {
  3893                 hasUserOrPass = true;
  3870                     url += ':';
  3894             }
  3871                     url += encodedPassword;
  3895             if (!(options & QUrl::RemovePassword) && !password.isEmpty()) {
  3872                 }
  3896                 url += ':';
       
  3897                 url += encodedPassword;
       
  3898                 hasUserOrPass = true;
       
  3899             }
       
  3900             if (hasUserOrPass)
  3873                 url += '@';
  3901                 url += '@';
  3874             }
       
  3875         }
  3902         }
  3876 
  3903 
  3877         if (host.startsWith(QLatin1Char('['))) {
  3904         if (host.startsWith(QLatin1Char('['))) {
  3878             url += host.toLatin1();
  3905             url += host.toLatin1();
  3879         } else if (host.contains(QLatin1Char(':'))) {
  3906         } else if (host.contains(QLatin1Char(':'))) {
  3914     return url;
  3941     return url;
  3915 }
  3942 }
  3916 
  3943 
  3917 #define qToLower(ch) (((ch|32) >= 'a' && (ch|32) <= 'z') ? (ch|32) : ch)
  3944 #define qToLower(ch) (((ch|32) >= 'a' && (ch|32) <= 'z') ? (ch|32) : ch)
  3918 
  3945 
  3919 const QByteArray &QUrlPrivate::normalized()
  3946 const QByteArray &QUrlPrivate::normalized() const
  3920 {
  3947 {
  3921     if (QURL_HASFLAG(stateFlags, QUrlPrivate::Normalized))
  3948     if (QURL_HASFLAG(stateFlags, QUrlPrivate::Normalized))
  3922         return encodedNormalized;
  3949         return encodedNormalized;
  3923 
  3950 
  3924     QURL_SETFLAG(stateFlags, QUrlPrivate::Normalized);
  3951     QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
       
  3952     QURL_SETFLAG(that->stateFlags, QUrlPrivate::Normalized);
  3925 
  3953 
  3926     QUrlPrivate tmp = *this;
  3954     QUrlPrivate tmp = *this;
  3927     tmp.scheme = tmp.scheme.toLower();
  3955     tmp.scheme = tmp.scheme.toLower();
  3928     tmp.host = tmp.canonicalHost();
  3956     tmp.host = tmp.canonicalHost();
  3929 
  3957 
  4068 
  4096 
  4069     \snippet doc/src/snippets/code/src_corelib_io_qurl.cpp 1
  4097     \snippet doc/src/snippets/code/src_corelib_io_qurl.cpp 1
  4070 
  4098 
  4071     \sa setUrl(), setEncodedUrl(), fromEncoded(), TolerantMode
  4099     \sa setUrl(), setEncodedUrl(), fromEncoded(), TolerantMode
  4072 */
  4100 */
  4073 QUrl::QUrl(const QString &url) : d(new QUrlPrivate)
  4101 QUrl::QUrl(const QString &url) : d(0)
  4074 {
  4102 {
  4075     if (!url.isEmpty())
  4103     if (!url.isEmpty())
  4076         setUrl(url);
  4104         setUrl(url);
  4077 }
  4105 }
  4078 
  4106 
  4081 
  4109 
  4082     Parses the \a url using the parser mode \a parsingMode.
  4110     Parses the \a url using the parser mode \a parsingMode.
  4083 
  4111 
  4084     \sa setUrl()
  4112     \sa setUrl()
  4085 */
  4113 */
  4086 QUrl::QUrl(const QString &url, ParsingMode parsingMode) : d(new QUrlPrivate)
  4114 QUrl::QUrl(const QString &url, ParsingMode parsingMode) : d(0)
  4087 {
  4115 {
  4088     if (!url.isEmpty())
  4116     if (!url.isEmpty())
  4089         setUrl(url, parsingMode);
  4117         setUrl(url, parsingMode);
  4090     else
  4118     else {
       
  4119         d = new QUrlPrivate;
  4091         d->parsingMode = parsingMode;
  4120         d->parsingMode = parsingMode;
       
  4121     }
  4092 }
  4122 }
  4093 
  4123 
  4094 /*!
  4124 /*!
  4095     Constructs an empty QUrl object.
  4125     Constructs an empty QUrl object.
  4096 */
  4126 */
  4097 QUrl::QUrl() : d(new QUrlPrivate)
  4127 QUrl::QUrl() : d(0)
  4098 {
  4128 {
  4099 }
  4129 }
  4100 
  4130 
  4101 /*!
  4131 /*!
  4102     Constructs a copy of \a other.
  4132     Constructs a copy of \a other.
  4103 */
  4133 */
  4104 QUrl::QUrl(const QUrl &other) : d(other.d)
  4134 QUrl::QUrl(const QUrl &other) : d(other.d)
  4105 {
  4135 {
  4106     d->ref.ref();
  4136     if (d)
       
  4137         d->ref.ref();
  4107 }
  4138 }
  4108 
  4139 
  4109 /*!
  4140 /*!
  4110     Destructor; called immediately before the object is deleted.
  4141     Destructor; called immediately before the object is deleted.
  4111 */
  4142 */
  4112 QUrl::~QUrl()
  4143 QUrl::~QUrl()
  4113 {
  4144 {
  4114     if (!d->ref.deref())
  4145     if (d && !d->ref.deref())
  4115         delete d;
  4146         delete d;
  4116 }
  4147 }
  4117 
  4148 
  4118 /*!
  4149 /*!
  4119     Returns true if the URL is valid; otherwise returns false.
  4150     Returns true if the URL is valid; otherwise returns false.
  4124 
  4155 
  4125     \snippet doc/src/snippets/code/src_corelib_io_qurl.cpp 2
  4156     \snippet doc/src/snippets/code/src_corelib_io_qurl.cpp 2
  4126 */
  4157 */
  4127 bool QUrl::isValid() const
  4158 bool QUrl::isValid() const
  4128 {
  4159 {
       
  4160     if (!d) return false;
       
  4161 
  4129     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4162     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4130     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Validated)) d->validate();
  4163     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Validated)) d->validate();
  4131 
  4164 
  4132     return d->isValid;
  4165     return d->isValid;
  4133 }
  4166 }
  4135 /*!
  4168 /*!
  4136     Returns true if the URL has no data; otherwise returns false.
  4169     Returns true if the URL has no data; otherwise returns false.
  4137 */
  4170 */
  4138 bool QUrl::isEmpty() const
  4171 bool QUrl::isEmpty() const
  4139 {
  4172 {
       
  4173     if (!d) return true;
       
  4174 
  4140     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed))
  4175     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed))
  4141         return d->encodedOriginal.isEmpty();
  4176         return d->encodedOriginal.isEmpty();
  4142     else
  4177     else
  4143         return d->scheme.isEmpty()   // no encodedScheme
  4178         return d->scheme.isEmpty()   // no encodedScheme
  4144         && d->userName.isEmpty() && d->encodedUserName.isEmpty()
  4179         && d->userName.isEmpty() && d->encodedUserName.isEmpty()
  4155     QUrl is equal to one that has been constructed with the default
  4190     QUrl is equal to one that has been constructed with the default
  4156     empty constructor.
  4191     empty constructor.
  4157 */
  4192 */
  4158 void QUrl::clear()
  4193 void QUrl::clear()
  4159 {
  4194 {
  4160     detach();
  4195     if (d && !d->ref.deref())
  4161     d->clear();
  4196         delete d;
       
  4197     d = 0;
  4162 }
  4198 }
  4163 
  4199 
  4164 /*!
  4200 /*!
  4165     Constructs a URL by parsing the contents of \a url.
  4201     Constructs a URL by parsing the contents of \a url.
  4166 
  4202 
  4255     Constructs a URL by parsing the contents of \a encodedUrl using
  4291     Constructs a URL by parsing the contents of \a encodedUrl using
  4256     the given \a parsingMode.
  4292     the given \a parsingMode.
  4257 */
  4293 */
  4258 void QUrl::setEncodedUrl(const QByteArray &encodedUrl, ParsingMode parsingMode)
  4294 void QUrl::setEncodedUrl(const QByteArray &encodedUrl, ParsingMode parsingMode)
  4259 {
  4295 {
  4260     clear();
       
  4261     QByteArray tmp = encodedUrl;
  4296     QByteArray tmp = encodedUrl;
       
  4297     if (!d) d = new QUrlPrivate;
       
  4298     else d->clear();
  4262     if ((d->parsingMode = parsingMode) == TolerantMode) {
  4299     if ((d->parsingMode = parsingMode) == TolerantMode) {
  4263         // Replace stray % with %25
  4300         // Replace stray % with %25
  4264         QByteArray copy = tmp;
  4301         QByteArray copy = tmp;
  4265         for (int i = 0, j = 0; i < copy.size(); ++i, ++j) {
  4302         for (int i = 0, j = 0; i < copy.size(); ++i, ++j) {
  4266             if (copy.at(i) == '%') {
  4303             if (copy.at(i) == '%') {
  4330 
  4367 
  4331     \sa scheme(), isRelative()
  4368     \sa scheme(), isRelative()
  4332 */
  4369 */
  4333 void QUrl::setScheme(const QString &scheme)
  4370 void QUrl::setScheme(const QString &scheme)
  4334 {
  4371 {
       
  4372     if (!d) d = new QUrlPrivate;
  4335     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4373     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4336     detach();
  4374     detach();
  4337     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4375     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4338 
  4376 
  4339     d->scheme = scheme;
  4377     d->scheme = scheme;
  4345 
  4383 
  4346     \sa setScheme(), isRelative()
  4384     \sa setScheme(), isRelative()
  4347 */
  4385 */
  4348 QString QUrl::scheme() const
  4386 QString QUrl::scheme() const
  4349 {
  4387 {
       
  4388     if (!d) return QString();
  4350     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4389     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4351 
  4390 
  4352     return d->scheme;
  4391     return d->scheme;
  4353 }
  4392 }
  4354 
  4393 
  4368 
  4407 
  4369     \img qurl-authority.png
  4408     \img qurl-authority.png
  4370 */
  4409 */
  4371 void QUrl::setAuthority(const QString &authority)
  4410 void QUrl::setAuthority(const QString &authority)
  4372 {
  4411 {
       
  4412     if (!d) d = new QUrlPrivate;
       
  4413 
  4373     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4414     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4374     detach();
  4415     detach();
  4375     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4416     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4376 
  4417 
  4377     d->setAuthority(authority);
  4418     d->setAuthority(authority);
  4383 
  4424 
  4384     \sa setAuthority()
  4425     \sa setAuthority()
  4385 */
  4426 */
  4386 QString QUrl::authority() const
  4427 QString QUrl::authority() const
  4387 {
  4428 {
       
  4429     if (!d) return QString();
       
  4430 
  4388     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4431     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4389 
  4432 
  4390     return d->authority();
  4433     return d->authority();
  4391 }
  4434 }
  4392 
  4435 
  4403 
  4446 
  4404     \sa userInfo(), setUserName(), setPassword(), setAuthority()
  4447     \sa userInfo(), setUserName(), setPassword(), setAuthority()
  4405 */
  4448 */
  4406 void QUrl::setUserInfo(const QString &userInfo)
  4449 void QUrl::setUserInfo(const QString &userInfo)
  4407 {
  4450 {
       
  4451     if (!d) d = new QUrlPrivate;
       
  4452 
  4408     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4453     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4409     detach();
  4454     detach();
  4410     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4455     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4411 
  4456 
  4412     d->setUserInfo(userInfo.trimmed());
  4457     d->setUserInfo(userInfo.trimmed());
  4416     Returns the user info of the URL, or an empty string if the user
  4461     Returns the user info of the URL, or an empty string if the user
  4417     info is undefined.
  4462     info is undefined.
  4418 */
  4463 */
  4419 QString QUrl::userInfo() const
  4464 QString QUrl::userInfo() const
  4420 {
  4465 {
       
  4466     if (!d) return QString();
       
  4467 
  4421     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4468     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4422 
  4469 
  4423     return d->userInfo();
  4470     return d->userInfo();
  4424 }
  4471 }
  4425 
  4472 
  4430 
  4477 
  4431     \sa setEncodedUserName(), userName(), setUserInfo()
  4478     \sa setEncodedUserName(), userName(), setUserInfo()
  4432 */
  4479 */
  4433 void QUrl::setUserName(const QString &userName)
  4480 void QUrl::setUserName(const QString &userName)
  4434 {
  4481 {
       
  4482     if (!d) d = new QUrlPrivate;
       
  4483 
  4435     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4484     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4436     detach();
  4485     detach();
  4437     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4486     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4438 
  4487 
  4439     d->userName = userName;
  4488     d->userName = userName;
  4446 
  4495 
  4447     \sa setUserName(), encodedUserName()
  4496     \sa setUserName(), encodedUserName()
  4448 */
  4497 */
  4449 QString QUrl::userName() const
  4498 QString QUrl::userName() const
  4450 {
  4499 {
       
  4500     if (!d) return QString();
       
  4501 
  4451     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4502     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4452 
  4503 
  4453     d->userInfo();              // causes the unencoded form to be set
  4504     d->userInfo();              // causes the unencoded form to be set
  4454     return d->userName;
  4505     return d->userName;
  4455 }
  4506 }
  4467 
  4518 
  4468     \sa setUserName(), encodedUserName(), setUserInfo()
  4519     \sa setUserName(), encodedUserName(), setUserInfo()
  4469 */
  4520 */
  4470 void QUrl::setEncodedUserName(const QByteArray &userName)
  4521 void QUrl::setEncodedUserName(const QByteArray &userName)
  4471 {
  4522 {
       
  4523     if (!d) d = new QUrlPrivate;
  4472     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4524     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4473     detach();
  4525     detach();
  4474     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4526     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4475 
  4527 
  4476     d->encodedUserName = userName;
  4528     d->encodedUserName = userName;
  4487 
  4539 
  4488     \sa setEncodedUserName()
  4540     \sa setEncodedUserName()
  4489 */
  4541 */
  4490 QByteArray QUrl::encodedUserName() const
  4542 QByteArray QUrl::encodedUserName() const
  4491 {
  4543 {
       
  4544     if (!d) return QByteArray();
  4492     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4545     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4493 
  4546 
  4494     d->ensureEncodedParts();
  4547     d->ensureEncodedParts();
  4495     return d->encodedUserName;
  4548     return d->encodedUserName;
  4496 }
  4549 }
  4502 
  4555 
  4503     \sa password(), setUserInfo()
  4556     \sa password(), setUserInfo()
  4504 */
  4557 */
  4505 void QUrl::setPassword(const QString &password)
  4558 void QUrl::setPassword(const QString &password)
  4506 {
  4559 {
       
  4560     if (!d) d = new QUrlPrivate;
  4507     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4561     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4508     detach();
  4562     detach();
  4509     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4563     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4510 
  4564 
  4511     d->password = password;
  4565     d->password = password;
  4518 
  4572 
  4519     \sa setPassword()
  4573     \sa setPassword()
  4520 */
  4574 */
  4521 QString QUrl::password() const
  4575 QString QUrl::password() const
  4522 {
  4576 {
       
  4577     if (!d) return QString();
  4523     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4578     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4524 
  4579 
  4525     d->userInfo();              // causes the unencoded form to be set
  4580     d->userInfo();              // causes the unencoded form to be set
  4526     return d->password;
  4581     return d->password;
  4527 }
  4582 }
  4539 
  4594 
  4540     \sa setPassword(), encodedPassword(), setUserInfo()
  4595     \sa setPassword(), encodedPassword(), setUserInfo()
  4541 */
  4596 */
  4542 void QUrl::setEncodedPassword(const QByteArray &password)
  4597 void QUrl::setEncodedPassword(const QByteArray &password)
  4543 {
  4598 {
       
  4599     if (!d) d = new QUrlPrivate;
  4544     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4600     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4545     detach();
  4601     detach();
  4546     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4602     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4547 
  4603 
  4548     d->encodedPassword = password;
  4604     d->encodedPassword = password;
  4559 
  4615 
  4560     \sa setEncodedPassword(), toEncoded()
  4616     \sa setEncodedPassword(), toEncoded()
  4561 */
  4617 */
  4562 QByteArray QUrl::encodedPassword() const
  4618 QByteArray QUrl::encodedPassword() const
  4563 {
  4619 {
       
  4620     if (!d) return QByteArray();
  4564     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4621     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4565 
  4622 
  4566     d->ensureEncodedParts();
  4623     d->ensureEncodedParts();
  4567     return d->encodedPassword;
  4624     return d->encodedPassword;
  4568 }
  4625 }
  4573 
  4630 
  4574     \sa host(), setAuthority()
  4631     \sa host(), setAuthority()
  4575 */
  4632 */
  4576 void QUrl::setHost(const QString &host)
  4633 void QUrl::setHost(const QString &host)
  4577 {
  4634 {
       
  4635     if (!d) d = new QUrlPrivate;
  4578     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4636     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4579     detach();
  4637     detach();
  4580     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized | QUrlPrivate::HostCanonicalized);
  4638     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized | QUrlPrivate::HostCanonicalized);
  4581 
  4639 
  4582     d->host = host;
  4640     d->host = host;
  4586     Returns the host of the URL if it is defined; otherwise
  4644     Returns the host of the URL if it is defined; otherwise
  4587     an empty string is returned.
  4645     an empty string is returned.
  4588 */
  4646 */
  4589 QString QUrl::host() const
  4647 QString QUrl::host() const
  4590 {
  4648 {
       
  4649     if (!d) return QString();
  4591     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4650     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4592 
  4651 
  4593     if (d->host.isEmpty() || d->host.at(0) != QLatin1Char('['))
  4652     if (d->host.isEmpty() || d->host.at(0) != QLatin1Char('['))
  4594         return d->canonicalHost();
  4653         return d->canonicalHost();
  4595     QString tmp = d->host.mid(1);
  4654     QString tmp = d->host.mid(1);
  4639     \a port must be between 0 and 65535 inclusive. Setting the
  4698     \a port must be between 0 and 65535 inclusive. Setting the
  4640     port to -1 indicates that the port is unspecified.
  4699     port to -1 indicates that the port is unspecified.
  4641 */
  4700 */
  4642 void QUrl::setPort(int port)
  4701 void QUrl::setPort(int port)
  4643 {
  4702 {
       
  4703     if (!d) d = new QUrlPrivate;
  4644     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4704     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4645     detach();
  4705     detach();
  4646     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4706     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4647 
  4707 
  4648     if (port < -1 || port > 65535) {
  4708     if (port < -1 || port > 65535) {
  4656 /*!
  4716 /*!
  4657     Returns the port of the URL, or -1 if the port is unspecified.
  4717     Returns the port of the URL, or -1 if the port is unspecified.
  4658 */
  4718 */
  4659 int QUrl::port() const
  4719 int QUrl::port() const
  4660 {
  4720 {
       
  4721     if (!d) return -1;
  4661     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4722     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4662     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Validated)) d->validate();
  4723     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Validated)) d->validate();
  4663     return d->port;
  4724     return d->port;
  4664 }
  4725 }
  4665 
  4726 
  4674 
  4735 
  4675     \snippet doc/src/snippets/code/src_corelib_io_qurl.cpp 3
  4736     \snippet doc/src/snippets/code/src_corelib_io_qurl.cpp 3
  4676 */
  4737 */
  4677 int QUrl::port(int defaultPort) const
  4738 int QUrl::port(int defaultPort) const
  4678 {
  4739 {
       
  4740     if (!d) return defaultPort;
  4679     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4741     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4680     return d->port == -1 ? defaultPort : d->port;
  4742     return d->port == -1 ? defaultPort : d->port;
  4681 }
  4743 }
  4682 
  4744 
  4683 /*!
  4745 /*!
  4693 
  4755 
  4694     \sa path()
  4756     \sa path()
  4695 */
  4757 */
  4696 void QUrl::setPath(const QString &path)
  4758 void QUrl::setPath(const QString &path)
  4697 {
  4759 {
       
  4760     if (!d) d = new QUrlPrivate;
  4698     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4761     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4699     detach();
  4762     detach();
  4700     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4763     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4701 
  4764 
  4702     d->path = path;
  4765     d->path = path;
  4708 
  4771 
  4709     \sa setPath()
  4772     \sa setPath()
  4710 */
  4773 */
  4711 QString QUrl::path() const
  4774 QString QUrl::path() const
  4712 {
  4775 {
       
  4776     if (!d) return QString();
  4713     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4777     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4714 
  4778 
  4715     if (d->path.isNull()) {
  4779     if (d->path.isNull()) {
  4716         QUrlPrivate *that = const_cast<QUrlPrivate *>(d);
  4780         QUrlPrivate *that = const_cast<QUrlPrivate *>(d);
  4717         that->path = fromPercentEncodingHelper(d->encodedPath);
  4781         that->path = fromPercentEncodingHelper(d->encodedPath);
  4739 
  4803 
  4740     \sa setPath(), encodedPath(), setUserInfo()
  4804     \sa setPath(), encodedPath(), setUserInfo()
  4741 */
  4805 */
  4742 void QUrl::setEncodedPath(const QByteArray &path)
  4806 void QUrl::setEncodedPath(const QByteArray &path)
  4743 {
  4807 {
       
  4808     if (!d) d = new QUrlPrivate;
  4744     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4809     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4745     detach();
  4810     detach();
  4746     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4811     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4747 
  4812 
  4748     d->encodedPath = path;
  4813     d->encodedPath = path;
  4759 
  4824 
  4760     \sa setEncodedPath(), toEncoded()
  4825     \sa setEncodedPath(), toEncoded()
  4761 */
  4826 */
  4762 QByteArray QUrl::encodedPath() const
  4827 QByteArray QUrl::encodedPath() const
  4763 {
  4828 {
       
  4829     if (!d) return QByteArray();
  4764     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4830     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4765 
  4831 
  4766     d->ensureEncodedParts();
  4832     d->ensureEncodedParts();
  4767     return d->encodedPath;
  4833     return d->encodedPath;
  4768 }
  4834 }
  4774 
  4840 
  4775     \sa hasQueryItem(), encodedQuery()
  4841     \sa hasQueryItem(), encodedQuery()
  4776 */
  4842 */
  4777 bool QUrl::hasQuery() const
  4843 bool QUrl::hasQuery() const
  4778 {
  4844 {
       
  4845     if (!d) return false;
  4779     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4846     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4780 
  4847 
  4781     return d->hasQuery;
  4848     return d->hasQuery;
  4782 }
  4849 }
  4783 
  4850 
  4803     current query string. It only affects queryItems(),
  4870     current query string. It only affects queryItems(),
  4804     setQueryItems() and addQueryItems().
  4871     setQueryItems() and addQueryItems().
  4805 */
  4872 */
  4806 void QUrl::setQueryDelimiters(char valueDelimiter, char pairDelimiter)
  4873 void QUrl::setQueryDelimiters(char valueDelimiter, char pairDelimiter)
  4807 {
  4874 {
       
  4875     if (!d) d = new QUrlPrivate;
  4808     detach();
  4876     detach();
  4809 
  4877 
  4810     d->valueDelimiter = valueDelimiter;
  4878     d->valueDelimiter = valueDelimiter;
  4811     d->pairDelimiter = pairDelimiter;
  4879     d->pairDelimiter = pairDelimiter;
  4812 }
  4880 }
  4815     Returns the character used to delimit between key-value pairs in
  4883     Returns the character used to delimit between key-value pairs in
  4816     the query string of the URL.
  4884     the query string of the URL.
  4817 */
  4885 */
  4818 char QUrl::queryPairDelimiter() const
  4886 char QUrl::queryPairDelimiter() const
  4819 {
  4887 {
       
  4888     if (!d) return '&';
  4820     return d->pairDelimiter;
  4889     return d->pairDelimiter;
  4821 }
  4890 }
  4822 
  4891 
  4823 /*!
  4892 /*!
  4824     Returns the character used to delimit between keys and values in
  4893     Returns the character used to delimit between keys and values in
  4825     the query string of the URL.
  4894     the query string of the URL.
  4826 */
  4895 */
  4827 char QUrl::queryValueDelimiter() const
  4896 char QUrl::queryValueDelimiter() const
  4828 {
  4897 {
       
  4898     if (!d) return '=';
  4829     return d->valueDelimiter;
  4899     return d->valueDelimiter;
  4830 }
  4900 }
  4831 
  4901 
  4832 /*!
  4902 /*!
  4833     Sets the query string of the URL to \a query. The string is
  4903     Sets the query string of the URL to \a query. The string is
  4846 
  4916 
  4847     \sa encodedQuery(), hasQuery()
  4917     \sa encodedQuery(), hasQuery()
  4848 */
  4918 */
  4849 void QUrl::setEncodedQuery(const QByteArray &query)
  4919 void QUrl::setEncodedQuery(const QByteArray &query)
  4850 {
  4920 {
       
  4921     if (!d) d = new QUrlPrivate;
  4851     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4922     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4852     detach();
  4923     detach();
  4853     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4924     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  4854 
  4925 
  4855     d->query = query;
  4926     d->query = query;
  4865 
  4936 
  4866     \sa setQueryDelimiters(), queryItems(), setEncodedQueryItems()
  4937     \sa setQueryDelimiters(), queryItems(), setEncodedQueryItems()
  4867 */
  4938 */
  4868 void QUrl::setQueryItems(const QList<QPair<QString, QString> > &query)
  4939 void QUrl::setQueryItems(const QList<QPair<QString, QString> > &query)
  4869 {
  4940 {
       
  4941     if (!d) d = new QUrlPrivate;
  4870     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4942     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4871     detach();
  4943     detach();
  4872 
  4944 
  4873     char alsoEncode[3];
  4945     char alsoEncode[3];
  4874     alsoEncode[0] = d->valueDelimiter;
  4946     alsoEncode[0] = d->valueDelimiter;
  4904 
  4976 
  4905     \sa setQueryDelimiters(), encodedQueryItems(), setQueryItems()
  4977     \sa setQueryDelimiters(), encodedQueryItems(), setQueryItems()
  4906 */
  4978 */
  4907 void QUrl::setEncodedQueryItems(const QList<QPair<QByteArray, QByteArray> > &query)
  4979 void QUrl::setEncodedQueryItems(const QList<QPair<QByteArray, QByteArray> > &query)
  4908 {
  4980 {
       
  4981     if (!d) d = new QUrlPrivate;
  4909     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4982     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4910     detach();
  4983     detach();
  4911 
  4984 
  4912     QByteArray queryTmp;
  4985     QByteArray queryTmp;
  4913     for (int i = 0; i < query.size(); i++) {
  4986     for (int i = 0; i < query.size(); i++) {
  4933 
  5006 
  4934     \sa addEncodedQueryItem()
  5007     \sa addEncodedQueryItem()
  4935 */
  5008 */
  4936 void QUrl::addQueryItem(const QString &key, const QString &value)
  5009 void QUrl::addQueryItem(const QString &key, const QString &value)
  4937 {
  5010 {
       
  5011     if (!d) d = new QUrlPrivate;
  4938     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5012     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4939     detach();
  5013     detach();
  4940 
  5014 
  4941     char alsoEncode[3];
  5015     char alsoEncode[3];
  4942     alsoEncode[0] = d->valueDelimiter;
  5016     alsoEncode[0] = d->valueDelimiter;
  4967 
  5041 
  4968     \sa addQueryItem(), setQueryDelimiters()
  5042     \sa addQueryItem(), setQueryDelimiters()
  4969 */
  5043 */
  4970 void QUrl::addEncodedQueryItem(const QByteArray &key, const QByteArray &value)
  5044 void QUrl::addEncodedQueryItem(const QByteArray &key, const QByteArray &value)
  4971 {
  5045 {
       
  5046     if (!d) d = new QUrlPrivate;
  4972     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5047     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4973     detach();
  5048     detach();
  4974 
  5049 
  4975     if (!d->query.isEmpty())
  5050     if (!d->query.isEmpty())
  4976         d->query += d->pairDelimiter;
  5051         d->query += d->pairDelimiter;
  4987 
  5062 
  4988     \sa setQueryItems(), setEncodedQuery()
  5063     \sa setQueryItems(), setEncodedQuery()
  4989 */
  5064 */
  4990 QList<QPair<QString, QString> > QUrl::queryItems() const
  5065 QList<QPair<QString, QString> > QUrl::queryItems() const
  4991 {
  5066 {
       
  5067     if (!d) return QList<QPair<QString, QString> >();
  4992     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5068     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  4993 
  5069 
  4994     QList<QPair<QString, QString> > itemMap;
  5070     QList<QPair<QString, QString> > itemMap;
  4995 
  5071 
  4996     int pos = 0;
  5072     int pos = 0;
  5019 
  5095 
  5020     \sa setEncodedQueryItems(), setQueryItems(), setEncodedQuery()
  5096     \sa setEncodedQueryItems(), setQueryItems(), setEncodedQuery()
  5021 */
  5097 */
  5022 QList<QPair<QByteArray, QByteArray> > QUrl::encodedQueryItems() const
  5098 QList<QPair<QByteArray, QByteArray> > QUrl::encodedQueryItems() const
  5023 {
  5099 {
       
  5100     if (!d) return QList<QPair<QByteArray, QByteArray> >();
  5024     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5101     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5025 
  5102 
  5026     QList<QPair<QByteArray, QByteArray> > itemMap;
  5103     QList<QPair<QByteArray, QByteArray> > itemMap;
  5027 
  5104 
  5028     int pos = 0;
  5105     int pos = 0;
  5047 
  5124 
  5048     \sa hasEncodedQueryItem()
  5125     \sa hasEncodedQueryItem()
  5049 */
  5126 */
  5050 bool QUrl::hasQueryItem(const QString &key) const
  5127 bool QUrl::hasQueryItem(const QString &key) const
  5051 {
  5128 {
       
  5129     if (!d) return false;
  5052     return hasEncodedQueryItem(toPercentEncoding(key, queryExcludeChars));
  5130     return hasEncodedQueryItem(toPercentEncoding(key, queryExcludeChars));
  5053 }
  5131 }
  5054 
  5132 
  5055 /*!
  5133 /*!
  5056     \since 4.4
  5134     \since 4.4
  5065 
  5143 
  5066     \sa hasQueryItem()
  5144     \sa hasQueryItem()
  5067 */
  5145 */
  5068 bool QUrl::hasEncodedQueryItem(const QByteArray &key) const
  5146 bool QUrl::hasEncodedQueryItem(const QByteArray &key) const
  5069 {
  5147 {
       
  5148     if (!d) return false;
  5070     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5149     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5071 
  5150 
  5072     int pos = 0;
  5151     int pos = 0;
  5073     const char *query = d->query.constData();
  5152     const char *query = d->query.constData();
  5074     while (pos < d->query.size()) {
  5153     while (pos < d->query.size()) {
  5087 
  5166 
  5088     \sa allQueryItemValues()
  5167     \sa allQueryItemValues()
  5089 */
  5168 */
  5090 QString QUrl::queryItemValue(const QString &key) const
  5169 QString QUrl::queryItemValue(const QString &key) const
  5091 {
  5170 {
       
  5171     if (!d) return QString();
  5092     QByteArray tmp = encodedQueryItemValue(toPercentEncoding(key, queryExcludeChars));
  5172     QByteArray tmp = encodedQueryItemValue(toPercentEncoding(key, queryExcludeChars));
  5093     return fromPercentEncodingMutable(&tmp);
  5173     return fromPercentEncodingMutable(&tmp);
  5094 }
  5174 }
  5095 
  5175 
  5096 /*!
  5176 /*!
  5106 
  5186 
  5107     \sa queryItemValue(), allQueryItemValues()
  5187     \sa queryItemValue(), allQueryItemValues()
  5108 */
  5188 */
  5109 QByteArray QUrl::encodedQueryItemValue(const QByteArray &key) const
  5189 QByteArray QUrl::encodedQueryItemValue(const QByteArray &key) const
  5110 {
  5190 {
       
  5191     if (!d) return QByteArray();
  5111     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5192     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5112 
  5193 
  5113     int pos = 0;
  5194     int pos = 0;
  5114     const char *query = d->query.constData();
  5195     const char *query = d->query.constData();
  5115     while (pos < d->query.size()) {
  5196     while (pos < d->query.size()) {
  5129 
  5210 
  5130     \sa queryItemValue()
  5211     \sa queryItemValue()
  5131 */
  5212 */
  5132 QStringList QUrl::allQueryItemValues(const QString &key) const
  5213 QStringList QUrl::allQueryItemValues(const QString &key) const
  5133 {
  5214 {
       
  5215     if (!d) return QStringList();
  5134     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5216     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5135 
  5217 
  5136     QByteArray encodedKey = toPercentEncoding(key, queryExcludeChars);
  5218     QByteArray encodedKey = toPercentEncoding(key, queryExcludeChars);
  5137     QStringList values;
  5219     QStringList values;
  5138 
  5220 
  5166 
  5248 
  5167     \sa allQueryItemValues(), queryItemValue(), encodedQueryItemValue()
  5249     \sa allQueryItemValues(), queryItemValue(), encodedQueryItemValue()
  5168 */
  5250 */
  5169 QList<QByteArray> QUrl::allEncodedQueryItemValues(const QByteArray &key) const
  5251 QList<QByteArray> QUrl::allEncodedQueryItemValues(const QByteArray &key) const
  5170 {
  5252 {
       
  5253     if (!d) return QList<QByteArray>();
  5171     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5254     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5172 
  5255 
  5173     QList<QByteArray> values;
  5256     QList<QByteArray> values;
  5174 
  5257 
  5175     int pos = 0;
  5258     int pos = 0;
  5193 
  5276 
  5194     \sa removeAllQueryItems()
  5277     \sa removeAllQueryItems()
  5195 */
  5278 */
  5196 void QUrl::removeQueryItem(const QString &key)
  5279 void QUrl::removeQueryItem(const QString &key)
  5197 {
  5280 {
       
  5281     if (!d) return;
  5198     removeEncodedQueryItem(toPercentEncoding(key, queryExcludeChars));
  5282     removeEncodedQueryItem(toPercentEncoding(key, queryExcludeChars));
  5199 }
  5283 }
  5200 
  5284 
  5201 /*!
  5285 /*!
  5202     \since 4.4
  5286     \since 4.4
  5211 
  5295 
  5212     \sa removeQueryItem(), removeAllQueryItems()
  5296     \sa removeQueryItem(), removeAllQueryItems()
  5213 */
  5297 */
  5214 void QUrl::removeEncodedQueryItem(const QByteArray &key)
  5298 void QUrl::removeEncodedQueryItem(const QByteArray &key)
  5215 {
  5299 {
       
  5300     if (!d) return;
  5216     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5301     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5217     detach();
  5302     detach();
  5218 
  5303 
  5219     int pos = 0;
  5304     int pos = 0;
  5220     const char *query = d->query.constData();
  5305     const char *query = d->query.constData();
  5237 
  5322 
  5238    \sa removeQueryItem()
  5323    \sa removeQueryItem()
  5239 */
  5324 */
  5240 void QUrl::removeAllQueryItems(const QString &key)
  5325 void QUrl::removeAllQueryItems(const QString &key)
  5241 {
  5326 {
       
  5327     if (!d) return;
  5242     removeAllEncodedQueryItems(toPercentEncoding(key, queryExcludeChars));
  5328     removeAllEncodedQueryItems(toPercentEncoding(key, queryExcludeChars));
  5243 }
  5329 }
  5244 
  5330 
  5245 /*!
  5331 /*!
  5246     \since 4.4
  5332     \since 4.4
  5255 
  5341 
  5256    \sa removeQueryItem()
  5342    \sa removeQueryItem()
  5257 */
  5343 */
  5258 void QUrl::removeAllEncodedQueryItems(const QByteArray &key)
  5344 void QUrl::removeAllEncodedQueryItems(const QByteArray &key)
  5259 {
  5345 {
       
  5346     if (!d) return;
  5260     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5347     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5261     detach();
  5348     detach();
  5262 
  5349 
  5263     int pos = 0;
  5350     int pos = 0;
  5264     const char *query = d->query.constData();
  5351     const char *query = d->query.constData();
  5278 /*!
  5365 /*!
  5279     Returns the query string of the URL in percent encoded form.
  5366     Returns the query string of the URL in percent encoded form.
  5280 */
  5367 */
  5281 QByteArray QUrl::encodedQuery() const
  5368 QByteArray QUrl::encodedQuery() const
  5282 {
  5369 {
       
  5370     if (!d) return QByteArray();
  5283     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5371     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5284 
  5372 
  5285     return d->query;
  5373     return d->query;
  5286 }
  5374 }
  5287 
  5375 
  5302 
  5390 
  5303     \sa fragment(), hasFragment()
  5391     \sa fragment(), hasFragment()
  5304 */
  5392 */
  5305 void QUrl::setFragment(const QString &fragment)
  5393 void QUrl::setFragment(const QString &fragment)
  5306 {
  5394 {
       
  5395     if (!d) d = new QUrlPrivate;
  5307     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5396     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5308     detach();
  5397     detach();
  5309     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  5398     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  5310 
  5399 
  5311     d->fragment = fragment;
  5400     d->fragment = fragment;
  5318 
  5407 
  5319     \sa setFragment()
  5408     \sa setFragment()
  5320 */
  5409 */
  5321 QString QUrl::fragment() const
  5410 QString QUrl::fragment() const
  5322 {
  5411 {
       
  5412     if (!d) return QString();
  5323     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5413     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5324 
  5414 
  5325     if (d->fragment.isNull() && !d->encodedFragment.isNull()) {
  5415     if (d->fragment.isNull() && !d->encodedFragment.isNull()) {
  5326         QUrlPrivate *that = const_cast<QUrlPrivate *>(d);
  5416         QUrlPrivate *that = const_cast<QUrlPrivate *>(d);
  5327         that->fragment = fromPercentEncodingHelper(d->encodedFragment);
  5417         that->fragment = fromPercentEncodingHelper(d->encodedFragment);
  5348 
  5438 
  5349     \sa setFragment(), encodedFragment()
  5439     \sa setFragment(), encodedFragment()
  5350 */
  5440 */
  5351 void QUrl::setEncodedFragment(const QByteArray &fragment)
  5441 void QUrl::setEncodedFragment(const QByteArray &fragment)
  5352 {
  5442 {
       
  5443     if (!d) d = new QUrlPrivate;
  5353     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5444     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5354     detach();
  5445     detach();
  5355     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  5446     QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized);
  5356 
  5447 
  5357     d->encodedFragment = fragment;
  5448     d->encodedFragment = fragment;
  5369 
  5460 
  5370     \sa setEncodedFragment(), toEncoded()
  5461     \sa setEncodedFragment(), toEncoded()
  5371 */
  5462 */
  5372 QByteArray QUrl::encodedFragment() const
  5463 QByteArray QUrl::encodedFragment() const
  5373 {
  5464 {
       
  5465     if (!d) return QByteArray();
  5374     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5466     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5375 
  5467 
  5376     d->ensureEncodedParts();
  5468     d->ensureEncodedParts();
  5377     return d->encodedFragment;
  5469     return d->encodedFragment;
  5378 }
  5470 }
  5384 
  5476 
  5385     \sa fragment(), setFragment()
  5477     \sa fragment(), setFragment()
  5386 */
  5478 */
  5387 bool QUrl::hasFragment() const
  5479 bool QUrl::hasFragment() const
  5388 {
  5480 {
       
  5481     if (!d) return false;
  5389     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5482     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5390 
  5483 
  5391     return d->hasFragment;
  5484     return d->hasFragment;
  5392 }
  5485 }
  5393 
  5486 
  5410 
  5503 
  5411     \sa isRelative()
  5504     \sa isRelative()
  5412 */
  5505 */
  5413 QUrl QUrl::resolved(const QUrl &relative) const
  5506 QUrl QUrl::resolved(const QUrl &relative) const
  5414 {
  5507 {
       
  5508     if (!d) return relative;
       
  5509     if (!relative.d) return *this;
  5415     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5510     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5416 
  5511 
  5417     if (!QURL_HASFLAG(relative.d->stateFlags, QUrlPrivate::Parsed))
  5512     if (!QURL_HASFLAG(relative.d->stateFlags, QUrlPrivate::Parsed))
  5418         relative.d->parse();
  5513         relative.d->parse();
  5419 
  5514 
  5426         t = relative;
  5521         t = relative;
  5427     } else {
  5522     } else {
  5428         if (!relative.authority().isEmpty()) {
  5523         if (!relative.authority().isEmpty()) {
  5429             t = relative;
  5524             t = relative;
  5430         } else {
  5525         } else {
       
  5526             t.d = new QUrlPrivate;
  5431             if (relative.d->encodedPath.isEmpty()) {
  5527             if (relative.d->encodedPath.isEmpty()) {
  5432                 t.d->encodedPath = d->encodedPath;
  5528                 t.d->encodedPath = d->encodedPath;
  5433                 t.setEncodedQuery(relative.d->hasQuery ? relative.d->query : d->query);
  5529                 t.setEncodedQuery(relative.d->hasQuery ? relative.d->query : d->query);
  5434             } else {
  5530             } else {
  5435                 t.d->encodedPath = relative.d->encodedPath.at(0) == '/'
  5531                 t.d->encodedPath = relative.d->encodedPath.at(0) == '/'
  5456     URL is relative if its scheme is undefined; this function is
  5552     URL is relative if its scheme is undefined; this function is
  5457     therefore equivalent to calling scheme().isEmpty().
  5553     therefore equivalent to calling scheme().isEmpty().
  5458 */
  5554 */
  5459 bool QUrl::isRelative() const
  5555 bool QUrl::isRelative() const
  5460 {
  5556 {
       
  5557     if (!d) return true;
  5461     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5558     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5462 
  5559 
  5463     return d->scheme.isEmpty();
  5560     return d->scheme.isEmpty();
  5464 }
  5561 }
  5465 
  5562 
  5470 
  5567 
  5471     \sa FormattingOptions, toEncoded()
  5568     \sa FormattingOptions, toEncoded()
  5472 */
  5569 */
  5473 QString QUrl::toString(FormattingOptions options) const
  5570 QString QUrl::toString(FormattingOptions options) const
  5474 {
  5571 {
       
  5572     if (!d) return QString();
  5475     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5573     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5476 
  5574 
  5477     QString url;
  5575     QString url;
  5478 
  5576 
  5479     if (!(options & QUrl::RemoveScheme) && !d->scheme.isEmpty())
  5577     if (!(options & QUrl::RemoveScheme) && !d->scheme.isEmpty())
  5521     all non-ASCII characters are then percent encoded. The host name
  5619     all non-ASCII characters are then percent encoded. The host name
  5522     is encoded using Punycode.
  5620     is encoded using Punycode.
  5523 */
  5621 */
  5524 QByteArray QUrl::toEncoded(FormattingOptions options) const
  5622 QByteArray QUrl::toEncoded(FormattingOptions options) const
  5525 {
  5623 {
       
  5624     if (!d) return QByteArray();
  5526     return d->toEncoded(options);
  5625     return d->toEncoded(options);
  5527 }
  5626 }
  5528 
  5627 
  5529 /*!
  5628 /*!
  5530     Parses \a input and returns the corresponding QUrl. \a input is
  5629     Parses \a input and returns the corresponding QUrl. \a input is
  5771     Returns true if this URL is "less than" the given \a url. This
  5870     Returns true if this URL is "less than" the given \a url. This
  5772     provides a means of ordering URLs.
  5871     provides a means of ordering URLs.
  5773 */
  5872 */
  5774 bool QUrl::operator <(const QUrl &url) const
  5873 bool QUrl::operator <(const QUrl &url) const
  5775 {
  5874 {
       
  5875     if (!d) return url.d ? QByteArray() < url.d->normalized() : false;
  5776     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5876     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
       
  5877     if (!url.d) return d->normalized() < QByteArray();
  5777     if (!QURL_HASFLAG(url.d->stateFlags, QUrlPrivate::Parsed)) url.d->parse();
  5878     if (!QURL_HASFLAG(url.d->stateFlags, QUrlPrivate::Parsed)) url.d->parse();
  5778     return d->normalized() < url.d->normalized();
  5879     return d->normalized() < url.d->normalized();
  5779 }
  5880 }
  5780 
  5881 
  5781 /*!
  5882 /*!
  5782     Returns true if this URL and the given \a url are equal;
  5883     Returns true if this URL and the given \a url are equal;
  5783     otherwise returns false.
  5884     otherwise returns false.
  5784 */
  5885 */
  5785 bool QUrl::operator ==(const QUrl &url) const
  5886 bool QUrl::operator ==(const QUrl &url) const
  5786 {
  5887 {
       
  5888     if (!d) return url.isEmpty();
       
  5889     if (!url.d) return isEmpty();
  5787     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5890     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5788     if (!QURL_HASFLAG(url.d->stateFlags, QUrlPrivate::Parsed)) url.d->parse();
  5891     if (!QURL_HASFLAG(url.d->stateFlags, QUrlPrivate::Parsed)) url.d->parse();
  5789     return d->normalized() == url.d->normalized();
  5892     return d->normalized() == url.d->normalized();
  5790 }
  5893 }
  5791 
  5894 
  5801 /*!
  5904 /*!
  5802     Assigns the specified \a url to this object.
  5905     Assigns the specified \a url to this object.
  5803 */
  5906 */
  5804 QUrl &QUrl::operator =(const QUrl &url)
  5907 QUrl &QUrl::operator =(const QUrl &url)
  5805 {
  5908 {
  5806     qAtomicAssign(d, url.d);
  5909     if (!d) {
       
  5910         if (url.d) {
       
  5911             url.d->ref.ref();
       
  5912             d = url.d;
       
  5913         }
       
  5914     } else {
       
  5915         if (url.d)
       
  5916             qAtomicAssign(d, url.d);
       
  5917         else
       
  5918             clear();
       
  5919     }
  5807     return *this;
  5920     return *this;
  5808 }
  5921 }
  5809 
  5922 
  5810 /*!
  5923 /*!
  5811     Assigns the specified \a url to this object.
  5924     Assigns the specified \a url to this object.
  5812 */
  5925 */
  5813 QUrl &QUrl::operator =(const QString &url)
  5926 QUrl &QUrl::operator =(const QString &url)
  5814 {
  5927 {
  5815     QUrl tmp(url);
  5928     if (url.isEmpty()) {
  5816     qAtomicAssign(d, tmp.d);
  5929         clear();
       
  5930     } else {
       
  5931         QUrl tmp(url);
       
  5932         if (!d) d = new QUrlPrivate;
       
  5933         qAtomicAssign(d, tmp.d);
       
  5934     }
  5817     return *this;
  5935     return *this;
  5818 }
  5936 }
  5819 
  5937 
  5820 /*! \internal
  5938 /*! \internal
  5821 
  5939 
  5822     Forces a detach.
  5940     Forces a detach.
  5823 */
  5941 */
  5824 void QUrl::detach()
  5942 void QUrl::detach()
  5825 { qAtomicDetach(d); }
  5943 {
       
  5944     if (!d)
       
  5945         d = new QUrlPrivate;
       
  5946     else
       
  5947         qAtomicDetach(d);
       
  5948 }
  5826 
  5949 
  5827 /*!
  5950 /*!
  5828     \internal
  5951     \internal
  5829 */
  5952 */
  5830 bool QUrl::isDetached() const
  5953 bool QUrl::isDetached() const
  5831 {
  5954 {
  5832     return d->ref == 1;
  5955     return !d || d->ref == 1;
  5833 }
  5956 }
  5834 
  5957 
  5835 
  5958 
  5836 /*!
  5959 /*!
  5837     Returns a QUrl representation of \a localFile, interpreted as a
  5960     Returns a QUrl representation of \a localFile, interpreted as a
  5869 
  5992 
  5870     \sa fromLocalFile()
  5993     \sa fromLocalFile()
  5871 */
  5994 */
  5872 QString QUrl::toLocalFile() const
  5995 QString QUrl::toLocalFile() const
  5873 {
  5996 {
       
  5997     if (!d) return QString();
  5874     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5998     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5875 
  5999 
  5876     QString tmp;
  6000     QString tmp;
  5877     QString ourPath = path();
  6001     QString ourPath = path();
  5878     if (d->scheme.isEmpty() || QString::compare(d->scheme, QLatin1String("file"), Qt::CaseInsensitive) == 0) {
  6002     if (d->scheme.isEmpty() || QString::compare(d->scheme, QLatin1String("file"), Qt::CaseInsensitive) == 0) {
  5897     of this URL if the two URLs share the same scheme and authority,
  6021     of this URL if the two URLs share the same scheme and authority,
  5898     and this URL's path is a parent of the path of \a childUrl.
  6022     and this URL's path is a parent of the path of \a childUrl.
  5899 */
  6023 */
  5900 bool QUrl::isParentOf(const QUrl &childUrl) const
  6024 bool QUrl::isParentOf(const QUrl &childUrl) const
  5901 {
  6025 {
       
  6026     QString childPath = childUrl.path();
       
  6027 
       
  6028     if (!d)
       
  6029         return ((childUrl.scheme().isEmpty())
       
  6030             && (childUrl.authority().isEmpty())
       
  6031             && childPath.length() > 0 && childPath.at(0) == QLatin1Char('/'));
       
  6032 
  5902     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  6033     if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
  5903 
  6034 
  5904     QString childPath = childUrl.path();
       
  5905     QString ourPath = path();
  6035     QString ourPath = path();
  5906 
  6036 
  5907     return ((childUrl.scheme().isEmpty() || d->scheme == childUrl.scheme())
  6037     return ((childUrl.scheme().isEmpty() || d->scheme == childUrl.scheme())
  5908             && (childUrl.authority().isEmpty() || d->authority() == childUrl.authority())
  6038             && (childUrl.authority().isEmpty() || d->authority() == childUrl.authority())
  5909             &&  childPath.startsWith(ourPath)
  6039             &&  childPath.startsWith(ourPath)
  6139     Returns a text string that explains why an URL is invalid in the case being;
  6269     Returns a text string that explains why an URL is invalid in the case being;
  6140     otherwise returns an empty string.
  6270     otherwise returns an empty string.
  6141 */
  6271 */
  6142 QString QUrl::errorString() const
  6272 QString QUrl::errorString() const
  6143 {
  6273 {
       
  6274     if (!d)
       
  6275         return QLatin1String(QT_TRANSLATE_NOOP(QUrl, "Invalid URL \"\": ")); // XXX not a good message, but the one an empty URL produces
  6144     return d->createErrorString();
  6276     return d->createErrorString();
  6145 }
  6277 }
  6146 
  6278 
  6147 /*!
  6279 /*!
  6148     \typedef QUrl::DataPtr
  6280     \typedef QUrl::DataPtr