Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/corelib/io/qurl.cpp

    r172 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information ([email protected])
     4** All rights reserved.
     5** Contact: Nokia Corporation ([email protected])
    56**
    67** This file is part of the QtCore module of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you
     37** @nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848    \reentrant
    4949    \ingroup io
    50     \ingroup misc
     50    \ingroup
    5151    \ingroup shared
    52     \mainclass
     52
    5353
    5454    It can parse and construct URLs in both encoded and unencoded
     
    173173#include "qatomic.h"
    174174#include "qbytearray.h"
     175
     176
    175177#include "qlist.h"
    176178#ifndef QT_NO_REGEXP
     
    23372339};
    23382340
    2339 static void mapToLowerCase(QString *str)
     2341static void mapToLowerCase(QString *str)
    23402342{
    23412343    int N = sizeof(NameprepCaseFolding) / sizeof(NameprepCaseFolding[0]);
    23422344
    23432345    QChar *d = 0;
    2344     for (int i = 0; i < str->size(); ++i) {
     2346    for (int i = ; i < str->size(); ++i) {
    23452347        int uc = str->at(i).unicode();
    23462348        if (uc < 0x80) {
     
    23892391
    23902392
    2391 static void stripProhibitedOutput(QString *str)
    2392 {
    2393     ushort *out = (ushort *)str->data();
     2393static void stripProhibitedOutput(QString *str)
     2394{
     2395    ushort *out = (ushort *)str->data()
    23942396    const ushort *in = out;
    2395     const ushort *end = out + str->size();
     2397    const ushort *end = + str->size();
    23962398    while (in < end) {
    23972399        ushort uc = *in;
     
    29022904}
    29032905
    2904 
    2905 Q_AUTOTEST_EXPORT QString qt_nameprep(const QString &source)
    2906 {
    2907     QString mapped = source;
    2908    
    2909     bool simple = true;
    2910     for (int i = 0; i < mapped.size(); ++i) {
    2911         ushort uc = mapped.at(i).unicode();
     2906#ifdef QT_BUILD_INTERNAL
     2907// export for tst_qurl.cpp
     2908Q_AUTOTEST_EXPORT void qt_nameprep(QString *source, int from);
     2909Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QChar *uc, int len);
     2910#else
     2911// non-test build, keep the symbols for ourselves
     2912static void qt_nameprep(QString *source, int from);
     2913static bool qt_check_std3rules(const QChar *uc, int len);
     2914#endif
     2915
     2916void qt_nameprep(QString *source, int from)
     2917{
     2918    QChar *src = source->data(); // causes a detach, so we're sure the only one using it
     2919    QChar *out = src + from;
     2920    const QChar *e = src + source->size();
     2921
     2922    for ( ; out < e; ++out) {
     2923        register ushort uc = out->unicode();
    29122924        if (uc > 0x80) {
    2913             simple = false;
    29142925            break;
    29152926        } else if (uc >= 'A' && uc <= 'Z') {
    2916             mapped[i] = QChar(uc | 0x20);
     2927            = QChar(uc | 0x20);
    29172928        }
    29182929    }
    2919     if (simple)
    2920         return mapped;
    2921    
     2930    if (out == e)
     2931        return; // everything was mapped easily (lowercased, actually)
     2932    int firstNonAscii = out - src;
     2933
    29222934    // Characters commonly mapped to nothing are simply removed
    29232935    // (Table B.1)
    2924     QChar *out = mapped.data();
    29252936    const QChar *in = out;
    2926     const QChar *e = in + mapped.size();
    29272937    while (in < e) {
    29282938        if (!isMappedToNothing(*in))
     
    29312941    }
    29322942    if (out != in)
    2933         mapped.truncate(out - mapped.constData());
     2943        );
    29342944
    29352945    // Map to lowercase (Table B.2)
    2936     mapToLowerCase(&mapped);
     2946    mapToLowerCase();
    29372947
    29382948    // Normalize to Unicode 3.2 form KC
    2939     mapped = mapped.normalized(QString::NormalizationForm_KC, QChar::Unicode_3_2);
     2949    extern void qt_string_normalize(QString *data, QString::NormalizationForm mode,
     2950                                    QChar::UnicodeVersion version, int from);
     2951    qt_string_normalize(source, QString::NormalizationForm_KC, QChar::Unicode_3_2, firstNonAscii);
    29402952
    29412953    // Strip prohibited output
    2942     stripProhibitedOutput(&mapped);
     2954    stripProhibitedOutput();
    29432955
    29442956    // Check for valid bidirectional characters
    29452957    bool containsLCat = false;
    29462958    bool containsRandALCat = false;
    2947     for (int j = 0; j < mapped.size() && (!containsLCat || !containsRandALCat); ++j) {
    2948         if (isBidirectionalL(mapped.at(j)))
     2959    src = source->data();
     2960    e = src + source->size();
     2961    for (in = src + from; in < e && (!containsLCat || !containsRandALCat); ++in) {
     2962        if (isBidirectionalL(*in))
    29492963            containsLCat = true;
    2950         else if (isBidirectionalRorAL(mapped.at(j)))
     2964        else if (isBidirectionalRorAL())
    29512965            containsRandALCat = true;
    29522966    }
    29532967    if (containsRandALCat) {
    2954         if (containsLCat || (!isBidirectionalRorAL(mapped.at(0))
    2955                              || !isBidirectionalRorAL(mapped.at(mapped.size() - 1))))
    2956             mapped.clear();
    2957     }
    2958 
    2959     return mapped;
    2960 }
    2961 
    2962 
    2963 static inline char encodeDigit(uint digit)
     2968        if (containsLCat || (!isBidirectionalRorAL(src[from])
     2969                             || !isBidirectionalRorAL(e[-1])))
     2970            source->resize(from); // not allowed, clear the label
     2971    }
     2972}
     2973
     2974bool qt_check_std3rules(const QChar *uc, int len)
     2975{
     2976    if (len > 63)
     2977        return false;
     2978
     2979    for (int i = 0; i < len; ++i) {
     2980        register ushort c = uc[i].unicode();
     2981        if (c == '-' && (i == 0 || i == len - 1))
     2982            return false;
     2983
     2984        // verifying the absence of LDH is the same as verifying that
     2985        // only LDH is present
     2986        if (c == '-' || (c >= '0' && c <= '9')
     2987            || (c >= 'A' && c <= 'Z')
     2988            || (c >= 'a' && c <= 'z'))
     2989            continue;
     2990
     2991        return false;
     2992    }
     2993
     2994    return true;
     2995}
     2996
     2997
     2998static inline uint encodeDigit(uint digit)
    29642999{
    29653000  return digit + 22 + 75 * (digit < 26);
     
    29783013}
    29793014
    2980 static inline void appendEncode(QByteArray* output, uint& delta, uint& bias, uint& b, uint& h)
     3015static inline void appendEncode(Q* output, uint& delta, uint& bias, uint& b, uint& h)
    29813016{
    29823017    uint qq;
     
    29923027        if (qq < t) break;
    29933028
    2994         *output += encodeDigit(t + (qq - t) % (base - t));
     3029        *output += ));
    29953030        qq = (qq - t) / (base - t);
    29963031    }
    29973032
    2998     *output += encodeDigit(qq);
     3033    *output += );
    29993034    bias = adapt(delta, h + 1, h == b);
    30003035    delta = 0;
     
    30023037}
    30033038
    3004 static void toPunycodeHelper(const QChar *s, int ucLength, QByteArray *output)
     3039static void toPunycodeHelper(const QChar *s, int ucLength, Q *output)
    30053040{
    30063041    uint n = initial_n;
     
    30113046    output->resize(outLen + ucLength);
    30123047
    3013     char *d = output->data() + outLen;
     3048    har *d = output->data() + outLen;
    30143049    bool skipped = false;
    30153050    // copy all basic code points verbatim to output.
     
    30363071    // if basic code points were copied, add the delimiter character.
    30373072    if (h > 0)
    3038         *output += 0x2d;
     3073        *output += ;
    30393074
    30403075    // while there are still unprocessed non-basic code points left in
     
    30843119
    30853120    // prepend ACE prefix
    3086     output->insert(outLen, "xn--");
     3121    output->insert(outLen, );
    30873122    return;
    30883123}
     
    31453180    if (idx == -1)
    31463181        return false;
    3147     const QChar *tld = domain.constData() + idx + 1;
     3182
    31483183    int len = domain.size() - idx - 1;
     3184
     3185
     3186
     3187
    31493188
    31503189    if (user_idn_whitelist)
    3151         return user_idn_whitelist->contains(QString(tld, len));
     3190        return user_idn_whitelist->contains();
    31523191
    31533192    int l = 0;
     
    31653204}
    31663205
    3167 static QString qt_from_ACE(const QString &domainMC)
    3168 {
    3169     QString domain = domainMC.toLower();
    3170     int idx = domain.indexOf(QLatin1Char('.'));
    3171     if (idx != -1) {
    3172         if (!domain.contains(QLatin1String("xn--"))) {
    3173             bool simple = true;
    3174             for (int i = 0; i < domain.size(); ++i) {
    3175                 ushort ch = domain.at(i).unicode();
    3176                 if (ch > 'z' || ch < '-' || ch == '/' || (ch > '9' && ch < 'A') || (ch > 'Z' && ch < 'a')) {
     3206static inline bool isDotDelimiter(ushort uc)
     3207{
     3208    // IDNA / rfc3490 describes these four delimiters used for
     3209    // separating labels in unicode international domain
     3210    // names.
     3211    return uc == 0x2e || uc == 0x3002 || uc == 0xff0e || uc == 0xff61;
     3212}
     3213
     3214static int nextDotDelimiter(const QString &domain, int from = 0)
     3215{
     3216    const QChar *b = domain.unicode();
     3217    const QChar *ch = b + from;
     3218    const QChar *e = b + domain.length();
     3219    while (ch < e) {
     3220        if (isDotDelimiter(ch->unicode()))
     3221            break;
     3222        else
     3223            ++ch;
     3224    }
     3225    return ch - b;
     3226}
     3227
     3228enum AceOperation { ToAceOnly, NormalizeAce };
     3229static QString qt_ACE_do(const QString &domain, AceOperation op)
     3230{
     3231    if (domain.isEmpty())
     3232        return domain;
     3233
     3234    QString result;
     3235    result.reserve(domain.length());
     3236
     3237    const bool isIdnEnabled = op == NormalizeAce ? qt_is_idn_enabled(domain) : false;
     3238    int lastIdx = 0;
     3239    QString aceForm; // this variable is here for caching
     3240
     3241    while (1) {
     3242        int idx = nextDotDelimiter(domain, lastIdx);
     3243        int labelLength = idx - lastIdx;
     3244        if (labelLength == 0)
     3245            return QString(); // two delimiters in a row -- empty label not allowed
     3246
     3247        // RFC 3490 says, about the ToASCII operation:
     3248        //   3. If the UseSTD3ASCIIRules flag is set, then perform these checks:
     3249        //
     3250        //     (a) Verify the absence of non-LDH ASCII code points; that is, the
     3251        //         absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F.
     3252        //
     3253        //     (b) Verify the absence of leading and trailing hyphen-minus; that
     3254        //         is, the absence of U+002D at the beginning and end of the
     3255        //         sequence.
     3256        // and:
     3257        //   8. Verify that the number of code points is in the range 1 to 63
     3258        //      inclusive.
     3259
     3260        // copy the label to the destination, which also serves as our scratch area, lowercasing it
     3261        int prevLen = result.size();
     3262        bool simple = true;
     3263        result.resize(prevLen + labelLength);
     3264        {
     3265            QChar *out = result.data() + prevLen;
     3266            const QChar *in = domain.constData() + lastIdx;
     3267            const QChar *e = in + labelLength;
     3268            for (; in < e; ++in, ++out) {
     3269                register ushort uc = in->unicode();
     3270                if (uc > 0x7f)
    31773271                    simple = false;
    3178                     break;
    3179                 }
     3272                if (uc >= 'A' && uc <= 'Z')
     3273                    *out = QChar(uc | 0x20);
     3274                else
     3275                    *out = *in;
    31803276            }
    3181             if (simple)
    3182                 return domain;
    31833277        }
    3184        
    3185         const bool isIdnEnabled = qt_is_idn_enabled(domain);
    3186         int lastIdx = 0;
    3187         QString result;
    3188         while (1) {
    3189             // Nameprep the host. If the labels in the hostname are Punycode
    3190             // encoded, we decode them immediately, then nameprep them.
    3191             QByteArray label;
    3192             toPunycodeHelper(domain.constData() + lastIdx, idx - lastIdx, &label);
    3193             result += qt_nameprep(isIdnEnabled ? QUrl::fromPunycode(label) : QString::fromLatin1(label));
    3194             lastIdx = idx + 1;
    3195             if (lastIdx < domain.size() + 1)
    3196                 result += QLatin1Char('.');
    3197             else
    3198                 break;
    3199             idx = domain.indexOf(QLatin1Char('.'), lastIdx);
    3200             if (idx == -1)
    3201                 idx = domain.size();
     3278
     3279        if (simple && labelLength > 6) {
     3280            // ACE form domains contain only ASCII characters, but we can't consider them simple
     3281            // is this an ACE form?
     3282            // the shortest valid ACE domain is 6 characters long (U+0080 would be 1, but it's not allowed)
     3283            static const ushort acePrefixUtf16[] = { 'x', 'n', '-', '-' };
     3284            if (memcmp(result.constData() + prevLen, acePrefixUtf16, sizeof acePrefixUtf16) == 0)
     3285                simple = false;
    32023286        }
    3203         return result;
    3204     } else {
    3205         return qt_nameprep(domain);
    3206     }
     3287
     3288        if (simple) {
     3289            // fastest case: this is the common case (non IDN-domains)
     3290            // so we're done
     3291            if (!qt_check_std3rules(result.constData() + prevLen, labelLength))
     3292                return QString();
     3293        } else {
     3294            // Punycode encoding and decoding cannot be done in-place
     3295            // That means we need one or two temporaries
     3296            qt_nameprep(&result, prevLen);
     3297            labelLength = result.length() - prevLen;
     3298            register int toReserve = labelLength + 4 + 6; // "xn--" plus some extra bytes
     3299            if (toReserve > aceForm.capacity())
     3300                aceForm.reserve(toReserve);
     3301            toPunycodeHelper(result.constData() + prevLen, result.size() - prevLen, &aceForm);
     3302
     3303            // We use resize()+memcpy() here because we're overwriting the data we've copied
     3304            if (isIdnEnabled) {
     3305                QString tmp = QUrl::fromPunycode(aceForm.toLatin1());
     3306                if (tmp.isEmpty())
     3307                    return QString(); // shouldn't happen, since we've just punycode-encoded it
     3308                result.resize(prevLen + tmp.size());
     3309                memcpy(result.data() + prevLen, tmp.constData(), tmp.size() * sizeof(QChar));
     3310            } else {
     3311                result.resize(prevLen + aceForm.size());
     3312                memcpy(result.data() + prevLen, aceForm.constData(), aceForm.size() * sizeof(QChar));
     3313            }
     3314
     3315            if (!qt_check_std3rules(aceForm.constData(), aceForm.size()))
     3316                return QString();
     3317        }
     3318
     3319
     3320        lastIdx = idx + 1;
     3321        if (lastIdx < domain.size() + 1)
     3322            result += QLatin1Char('.');
     3323        else
     3324            break;
     3325    }
     3326    return result;
    32073327}
    32083328
     
    32473367QString QUrlPrivate::canonicalHost() const
    32483368{
    3249     if (QURL_HASFLAG(stateFlags, HostCanonicalized))
     3369    if (QURL_HASFLAG(stateFlags, HostCanonicalized))
    32503370        return host;
    32513371
    32523372    QUrlPrivate *that = const_cast<QUrlPrivate *>(this);
    32533373    QURL_SETFLAG(that->stateFlags, HostCanonicalized);
    3254     that->host = qt_from_ACE(host);
     3374    if (host.contains(QLatin1Char(':'))) {
     3375        // This is an IP Literal, use _IPLiteral to validate
     3376        QByteArray ba = host.toLatin1();
     3377        if (!ba.startsWith('[')) {
     3378            // surround the IP Literal with [ ] if it's not already done so
     3379            ba.reserve(ba.length() + 2);
     3380            ba.prepend('[');
     3381            ba.append(']');
     3382        }
     3383
     3384        const char *ptr = ba.constData();
     3385        if (!_IPLiteral(&ptr))
     3386            that->host.clear();
     3387        else
     3388            that->host = host.toLower();
     3389    } else {
     3390        that->host = qt_ACE_do(host, NormalizeAce);
     3391    }
    32553392    return that->host;
    32563393}
     
    37283865
    37293866        if ((options & QUrl::RemoveUserInfo) != QUrl::RemoveUserInfo) {
     3867
    37303868            if (!userName.isEmpty()) {
    37313869                url += encodedUserName;
    3732                 if (!(options & QUrl::RemovePassword) && !password.isEmpty()) {
    3733                     url += ':';
    3734                     url += encodedPassword;
    3735                 }
     3870                hasUserOrPass = true;
     3871            }
     3872            if (!(options & QUrl::RemovePassword) && !password.isEmpty()) {
     3873                url += ':';
     3874                url += encodedPassword;
     3875                hasUserOrPass = true;
     3876            }
     3877            if (hasUserOrPass)
    37363878                url += '@';
    3737             }
    37383879        }
    37393880
    3740         url += QUrl::toAce(host);
     3881        if (host.startsWith(QLatin1Char('['))) {
     3882            url += host.toLatin1();
     3883        } else if (host.contains(QLatin1Char(':'))) {
     3884            url += '[';
     3885            url += host.toLatin1();
     3886            url += ']';
     3887        } else {
     3888            url += QUrl::toAce(host);
     3889        }
    37413890        if (!(options & QUrl::RemovePort) && port != -1) {
    37423891            url += ':';
     
    38894038
    38904039/*!
     4040
     4041
     4042
     4043
     4044
     4045
     4046
     4047
     4048
     4049
     4050
     4051
     4052
     4053
     4054
     4055
     4056
     4057
     4058
     4059
     4060
     4061
     4062
    38914063    Constructs a URL by parsing \a url. \a url is assumed to be in human
    38924064    readable representation, with no percent encoding. QUrl will automatically
     
    39034075    \sa setUrl(), setEncodedUrl(), fromEncoded(), TolerantMode
    39044076*/
    3905 QUrl::QUrl(const QString &url) : d(new QUrlPrivate)
     4077QUrl::QUrl(const QString &url) : d()
    39064078{
    39074079    if (!url.isEmpty())
     
    39164088    \sa setUrl()
    39174089*/
    3918 QUrl::QUrl(const QString &url, ParsingMode parsingMode) : d(new QUrlPrivate)
     4090QUrl::QUrl(const QString &url, ParsingMode parsingMode) : d()
    39194091{
    39204092    if (!url.isEmpty())
    39214093        setUrl(url, parsingMode);
    3922     else
     4094    else {
     4095        d = new QUrlPrivate;
    39234096        d->parsingMode = parsingMode;
     4097
    39244098}
    39254099
     
    39274101    Constructs an empty QUrl object.
    39284102*/
    3929 QUrl::QUrl() : d(new QUrlPrivate)
     4103QUrl::QUrl() : d()
    39304104{
    39314105}
     
    39364110QUrl::QUrl(const QUrl &other) : d(other.d)
    39374111{
    3938     d->ref.ref();
     4112    if (d)
     4113        d->ref.ref();
    39394114}
    39404115
     
    39444119QUrl::~QUrl()
    39454120{
    3946     if (!d->ref.deref())
     4121    if (!d->ref.deref())
    39474122        delete d;
    39484123}
     
    39594134bool QUrl::isValid() const
    39604135{
     4136
     4137
    39614138    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    39624139    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Validated)) d->validate();
     
    39704147bool QUrl::isEmpty() const
    39714148{
     4149
     4150
    39724151    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed))
    39734152        return d->encodedOriginal.isEmpty();
     
    39904169void QUrl::clear()
    39914170{
    3992     detach();
    3993     d->clear();
     4171    if (d && !d->ref.deref())
     4172        delete d;
     4173    d = 0;
    39944174}
    39954175
     
    40904270void QUrl::setEncodedUrl(const QByteArray &encodedUrl, ParsingMode parsingMode)
    40914271{
    4092     clear();
    40934272    QByteArray tmp = encodedUrl;
     4273
     4274
    40944275    if ((d->parsingMode = parsingMode) == TolerantMode) {
    40954276        // Replace stray % with %25
     
    41654346void QUrl::setScheme(const QString &scheme)
    41664347{
     4348
    41674349    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    41684350    detach();
     
    41804362QString QUrl::scheme() const
    41814363{
     4364
    41824365    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    41834366
     
    42034386void QUrl::setAuthority(const QString &authority)
    42044387{
     4388
     4389
    42054390    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    42064391    detach();
     
    42184403QString QUrl::authority() const
    42194404{
     4405
     4406
    42204407    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    42214408
     
    42384425void QUrl::setUserInfo(const QString &userInfo)
    42394426{
     4427
     4428
    42404429    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    42414430    detach();
     
    42514440QString QUrl::userInfo() const
    42524441{
     4442
     4443
    42534444    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    42544445
     
    42654456void QUrl::setUserName(const QString &userName)
    42664457{
     4458
     4459
    42674460    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    42684461    detach();
     
    42814474QString QUrl::userName() const
    42824475{
     4476
     4477
    42834478    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    42844479
     
    43024497void QUrl::setEncodedUserName(const QByteArray &userName)
    43034498{
     4499
    43044500    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    43054501    detach();
     
    43224518QByteArray QUrl::encodedUserName() const
    43234519{
     4520
    43244521    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    43254522
     
    43374534void QUrl::setPassword(const QString &password)
    43384535{
     4536
    43394537    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    43404538    detach();
     
    43534551QString QUrl::password() const
    43544552{
     4553
    43554554    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    43564555
     
    43744573void QUrl::setEncodedPassword(const QByteArray &password)
    43754574{
     4575
    43764576    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    43774577    detach();
     
    43944594QByteArray QUrl::encodedPassword() const
    43954595{
     4596
    43964597    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    43974598
     
    44084609void QUrl::setHost(const QString &host)
    44094610{
     4611
    44104612    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    44114613    detach();
     
    44134615
    44144616    d->host = host;
    4415     if (d->host.contains(QLatin1Char(':')))
    4416         d->host = QLatin1Char('[') + d->host + QLatin1Char(']');
    44174617}
    44184618
     
    44234623QString QUrl::host() const
    44244624{
     4625
    44254626    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    44264627
     
    44764677void QUrl::setPort(int port)
    44774678{
     4679
    44784680    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    44794681    detach();
     
    44934695int QUrl::port() const
    44944696{
     4697
    44954698    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    44964699    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Validated)) d->validate();
     
    45114714int QUrl::port(int defaultPort) const
    45124715{
     4716
    45134717    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    45144718    return d->port == -1 ? defaultPort : d->port;
     
    45304734void QUrl::setPath(const QString &path)
    45314735{
     4736
    45324737    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    45334738    detach();
     
    45454750QString QUrl::path() const
    45464751{
     4752
    45474753    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    45484754
     
    45764782void QUrl::setEncodedPath(const QByteArray &path)
    45774783{
     4784
    45784785    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    45794786    detach();
     
    45964803QByteArray QUrl::encodedPath() const
    45974804{
     4805
    45984806    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    45994807
     
    46114819bool QUrl::hasQuery() const
    46124820{
     4821
    46134822    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    46144823
     
    46404849void QUrl::setQueryDelimiters(char valueDelimiter, char pairDelimiter)
    46414850{
     4851
    46424852    detach();
    46434853
     
    46524862char QUrl::queryPairDelimiter() const
    46534863{
     4864
    46544865    return d->pairDelimiter;
    46554866}
     
    46614872char QUrl::queryValueDelimiter() const
    46624873{
     4874
    46634875    return d->valueDelimiter;
    46644876}
     
    46834895void QUrl::setEncodedQuery(const QByteArray &query)
    46844896{
     4897
    46854898    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    46864899    detach();
     
    47024915void QUrl::setQueryItems(const QList<QPair<QString, QString> > &query)
    47034916{
     4917
    47044918    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    47054919    detach();
     
    47414955void QUrl::setEncodedQueryItems(const QList<QPair<QByteArray, QByteArray> > &query)
    47424956{
     4957
    47434958    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    47444959    detach();
     
    47604975    URL.
    47614976
     4977
     4978
     4979
     4980
     4981
     4982
    47624983    \sa addEncodedQueryItem()
    47634984*/
    47644985void QUrl::addQueryItem(const QString &key, const QString &value)
    47654986{
     4987
    47664988    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    47674989    detach();
     
    47985020void QUrl::addEncodedQueryItem(const QByteArray &key, const QByteArray &value)
    47995021{
     5022
    48005023    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    48015024    detach();
     
    48185041QList<QPair<QString, QString> > QUrl::queryItems() const
    48195042{
     5043
    48205044    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    48215045
     
    48505074QList<QPair<QByteArray, QByteArray> > QUrl::encodedQueryItems() const
    48515075{
     5076
    48525077    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    48535078
     
    48785103bool QUrl::hasQueryItem(const QString &key) const
    48795104{
     5105
    48805106    return hasEncodedQueryItem(toPercentEncoding(key, queryExcludeChars));
    48815107}
     
    48965122bool QUrl::hasEncodedQueryItem(const QByteArray &key) const
    48975123{
     5124
    48985125    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    48995126
     
    49185145QString QUrl::queryItemValue(const QString &key) const
    49195146{
     5147
    49205148    QByteArray tmp = encodedQueryItemValue(toPercentEncoding(key, queryExcludeChars));
    49215149    return fromPercentEncodingMutable(&tmp);
     
    49375165QByteArray QUrl::encodedQueryItemValue(const QByteArray &key) const
    49385166{
     5167
    49395168    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    49405169
     
    49605189QStringList QUrl::allQueryItemValues(const QString &key) const
    49615190{
     5191
    49625192    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    49635193
     
    49975227QList<QByteArray> QUrl::allEncodedQueryItemValues(const QByteArray &key) const
    49985228{
     5229
    49995230    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    50005231
     
    50245255void QUrl::removeQueryItem(const QString &key)
    50255256{
     5257
    50265258    removeEncodedQueryItem(toPercentEncoding(key, queryExcludeChars));
    50275259}
     
    50425274void QUrl::removeEncodedQueryItem(const QByteArray &key)
    50435275{
     5276
    50445277    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    50455278    detach();
     
    50685301void QUrl::removeAllQueryItems(const QString &key)
    50695302{
     5303
    50705304    removeAllEncodedQueryItems(toPercentEncoding(key, queryExcludeChars));
    50715305}
     
    50865320void QUrl::removeAllEncodedQueryItems(const QByteArray &key)
    50875321{
     5322
    50885323    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    50895324    detach();
     
    51095344QByteArray QUrl::encodedQuery() const
    51105345{
     5346
    51115347    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    51125348
     
    51335369void QUrl::setFragment(const QString &fragment)
    51345370{
     5371
    51355372    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    51365373    detach();
     
    51495386QString QUrl::fragment() const
    51505387{
     5388
    51515389    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    51525390
     
    51795417void QUrl::setEncodedFragment(const QByteArray &fragment)
    51805418{
     5419
    51815420    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    51825421    detach();
     
    52005439QByteArray QUrl::encodedFragment() const
    52015440{
     5441
    52025442    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    52035443
     
    52155455bool QUrl::hasFragment() const
    52165456{
     5457
    52175458    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    52185459
     
    52415482QUrl QUrl::resolved(const QUrl &relative) const
    52425483{
     5484
     5485
    52435486    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    52445487
     
    52575500            t = relative;
    52585501        } else {
     5502
    52595503            if (relative.d->encodedPath.isEmpty()) {
    52605504                t.d->encodedPath = d->encodedPath;
     
    52875531bool QUrl::isRelative() const
    52885532{
     5533
    52895534    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    52905535
     
    53015546QString QUrl::toString(FormattingOptions options) const
    53025547{
     5548
    53035549    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    53045550
     
    53255571        url += ourPath;
    53265572        // check if we need to remove trailing slashes
    5327         while ((options & StripTrailingSlash) && url.right(1) == QLatin1String("/"))
     5573        while ((options & StripTrailingSlash) && url.))
    53285574            url.chop(1);
    53295575    }
     
    53525598QByteArray QUrl::toEncoded(FormattingOptions options) const
    53535599{
     5600
    53545601    return d->toEncoded(options);
    53555602}
     
    54205667QByteArray QUrl::toPunycode(const QString &uc)
    54215668{
    5422     QByteArray output;
     5669    Q output;
    54235670    toPunycodeHelper(uc.constData(), uc.size(), &output);
    5424     return output;
     5671    return output;
    54255672}
    54265673
     
    55185765    and RFC 3492. It is part of the Internationalizing Domain Names in
    55195766    Applications (IDNA) specification, which allows for domain names
    5520     (like \c "qtsoftware.com") to be written using international
     5767    (like \c "e.com") to be written using international
    55215768    characters.
    55225769*/
    55235770QString QUrl::fromAce(const QByteArray &domain)
    55245771{
    5525     return qt_from_ACE(QString::fromLatin1(domain));
     5772    return qt_);
    55265773}
    55275774
     
    55355782    and RFC 3492. It is part of the Internationalizing Domain Names in
    55365783    Applications (IDNA) specification, which allows for domain names
    5537     (like \c "qtsoftware.com") to be written using international
     5784    (like \c "e.com") to be written using international
    55385785    characters.
     5786
     5787
     5788
     5789
    55395790*/
    55405791QByteArray QUrl::toAce(const QString &domain)
    55415792{
    5542     // IDNA / rfc3490 describes these four delimiters used for
    5543     // separating labels in unicode international domain
    5544     // names.
    5545     QString nameprepped = qt_nameprep(domain);
    5546     int lastIdx = 0;
    5547     QByteArray result;
    5548     for (int i = 0; i < nameprepped.size(); ++i) {
    5549         ushort uc = nameprepped.at(i).unicode();
    5550         if (uc == 0x2e || uc == 0x3002 || uc == 0xff0e || uc == 0xff61) {
    5551             if (lastIdx)
    5552                 result += '.';
    5553             toPunycodeHelper(nameprepped.constData() + lastIdx, i - lastIdx, &result);
    5554             lastIdx = i + 1;
    5555         }
    5556     }
    5557     if (lastIdx)
    5558         result += '.';
    5559     toPunycodeHelper(nameprepped.constData() + lastIdx, nameprepped.size() - lastIdx, &result);
    5560    
    5561     return result;
     5793    QString result = qt_ACE_do(domain, ToAceOnly);
     5794    return result.toLatin1();
    55625795}
    55635796
     
    56165849bool QUrl::operator <(const QUrl &url) const
    56175850{
     5851
    56185852    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
     5853
    56195854    if (!QURL_HASFLAG(url.d->stateFlags, QUrlPrivate::Parsed)) url.d->parse();
    56205855    return d->normalized() < url.d->normalized();
     
    56275862bool QUrl::operator ==(const QUrl &url) const
    56285863{
     5864
     5865
    56295866    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    56305867    if (!QURL_HASFLAG(url.d->stateFlags, QUrlPrivate::Parsed)) url.d->parse();
     
    56465883QUrl &QUrl::operator =(const QUrl &url)
    56475884{
    5648     qAtomicAssign(d, url.d);
     5885    if (!d) {
     5886        if (url.d) {
     5887            url.d->ref.ref();
     5888            d = url.d;
     5889        }
     5890    } else {
     5891        if (url.d)
     5892            qAtomicAssign(d, url.d);
     5893        else
     5894            clear();
     5895    }
    56495896    return *this;
    56505897}
     
    56555902QUrl &QUrl::operator =(const QString &url)
    56565903{
    5657     QUrl tmp(url);
    5658     qAtomicAssign(d, tmp.d);
     5904    if (url.isEmpty()) {
     5905        clear();
     5906    } else {
     5907        QUrl tmp(url);
     5908        if (!d) d = new QUrlPrivate;
     5909        qAtomicAssign(d, tmp.d);
     5910    }
    56595911    return *this;
    56605912}
     
    56655917*/
    56665918void QUrl::detach()
    5667 { qAtomicDetach(d); }
     5919{
     5920    if (!d)
     5921        d = new QUrlPrivate;
     5922    else
     5923        qAtomicDetach(d);
     5924}
    56685925
    56695926/*!
     
    56725929bool QUrl::isDetached() const
    56735930{
    5674     return d->ref == 1;
     5931    return d->ref == 1;
    56755932}
    56765933
     
    56935950    // magic for drives on windows
    56945951    if (deslashified.length() > 1 && deslashified.at(1) == QLatin1Char(':') && deslashified.at(0) != QLatin1Char('/')) {
    5695         url.setPath(QLatin1String("/") + deslashified);
     5952        url.setPath(QLatin1) + deslashified);
    56965953    // magic for shared drive on windows
    56975954    } else if (deslashified.startsWith(QLatin1String("//"))) {
     
    57145971QString QUrl::toLocalFile() const
    57155972{
     5973
    57165974    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    57175975
    57185976    QString tmp;
    57195977    QString ourPath = path();
    5720     if (d->scheme.isEmpty() || d->scheme.toLower() == QLatin1String("file")) {
     5978    if (d->scheme.isEmpty() || ) {
    57215979
    57225980        // magic for shared drive on windows
    57235981        if (!d->host.isEmpty()) {
    57245982            tmp = QLatin1String("//") + d->host + (ourPath.length() > 0 && ourPath.at(0) != QLatin1Char('/')
    5725                                                   ? QLatin1String("/") + ourPath :  ourPath);
     5983                                                  ? QLatin1) + ourPath :  ourPath);
    57265984        } else {
    57275985            tmp = ourPath;
     
    57426000bool QUrl::isParentOf(const QUrl &childUrl) const
    57436001{
     6002
     6003
     6004
     6005
     6006
     6007
     6008
    57446009    if (!QURL_HASFLAG(d->stateFlags, QUrlPrivate::Parsed)) d->parse();
    57456010
    5746     QString childPath = childUrl.path();
    57476011    QString ourPath = path();
    57486012
     
    58456109
    58466110    \oldcode
    5847         QUrl url("http://qtsoftware.com/Developer/");
     6111        QUrl url("http://e.com/Developer/");
    58486112        url.cdUp();
    58496113    \newcode
    5850         QUrl url("http://qtsoftware.com/Developer/");
     6114        QUrl url("http://e.com/Developer/");
    58516115        url = url.resolved("..");
    58526116    \endcode
     
    59716235QDebug operator<<(QDebug d, const QUrl &url)
    59726236{
    5973     d.maybeSpace() << "QUrl(" << url.toString() << ")";
     6237    d.maybeSpace() << "QUrl(" << url.toString() << ;
    59746238    return d.space();
    59756239}
     
    59846248QString QUrl::errorString() const
    59856249{
     6250
     6251
    59866252    return d->createErrorString();
    59876253}
     
    59976263*/
    59986264
     6265
     6266
     6267
     6268
     6269
     6270
     6271
     6272
     6273
     6274
     6275
     6276
     6277
     6278
     6279
     6280
     6281
     6282
     6283
     6284
     6285
     6286
     6287
     6288
     6289
     6290
     6291
     6292
     6293
     6294
     6295
     6296
     6297
     6298
     6299
     6300
     6301
     6302
     6303
     6304
     6305
     6306
     6307
     6308
     6309
     6310
     6311
     6312
     6313
     6314
     6315
     6316
     6317
     6318
     6319
     6320
     6321
     6322
     6323
     6324
     6325
     6326
     6327
     6328
     6329
     6330
     6331
     6332
     6333
     6334
     6335
     6336
     6337
     6338
     6339
     6340
     6341
     6342
     6343
     6344
     6345
     6346
     6347
     6348
     6349
     6350
     6351
     6352
     6353
     6354
     6355
     6356
     6357
     6358
     6359
     6360
     6361
     6362
     6363
     6364
     6365
     6366
     6367
     6368
    59996369QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.