#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* 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(), constructor, false}); } else { if (currentPathElement->elem == PathEntry{1, "*"}) currentNode->children.append(new VFSTreeNode{currentPathElement->elem, xnoe::linkedlist(), 0, true}); else currentNode->children.append(new VFSTreeNode{currentPathElement->elem, xnoe::linkedlist(), 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* 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* 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* 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* 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; } }