File indexing completed on 2024-04-28 07:40:03
0001 /* 0002 This file is part of the KDE Baloo Project 0003 SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0006 */ 0007 0008 #ifndef BALOO_ID_UTILS_ 0009 #define BALOO_ID_UTILS_ 0010 0011 #include <qplatformdefs.h> 0012 #include <qglobal.h> 0013 0014 #ifdef Q_OS_WIN 0015 # include <QFileInfo> 0016 #else 0017 # include <sys/statvfs.h> 0018 #endif 0019 0020 namespace Baloo { 0021 0022 inline quint64 devIdAndInodeToId(quint32 devId, quint32 inode) 0023 { 0024 quint64 res; 0025 quint32 arr[2]; 0026 arr[0] = devId; 0027 arr[1] = inode; 0028 0029 memcpy(&res, arr, sizeof(arr)); 0030 return res; 0031 } 0032 0033 /** 0034 * Convert the QT_STATBUF into a 64 bit unique identifier for the file. 0035 * This identifier is combination of the device id and inode number. 0036 */ 0037 inline quint64 statBufToId(const QT_STATBUF& stBuf) 0038 { 0039 // We're losing 32 bits of info, so this could potentially break 0040 // on file systems with really large inode and device ids 0041 return devIdAndInodeToId(static_cast<quint32>(stBuf.st_dev), 0042 static_cast<quint32>(stBuf.st_ino)); 0043 } 0044 0045 #ifndef Q_OS_WIN 0046 inline int statWithFsid(const char* path, QT_STATBUF* statBuf) 0047 { 0048 int ret = QT_LSTAT(path, statBuf); 0049 if (ret != 0) { 0050 return ret; 0051 } 0052 0053 struct statvfs fsBuf; 0054 ret = statvfs(path, &fsBuf); 0055 if (ret == 0 && fsBuf.f_fsid != 0) { 0056 // Fold FSID into 32 bits, statBufToId would discard anything else 0057 statBuf->st_dev = static_cast<quint32>(fsBuf.f_fsid ^ (fsBuf.f_fsid >> 32)); 0058 } 0059 return ret; 0060 } 0061 #endif 0062 0063 inline int filePathToStat(const QByteArray& filePath, QT_STATBUF& statBuf) 0064 { 0065 #ifndef Q_OS_WIN 0066 return statWithFsid(filePath.constData(), &statBuf); 0067 #else 0068 const int ret = QT_STAT(filePath.constData(), &statBuf); 0069 const QString filePathStr = QString::fromUtf8(filePath); 0070 if (ret == 0 && QFileInfo(filePathStr).isSymLink()) { 0071 return QT_STAT(QFileInfo(filePathStr).symLinkTarget().toUtf8().constData(), &statBuf); 0072 } else { 0073 return ret; 0074 } 0075 #endif 0076 } 0077 0078 inline quint64 filePathToId(const QByteArray& filePath) 0079 { 0080 QT_STATBUF statBuf; 0081 const int ret = filePathToStat(filePath, statBuf); 0082 return ret ? 0 : statBufToId(statBuf); 0083 } 0084 0085 inline quint32 idToInode(quint64 id) 0086 { 0087 quint32* arr = reinterpret_cast<quint32*>(&id); 0088 return arr[1]; 0089 } 0090 0091 inline quint32 idToDeviceId(quint64 id) 0092 { 0093 quint32* arr = reinterpret_cast<quint32*>(&id); 0094 return arr[0]; 0095 } 0096 0097 template<typename T, typename V> 0098 inline void sortedIdInsert(T& vec, const V& id) 0099 { 0100 /** 0101 * search with normal < 0102 */ 0103 const auto i(std::lower_bound(vec.begin(), vec.end(), id)); 0104 0105 /** 0106 * end reached or element found smaller? 0107 * => insert new element! 0108 */ 0109 if (i == vec.end() || (id != *i)) 0110 vec.insert(i, id); 0111 } 0112 0113 template<typename T, typename V> 0114 inline void sortedIdRemove(T& vec, const V& id) 0115 { 0116 const int idx = vec.indexOf(id); 0117 if (idx >= 0) { 0118 vec.remove(idx); 0119 } 0120 } 0121 0122 } 0123 0124 #endif