File indexing completed on 2024-05-12 05:48:50
0001 // SPDX-FileCopyrightText: 2020 Simon Persson <simon.persson@mykolab.com> 0002 // 0003 // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 0005 #ifndef BUPVFS_H 0006 #define BUPVFS_H 0007 0008 #include <QHash> 0009 #include <QObject> 0010 #include <kio/global.h> 0011 #include <sys/types.h> 0012 0013 #include "vfshelpers.h" 0014 0015 class Node: public QObject, public Metadata { 0016 Q_OBJECT 0017 public: 0018 Node(QObject *pParent, const QString &pName, qint64 pMode); 0019 ~Node() override {} 0020 virtual int readMetadata(VintStream &pMetadataStream); 0021 Node *resolve(const QString &pPath, bool pFollowLinks = false); 0022 Node *resolve(const QStringList &pPathList, bool pFollowLinks = false); 0023 QString completePath(); 0024 Node *parentCommit(); 0025 // Node *parentRepository(); 0026 QString mMimeType; 0027 0028 protected: 0029 static git_revwalk *mRevisionWalker; 0030 static git_repository *mRepository; 0031 }; 0032 0033 typedef QHash<QString, Node*> NodeMap; 0034 typedef QHashIterator<QString, Node*> NodeMapIterator; 0035 0036 class Directory: public Node { 0037 Q_OBJECT 0038 public: 0039 Directory(QObject *pParent, const QString &pName, qint64 pMode); 0040 ~Directory() override { 0041 delete mSubNodes; 0042 } 0043 virtual NodeMap subNodes(); 0044 virtual void reload() {} 0045 0046 protected: 0047 virtual void generateSubNodes() {} 0048 NodeMap *mSubNodes; 0049 }; 0050 0051 class File: public Node { 0052 Q_OBJECT 0053 public: 0054 File(QObject *pParent, const QString &pName, qint64 pMode) 0055 :Node(pParent, pName, pMode) 0056 { 0057 mOffset = 0; 0058 mCachedSize = 0; 0059 } 0060 virtual quint64 size() { 0061 if(mCachedSize == 0) { 0062 mCachedSize = calculateSize(); 0063 } 0064 return mCachedSize; 0065 } 0066 virtual int seek(quint64 pOffset) { 0067 if(pOffset >= size()) { 0068 return KIO::ERR_CANNOT_SEEK; 0069 } 0070 mOffset = pOffset; 0071 return 0; // success 0072 } 0073 virtual int read(QByteArray &pChunk, qint64 pReadSize = -1) = 0; 0074 int readMetadata(VintStream &pMetadataStream) override; 0075 0076 protected: 0077 virtual quint64 calculateSize() = 0; 0078 quint64 mOffset; 0079 quint64 mCachedSize; 0080 }; 0081 0082 class BlobFile: public File { 0083 Q_OBJECT 0084 public: 0085 BlobFile(Node *pParent, const git_oid *pOid, const QString &pName, qint64 pMode); 0086 ~BlobFile() override; 0087 int read(QByteArray &pChunk, qint64 pReadSize = -1) override; 0088 0089 protected: 0090 git_blob *cachedBlob(); 0091 quint64 calculateSize() override; 0092 git_oid mOid{}; 0093 git_blob *mBlob; 0094 }; 0095 0096 class Symlink: public BlobFile { 0097 Q_OBJECT 0098 public: 0099 Symlink(Node *pParent, const git_oid *pOid, const QString &pName, qint64 pMode) 0100 : BlobFile(pParent, pOid, pName, pMode) 0101 { 0102 QByteArray lArray; 0103 if(0 == read(lArray)) { 0104 mSymlinkTarget = QString::fromUtf8(lArray.data(), lArray.size()); 0105 Symlink::seek(0); 0106 } 0107 } 0108 }; 0109 0110 class ChunkFile: public File { 0111 Q_OBJECT 0112 public: 0113 ChunkFile(Node *pParent, const git_oid *pOid, const QString &pName, qint64 pMode); 0114 ~ChunkFile() override; 0115 int seek(quint64 pOffset) override; 0116 int read(QByteArray &pChunk, qint64 pReadSize = -1) override; 0117 0118 protected: 0119 quint64 calculateSize() override; 0120 0121 git_oid mOid; 0122 git_blob *mCurrentBlob; 0123 struct TreePosition { 0124 explicit TreePosition(git_tree *pTree); 0125 ~TreePosition(); 0126 git_tree *mTree; 0127 ulong mIndex; 0128 quint64 mSkipSize; 0129 }; 0130 0131 QList<TreePosition *> mPositionStack; 0132 bool mValidSeekPosition; 0133 }; 0134 0135 class ArchivedDirectory: public Directory { 0136 Q_OBJECT 0137 public: 0138 ArchivedDirectory(Node *pParent, const git_oid *pOid, const QString &pName, qint64 pMode); 0139 0140 protected: 0141 void generateSubNodes() override; 0142 git_oid mOid{}; 0143 git_blob *mMetadataBlob{}; 0144 git_tree *mTree; 0145 VintStream *mMetadataStream; 0146 }; 0147 0148 class Branch: public Directory { 0149 Q_OBJECT 0150 public: 0151 Branch(Node *pParent, const char *pName); 0152 void reload() override; 0153 0154 protected: 0155 void generateSubNodes() override; 0156 QByteArray mRefName; 0157 }; 0158 0159 0160 class Repository: public Directory { 0161 Q_OBJECT 0162 public: 0163 Repository(QObject *pParent, const QString &pRepositoryPath); 0164 ~Repository() override; 0165 bool isValid() { 0166 return mRepository != nullptr && mRevisionWalker != nullptr; 0167 } 0168 0169 protected: 0170 void generateSubNodes() override; 0171 }; 0172 0173 0174 0175 #endif // BUPVFS_H