-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHierarchicalFileSystem.cpp
More file actions
147 lines (132 loc) · 4.06 KB
/
HierarchicalFileSystem.cpp
File metadata and controls
147 lines (132 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
Author: Jon Shidal
Purpose: CSE 332 lab5 - defines the hierarchical file system class
*/
#include "HierarchicalFileSystem.h"
#include<iostream>
using namespace std;
HierarchicalFileSystem::HierarchicalFileSystem() : rootDirectory(nullptr){
rootDirectory = new DirectoryFile("root");
rootDirectory->setParent(rootDirectory); // root, so parent is itself
}
int HierarchicalFileSystem::addFile(std::string path, AbstractFile* fp) {
size_t endOfDirectories = path.find_last_of('/');
if (endOfDirectories == string::npos) { // not '/' so not a valid path
return invalidpath;
}
string filename = path.substr(endOfDirectories + 1, string::npos);
string directoryPath = path.substr(0, endOfDirectories);
AbstractFile* toAddTo = parsePath(directoryPath);
if (toAddTo == nullptr) { // directory doesn't exist
return locationdoesnotexist;
}
if (fp == nullptr) {
return nullfile;
}
else {
if (fp->getParent() != nullptr) { // file already exist elsewhere in the filesystem
return filealreadyadded;
}
int result = toAddTo->addChild(fp);
if ( result == AbstractFile::notacomposite || result == AbstractFile::filealreadyexists) { // unable to addChild, must not be a directoryFile
return result;
}
fp->setParent(toAddTo);
return success;
}
}
int HierarchicalFileSystem::deleteFile(std::string path) {
AbstractFile* fileToDelete = parsePath(path);
if (fileToDelete == nullptr) {
return filedoesnotexist; // unable to find file
}
if (openFiles.find(fileToDelete) != openFiles.end()) {
return fileisopen; // file in use
}
AbstractFile* parent = fileToDelete->getParent();
if (parent == fileToDelete) { // in case it is the root directory
return cantdeleteroot;
}
/* TODO: What if the file is a directory?
We shoud only remove it if it is empty, or if the user specifies we should delete the file recursively.
This will be fixed in lab 5
*/
if (DirectoryFile * judge = dynamic_cast<DirectoryFile*>(fileToDelete)) {
if (judge->getSize() > 0) {
cout << "The directory is non-empty, you cannot remove it." << endl;
return unabletodeletedirectory;
}
}
parent->removeChild(fileToDelete->getName()); // remove from parent, this rewrites parent's contents also
delete fileToDelete;
return success;
}
AbstractFile* HierarchicalFileSystem::openFile(std::string path) {
AbstractFile* fileToOpen = parsePath(path);
if (fileToOpen == nullptr) {
return nullptr;
}
if (openFiles.find(fileToOpen) == openFiles.end()) {
openFiles.insert(fileToOpen);
return fileToOpen;
}
else {
return nullptr;
}
}
int HierarchicalFileSystem::closeFile(AbstractFile* file) {
auto it = openFiles.find(file);
if (it != openFiles.end()) { // file is currently open
openFiles.erase(it);
return success;
}
else { // file not open
return filenotopen;
}
}
AbstractFile* HierarchicalFileSystem::parsePath(string path) {
size_t startIndex = 0;
size_t endIndex = path.find_first_of('/', startIndex);
AbstractFile* current;
string directory;
if (endIndex != string::npos) {
directory = path.substr(startIndex, endIndex - startIndex);
if (directory == "root") {
current = rootDirectory;
startIndex = endIndex + 1;
}
else {
return nullptr;
}
}
else {
if (path.substr(startIndex, string::npos) == "root") {
return rootDirectory;
}
else {
return nullptr;
}
}
// root handled, traverse the rest of the path
while (startIndex != string::npos) {
endIndex = path.find_first_of('/',startIndex);
if (endIndex == string::npos) {
directory = path.substr(startIndex, string::npos);
startIndex = string::npos;
}
else {
directory = path.substr(startIndex, endIndex - startIndex);
startIndex = endIndex + 1;
}
current = current->getChild(directory);
if (current == nullptr) {
return nullptr;
}
}
return current;
}
HierarchicalFileSystem::~HierarchicalFileSystem() {
for (auto it = rootDirectory->children.begin(); it != rootDirectory->children.end(); ++it) {
delete it->second;
}
}