link initial unstable
This commit is contained in:
parent
3138b0aad3
commit
21e8730f41
5 changed files with 105 additions and 8 deletions
|
|
@ -63,12 +63,14 @@ public:
|
|||
|
||||
class Link : public Node {
|
||||
public:
|
||||
Link();
|
||||
Link(Node* target, bool isHard);
|
||||
Link(const Link& node);
|
||||
|
||||
[[nodiscard]] Link* clone() const override;
|
||||
|
||||
[[nodiscard]] Node* getLink() const;
|
||||
[[nodiscard]] bool isHard() const;
|
||||
void setHard(bool);
|
||||
|
||||
private:
|
||||
Node* mLink = nullptr;
|
||||
|
|
@ -103,7 +105,7 @@ public:
|
|||
}
|
||||
|
||||
void getNodePath(Node* node, std::vector<const Key*>& path) const;
|
||||
ui64 size() const;
|
||||
[[nodiscard]] ui64 size() const;
|
||||
|
||||
private:
|
||||
void updateTreeLinkCount(Node* node);
|
||||
|
|
|
|||
|
|
@ -29,10 +29,11 @@ public:
|
|||
bool removeFileOrLink(const Path& path);
|
||||
bool copyNode(const Path& source, const Path& to);
|
||||
bool moveNode(const Path& source, const Path& to);
|
||||
bool makeLink(const Path& source, const Path& to, bool isDynamic);
|
||||
|
||||
void log() const;
|
||||
|
||||
const std::string& getLastError();
|
||||
static const std::string& getLastError();
|
||||
|
||||
private:
|
||||
bool isPathContainsCurrent(Node* node);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <sstream>
|
||||
|
||||
std::string gError;
|
||||
bool gDebug = true;
|
||||
|
||||
Node::~Node() = default;
|
||||
|
||||
|
|
@ -27,14 +28,25 @@ File *File::clone() const {
|
|||
return new File(*this);
|
||||
}
|
||||
|
||||
Link::Link() {
|
||||
Link::Link(Node* target, bool isHard) {
|
||||
mType = LINK;
|
||||
mIsHard = isHard;
|
||||
mLink = target;
|
||||
}
|
||||
|
||||
Node *Link::getLink() const {
|
||||
return mLink;
|
||||
}
|
||||
|
||||
bool Link::isHard() const {
|
||||
return mIsHard;
|
||||
}
|
||||
|
||||
void Link::setHard(bool val) {
|
||||
mIsHard = val;
|
||||
// TODO : do we need to update cache here?
|
||||
}
|
||||
|
||||
Link::Link(const Link &node) : Node(node) {
|
||||
mLink = node.mLink;
|
||||
mIsHard = node.mIsHard;
|
||||
|
|
@ -133,6 +145,7 @@ Node* Directory::findNode(const std::vector<Key>& path, ui32 currentDepth) {
|
|||
return ((Directory*)node)->findNode(path, ++currentDepth);
|
||||
|
||||
case Node::LINK:
|
||||
if (currentDepth == path.size() - 1) return node;
|
||||
node = ((Link*)node)->getLink();
|
||||
break;
|
||||
|
||||
|
|
@ -186,15 +199,34 @@ void Directory::dumpUtil(std::stringstream& ss, ui32 currentDepth, std::vector<b
|
|||
if (lastNode == node) indents[currentDepth - 1] = false;
|
||||
|
||||
indent(ss, currentDepth, indents);
|
||||
ss << node->key.val << "\n";
|
||||
|
||||
switch (node->data->mType) {
|
||||
case Node::DIRECTORY:
|
||||
ss << node->key.val;
|
||||
if (gDebug) ss << " [" << node->key.incomingLinksHard << ":" << node->key.incomingLinksDynamic << "]";
|
||||
ss << "\n";
|
||||
((Directory*) node->data)->dumpUtil(ss, currentDepth, indents);
|
||||
return;
|
||||
|
||||
case Node::LINK: {
|
||||
auto linkNode = ((Link*)node->data);
|
||||
ss << node->key.val << (linkNode->isHard() ? " hlink[/" : " dlink[/");
|
||||
std::vector<const Key*> path;
|
||||
getNodePath(linkNode->getLink(), path);
|
||||
std::reverse(path.begin(), path.end());
|
||||
for (auto key : path) ss << *key << "/";
|
||||
ss << "]\n";
|
||||
return;
|
||||
}
|
||||
|
||||
case Node::FILE:
|
||||
ss << node->key.val;
|
||||
if (gDebug) ss << " [file]";
|
||||
ss << "\n";
|
||||
return;
|
||||
|
||||
default:
|
||||
// do nothing for now
|
||||
ss << " ERROR \n";
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
|
@ -212,8 +244,12 @@ ui64 Directory::size() const {
|
|||
|
||||
Directory::Directory(const Directory &node) : Node(node) {
|
||||
node.traverseInorder([&](const DirectoryTree::Node* node){
|
||||
mMembers.insert(node->key, node->data->clone());
|
||||
auto newNode = node->data->clone();
|
||||
mMembers.insert(node->key, newNode);
|
||||
newNode->mParent = this;
|
||||
});
|
||||
|
||||
updateTreeLinkCount(this);
|
||||
}
|
||||
|
||||
Directory *Directory::clone() const {
|
||||
|
|
|
|||
|
|
@ -176,6 +176,48 @@ bool FileSystem::moveNode(const Path &source, const Path &target) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FileSystem::makeLink(const Path& source, const Path& target, bool isDynamic) {
|
||||
if (source.getDepth() < 1 || source.isInvalid()) {
|
||||
gError = "Invalid source path";
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO : remove code duplication
|
||||
Directory* workingDirectorySource = source.isAbsolute() ? root : currentDirectory;
|
||||
Directory* workingDirectoryTarget = target.isAbsolute() ? root : currentDirectory;
|
||||
|
||||
auto sourceNode = workingDirectorySource->findNode(source.getChain());
|
||||
if (!sourceNode) {
|
||||
gError = "Invalid source path";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sourceNode->mType == Node::LINK) {
|
||||
gError = "Link on link is not allowed";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto targetNode = workingDirectoryTarget->findNode(target.getChain());
|
||||
if (!targetNode || targetNode->mType != Node::DIRECTORY) {
|
||||
gError = "Invalid target directory";
|
||||
return false;
|
||||
}
|
||||
|
||||
const Key& key = sourceNode->mTreeNode->key.val;
|
||||
auto targetDirectory = (Directory*)targetNode;
|
||||
|
||||
if (targetDirectory->findNode(key)) {
|
||||
gError = "Node with such name already exists in the target directory";
|
||||
return false;
|
||||
}
|
||||
|
||||
auto newLink = new Link(sourceNode, !isDynamic);
|
||||
|
||||
assert(targetDirectory->attachNode(key, newLink));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileSystem::removeFileOrLink(const Path &path) {
|
||||
if (path.getDepth() < 1 || path.isInvalid()) {
|
||||
gError = "Invalid path";
|
||||
|
|
|
|||
|
|
@ -73,6 +73,22 @@ Interpreter::Interpreter() {
|
|||
return filesystem.moveNode(args[1], args[2]);
|
||||
}
|
||||
};
|
||||
|
||||
mCommands["mhl"] = {
|
||||
"make hard link",
|
||||
2,
|
||||
[](FileSystem& filesystem, const std::vector<std::string>& args){
|
||||
return filesystem.makeLink(args[1], args[2], false);
|
||||
}
|
||||
};
|
||||
|
||||
mCommands["mdl"] = {
|
||||
"make dynamic link",
|
||||
2,
|
||||
[](FileSystem& filesystem, const std::vector<std::string>& args){
|
||||
return filesystem.makeLink(args[1], args[2], true);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void Interpreter::reportError(const std::string& description) {
|
||||
|
|
@ -116,7 +132,7 @@ void Interpreter::interpret(const std::string& command) {
|
|||
bool success = iter->second.callback(mFileSystem, words);
|
||||
|
||||
if (!success) {
|
||||
reportError(mFileSystem.getLastError());
|
||||
reportError(FileSystem::getLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue