* Is the file at @p filePath in the directory at @p dirPath within a maximum depth of @p maxDepth? * @param filePath the path to a file. * @param dirPath the path to a file or a directory without a trailing slash * (an empty string is the root directory path). * @param maxDepth maximum depth of recursion or -1 if unlimited. * @note When @p dirPath points to a file rather than a
| 41 | * @note When @p dirPath points to a file rather than a directory, this function always returns @c false. |
| 42 | */ |
| 43 | bool isInDirectory(const QString& filePath, const QString& dirPath, int maxDepth) |
| 44 | { |
| 45 | constexpr QLatin1Char slash{'/'}; |
| 46 | |
| 47 | Q_ASSERT(!filePath.endsWith(slash)); // the path to a file cannot end with a slash |
| 48 | Q_ASSERT(!dirPath.endsWith(slash)); // precondition |
| 49 | |
| 50 | // First check whether dirPath is a parent directory of filePath. |
| 51 | // The parent directory check below is a simplified (thanks to preconditions) version of QUrl::isParentOf(). |
| 52 | |
| 53 | if (!filePath.startsWith(dirPath)) { |
| 54 | return false; // dirPath is not a parent directory of filePath |
| 55 | } |
| 56 | |
| 57 | const auto dirPathSize = dirPath.size(); |
| 58 | if (filePath.size() == dirPathSize) { |
| 59 | Q_ASSERT(filePath == dirPath); |
| 60 | return false; // dirPath points to the same file as filePath |
| 61 | } |
| 62 | Q_ASSERT(filePath.size() > dirPathSize); |
| 63 | if (filePath.at(dirPathSize) != slash) { |
| 64 | return false; // dirPath is not a parent directory of filePath |
| 65 | } |
| 66 | |
| 67 | // dirPath *is* a parent directory of filePath. Check whether it is within the maxDepth limit. |
| 68 | |
| 69 | if (maxDepth < 0) { |
| 70 | return true; // unlimited depth |
| 71 | } |
| 72 | |
| 73 | int indexOfSlashInUrlPath = 0; |
| 74 | do { |
| 75 | indexOfSlashInUrlPath = filePath.lastIndexOf(slash, indexOfSlashInUrlPath - 1); |
| 76 | Q_ASSERT(indexOfSlashInUrlPath >= dirPathSize); // because dirPath is a parent directory of filePath |
| 77 | if (indexOfSlashInUrlPath == dirPathSize) { |
| 78 | return true; |
| 79 | } |
| 80 | } while (--maxDepth >= 0); |
| 81 | return false; |
| 82 | } |
| 83 | |
| 84 | /** |
| 85 | * Returns a slash plus the path to @p filePath relative to its parent directory @p parentDirectoryPath. |
no test coverage detected