#include "Object.h" #include "VirtualFolder_cl.h" #include #include #include #include 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); }