summaryrefslogtreecommitdiff
path: root/src/kernel/Object/Object.c
diff options
context:
space:
mode:
authorAlex AUVOLAT <alexis211@gmail.com>2012-05-01 23:48:56 +0200
committerAlex AUVOLAT <alexis211@gmail.com>2012-05-01 23:48:56 +0200
commit43d0bb8e3997022e5270f7f75f615a47819c929e (patch)
tree937992d286966edecf81b405e414230c85d19bad /src/kernel/Object/Object.c
parente9683297bf480f9590b0e5796f4520fb430e2e03 (diff)
downloadTCE-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.c188
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(&current_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(&current_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(&current_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);
+}