File indexing completed on 2024-12-01 12:36:44
0001 /* 0002 This file is part of the KDE project. 0003 SPDX-FileCopyrightText: 2017 Anthony Fieroni <bvbfan@abv.bg> 0004 SPDX-FileCopyrightText: 2022 Ahmad Samir <a.samirh78@gmail.com> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef KIO_UTILS_P_H 0010 #define KIO_UTILS_P_H 0011 0012 #include <QDir> 0013 #include <QString> 0014 #include <QUrl> 0015 #include <QtGlobal> 0016 #include <qplatformdefs.h> 0017 0018 // QT_STAT_LNK on Windows MinGW 0019 #include "kioglobal_p.h" 0020 0021 namespace Utils 0022 { 0023 0024 static const QLatin1Char s_slash('/'); 0025 0026 inline bool isAbsoluteLocalPath(const QString &path) 0027 { 0028 // QDir::isAbsolutePath() will return true if "path" starts with ':', the latter denotes a 0029 // Qt Resource (qrc). 0030 // "Local" as in on local disk not in memory (qrc) 0031 return !path.startsWith(QLatin1Char(':')) && QDir::isAbsolutePath(path); 0032 } 0033 0034 /** 0035 * Appends a slash to @p path if it's not empty, and doesn't already end with a '/'. 0036 * This method modifies its arg directly: 0037 * QString p = "foo"; 0038 * appenSlash(p); // Now p is "foo/" 0039 * 0040 * For `const QString&` use slashAppended(). 0041 * 0042 * All the slash-related methods are modeled after: 0043 * - QString::chop(), which modifies the string it's called on, and returns void 0044 * - QString::chopped(), which takes a copy, modifies it, and return it 0045 */ 0046 inline void appendSlash(QString &path) 0047 { 0048 if (path.isEmpty()) { 0049 Q_ASSERT_X(false, Q_FUNC_INFO, "Not appending '/' to an empty string"); 0050 return; 0051 } 0052 0053 const auto slash = QLatin1Char('/'); 0054 if (!path.endsWith(slash)) { 0055 path += slash; 0056 } 0057 } 0058 0059 [[nodiscard]] inline QString slashAppended(QString &&path) 0060 { 0061 appendSlash(path); 0062 return path; 0063 } 0064 0065 [[nodiscard]] inline QString slashAppended(const QString &s) 0066 { 0067 QString path{s}; 0068 appendSlash(path); 0069 return path; 0070 } 0071 0072 inline void removeTrailingSlash(QString &path) 0073 { 0074 if (path.endsWith(QLatin1Char('/'))) { 0075 path.chop(1); 0076 } 0077 } 0078 0079 inline QString trailingSlashRemoved(QString &&path) 0080 { 0081 removeTrailingSlash(path); 0082 return path; 0083 } 0084 0085 inline QString trailingSlashRemoved(const QString &s) 0086 { 0087 QString path = s; 0088 removeTrailingSlash(path); 0089 return path; 0090 } 0091 0092 /** 0093 * Appends a slash '/' to @p url path, if url.path() isn't empty and doesn't already 0094 * end with a slash. 0095 */ 0096 inline void appendSlashToPath(QUrl &url) 0097 { 0098 const auto slash = QLatin1Char('/'); 0099 QString path = url.path(); 0100 if (!path.isEmpty() && !path.endsWith(slash)) { 0101 appendSlash(path); 0102 url.setPath(path); 0103 } 0104 } 0105 0106 // concatPaths() 0107 inline QString concatPaths(const QString &path1, const QString &path2) 0108 { 0109 Q_ASSERT(!path2.startsWith(QLatin1Char('/'))); 0110 0111 if (path1.isEmpty()) { 0112 return path2; 0113 } 0114 0115 QString ret = slashAppended(path1); 0116 ret += path2; 0117 return ret; 0118 } 0119 0120 inline QString concatPaths(QString &&path1, const QString &path2) 0121 { 0122 Q_ASSERT(!path2.startsWith(s_slash)); 0123 0124 if (path1.isEmpty()) { 0125 return path2; 0126 } 0127 0128 appendSlash(path1); 0129 path1 += path2; 0130 return path1; 0131 } 0132 0133 inline QString concatPaths(const QString &path1, QString &&path2) 0134 { 0135 Q_ASSERT(!path2.startsWith(s_slash)); 0136 0137 if (path1.isEmpty()) { 0138 return path2; 0139 } 0140 0141 path2.prepend(s_slash); 0142 path2.prepend(path1); 0143 return path2; 0144 } 0145 0146 inline QString concatPaths(QString &&path1, QString &&path2) 0147 { 0148 Q_ASSERT(!path2.startsWith(s_slash)); 0149 0150 if (path1.isEmpty()) { 0151 return path2; 0152 } 0153 0154 appendSlash(path1); 0155 path1 += path2; 0156 return path1; 0157 } 0158 0159 // mode_t 0160 inline bool isRegFileMask(mode_t mode) 0161 { 0162 return (mode & QT_STAT_MASK) == QT_STAT_REG; 0163 } 0164 0165 inline bool isDirMask(mode_t mode) 0166 { 0167 return (mode & QT_STAT_MASK) == QT_STAT_DIR; 0168 } 0169 0170 inline bool isLinkMask(mode_t mode) 0171 { 0172 return (mode & QT_STAT_MASK) == QT_STAT_LNK; 0173 } 0174 0175 } // namespace 0176 0177 #endif // KIO_UTILS_P_H