#include static object_namespace_t *global_ns; struct object_namespace { /* root directory set object */ object_t *ns_root; }; static kern_status_t ns_query_name(object_t *obj, char out[OBJECT_NAME_MAX]) { out[0] = '/'; out[1] = 0; return KERN_OK; } static kern_status_t ns_get_child_at(object_t *obj, size_t at, object_t **out) { object_namespace_t *ns = object_data(obj); return object_get_child_at(ns->ns_root, at, out); } static kern_status_t ns_get_child_named(object_t *obj, const char *name, object_t **out) { object_namespace_t *ns = object_data(obj); return object_get_child_named(ns->ns_root, name, out); } static object_type_t ns_type = { .ob_name = "namespace", .ob_size = sizeof(object_namespace_t), .ob_ops = { .query_name = ns_query_name, .get_named = ns_get_child_named, .get_at = ns_get_child_at, }, }; void init_global_namespace(void) { object_type_register(&ns_type); global_ns = object_namespace_create(); } object_namespace_t *global_namespace(void) { return global_ns; } object_namespace_t *object_namespace_create(void) { object_t *ns_object = object_create(&ns_type); object_namespace_t *ns = object_data(ns_object); ns->ns_root = set_create("/"); return ns; } kern_status_t object_namespace_get_object(object_namespace_t *ns, const char *path, object_t **out) { return KERN_OK; } static void cleanup_object_path(char *path, size_t len, size_t *parts) { while (path[len - 1] == '/') { path[--len] = 0; } size_t final_len = len; *parts = 0; int slashes = 0; for (int i = 0; path[i]; i++) { if (path[i] == '/') { slashes++; continue; } if (slashes < 1) { continue; } char *from = path + i; char *to = path + i - slashes + 1; int count = len - i; memmove(to, from, count); final_len -= (slashes - 1); slashes = 0; (*parts)++; } path[final_len] = 0; } kern_status_t object_publish(object_namespace_t *ns, const char *path, object_t *obj) { if (*path != '/') { return KERN_INVALID_ARGUMENT; } while (*path == '/') { path++; } size_t path_len = strlen(path); if (path_len == 0) { return set_add_object(ns->ns_root, obj); } size_t parts = 0; char *rpath = kmalloc(path_len, 0); if (!rpath) { return KERN_NO_MEMORY; } memcpy(rpath, path, path_len); cleanup_object_path(rpath, path_len, &parts); char *sp; char *tok = strtok_r(rpath, "/", &sp); object_t *cur = ns->ns_root; unsigned long flags; while (tok) { object_lock(cur, &flags); object_t *next; kern_status_t status = object_get_child_named(cur, tok, &next); if (status == KERN_NO_ENTRY) { next = set_create(tok); if (!next) { object_unlock(cur, flags); kfree(rpath); return KERN_NO_MEMORY; } status = set_add_object(cur, next); } if (status != KERN_OK) { object_unlock(cur, flags); kfree(rpath); return status; } object_unlock(cur, flags); cur = next; tok = strtok_r(NULL, "/", &sp); } kfree(rpath); return set_add_object(cur, obj); } kern_status_t object_unpublish(object_namespace_t *ns, object_t *obj) { return KERN_OK; }