diff --git a/inc/DirectoryTree.hpp b/inc/DirectoryTree.hpp index 83aa933..d5ab24a 100644 --- a/inc/DirectoryTree.hpp +++ b/inc/DirectoryTree.hpp @@ -83,6 +83,8 @@ public: } void getNodePath(Node* node, std::vector& path) const; + ui64 size() const; + private: void updateTreeLinkCount(Node* node); void getMaxDepthUtil(ui32 depth, ui32& maxDepth) const; diff --git a/inc/FileSystem.hpp b/inc/FileSystem.hpp index 2d6f172..05b7636 100644 --- a/inc/FileSystem.hpp +++ b/inc/FileSystem.hpp @@ -25,8 +25,10 @@ public: ~FileSystem(); bool makeDirectory(const Path& path); + bool makeFile(const Path& path); bool changeCurrent(const Path& path); - bool removeDirectory(const Path& path); + bool removeDirectory(const Path& path, bool recursively); + bool removeFileOrLink(const Path& path); void log() const; diff --git a/src/DirectoryTree.cpp b/src/DirectoryTree.cpp index 438f02c..5231bae 100644 --- a/src/DirectoryTree.cpp +++ b/src/DirectoryTree.cpp @@ -170,4 +170,8 @@ void Directory::getNodePath(Node* node, std::vector& path) const { if (!node || !node->mTreeNode) return; path.push_back(&node->mTreeNode->key.val); getNodePath(node->mParent, path); +} + +ui64 Directory::size() const { + return mMembers.size(); } \ No newline at end of file diff --git a/src/FileSystem.cpp b/src/FileSystem.cpp index a7b7eda..6344ca3 100644 --- a/src/FileSystem.cpp +++ b/src/FileSystem.cpp @@ -24,21 +24,46 @@ bool FileSystem::makeDirectory(const Path& path) { auto existingNode = parentDirectory->findNode(path.getChain()); if (existingNode) { if (existingNode->mType == Node::DIRECTORY) return true; - gError = "Cant create directory, such node exists"; + gError = "Can not create directory, such node exists"; return false; } auto newDirectory = new Directory(); if (!parentDirectory->attachNode(path.getParentChain(), path.getFilename(), newDirectory)) { delete newDirectory; - gError = "Creation of intermediate directories is not supported"; + gError = "Invalid path"; return false; } return true; } -bool FileSystem::removeDirectory(const Path& path) { +bool FileSystem::makeFile(const Path& path) { + if (path.getDepth() < 1 || path.isInvalid()) { + gError = "Invalid path"; + return false; + } + + Directory* parentDirectory = path.isAbsolute() ? root : currentDirectory; + + auto existingNode = parentDirectory->findNode(path.getChain()); + if (existingNode) { + if (existingNode->mType == Node::FILE) return true; + gError = "Can not create file, such node exists"; + return false; + } + + auto newFile = new File(); + if (!parentDirectory->attachNode(path.getParentChain(), path.getFilename(), newFile)) { + delete newFile; + gError = "Invalid path"; + return false; + } + + return true; +} + +bool FileSystem::removeDirectory(const Path& path, bool recursively) { if (path.getDepth() < 1 || path.isInvalid()) { gError = "Invalid path"; return false; @@ -52,6 +77,16 @@ bool FileSystem::removeDirectory(const Path& path) { return false; } + if (existingNode->mType != Node::DIRECTORY) { + gError = "Path is not a directory"; + return false; + } + + if (!recursively && existingNode->mType == Node::DIRECTORY && ((Directory*)existingNode)->size()) { + gError = "Directory is not empty"; + return false; + } + if (isPathContainsCurrent(existingNode)) { gError = "Can not remove directory you are currently working in"; return false; @@ -63,6 +98,31 @@ bool FileSystem::removeDirectory(const Path& path) { return true; } +bool FileSystem::removeFileOrLink(const Path &path) { + if (path.getDepth() < 1 || path.isInvalid()) { + gError = "Invalid path"; + return false; + } + + Directory* parentDirectory = path.isAbsolute() ? root : currentDirectory; + + auto existingNode = parentDirectory->findNode(path.getChain()); + if (!existingNode) { + gError = "Cant remove, such node doesnt exists"; + return false; + } + + if (existingNode->mType == Node::DIRECTORY) { + gError = "Path is a directory"; + return false; + } + + assert(parentDirectory->detachNode(path.getParentChain(), path.getFilename())); + + delete existingNode; + return true; +} + bool FileSystem::changeCurrent(const Path& path) { if (path.isInvalid()) { gError = "Invalid path"; diff --git a/src/Interpreter.cpp b/src/Interpreter.cpp index 8bc2b05..2f4599c 100644 --- a/src/Interpreter.cpp +++ b/src/Interpreter.cpp @@ -30,7 +30,31 @@ Interpreter::Interpreter() { "remove directory", 1, [](FileSystem& filesystem, const std::vector& args){ - return filesystem.removeDirectory(args[1]); + return filesystem.removeDirectory(args[1], false); + } + }; + + mCommands["deltree"] = { + "remove directory recursively", + 1, + [](FileSystem& filesystem, const std::vector& args){ + return filesystem.removeDirectory(args[1], true); + } + }; + + mCommands["mf"] = { + "make file", + 1, + [](FileSystem& filesystem, const std::vector& args){ + return filesystem.makeFile(args[1]); + } + }; + + mCommands["del"] = { + "remove file or link", + 1, + [](FileSystem& filesystem, const std::vector& args){ + return filesystem.removeFileOrLink(args[1]); } }; } diff --git a/src/Path.cpp b/src/Path.cpp index 0edaec2..ae402fd 100644 --- a/src/Path.cpp +++ b/src/Path.cpp @@ -8,7 +8,7 @@ void initializeTransitions() { std::fill(transitions.begin(), transitions.end(), 1); for (char i = 'a'; i <= 'z'; i++) transitions[i] = i; for (char i = '0'; i <= '9'; i++) transitions[i] = i; - for (char i = 'A'; i <= 'Z'; i++) transitions[i] = i + ('a' - 'A'); + for (char i = 'A'; i <= 'Z'; i++) transitions[i] = i /* + ('a' - 'A')*/; transitions['/'] = '/'; transitions['.'] = '.'; }