diff options
Diffstat (limited to 'src/kernel/Object/VirtualFolder_cl.c')
-rw-r--r-- | src/kernel/Object/VirtualFolder_cl.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/kernel/Object/VirtualFolder_cl.c b/src/kernel/Object/VirtualFolder_cl.c new file mode 100644 index 0000000..98641dd --- /dev/null +++ b/src/kernel/Object/VirtualFolder_cl.c @@ -0,0 +1,96 @@ +#include <string.h> + +#include <core/monitor.h> +#include <core/sys.h> + +#include "VirtualFolder_cl.h" + +MethodPtr _VirtualFolderMethodsAsFolder[] = { + &VirtualFolder_GetChildNameAt, + &VirtualFolder_addChild, + 0 + }; +Class VirtualFolderClass = { + "VirtualFolder", + VirtualFolder_findChild, 0, 0, VirtualFolder_delete, + { + { &FolderIface, &_VirtualFolderMethodsAsFolder + }, + { 0, { 0 } } + } +}; + +Object *VirtualFolder_new() { + struct _VirtualFolder *f = kmalloc(sizeof(struct _VirtualFolder)); + f->obj.data = f; + f->obj._class = &VirtualFolderClass; + f->obj.handles = 0; + + f->children.ref_vect_init_len = 32; + f->children.vect_len = 64; + f->children.data = 0; + earray_init(&f->children); + + struct _VirtualFolder_child *fc = kmalloc(sizeof(struct _VirtualFolder)); + fc->name = "."; + fc->obj = &f->obj; + + earray_add(&f->children, fc); + f->child_count = 1; + + return &f->obj; +} + +void VirtualFolder_delete(Object *o) { + struct _VirtualFolder *f = o->data; + int i; + for (i = 1; i < f->child_count; i++) { + struct _VirtualFolder_child *child = earray_at(&f->children, i); + if (child->obj->_class->deleted != 0) child->obj->_class->deleted(child->obj); + kfree(child); + } + kfree(earray_at(&f->children, 0)); // self-reference, "." + earray_free(&f->children); + kfree(f); +} + +Object *VirtualFolder_findChild(Object* object, const char* name) { + struct _VirtualFolder *f = object->data; + int i; + for (i = 1; i < f->child_count; i++) { + struct _VirtualFolder_child *child = earray_at(&f->children, i); + if (strcmp(name, child->name) == 0) return child->obj; + } + return 0; +} + + +int VirtualFolder_GetChildNameAt(Object *object, struct process *process, size_t a, size_t b, size_t c, size_t d) { + struct _VirtualFolder *f = object->data; + if (a >= f->child_count) return E_NOT_FOUND; + struct _VirtualFolder_child *child = earray_at(&f->children, a); + strcpy((char*)b, child->name); + return strlen(child->name); +} + +int VirtualFolder_addChild(Object *object, struct process *process, size_t a, size_t b, size_t c, size_t d) { + ASSERT(process == 0); // this is done in kernel land + struct _VirtualFolder *f = object->data; + + if (b == 0) return E_INVALID; + + struct _VirtualFolder_child *fc = kmalloc(sizeof(struct _VirtualFolder)); + fc->name = strdup((char*)a); + fc->obj = (Object*)b; + + if (strlen(fc->name) >= FILENAME_MAX_LEN) { + fc->name[FILENAME_MAX_LEN] = 0; + } + + // THIS SHOULD'NT BE DONE LIKE THIS, IT'S TO CHECK OUR CODE WORKS! + ASSERT(earray_add(&f->children, fc) == f->child_count); + + f->child_count++; + + return 0; +} |