133 lines
3.9 KiB
C++
133 lines
3.9 KiB
C++
#include "vfs.h"
|
|
|
|
void VFS::addEntry(Path p, ReadWriter*(*constructor)(Path)) {
|
|
PathElement* currentPathElement = p.start;
|
|
|
|
VFSTreeNode* currentNode = this->root;
|
|
|
|
if (!currentPathElement)
|
|
return currentNode;
|
|
|
|
nextPE:
|
|
while (currentPathElement) {
|
|
xnoe::linkedlistelem<VFSTreeNode*>* currentChild = currentNode->children.start;
|
|
while (currentChild) {
|
|
if (currentChild->elem->self == currentPathElement->elem) {
|
|
currentNode = currentChild->elem;
|
|
currentPathElement = currentPathElement->next;
|
|
goto nextPE;
|
|
}
|
|
currentChild = currentChild->next;
|
|
}
|
|
if (currentPathElement = p.end) {
|
|
currentNode->children.append(new VFSTreeNode{currentPathElement->elem, xnoe::linkedlist<VFSTreeNode*>(), constructor, false});
|
|
} else {
|
|
if (currentPathElement->elem == PathEntry{1, "*"})
|
|
currentNode->children.append(new VFSTreeNode{currentPathElement->elem, xnoe::linkedlist<VFSTreeNode*>(), 0, true});
|
|
else
|
|
currentNode->children.append(new VFSTreeNode{currentPathElement->elem, xnoe::linkedlist<VFSTreeNode*>(), 0, false});
|
|
}
|
|
currentNode = currentNode->children.end->elem;
|
|
currentPathElement = currentPathElement->next;
|
|
}
|
|
|
|
return currentNode;
|
|
}
|
|
|
|
Constructor VFS::getEntry(Path p) {
|
|
PathElement* currentPathElement = p.start;
|
|
VFSTreeNode* currentNode = this->root;
|
|
|
|
if (!currentPathElement)
|
|
return 0;
|
|
|
|
nextPE:
|
|
while (currentPathElement) {
|
|
xnoe::linkedlistelem<VFSTreeNode*>* currentChild = currentNode->children.start;
|
|
while (currentChild) {
|
|
if (currentChild->elem->self == currentPathElement->elem || currentChild->elem->wildcard) {
|
|
currentNode = currentChild->elem;
|
|
currentPathElement = currentPathElement->next;
|
|
goto nextPE;
|
|
}
|
|
currentChild = currentChild->next;
|
|
}
|
|
return 0;
|
|
}
|
|
if (currentNode->children.length == 0)
|
|
return currentNode->constructor;
|
|
return 0;
|
|
}
|
|
|
|
VFSTreeNode* VFS::getNode(Path p) {
|
|
PathElement* currentPathElement = p.start;
|
|
VFSTreeNode* currentNode = this->root;
|
|
|
|
nextPE:
|
|
while (currentPathElement) {
|
|
xnoe::linkedlistelem<VFSTreeNode*>* currentChild = currentNode->children.start;
|
|
while (currentChild) {
|
|
if (currentChild->elem->self == currentPathElement->elem || currentChild->elem->wildcard) {
|
|
currentNode = currentChild->elem;
|
|
currentPathElement = currentPathElement->next;
|
|
goto nextPE;
|
|
}
|
|
currentChild = currentChild->next;
|
|
}
|
|
return 0;
|
|
}
|
|
return currentNode;
|
|
}
|
|
|
|
bool VFS::exists(Path p) {
|
|
return getEntry(p);
|
|
}
|
|
|
|
ReadWriter* VFS::open(Path p) {
|
|
Constructor c = getEntry(p);
|
|
return c(p);
|
|
}
|
|
|
|
uint32_t VFS::getDentsSize(Path p) {
|
|
VFSTreeNode* node = getNode(p);
|
|
if (!node)
|
|
return 0;
|
|
|
|
uint32_t total = sizeof(FSDirectoryListing);
|
|
xnoe::linkedlistelem<VFSTreeNode*>* currentNode = node->children.start;
|
|
while (currentNode) {
|
|
total += sizeof(FSDirectoryEntry);
|
|
total += currentNode->elem->self.length;
|
|
currentNode = currentNode->next;
|
|
}
|
|
return total;
|
|
}
|
|
|
|
void VFS::getDents(Path p, FSDirectoryListing* buffer) {
|
|
VFSTreeNode* node = getNode(p);
|
|
if (!node)
|
|
return;
|
|
|
|
uint32_t total = sizeof(FSDirectoryListing);
|
|
xnoe::linkedlistelem<VFSTreeNode*>* currentNode = node->children.start;
|
|
buffer->count = 0;
|
|
while (currentNode) {
|
|
buffer->count++;
|
|
currentNode = currentNode->next;
|
|
}
|
|
|
|
uint8_t* strings = (uint8_t*)(buffer) + sizeof(FSDirectoryListing) + sizeof(FSDirectoryEntry) * buffer->count;
|
|
currentNode = node->children.start;
|
|
uint32_t index = 0;
|
|
while (currentNode) {
|
|
memcpy(strings, currentNode->elem->self.path, currentNode->elem->self.length);
|
|
buffer->entries[index++] = FSDirectoryEntry{
|
|
PathEntry{currentNode->elem->self.length, strings},
|
|
File,
|
|
0
|
|
};
|
|
strings += currentNode->elem->self.length;
|
|
buffer->stringsLength += currentNode->elem->self.length;
|
|
currentNode = currentNode->next;
|
|
}
|
|
} |