2024-04-14 00:50:21 +01:00

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;
}
}