File indexing completed on 2024-04-21 05:50:50

0001 /*
0002  * Copyright 2016 Boudhayan Gupta <bgupta@kde.org>
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  *
0008  * 1. Redistributions of source code must retain the above copyright
0009  *    notice, this list of conditions and the following disclaimer.
0010  * 2. Redistributions in binary form must reproduce the above copyright
0011  *    notice, this list of conditions and the following disclaimer in the
0012  *    documentation and/or other materials provided with the distribution.
0013  * 3. Neither the name of KDE e.V. (or its successor approved by the
0014  *    membership of KDE e.V.) nor the names of its contributors may be used
0015  *    to endorse or promote products derived from this software without
0016  *    specific prior written permission.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
0019  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0020  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
0021  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0023  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0024  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0025  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0026  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0027  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0028  */
0029 
0030 #include "fs.h"
0031 
0032 StashFileSystem::StashFileSystem(QObject *parent)
0033     : QObject(parent)
0034     , root(DirectoryNode)
0035 {
0036     root.children = new StashNode();
0037     displayRoot();
0038 }
0039 
0040 StashFileSystem::~StashFileSystem()
0041 {
0042     deleteChildren(root);
0043 }
0044 
0045 StashFileSystem::StashNodeData StashFileSystem::getRoot()
0046 {
0047     return root;
0048 }
0049 
0050 void StashFileSystem::findPathFromSource(const QString &path, const QString &dir, QStringList &fileList, StashNode *node)
0051 {
0052     for (auto it = node->begin(); it != node->end(); ++it) {
0053         if (it.value().source == path) {
0054             fileList.append(dir + QLatin1Char('/') + it.key());
0055         }
0056         if (it.value().type == DirectoryNode) {
0057             findPathFromSource(path, dir + QLatin1Char('/') + it.key(), fileList, it.value().children);
0058         }
0059     }
0060 }
0061 
0062 void StashFileSystem::deleteChildren(StashNodeData nodeData)
0063 {
0064     if (nodeData.children != nullptr) {
0065         Q_FOREACH (auto data, nodeData.children->values()) {
0066             deleteChildren(data);
0067         }
0068         delete nodeData.children;
0069         nodeData.children = nullptr;
0070     }
0071 }
0072 
0073 QStringList StashFileSystem::splitPath(const QString &path)
0074 {
0075     QString filePath = path;
0076     if (filePath.startsWith(QLatin1Char('/'))) {
0077         filePath = filePath.right(filePath.size() - 1);
0078     }
0079 
0080     if (filePath.endsWith(QLatin1Char('/'))) {
0081         filePath = filePath.left(filePath.size() - 1);
0082     }
0083     return filePath.split(QLatin1Char('/'));
0084 }
0085 
0086 bool StashFileSystem::delEntry(const QString &location)
0087 {
0088     QStringList path = splitPath(location);
0089     QString name = path.takeLast();
0090     StashNodeData baseData = findNode(path);
0091     if (!(baseData.type == DirectoryNode)) {
0092         return false;
0093     }
0094 
0095     if (!(baseData.children->contains(name))) {
0096         return false;
0097     }
0098 
0099     deleteChildren(baseData.children->value(name, StashNodeData(InvalidNode)));
0100     return (baseData.children->remove(name) > 0);
0101 }
0102 
0103 bool StashFileSystem::addNode(const QString &location, const StashNodeData &data)
0104 {
0105     QStringList path = splitPath(location);
0106     QString name = path.takeLast();
0107     StashNodeData baseData = findNode(path);
0108 
0109     if (!(baseData.type == DirectoryNode)) {
0110         deleteChildren(data);
0111         return false;
0112     }
0113 
0114     baseData.children->insert(name, data);
0115     return true;
0116 }
0117 
0118 bool StashFileSystem::addFile(const QString &src, const QString &dest)
0119 {
0120     StashNodeData fileData(FileNode);
0121     fileData.source = src;
0122     return addNode(dest, fileData);
0123 }
0124 
0125 bool StashFileSystem::addSymlink(const QString &src, const QString &dest)
0126 {
0127     StashNodeData fileData(SymlinkNode);
0128     fileData.source = src;
0129     return addNode(dest, fileData);
0130 }
0131 
0132 bool StashFileSystem::addFolder(const QString &dest)
0133 {
0134     StashNodeData fileData(DirectoryNode);
0135     fileData.source = QStringLiteral("");
0136     fileData.children = new StashNode();
0137 
0138     return addNode(dest, fileData);
0139 }
0140 
0141 bool StashFileSystem::copyFile(const QString &src, const QString &dest)
0142 {
0143     StashNodeData fileToCopy = findNode(src);
0144     return addNode(dest, fileToCopy);
0145 }
0146 
0147 StashFileSystem::StashNodeData StashFileSystem::findNode(const QString &path)
0148 {
0149     return findNode(splitPath(path));
0150 }
0151 
0152 StashFileSystem::StashNodeData StashFileSystem::findNode(const QStringList &path)
0153 {
0154     StashNode *node = root.children;
0155     StashNodeData data = StashNodeData(InvalidNode);
0156     if (!path.size() || path.at(0).isEmpty()) {
0157         return root;
0158     } else {
0159         for (int i = 0; i < path.size(); ++i) {
0160             if (node->contains(path[i])) {
0161                 data = node->value(path[i], StashNodeData(InvalidNode));
0162                 if (data.type == DirectoryNode) {
0163                     node = data.children;
0164                 }
0165                 if (i == path.size() - 1) {
0166                     return data;
0167                 }
0168             } else {
0169                 return StashNodeData(InvalidNode);
0170             }
0171         }
0172         return StashNodeData(InvalidNode);
0173     }
0174 }
0175 
0176 void StashFileSystem::deleteAllItems()
0177 {
0178     deleteChildren(root);
0179 }
0180 
0181 void StashFileSystem::displayNode(StashNode *node)
0182 {
0183     for (auto it = node->begin(); it != node->end(); ++it) {
0184         qDebug() << "Stash Path" << it.key();
0185         qDebug() << "File Path" << it.value().source;
0186         qDebug() << "File Type" << it.value().type;
0187         if (it.value().type == DirectoryNode) {
0188             qDebug() << "Parent" << it.key();
0189             displayNode(it.value().children);
0190         }
0191     }
0192     return;
0193 }
0194 
0195 void StashFileSystem::displayRoot()
0196 {
0197     displayNode(root.children);
0198 }