diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-01 23:48:56 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-01 23:48:56 +0200 |
commit | 43d0bb8e3997022e5270f7f75f615a47819c929e (patch) | |
tree | 937992d286966edecf81b405e414230c85d19bad /src/kernel/Object/Object.c | |
parent | e9683297bf480f9590b0e5796f4520fb430e2e03 (diff) | |
download | TCE-43d0bb8e3997022e5270f7f75f615a47819c929e.tar.gz TCE-43d0bb8e3997022e5270f7f75f615a47819c929e.zip |
Basic object system - THIS IS STILL A LONG WAY TO GO!!
Diffstat (limited to 'src/kernel/Object/Object.c')
-rw-r--r-- | src/kernel/Object/Object.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/src/kernel/Object/Object.c b/src/kernel/Object/Object.c new file mode 100644 index 0000000..3af8fff --- /dev/null +++ b/src/kernel/Object/Object.c @@ -0,0 +1,188 @@ +#include "Object.h" + +#include "VirtualFolder_cl.h" +#include <task/task.h> +#include <core/sys.h> +#include <core/monitor.h> + +#include <lib/earray.h> + +struct earray numberedMethods; +struct earray interfaces; + +void setup_object_system() { + numberedMethods.ref_vect_init_len = 32; + numberedMethods.vect_len = 256; + numberedMethods.data = 0; + earray_init(&numberedMethods); + + interfaces.ref_vect_init_len = 32; + interfaces.vect_len = 32; + interfaces.data = 0; + earray_init(&interfaces); + + Class_setup(&VirtualFolderClass); + + rootObject = VirtualFolder_new(); + deviceListObject = VirtualFolder_new(); + VirtualFolder_addChild(rootObject, 0, ".dev", deviceListObject, 0, 0); +} + +void Class_setup(Class *_class) { + monitor_write("\n * Setup class '"); + monitor_write(_class->name); + monitor_write("'... "); + + int i; + for (i = 0; _class->interfaces[i].interface != 0; i++) { + Interface_setup(_class->interfaces[i].interface); + } +} + +void Interface_setup(Interface *iface) { + int i; + + monitor_write("\n - Setup interface '"); + monitor_write(iface->name); + monitor_write("' :"); + + if (iface->numberedMethods != 0) return; + + earray_add(&interfaces, iface); + + iface->numberedMethods = kmalloc(iface->method_count * sizeof(NumberedMethod)); + iface->methodNumbers = kmalloc(iface->method_count * sizeof(int)); + + for (i = 0; i < iface->method_count; i++) { + iface->numberedMethods[i].iface = iface; + iface->numberedMethods[i].numberInIface = i; + iface->methodNumbers[i] = earray_add(&numberedMethods, &iface->numberedMethods[i]); + monitor_write(" #"); monitor_writeDec(iface->methodNumbers[i]); + } +} + +MethodPtr *Class_getInterfaceImpl(Class *_class, Interface *iface) { + int i; + for (i = 0; _class->interfaces[i].interface != 0; i++) { + if (_class->interfaces[i].interface == iface) { + return _class->interfaces[i].methods; + } + } + return 0; +} + +Object* Object_get(Object *parent, char *path) { + char* member = path; + Object *object = parent; + + while (*path != 0 && object != 0) { + if (*path == '/') { + if (member == path) { + member++; + path++; + } else { + *path = 0; + if (object->_class->findChild != 0) { + object = object->_class->findChild(object, member); + } else { + object = 0; + } + path++; + member = path; + } + } else { + path++; + } + } + if (object != 0 && member != path) { + if (object->_class->findChild != 0) { + object = object->_class->findChild(object, member); + } else { + object = 0; + } + } + + return object; +} + +// SYSCALLS + +int open(char* name) { + ASSERT(current_process != 0); + + Object *obj = Object_get(rootObject, name); + if (obj == 0) return E_NOT_FOUND; + obj->handles++; + return earray_add(¤t_process->handles, obj); +} + +int open_relative(char* name, int root_handle) { + ASSERT(current_process != 0); + + Object *parent = read_handle(current_process, root_handle); + if (parent == 0) return E_BAD_HANDLE; + Object *obj = Object_get(parent, name); + if (obj == 0) return E_NOT_FOUND; + if (obj->_class->open != 0) { + int r = obj->_class->open(obj, current_process); + if (r != 0) return r; + } + obj->handles++; + return earray_add(¤t_process->handles, obj); +} + +void close(size_t handle) { + ASSERT(current_process != 0); + + Object *obj = read_handle(current_process, handle); + if (obj == 0) return; + obj->handles--; + if (obj->_class->closed != 0) obj->_class->closed(obj); + earray_set(¤t_process->handles, handle, 0); +} + +int get_methods(char* iface_name, int* whereto) { + int i = 0; + Interface *iface = 0, *tmp; + for (i = 0; i < interfaces.elements; i++) { + tmp = earray_at(&interfaces, i); + if (tmp != 0) { + if (strcmp(tmp->name, iface_name) == 0) { + iface = tmp; + break; + } + } + } + if (iface == 0) return E_NOT_FOUND; + for (i = 0; i < iface->public_method_count; i++) { + whereto[i] = iface->methodNumbers[i]; + } + return iface->public_method_count; +} + +Object* read_handle(struct process *proc, size_t handle) { + if (proc == 0) return (Object*)handle; + return earray_at(&proc->handles, handle); +} + +int do_method_call_2(int handle, int method, size_t a, size_t b, size_t c, size_t d) { + ASSERT(current_process != 0) + + Object *obj = read_handle(current_process, handle); + if (obj == 0) return E_BAD_HANDLE; + + NumberedMethod *nm = earray_at(&numberedMethods, method); + if (nm == 0) return E_NOT_IMPLEMENTED; + if (nm->numberInIface >= nm->iface->public_method_count) return E_NOT_PUBLIC; + + MethodPtr* m = Class_getInterfaceImpl(obj->_class, nm->iface); + if (m == 0) return E_NOT_IMPLEMENTED; + MethodPtr p = m[nm->numberInIface]; + ASSERT(p != 0); + + return p(obj, current_process, a, b, c, d); +} + +void do_method_call(struct registers *regs) { + regs->eax = do_method_call_2(regs->eax, regs->ebx, regs->ecx, regs->edx, regs->esi, regs->edi); +} |