From 83fa66b6d23907ccd443344f9865fcf4ad14e3a9 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 14 Dec 2017 10:32:15 +0100 Subject: Add more code examples to QUrl documentation Code examples make it much easier to learn how an API behaves. One area that the patch tries to address is the distinction between a relative URL and a relative path. Change-Id: Ife52172816b89afb6cd810b07d3573480e2cd747 Reviewed-by: Thiago Macieira --- src/corelib/io/qurl.cpp | 110 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 105 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index cf7ed130ba..4587b9fcd6 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -90,11 +90,6 @@ fromPercentEncoding() and toPercentEncoding() which deal with percent encoding and decoding of QString objects. - Calling isRelative() will tell whether or not the URL is - relative. A relative URL can be resolved by passing it as argument - to resolved(), which returns an absolute URL. isParentOf() is used - for determining whether one URL is a parent of another. - fromLocalFile() constructs a QUrl by parsing a local file path. toLocalFile() converts a URL to a local file path. @@ -116,6 +111,37 @@ from freedesktop.org, provided that the locale encodes file names using UTF-8 (required by IDN). + \section2 Relative URLs vs Relative Paths + + Calling isRelative() will return whether or not the URL is relative. + A relative URL has no \l {scheme}. For example: + + \code + qDebug() << QUrl("main.qml").isRelative(); // true: no scheme + qDebug() << QUrl("qml/main.qml").isRelative(); // true: no scheme + qDebug() << QUrl("file:main.qml").isRelative(); // false: has "file" scheme + qDebug() << QUrl("file:qml/main.qml").isRelative(); // false: has "file" scheme + \endcode + + Notice that a URL can be absolute while containing a relative path, and + vice versa: + + \code + // Absolute URL, relative path + QUrl url("file:file.txt"); + qDebug() << url.isRelative(); // false: has "file" scheme + qDebug() << QDir::isAbsolutePath(url.path()); // false: relative path + + // Relative URL, absolute path + url = QUrl("/home/user/file.txt"); + qDebug() << url.isRelative(); // true: has no scheme + qDebug() << QDir::isAbsolutePath(url.path()); // true: absolute path + \endcode + + A relative URL can be resolved by passing it as an argument to resolved(), + which returns an absolute URL. isParentOf() is used for determining whether + one URL is a parent of another. + \section2 Error checking QUrl is capable of detecting many errors in URLs while parsing it or when @@ -2539,6 +2565,12 @@ void QUrl::setPath(const QString &path, ParsingMode mode) /*! Returns the path of the URL. + \code + qDebug() << QUrl("file:file.txt").path(); // "file.txt" + qDebug() << QUrl("/home/user/file.txt").path(); // "/home/user/file.txt" + qDebug() << QUrl("http://www.example.com/test/123").path(); // "/test/123" + \endcode + The \a options argument controls how to format the path component. All values produce an unambiguous result. With QUrl::FullyDecoded, all percent-encoded sequences are decoded; otherwise, the returned value may @@ -2549,6 +2581,31 @@ void QUrl::setPath(const QString &path, ParsingMode mode) sequences are present. It is recommended to use that value when the result will be used in a non-URL context, such as sending to an FTP server. + An example of data loss is when you have non-Unicode percent-encoded sequences + and use FullyDecoded (the default): + + \code + qDebug() << QUrl("/foo%FFbar").path(); + \endcode + + In this example, there will be some level of data loss because the \c %FF cannot + be converted. + + Data loss can also occur when the path contains sub-delimiters (such as \c +): + + \code + qDebug() << QUrl("/foo+bar%2B").path(); // "/foo+bar+" + \endcode + + Other decoding examples: + + \code + const QUrl url("/tmp/Mambo %235%3F.mp3"); + qDebug() << url.path(QUrl::FullyDecoded); // "/tmp/Mambo #5?.mp3" + qDebug() << url.path(QUrl::PrettyDecoded); // "/tmp/Mambo #5?.mp3" + qDebug() << url.path(QUrl::FullyEncoded); // "/tmp/Mambo%20%235%3F.mp3" + \endcode + \sa setPath() */ QString QUrl::path(ComponentFormattingOptions options) const @@ -3257,6 +3314,8 @@ QUrl QUrl::resolved(const QUrl &relative) const equivalent to calling scheme().isEmpty(). Relative references are defined in RFC 3986 section 4.2. + + \sa {Relative URLs vs Relative Paths} */ bool QUrl::isRelative() const { @@ -3796,6 +3855,41 @@ bool QUrl::isDetached() const An empty \a localFile leads to an empty URL (since Qt 5.4). + \code + qDebug() << QUrl::fromLocalFile("file.txt"); // QUrl("file:file.txt") + qDebug() << QUrl::fromLocalFile("/home/user/file.txt"); // QUrl("file:///home/user/file.txt") + qDebug() << QUrl::fromLocalFile("file:file.txt"); // doesn't make sense; expects path, not url with scheme + \endcode + + In the first line in snippet above, a file URL is constructed from a + local, relative path. A file URL with a relative path only makes sense + if there is a base URL to resolve it against. For example: + + \code + QUrl url = QUrl::fromLocalFile("file.txt"); + QUrl baseUrl = QUrl("file:/home/user/"); + // wrong: prints QUrl("file:file.txt"), as url already has a scheme + qDebug() << baseUrl.resolved(url); + \endcode + + To resolve such a URL, it's necessary to remove the scheme beforehand: + + \code + // correct: prints QUrl("file:///home/user/file.txt") + url.setScheme(QString()); + qDebug() << baseUrl.resolved(url); + \endcode + + For this reason, it is better to use a relative URL (that is, no scheme) + for relative file paths: + + \code + QUrl url = QUrl("file.txt"); + QUrl baseUrl = QUrl("file:/home/user/"); + // prints QUrl("file:///home/user/file.txt") + qDebug() << baseUrl.resolved(url); + \endcode + \sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators() */ QUrl QUrl::fromLocalFile(const QString &localFile) @@ -3840,6 +3934,12 @@ QUrl QUrl::fromLocalFile(const QString &localFile) returned value in the form found on SMB networks (for example, "//servername/path/to/file.txt"). + \code + qDebug() << QUrl("file:file.txt").toLocalFile(); // "file:file.txt" + qDebug() << QUrl("file:/home/user/file.txt").toLocalFile(); // "file:///home/user/file.txt" + qDebug() << QUrl("file.txt").toLocalFile(); // ""; wasn't a local file as it had no scheme + \endcode + Note: if the path component of this URL contains a non-UTF-8 binary sequence (such as %80), the behaviour of this function is undefined. -- cgit v1.2.3