summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2009-03-19 10:34:54 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2009-07-21 13:48:45 (GMT)
commitb01ae86c02d2ca81f30055be4641ca418ac94d9b (patch)
tree65a9e5436a8797655760be1888575a9cdc4c8040 /src
parent3b545a4008fed0250d61ce1bb54af1a47fd8df92 (diff)
downloadQt-b01ae86c02d2ca81f30055be4641ca418ac94d9b.zip
Qt-b01ae86c02d2ca81f30055be4641ca418ac94d9b.tar.gz
Qt-b01ae86c02d2ca81f30055be4641ca418ac94d9b.tar.bz2
Improve performance in QUrl parsing by doing in-line operations.
Unfortunately, I can't do it all inline because the punycode encoding and decoding requires reading the source several times. (Maybe the decoding can be done with some effort in the future)
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qurl.cpp63
1 files changed, 32 insertions, 31 deletions
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index d65cee2..fcae0d6 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -2904,11 +2904,11 @@ static bool isBidirectionalL(const QChar &ch)
#ifdef QT_BUILD_INTERNAL
// export for tst_qurl.cpp
Q_AUTOTEST_EXPORT void qt_nameprep(QString *source, int from);
-Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QStringRef &);
+Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QChar *uc, int len);
#else
// non-test build, keep the symbols for ourselves
-static QString void qt_nameprep(QString *source, int from)
-static bool qt_check_std3rules(const QStringRef &);
+static void qt_nameprep(QString *source, int from);
+static bool qt_check_std3rules(const QChar *uc, int len);
#endif
void qt_nameprep(QString *source, int from)
@@ -2966,14 +2966,13 @@ void qt_nameprep(QString *source, int from)
}
}
-bool qt_check_std3rules(const QStringRef &source)
+bool qt_check_std3rules(const QChar *uc, int len)
{
- int len = source.length();
if (len > 63)
return false;
for (int i = 0; i < len; ++i) {
- register ushort c = source.at(i).unicode();
+ register ushort c = uc[i].unicode();
if (c == '-' && (i == 0 || i == len - 1))
return false;
@@ -3264,41 +3263,43 @@ static QString qt_ACE_do(const QString &domainMC, AceOperation op)
simple = false;
}
- QString aux;
- QStringRef label;
+ // copy the label to the destination, which also serves as our scratch area
+ int prevLen = result.size();
+ result.resize(prevLen + idx - lastIdx);
+ memcpy(result.data() + prevLen, domain.constData() + lastIdx, (idx - lastIdx) * sizeof(QChar));
+
if (simple) {
- // fastest conversion: this is the common case (non IDN-domains)
- // just memcpy from source (domain) to destination (result)
+ // fastest case: this is the common case (non IDN-domains)
// there's no need to nameprep since everything is ASCII already
- int prevLen = result.size();
- result.resize(prevLen + idx - lastIdx);
- memcpy(result.data() + prevLen, domain.constData() + lastIdx, (idx - lastIdx) * sizeof(QChar));
-
- label = QStringRef(&result, prevLen, result.length() - prevLen);
- } else {
+ // so we're done
+ if (!qt_check_std3rules(result.constData() + prevLen, result.length() - prevLen))
+ return QString();
+ } else {
// Nameprep the host. If the labels in the hostname are Punycode
- // encoded, we decode them immediately, then nameprep them.
- QString tmp = domain.mid(lastIdx, idx - lastIdx);
- qt_nameprep(&tmp, 0);
+ // encoded, we decode them immediately.
+ qt_nameprep(&result, prevLen);
- if (isIdnEnabled) {
- toPunycodeHelper(tmp.constData(), tmp.size(), &aux);
- label = QStringRef(&aux);
+ // Punycode encoding and decoding cannot be done in-place
+ // That means we need one or two temporaries
+ QString aceForm;
+ aceForm.reserve(result.size() - prevLen + 4 + 4); // "xn--" and "-xyz"
+ toPunycodeHelper(result.constData() + prevLen, result.size() - prevLen, &aceForm);
- tmp = QUrl::fromPunycode(aux.toLatin1());
+ if (isIdnEnabled) {
+ QString tmp = QUrl::fromPunycode(aceForm.toLatin1());
if (tmp.isEmpty())
- return QString();
- result += tmp;
+ return QString(); // shouldn't happen, since we've just punycode-encoded it
+ result.resize(prevLen + tmp.size());
+ memcpy(result.data() + prevLen, tmp.constData(), tmp.size() * sizeof(QChar));
} else {
- int prevLen = result.size();
- toPunycodeHelper(tmp.constData(), tmp.size(), &result);
-
- label = QStringRef(&result, prevLen, result.length() - prevLen);
+ result.resize(prevLen + aceForm.size());
+ memcpy(result.data() + prevLen, aceForm.constData(), aceForm.size() * sizeof(QChar));
}
+
+ if (!qt_check_std3rules(aceForm.constData(), aceForm.size()))
+ return QString();
}
- if (!qt_check_std3rules(label))
- return QString();
lastIdx = idx + 1;
if (lastIdx < domain.size() + 1)