1 | /* |
2 | SPDX-FileCopyrightText: 2015 Gregor Mi <codestruct@posteo.org> |
3 | |
4 | SPDX-License-Identifier: GPL-2.0-or-later |
5 | */ |
6 | |
7 | #ifndef URLUTIL_P_H |
8 | #define URLUTIL_P_H |
9 | |
10 | #include <QUrl> |
11 | |
12 | namespace KIO |
13 | { |
14 | namespace UrlUtil |
15 | { |
16 | /** |
17 | * Given that @p lastUrl is a child of @p currentUrl |
18 | * or put in other words: |
19 | * @p currentUrl is a parent in the hierarchy of @p lastUrl, |
20 | * then an URL 'currentUrl'/'childitem' is returned where |
21 | * 'childitem' is the first item in the hierarchy down to |
22 | * @p lastUrl. An example will illustrate this: |
23 | |
24 | \verbatim |
25 | lastUrl : "/home/test/data/documents/muh/" |
26 | currentUrl : "/home/test/" |
27 | returns : "/home/test/data/" |
28 | \endverbatim |
29 | |
30 | * In case @p currentUrl is a child of @p lastUrl, an invalid |
31 | * URL is returned: |
32 | |
33 | \verbatim |
34 | lastUrl : "/home/" |
35 | currentUrl : "/home/test/" |
36 | returns : "" (invalid url) |
37 | \endverbatim |
38 | |
39 | * In case both URLs are equal, an invalid URL is returned: |
40 | |
41 | \verbatim |
42 | lastUrl : "/home/test/" |
43 | currentUrl : "/home/test/" |
44 | returns : "" (invalid url) |
45 | \endverbatim |
46 | */ |
47 | static QUrl firstChildUrl(const QUrl &lastUrl, const QUrl ¤tUrl) |
48 | { |
49 | const QUrl adjustedLastUrl = lastUrl.adjusted(options: QUrl::StripTrailingSlash); |
50 | const QUrl adjustedCurrentUrl = currentUrl.adjusted(options: QUrl::StripTrailingSlash); |
51 | if (!adjustedCurrentUrl.isParentOf(url: adjustedLastUrl)) { |
52 | return QUrl(); |
53 | } |
54 | |
55 | const QString childPath = adjustedLastUrl.path(); |
56 | const QString parentPath = adjustedCurrentUrl.path(); |
57 | // if the parent path is root "/" |
58 | // one char more is a valid path, otherwise "/" and another char are needed. |
59 | const int minIndex = (parentPath == QLatin1String("/" )) ? 1 : 2; |
60 | |
61 | // e.g. this would just be ok: |
62 | // childPath = /a len=2 |
63 | // parentPath = / len=1 |
64 | // childPath = /home/a len=7 |
65 | // parentPath = /home len=5 |
66 | |
67 | if (childPath.length() < (parentPath.length() + minIndex)) { |
68 | return QUrl(); |
69 | } |
70 | |
71 | const int idx2 = childPath.indexOf(c: QLatin1Char('/'), from: parentPath.length() + minIndex); |
72 | // parentPath = /home |
73 | // childPath = /home/a |
74 | // idx = -1 |
75 | // => len2 = 7 |
76 | // |
77 | // childPath = /homa/a/b |
78 | // idx = 7 |
79 | // => len2 = 7 |
80 | const int len2 = (idx2 < 0) ? childPath.length() : idx2; |
81 | |
82 | const QString path3 = childPath.left(n: len2); |
83 | |
84 | QUrl res = lastUrl; // keeps the scheme (e.g. file://) |
85 | res.setPath(path: path3); |
86 | return res; |
87 | } |
88 | } |
89 | } |
90 | |
91 | #endif |
92 | |