1/*
2 This file is part of the KDE Baloo Project
3 SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#ifndef BALOO_ID_UTILS_
9#define BALOO_ID_UTILS_
10
11#include <qplatformdefs.h>
12#include <qglobal.h>
13
14#ifdef Q_OS_WIN
15# include <QFileInfo>
16#else
17# include <sys/statvfs.h>
18#endif
19
20namespace Baloo {
21
22inline quint64 devIdAndInodeToId(quint32 devId, quint32 inode)
23{
24 quint64 res;
25 quint32 arr[2];
26 arr[0] = devId;
27 arr[1] = inode;
28
29 memcpy(dest: &res, src: arr, n: sizeof(arr));
30 return res;
31}
32
33/**
34 * Convert the QT_STATBUF into a 64 bit unique identifier for the file.
35 * This identifier is combination of the device id and inode number.
36 */
37inline quint64 statBufToId(const QT_STATBUF& stBuf)
38{
39 // We're losing 32 bits of info, so this could potentially break
40 // on file systems with really large inode and device ids
41 return devIdAndInodeToId(devId: static_cast<quint32>(stBuf.st_dev),
42 inode: static_cast<quint32>(stBuf.st_ino));
43}
44
45#ifndef Q_OS_WIN
46inline int statWithFsid(const char* path, QT_STATBUF* statBuf)
47{
48 int ret = QT_LSTAT(file: path, buf: statBuf);
49 if (ret != 0) {
50 return ret;
51 }
52
53 struct statvfs fsBuf;
54 ret = statvfs(file: path, buf: &fsBuf);
55 if (ret == 0 && fsBuf.f_fsid != 0) {
56 // Fold FSID into 32 bits, statBufToId would discard anything else
57 statBuf->st_dev = static_cast<quint32>(fsBuf.f_fsid ^ (fsBuf.f_fsid >> 32));
58 }
59 return ret;
60}
61#endif
62
63inline int filePathToStat(const QByteArray& filePath, QT_STATBUF& statBuf)
64{
65#ifndef Q_OS_WIN
66 return statWithFsid(path: filePath.constData(), statBuf: &statBuf);
67#else
68 const int ret = QT_STAT(filePath.constData(), &statBuf);
69 const QString filePathStr = QString::fromUtf8(filePath);
70 if (ret == 0 && QFileInfo(filePathStr).isSymLink()) {
71 return QT_STAT(QFileInfo(filePathStr).symLinkTarget().toUtf8().constData(), &statBuf);
72 } else {
73 return ret;
74 }
75#endif
76}
77
78inline quint64 filePathToId(const QByteArray& filePath)
79{
80 QT_STATBUF statBuf;
81 const int ret = filePathToStat(filePath, statBuf);
82 return ret ? 0 : statBufToId(stBuf: statBuf);
83}
84
85inline quint32 idToInode(quint64 id)
86{
87 quint32* arr = reinterpret_cast<quint32*>(&id);
88 return arr[1];
89}
90
91inline quint32 idToDeviceId(quint64 id)
92{
93 quint32* arr = reinterpret_cast<quint32*>(&id);
94 return arr[0];
95}
96
97template<typename T, typename V>
98inline void sortedIdInsert(T& vec, const V& id)
99{
100 /**
101 * search with normal <
102 */
103 const auto i(std::lower_bound(vec.begin(), vec.end(), id));
104
105 /**
106 * end reached or element found smaller?
107 * => insert new element!
108 */
109 if (i == vec.end() || (id != *i))
110 vec.insert(i, id);
111}
112
113template<typename T, typename V>
114inline void sortedIdRemove(T& vec, const V& id)
115{
116 const int idx = vec.indexOf(id);
117 if (idx >= 0) {
118 vec.remove(idx);
119 }
120}
121
122}
123
124#endif
125

source code of baloo/src/engine/idutils.h