הערה (קובץ קוד)
קובץ זה הוא קובץ קוד מסוג CPP.
#include "FileSystem.h"
#include "Utilities.h"
#include "Action.h"
#include "HelpAction.h"
#include "HistoryAction.h"
#include "SymbolicLink.h"
#include <iostream>
#include <memory>
#include <stdexcept>
FileSystem::FileSystem()
: history(), root(std::make_unique<Directory>("/", nullptr)) {
}
std::unique_ptr<Action> FileSystem::handleHelp(const std::vector<std::string>& args) const {
checkAmountOfArgs(HELP, args.size());
return std::make_unique<HelpAction>();
}
std::unique_ptr<Action> FileSystem::handleCreate(const std::vector<std::string>& args) const {
const std::string& type = (args.size() > 1) ? args[1] : "";
checkAmountOfArgs(CREATE, args.size(), type);
std::vector<std::string> pathVector = Utilities::split(args[2]);
Directory& directory = getDirectoryFromPath(pathVector, Utilities::FileNotFoundMsg());
const std::string& name = args[3];
const std::vector<std::string>& vector = type == "symlink" ?
Utilities::split(args[4]) : std::vector<std::string>();
WriteRequest request = {name, type, vector};
return directory.CreateCreateAction(request);
}
std::unique_ptr<Action> FileSystem::handleDelete(const std::vector<std::string>& args) const {
checkAmountOfArgs(DELETE, args.size());
std::vector<std::string> pathVector = Utilities::split(args[1]);
Directory& directory = getDirectoryFromPath(pathVector, Utilities::TypeErrorMsg());
const std::string& name = args[2];
WriteRequest request = {name, "", std::vector<std::string>()};
return directory.CreateDeleteAction(request);
}
std::unique_ptr<Action> FileSystem::handleList(const std::vector<std::string>& args) const {
checkAmountOfArgs(LIST, args.size());
std::vector<std::string> pathVector = Utilities::split(args[1]);
Directory& directory = getDirectoryFromPath(pathVector, Utilities::TypeErrorMsg());
ReadRequest request = {"", true};
return directory.CreateReadAction(request);
}
std::unique_ptr<Action> FileSystem::handleRead(const std::vector<std::string>& args) const {
checkAmountOfArgs(READ, args.size());
std::vector<std::string> pathVector = Utilities::split(args[1] + "/" + args[2]);
File& file = (*root)[pathVector];
ReadRequest request = {"", true};
return file.CreateReadAction(request);
}
std::unique_ptr<Action> FileSystem::handleWrite(const std::vector<std::string>& args) const {
checkAmountOfArgs(WRITE, args.size());
std::vector<std::string> pathVector = Utilities::split(args[1] + "/" + args[2]);
TextFile& file = getTextFileFromPath(pathVector);
std::vector<std::string> line;
line.push_back(Utilities::joinArgs(args.cbegin() + 3, args.cend()));
WriteRequest request = {"", "", line};
return file.CreateWriteAction(request);
}
std::unique_ptr<Action> FileSystem::handleSearch(const std::vector<std::string>& args) const {
checkAmountOfArgs(SEARCH, args.size());
std::string path = args[1] + "/" + args[2];
std::vector<std::string> pathVector = Utilities::split(path);
File& file = (*root)[pathVector];
std::vector<std::string> temp;
std::string searchTerm = Utilities::joinArgs(args.cbegin() + 3, args.cend());
SearchRequest request = {searchTerm, false, temp, path};
return file.CreateSearchAction(request);
}
std::unique_ptr<Action> FileSystem::handleImport(const std::vector<std::string>& args) const {
checkAmountOfArgs(IMPORT, args.size());
std::vector<std::string> pathVector = Utilities::split(args[2] + "/" + args[3]);
TextFile& file = getTextFileFromPath(pathVector);
std::ifstream importFile(args[1]);
if (!importFile.good())
{
throw std::runtime_error(Utilities::HostFileErrorMsg());
}
std::vector<std::string> importedLines = Utilities::readLinesFromStream(importFile);
WriteRequest request = {"", "", importedLines};
return file.CreateWriteAction(request);
}
std::unique_ptr<Action> FileSystem::handleExport(const std::vector<std::string>& args) const {
checkAmountOfArgs(EXPORT, args.size());
std::vector<std::string> pathVector = Utilities::split(args[1] + "/" + args[2]);
TextFile& file = getTextFileFromPath(pathVector);
ReadRequest request = {args[3], false};
return file.CreateReadAction(request);
}
std::unique_ptr<Action> FileSystem::handleHistory(const std::vector<std::string>& args) const
{
checkAmountOfArgs(HISTORY, args.size());
return std::make_unique<HistoryAction>(history);
}
void FileSystem::checkAmountOfArgs(ActionType action, unsigned int num, const std::string& type) {
bool flag = false;
switch (action) {
case HELP:
case HISTORY:
flag = (num == 1);
break;
case DELETE:
case READ:
flag = (num == 3);
break;
case LIST:
flag = (num == 2);
break;
case IMPORT:
case EXPORT:
flag = (num == 4);
break;
case SEARCH: // "the word can contain spaces"
case WRITE:
flag = (num >= 4);
break;
case CREATE:
flag = (type == "symlink") ? (num == 5) : (num == 4);
break;
default:
flag = false;
break;
}
if (!flag) {
throw std::runtime_error(Utilities::commandErrorMsg());
}
}
Directory& FileSystem::getDirectoryFromPath(const std::vector<std::string>& pathVector,
const std::string& errorMessage) const {
try {
return dynamic_cast<Directory&>((*root)[pathVector]);
} catch (const std::bad_cast&) {
throw std::runtime_error(errorMessage);
}
}
TextFile &FileSystem::getTextFileFromPath(const std::vector<std::string> &pathVector) const
{
try {
return dynamic_cast<TextFile&>((*root)[pathVector]);
} catch (const std::bad_cast&) {
try {
return dynamic_cast<SymbolicLink&>((*root)[pathVector]).getFile();
} catch (const std::bad_cast&) {
throw std::runtime_error(Utilities::TypeErrorMsg());
}
}
}
FileSystem& FileSystem::getInstance() {
static FileSystem instance;
return instance;
}
void FileSystem::run() {
std::string line;
while (true) {
Utilities::printPrompt();
if (!std::getline(std::cin, line)) break;
auto args = Utilities::parseCommand(line);
if (args.empty()) continue;
const std::string& cmd = args[0];
try {
std::unique_ptr<Action> action;
if (cmd == "exit") {
break;
} else if (cmd == "help") {
action = handleHelp(args);
} else if (cmd == "create") {
action = handleCreate(args);
} else if (cmd == "delete") {
action = handleDelete(args);
} else if (cmd == "list") {
action = handleList(args);
} else if (cmd == "read") {
action = handleRead(args);
} else if (cmd == "write") {
action = handleWrite(args);
} else if (cmd == "search") {
action = handleSearch(args);
} else if (cmd == "history") {
action = handleHistory(args);
} else if (cmd == "import") {
action = handleImport(args);
} else if (cmd == "export") {
action = handleExport(args);
} else {
throw std::runtime_error(Utilities::commandErrorMsg());
}
if (action) {
action->execute();
Utilities::printActionExecuted(cmd);
if (cmd != "help" && cmd != "history") {
history.push_back(cmd);
}
}
} catch (const std::exception& e) {
Utilities::printError(e.what());
}
}
}