Move some of qurl.cpp into other files for ease of maintenance
The parsing code is now in qurlparser.cpp, whereas the IDNA related code is in qurlidna.cpp. Change-Id: I0b32c0bf0ee6c2f08dc3200c44af3c9d1504a3df Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
This commit is contained in:
parent
1c2144c39f
commit
4758c8fa48
@ -28,6 +28,7 @@ HEADERS += \
|
||||
io/qresource_iterator_p.h \
|
||||
io/qstandardpaths.h \
|
||||
io/qurl.h \
|
||||
io/qurl_p.h \
|
||||
io/qurlquery.h \
|
||||
io/qurltlds_p.h \
|
||||
io/qtldurl_p.h \
|
||||
@ -66,7 +67,9 @@ SOURCES += \
|
||||
io/qresource_iterator.cpp \
|
||||
io/qstandardpaths.cpp \
|
||||
io/qurl.cpp \
|
||||
io/qurlidna.cpp \
|
||||
io/qurlquery.cpp \
|
||||
io/qurlparser.cpp \
|
||||
io/qurlrecode.cpp \
|
||||
io/qsettings.cpp \
|
||||
io/qfsfileengine.cpp \
|
||||
|
File diff suppressed because it is too large
Load Diff
119
src/corelib/io/qurl_p.h
Normal file
119
src/corelib/io/qurl_p.h
Normal file
@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QURL_P_H
|
||||
#define QURL_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience of
|
||||
// qurl*.cpp This header file may change from version to version without
|
||||
// notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include "qurl.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
struct QUrlErrorInfo {
|
||||
inline QUrlErrorInfo() : _source(0), _message(0), _expected(0), _found(0)
|
||||
{ }
|
||||
|
||||
const char *_source;
|
||||
const char *_message;
|
||||
char _expected;
|
||||
char _found;
|
||||
|
||||
inline void setParams(const char *source, const char *message, char expected, char found)
|
||||
{
|
||||
_source = source;
|
||||
_message = message;
|
||||
_expected = expected;
|
||||
_found = found;
|
||||
}
|
||||
};
|
||||
|
||||
struct QUrlParseData
|
||||
{
|
||||
const char *scheme;
|
||||
int schemeLength;
|
||||
|
||||
const char *userInfo;
|
||||
int userInfoDelimIndex;
|
||||
int userInfoLength;
|
||||
|
||||
const char *host;
|
||||
int hostLength;
|
||||
int port;
|
||||
|
||||
const char *path;
|
||||
int pathLength;
|
||||
const char *query;
|
||||
int queryLength;
|
||||
const char *fragment;
|
||||
int fragmentLength;
|
||||
|
||||
QUrlErrorInfo *errorInfo;
|
||||
};
|
||||
|
||||
// in qurlrecode.cpp
|
||||
extern Q_AUTOTEST_EXPORT int qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
|
||||
QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications);
|
||||
|
||||
// in qurlidna.cpp
|
||||
enum AceOperation { ToAceOnly, NormalizeAce };
|
||||
extern QString qt_ACE_do(const QString &domain, AceOperation op);
|
||||
extern Q_AUTOTEST_EXPORT void qt_nameprep(QString *source, int from);
|
||||
extern Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QChar *uc, int len);
|
||||
extern Q_AUTOTEST_EXPORT void qt_punycodeEncoder(const QChar *s, int ucLength, QString *output);
|
||||
extern Q_AUTOTEST_EXPORT QString qt_punycodeDecoder(const QString &pc);
|
||||
|
||||
// in qurlparser.cpp
|
||||
extern bool qt_urlParse(const char *ptr, QUrlParseData &parseData);
|
||||
extern bool qt_isValidUrlIP(const char *ptr);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QURL_P_H
|
2592
src/corelib/io/qurlidna.cpp
Normal file
2592
src/corelib/io/qurlidna.cpp
Normal file
File diff suppressed because it is too large
Load Diff
698
src/corelib/io/qurlparser.cpp
Normal file
698
src/corelib/io/qurlparser.cpp
Normal file
@ -0,0 +1,698 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtCore module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** GNU Lesser General Public License Usage
|
||||
** This file may be used under the terms of the GNU Lesser General Public
|
||||
** License version 2.1 as published by the Free Software Foundation and
|
||||
** appearing in the file LICENSE.LGPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU Lesser
|
||||
** General Public License version 2.1 requirements will be met:
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qurl_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
static bool QT_FASTCALL _HEXDIG(const char **ptr)
|
||||
{
|
||||
char ch = **ptr;
|
||||
if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')) {
|
||||
++(*ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// pct-encoded = "%" HEXDIG HEXDIG
|
||||
static bool QT_FASTCALL _pctEncoded(const char **ptr)
|
||||
{
|
||||
const char *ptrBackup = *ptr;
|
||||
|
||||
if (**ptr != '%')
|
||||
return false;
|
||||
++(*ptr);
|
||||
|
||||
if (!_HEXDIG(ptr)) {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
if (!_HEXDIG(ptr)) {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
|
||||
static bool QT_FASTCALL _genDelims(const char **ptr, char *c)
|
||||
{
|
||||
char ch = **ptr;
|
||||
switch (ch) {
|
||||
case ':': case '/': case '?': case '#':
|
||||
case '[': case ']': case '@':
|
||||
*c = ch;
|
||||
++(*ptr);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
||||
// / "*" / "+" / "," / ";" / "="
|
||||
static bool QT_FASTCALL _subDelims(const char **ptr)
|
||||
{
|
||||
char ch = **ptr;
|
||||
switch (ch) {
|
||||
case '!': case '$': case '&': case '\'':
|
||||
case '(': case ')': case '*': case '+':
|
||||
case ',': case ';': case '=':
|
||||
++(*ptr);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
||||
static bool QT_FASTCALL _unreserved(const char **ptr)
|
||||
{
|
||||
char ch = **ptr;
|
||||
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
|
||||
|| (ch >= '0' && ch <= '9')
|
||||
|| ch == '-' || ch == '.' || ch == '_' || ch == '~') {
|
||||
++(*ptr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
|
||||
static bool QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData)
|
||||
{
|
||||
bool first = true;
|
||||
bool isSchemeValid = true;
|
||||
|
||||
parseData->scheme = *ptr;
|
||||
for (;;) {
|
||||
char ch = **ptr;
|
||||
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
|
||||
;
|
||||
} else if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.') {
|
||||
if (first)
|
||||
isSchemeValid = false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
++(*ptr);
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (**ptr != ':') {
|
||||
isSchemeValid = true;
|
||||
*ptr = parseData->scheme;
|
||||
} else {
|
||||
parseData->schemeLength = *ptr - parseData->scheme;
|
||||
++(*ptr); // skip ':'
|
||||
}
|
||||
|
||||
return isSchemeValid;
|
||||
}
|
||||
|
||||
// IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
|
||||
static bool QT_FASTCALL _IPvFuture(const char **ptr)
|
||||
{
|
||||
if (**ptr != 'v')
|
||||
return false;
|
||||
|
||||
const char *ptrBackup = *ptr;
|
||||
++(*ptr);
|
||||
|
||||
if (!_HEXDIG(ptr)) {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (_HEXDIG(ptr))
|
||||
;
|
||||
|
||||
if (**ptr != '.') {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
++(*ptr);
|
||||
|
||||
if (!_unreserved(ptr) && !_subDelims(ptr) && *((*ptr)++) != ':') {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
while (_unreserved(ptr) || _subDelims(ptr) || *((*ptr)++) == ':')
|
||||
;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// h16 = 1*4HEXDIG
|
||||
// ; 16 bits of address represented in hexadecimal
|
||||
static bool QT_FASTCALL _h16(const char **ptr)
|
||||
{
|
||||
int i = 0;
|
||||
for (; i < 4; ++i) {
|
||||
if (!_HEXDIG(ptr))
|
||||
break;
|
||||
}
|
||||
return (i != 0);
|
||||
}
|
||||
|
||||
// dec-octet = DIGIT ; 0-9
|
||||
// / %x31-39 DIGIT ; 10-99
|
||||
// / "1" 2DIGIT ; 100-199
|
||||
// / "2" %x30-34 DIGIT ; 200-249
|
||||
// / "25" %x30-35 ; 250-255
|
||||
static bool QT_FASTCALL _decOctet(const char **ptr)
|
||||
{
|
||||
const char *ptrBackup = *ptr;
|
||||
char c1 = **ptr;
|
||||
|
||||
if (c1 < '0' || c1 > '9')
|
||||
return false;
|
||||
|
||||
++(*ptr);
|
||||
|
||||
if (c1 == '0')
|
||||
return true;
|
||||
|
||||
char c2 = **ptr;
|
||||
|
||||
if (c2 < '0' || c2 > '9')
|
||||
return true;
|
||||
|
||||
++(*ptr);
|
||||
|
||||
char c3 = **ptr;
|
||||
if (c3 < '0' || c3 > '9')
|
||||
return true;
|
||||
|
||||
// If there is a three digit number larger than 255, reject the
|
||||
// whole token.
|
||||
if (c1 >= '2' && c2 >= '5' && c3 > '5') {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
++(*ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
|
||||
static bool QT_FASTCALL _IPv4Address(const char **ptr)
|
||||
{
|
||||
const char *ptrBackup = *ptr;
|
||||
|
||||
if (!_decOctet(ptr)) {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
char ch = *((*ptr)++);
|
||||
if (ch != '.') {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_decOctet(ptr)) {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ls32 = ( h16 ":" h16 ) / IPv4address
|
||||
// ; least-significant 32 bits of address
|
||||
static bool QT_FASTCALL _ls32(const char **ptr)
|
||||
{
|
||||
const char *ptrBackup = *ptr;
|
||||
if (_h16(ptr) && *((*ptr)++) == ':' && _h16(ptr))
|
||||
return true;
|
||||
|
||||
*ptr = ptrBackup;
|
||||
return _IPv4Address(ptr);
|
||||
}
|
||||
|
||||
// IPv6address = 6( h16 ":" ) ls32 // case 1
|
||||
// / "::" 5( h16 ":" ) ls32 // case 2
|
||||
// / [ h16 ] "::" 4( h16 ":" ) ls32 // case 3
|
||||
// / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 // case 4
|
||||
// / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 // case 5
|
||||
// / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 // case 6
|
||||
// / [ *4( h16 ":" ) h16 ] "::" ls32 // case 7
|
||||
// / [ *5( h16 ":" ) h16 ] "::" h16 // case 8
|
||||
// / [ *6( h16 ":" ) h16 ] "::" // case 9
|
||||
static bool QT_FASTCALL _IPv6Address(const char **ptr)
|
||||
{
|
||||
const char *ptrBackup = *ptr;
|
||||
|
||||
// count of (h16 ":") to the left of and including ::
|
||||
int leftHexColons = 0;
|
||||
// count of (h16 ":") to the right of ::
|
||||
int rightHexColons = 0;
|
||||
|
||||
// first count the number of (h16 ":") on the left of ::
|
||||
while (_h16(ptr)) {
|
||||
|
||||
// an h16 not followed by a colon is considered an
|
||||
// error.
|
||||
if (**ptr != ':') {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
++(*ptr);
|
||||
++leftHexColons;
|
||||
|
||||
// check for case 1, the only time when there can be no ::
|
||||
if (leftHexColons == 6 && _ls32(ptr)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// check for case 2 where the address starts with a :
|
||||
if (leftHexColons == 0 && *((*ptr)++) != ':') {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for the second colon in ::
|
||||
if (*((*ptr)++) != ':') {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
int canBeCase = -1;
|
||||
bool ls32WasRead = false;
|
||||
|
||||
const char *tmpBackup = *ptr;
|
||||
|
||||
// count the number of (h16 ":") on the right of ::
|
||||
for (;;) {
|
||||
tmpBackup = *ptr;
|
||||
if (!_h16(ptr)) {
|
||||
if (!_ls32(ptr)) {
|
||||
if (rightHexColons != 0) {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
// the address ended with :: (case 9)
|
||||
// only valid if 1 <= leftHexColons <= 7
|
||||
canBeCase = 9;
|
||||
} else {
|
||||
ls32WasRead = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
++rightHexColons;
|
||||
if (**ptr != ':') {
|
||||
// no colon could mean that what was read as an h16
|
||||
// was in fact the first part of an ls32. we backtrack
|
||||
// and retry.
|
||||
const char *pb = *ptr;
|
||||
*ptr = tmpBackup;
|
||||
if (_ls32(ptr)) {
|
||||
ls32WasRead = true;
|
||||
--rightHexColons;
|
||||
} else {
|
||||
*ptr = pb;
|
||||
// address ends with only 1 h16 after :: (case 8)
|
||||
if (rightHexColons == 1)
|
||||
canBeCase = 8;
|
||||
}
|
||||
break;
|
||||
}
|
||||
++(*ptr);
|
||||
}
|
||||
|
||||
// determine which case it is based on the number of rightHexColons
|
||||
if (canBeCase == -1) {
|
||||
|
||||
// check if a ls32 was read. If it wasn't and rightHexColons >= 2 then the
|
||||
// last 2 HexColons are in fact a ls32
|
||||
if (!ls32WasRead && rightHexColons >= 2)
|
||||
rightHexColons -= 2;
|
||||
|
||||
canBeCase = 7 - rightHexColons;
|
||||
}
|
||||
|
||||
// based on the case we need to check that the number of leftHexColons is valid
|
||||
if (leftHexColons > (canBeCase - 2)) {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// IP-literal = "[" ( IPv6address / IPvFuture ) "]"
|
||||
static bool QT_FASTCALL _IPLiteral(const char **ptr)
|
||||
{
|
||||
const char *ptrBackup = *ptr;
|
||||
if (**ptr != '[')
|
||||
return false;
|
||||
++(*ptr);
|
||||
|
||||
if (!_IPv6Address(ptr) && !_IPvFuture(ptr)) {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (**ptr != ']') {
|
||||
*ptr = ptrBackup;
|
||||
return false;
|
||||
}
|
||||
++(*ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// reg-name = *( unreserved / pct-encoded / sub-delims )
|
||||
static void QT_FASTCALL _regName(const char **ptr)
|
||||
{
|
||||
for (;;) {
|
||||
if (!_unreserved(ptr) && !_subDelims(ptr)) {
|
||||
if (!_pctEncoded(ptr))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// host = IP-literal / IPv4address / reg-name
|
||||
static void QT_FASTCALL _host(const char **ptr, QUrlParseData *parseData)
|
||||
{
|
||||
parseData->host = *ptr;
|
||||
if (!_IPLiteral(ptr)) {
|
||||
if (_IPv4Address(ptr)) {
|
||||
char ch = **ptr;
|
||||
if (ch && ch != ':' && ch != '/') {
|
||||
// reset
|
||||
*ptr = parseData->host;
|
||||
_regName(ptr);
|
||||
}
|
||||
} else {
|
||||
_regName(ptr);
|
||||
}
|
||||
}
|
||||
parseData->hostLength = *ptr - parseData->host;
|
||||
}
|
||||
|
||||
// userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
|
||||
static void QT_FASTCALL _userInfo(const char **ptr, QUrlParseData *parseData)
|
||||
{
|
||||
parseData->userInfo = *ptr;
|
||||
for (;;) {
|
||||
if (_unreserved(ptr) || _subDelims(ptr)) {
|
||||
;
|
||||
} else {
|
||||
if (_pctEncoded(ptr)) {
|
||||
;
|
||||
} else if (**ptr == ':') {
|
||||
parseData->userInfoDelimIndex = *ptr - parseData->userInfo;
|
||||
++(*ptr);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (**ptr != '@') {
|
||||
*ptr = parseData->userInfo;
|
||||
parseData->userInfoDelimIndex = -1;
|
||||
return;
|
||||
}
|
||||
parseData->userInfoLength = *ptr - parseData->userInfo;
|
||||
++(*ptr);
|
||||
}
|
||||
|
||||
// port = *DIGIT
|
||||
static void QT_FASTCALL _port(const char **ptr, int *port)
|
||||
{
|
||||
bool first = true;
|
||||
|
||||
for (;;) {
|
||||
const char *ptrBackup = *ptr;
|
||||
char ch = *((*ptr)++);
|
||||
if (ch < '0' || ch > '9') {
|
||||
*ptr = ptrBackup;
|
||||
break;
|
||||
}
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
*port = 0;
|
||||
}
|
||||
|
||||
*port *= 10;
|
||||
*port += ch - '0';
|
||||
}
|
||||
}
|
||||
|
||||
// authority = [ userinfo "@" ] host [ ":" port ]
|
||||
static void QT_FASTCALL _authority(const char **ptr, QUrlParseData *parseData)
|
||||
{
|
||||
_userInfo(ptr, parseData);
|
||||
_host(ptr, parseData);
|
||||
|
||||
if (**ptr != ':')
|
||||
return;
|
||||
|
||||
++(*ptr);
|
||||
_port(ptr, &parseData->port);
|
||||
}
|
||||
|
||||
// pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
||||
static bool QT_FASTCALL _pchar(const char **ptr)
|
||||
{
|
||||
char c = *(*ptr);
|
||||
|
||||
switch (c) {
|
||||
case '!': case '$': case '&': case '\'': case '(': case ')': case '*':
|
||||
case '+': case ',': case ';': case '=': case ':': case '@':
|
||||
case '-': case '.': case '_': case '~':
|
||||
++(*ptr);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
|
||||
++(*ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_pctEncoded(ptr))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// segment = *pchar
|
||||
static bool QT_FASTCALL _segmentNZ(const char **ptr)
|
||||
{
|
||||
if (!_pchar(ptr))
|
||||
return false;
|
||||
|
||||
while(_pchar(ptr))
|
||||
;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// path-abempty = *( "/" segment )
|
||||
static void QT_FASTCALL _pathAbEmpty(const char **ptr)
|
||||
{
|
||||
for (;;) {
|
||||
if (**ptr != '/')
|
||||
break;
|
||||
++(*ptr);
|
||||
|
||||
while (_pchar(ptr))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// path-abs = "/" [ segment-nz *( "/" segment ) ]
|
||||
static bool QT_FASTCALL _pathAbs(const char **ptr)
|
||||
{
|
||||
// **ptr == '/' already checked in caller
|
||||
++(*ptr);
|
||||
|
||||
// we might be able to unnest this to gain some performance.
|
||||
if (!_segmentNZ(ptr))
|
||||
return true;
|
||||
|
||||
_pathAbEmpty(ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// path-rootless = segment-nz *( "/" segment )
|
||||
static bool QT_FASTCALL _pathRootless(const char **ptr)
|
||||
{
|
||||
// we might be able to unnest this to gain some performance.
|
||||
if (!_segmentNZ(ptr))
|
||||
return false;
|
||||
|
||||
_pathAbEmpty(ptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// hier-part = "//" authority path-abempty
|
||||
// / path-abs
|
||||
// / path-rootless
|
||||
// / path-empty
|
||||
static void QT_FASTCALL _hierPart(const char **ptr, QUrlParseData *parseData)
|
||||
{
|
||||
const char *ptrBackup = *ptr;
|
||||
const char *pathStart = 0;
|
||||
if (*((*ptr)++) == '/' && *((*ptr)++) == '/') {
|
||||
_authority(ptr, parseData);
|
||||
pathStart = *ptr;
|
||||
_pathAbEmpty(ptr);
|
||||
} else {
|
||||
*ptr = ptrBackup;
|
||||
pathStart = *ptr;
|
||||
if (**ptr == '/')
|
||||
_pathAbs(ptr);
|
||||
else
|
||||
_pathRootless(ptr);
|
||||
}
|
||||
parseData->path = pathStart;
|
||||
parseData->pathLength = *ptr - pathStart;
|
||||
}
|
||||
|
||||
// query = *( pchar / "/" / "?" )
|
||||
static void QT_FASTCALL _query(const char **ptr, QUrlParseData *parseData)
|
||||
{
|
||||
parseData->query = *ptr;
|
||||
for (;;) {
|
||||
if (_pchar(ptr)) {
|
||||
;
|
||||
} else if (**ptr == '/' || **ptr == '?') {
|
||||
++(*ptr);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
parseData->queryLength = *ptr - parseData->query;
|
||||
}
|
||||
|
||||
// fragment = *( pchar / "/" / "?" )
|
||||
static void QT_FASTCALL _fragment(const char **ptr, QUrlParseData *parseData)
|
||||
{
|
||||
parseData->fragment = *ptr;
|
||||
for (;;) {
|
||||
if (_pchar(ptr)) {
|
||||
;
|
||||
} else if (**ptr == '/' || **ptr == '?' || **ptr == '#') {
|
||||
++(*ptr);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
parseData->fragmentLength = *ptr - parseData->fragment;
|
||||
}
|
||||
|
||||
bool qt_urlParse(const char *pptr, QUrlParseData &parseData)
|
||||
{
|
||||
const char **ptr = &pptr;
|
||||
|
||||
#if defined (QURL_DEBUG)
|
||||
qDebug("QUrlPrivate::parse(), parsing \"%s\"", pptr);
|
||||
#endif
|
||||
|
||||
// optional scheme
|
||||
bool isSchemeValid = _scheme(ptr, &parseData);
|
||||
|
||||
if (isSchemeValid == false) {
|
||||
char ch = *((*ptr)++);
|
||||
parseData.errorInfo->setParams(*ptr, QT_TRANSLATE_NOOP(QUrl, "unexpected URL scheme"),
|
||||
0, ch);
|
||||
#if defined (QURL_DEBUG)
|
||||
qDebug("QUrlPrivate::parse(), unrecognized: %c%s", ch, *ptr);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// hierpart
|
||||
_hierPart(ptr, &parseData);
|
||||
|
||||
// optional query
|
||||
char ch = *((*ptr)++);
|
||||
if (ch == '?') {
|
||||
_query(ptr, &parseData);
|
||||
ch = *((*ptr)++);
|
||||
}
|
||||
|
||||
// optional fragment
|
||||
if (ch == '#') {
|
||||
_fragment(ptr, &parseData);
|
||||
} else if (ch != '\0') {
|
||||
parseData.errorInfo->setParams(*ptr, QT_TRANSLATE_NOOP(QUrl, "expected end of URL"),
|
||||
0, ch);
|
||||
#if defined (QURL_DEBUG)
|
||||
qDebug("QUrlPrivate::parse(), unrecognized: %c%s", ch, *ptr);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool qt_isValidUrlIP(const char *ptr)
|
||||
{
|
||||
// returns true if it matches IP-Literal or IPv4Address
|
||||
// see _host above
|
||||
return (_IPLiteral(&ptr) || _IPv4Address(&ptr)) && !*ptr;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -40,6 +40,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qurlquery.h"
|
||||
#include "qurl_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -122,9 +123,6 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
typedef QList<QPair<QString, QString> > Map;
|
||||
|
||||
int qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
|
||||
QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications);
|
||||
|
||||
class QUrlQueryPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user