diff options
Diffstat (limited to 'lib/libjove/object/directory.c')
-rw-r--r-- | lib/libjove/object/directory.c | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/lib/libjove/object/directory.c b/lib/libjove/object/directory.c index a9487e8..9c12d5b 100644 --- a/lib/libjove/object/directory.c +++ b/lib/libjove/object/directory.c @@ -1,4 +1,191 @@ +#include "object-dir.h" #include <object.h> +#include <jove.h> #include <syscall.h> KernelObjectDirectory __rootdir; + +KernelObjectDirectory* +jove_object_as_objdir(KernelObjectTyped *typed) +{ + if(typed->type == KO_OBJECT_DIRECTORY) return (KernelObjectDirectory*)typed; + return NULL; +} + +void +_jove_alloc_objdir_inplace( + KernelObjectDirectory *dir, + KernelObjectDirectory *parent, + uint8_t memb) +{ + *dir = (KernelObjectDirectory) { + .typed = (KernelObjectTyped) { + .parent = parent, + .membi = memb, + .type = KO_OBJECT_DIRECTORY + }, + .lastmemb = 0, + .firstfree = 0, + .children = { 0 } + }; + + parent->children[memb] = JOVE_OBJECT_TYPED(dir); +} + +KernelObjectDirectory* +_jove_alloc_objdir( + KernelObjectDirectory *parent, + uint8_t memb) +{ + if(!_jove_alloc) { + jove_errno = EJOVE_NOALLOC; + return NULL; + } + if(parent->children[memb]) { + jove_errno = EJOVE_FULL; + return NULL; + } + + KernelObjectDirectory *dir = _jove_alloc(sizeof(KernelObjectDirectory)); + if(dir == NULL) return NULL; + + _jove_alloc_objdir_inplace(dir, parent, memb); + jove_errno = 0; + return dir; +} + +JoveError +jove_objdir_sync(KernelObjectDirectory *dir) +{ + if(dir->lastmemb) return dir->lastmemb; + + int kerr = _syscall_invoke_objdir_lastmemb(dir, &dir->lastmemb); + jove_errno = jove_error_from_kerror(kerr); + + return dir->lastmemb; +} + +extern JoveError +_jove_objdir_sync_at_arch( + KernelObjectDirectory *dir, + uint8_t i, + obj_type_t type, + KernelObjectTyped **memb + ); + +JoveError +jove_objdir_sync_at(KernelObjectDirectory *dir, uint8_t i, KernelObjectTyped** memb) +{ + obj_type_t type; + int err = _syscall_invoke_objdir_getmemb(dir, i, &type); + if(err != 0) return err; + + KernelObjectTyped *dirmemb = dir->children[i]; + if(dirmemb != NULL) { + if(dirmemb->type == type) { + if(memb) *memb = dirmemb; + return EJOVE_OK; + } + if(_jove_free == NULL) { + return EJOVE_NOFREE; + } + _jove_free(dirmemb); + } + if(_jove_alloc == NULL) + return EJOVE_NOALLOC; + + switch(type) { + case KO_NONE: + return EJOVE_OK; + case KO_OBJECT_DIRECTORY: + dirmemb = JOVE_OBJECT_TYPED(_jove_alloc_objdir(dir, i)); + if(memb) *memb = dirmemb; + break; + case KO_MEMORY_UNTYPED: + { + dirmemb = JOVE_OBJECT_TYPED(_jove_alloc_untyped(dir, i)); + if(memb) *memb = dirmemb; + break; + } + default: + return _jove_objdir_sync_at_arch(dir, i, type, memb); + } + return EJOVE_OK; +} + +int +jove_objdir_nmemb(KernelObjectDirectory *dir) +{ + int nmemb = 0; + for(unsigned i = 1; i < 256; i++) { + if(dir->children[i] != NULL) nmemb++; + } + return nmemb; +} + +int +jove_objdir_lastmemb(KernelObjectDirectory *dir) +{ + if(dir->lastmemb) return dir->lastmemb; + JoveError err = jove_error_from_kerror(_syscall_invoke_objdir_lastmemb(dir, &dir->lastmemb)); + if(err) { + jove_errno = err; + return 0; + } + return dir->lastmemb; +} + +KernelObjectTyped* +jove_objdir_get(KernelObjectDirectory *dir, uint8_t i) +{ + return dir->children[i]; +} + +JoveError +jove_objdir_move( + KernelObjectDirectory *dir, + uint8_t memb, + KernelObjectDirectory *dest_dir, + uint8_t dest_memb) +{ + if(!memb) + return EJOVE_BADOBJ; + if(!dir->children[memb]) + return EJOVE_BADOBJ; + + if(dest_memb) + return EJOVE_BADOBJ; + if(dest_dir->children[dest_memb]) + return EJOVE_FULL; + + int kerr = _syscall_invoke_objdir_move(dir, memb, dest_dir, dest_memb); + if(kerr) return jove_error_from_kerror(kerr); + + KernelObjectTyped *move = dir->children[memb]; + dir->children[memb] = NULL; + dest_dir->children[dest_memb] = move; + + if(dir->lastmemb == move->membi) { + dir->lastmemb = 0; + } + + move->parent = dest_dir; + move->membi = dest_memb; + return EJOVE_OK; +} + +JoveError jove_object_move( + KernelObjectTyped *typed, + KernelObjectDirectory *dest_dir, + uint8_t dest_memb) +{ + return jove_objdir_move(typed->parent, typed->membi, dest_dir, dest_memb); +} + +JoveError jove_object_move_inplace( + KernelObjectTyped *typed, + KernelObjectTyped *dest) +{ + return jove_objdir_move(typed->parent, typed->membi, dest->parent, dest->membi); +} + |