Some more additions to the objdb code.
This patch includes the previous change/delete calls and also adds calls
to iterate over the keys of an object and also to return the parent of
an object.
Chrissie
Index: exec/objdb.c
===================================================================
--- exec/objdb.c (revision 1504)
+++ exec/objdb.c (working copy)
@@ -51,10 +51,12 @@
void *object_name;
int object_name_len;
unsigned int object_handle;
+ unsigned int parent_handle;
struct list_head key_head;
struct list_head child_head;
struct list_head child_list;
struct list_head *find_child_list;
+ struct list_head *iter_key_list;
void *priv;
struct object_valid *object_valid_list;
int object_valid_list_entries;
@@ -178,9 +180,11 @@
object_instance->object_handle = *object_handle;
object_instance->find_child_list = &object_instance->child_head;
+ object_instance->iter_key_list = &object_instance->key_head;
object_instance->priv = NULL;
object_instance->object_valid_list = NULL;
object_instance->object_valid_list_entries = 0;
+ object_instance->parent_handle = parent_object_handle;
hdb_handle_put (&object_instance_database, *object_handle);
@@ -312,10 +316,66 @@
return (-1);
}
+
+static int _clear_object(struct object_instance *instance)
+{
+ struct list_head *list;
+ int res;
+ struct object_instance *find_instance = NULL;
+ struct object_key *object_key = NULL;
+
+ for (list = instance->key_head.next;
+ list != &instance->key_head; ) {
+
+ object_key = list_entry (list, struct object_key,
+ list);
+
+ list = list->next;
+
+ list_del(&object_key->list);
+ free(object_key->key_name);
+ free(object_key->value);
+ }
+
+ for (list = instance->child_head.next;
+ list != &instance->child_head; ) {
+
+ find_instance = list_entry (list, struct object_instance,
+ child_list);
+ res = _clear_object(find_instance);
+ if (res)
+ return res;
+
+ list = list->next;
+
+ list_del(&find_instance->child_list);
+ free(find_instance->object_name);
+ free(find_instance);
+ }
+
+ return 0;
+}
+
static int object_destroy (
unsigned int object_handle)
{
- return (0);
+ struct object_instance *instance;
+ unsigned int res;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ return (res);
+ }
+
+ /* Recursively clear sub-objects & keys */
+ res = _clear_object(instance);
+
+ list_del(&instance->child_list);
+ free(instance->object_name);
+ free(instance);
+
+ return (res);
}
static int object_valid_set (
@@ -477,6 +537,153 @@
return (-1);
}
+static int object_key_delete (
+ unsigned int object_handle,
+ void *key_name,
+ int key_len,
+ void *value,
+ int value_len)
+{
+ unsigned int res;
+ int ret = 0;
+ struct object_instance *instance;
+ struct object_key *object_key = NULL;
+ struct list_head *list;
+ int found = 0;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ for (list = instance->key_head.next;
+ list != &instance->key_head; list = list->next) {
+
+ object_key = list_entry (list, struct object_key, list);
+
+ if ((object_key->key_len == key_len) &&
+ (memcmp (object_key->key_name, key_name, key_len) == 0) &&
+ (value == NULL ||
+ (object_key->value_len == value_len &&
+ (memcmp (object_key->value, value, value_len) == 0)))) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ list_del(&object_key->list);
+ free(object_key->key_name);
+ free(object_key->value);
+ free(object_key);
+ }
+ else {
+ ret = -1;
+ errno = ENOENT;
+ }
+
+ hdb_handle_put (&object_instance_database, object_handle);
+ return (ret);
+
+error_exit:
+ return (-1);
+}
+
+static int object_key_replace (
+ unsigned int object_handle,
+ void *key_name,
+ int key_len,
+ void *old_value,
+ int old_value_len,
+ void *new_value,
+ int new_value_len)
+{
+ unsigned int res;
+ int ret = 0;
+ struct object_instance *instance;
+ struct object_key *object_key = NULL;
+ struct list_head *list;
+ int found = 0;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ for (list = instance->key_head.next;
+ list != &instance->key_head; list = list->next) {
+
+ object_key = list_entry (list, struct object_key, list);
+
+ if ((object_key->key_len == key_len) &&
+ (memcmp (object_key->key_name, key_name, key_len) == 0) &&
+ (old_value == NULL ||
+ (object_key->value_len == old_value_len &&
+ (memcmp (object_key->value, old_value, old_value_len) == 0)))) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ int i;
+
+ /*
+ * Do validation check if validation is configured for the parent object
+ */
+ if (instance->object_key_valid_list_entries) {
+ for (i = 0; i < instance->object_key_valid_list_entries; i++) {
+ if ((key_len ==
+ instance->object_key_valid_list[i].key_len) &&
+ (memcmp (key_name,
+ instance->object_key_valid_list[i].key_name,
+ key_len) == 0)) {
+
+ found = 1;
+ break;
+ }
+ }
+
+ /*
+ * Item not found in validation list
+ */
+ if (found == 0) {
+ goto error_put;
+ } else {
+ if (instance->object_key_valid_list[i].validate_callback) {
+ res = instance->object_key_valid_list[i].validate_callback (
+ key_name, key_len, new_value, new_value_len);
+ if (res != 0) {
+ goto error_put;
+ }
+ }
+ }
+ }
+
+ if (new_value_len <= object_key->value_len) {
+ void *replacement_value;
+ replacement_value = malloc(new_value_len);
+ if (!replacement_value)
+ goto error_exit;
+ free(object_key->value);
+ object_key->value = replacement_value;
+ }
+ memcpy(object_key->value, new_value, new_value_len);
+ object_key->value_len = new_value_len;
+ }
+ else {
+ ret = -1;
+ errno = ENOENT;
+ }
+
+ hdb_handle_put (&object_instance_database, object_handle);
+ return (ret);
+
+error_put:
+ hdb_handle_put (&object_instance_database, object_handle);
+error_exit:
+ return (-1);
+}
+
static int object_priv_get (
unsigned int object_handle,
void **priv)
@@ -499,18 +706,181 @@
return (-1);
}
+static int _dump_object(struct object_instance *instance, FILE *file, int depth)
+{
+ struct list_head *list;
+ int res;
+ int i;
+ struct object_instance *find_instance = NULL;
+ struct object_key *object_key = NULL;
+ char stringbuf1[1024];
+ char stringbuf2[1024];
+
+ memcpy(stringbuf1, instance->object_name, instance->object_name_len);
+ stringbuf1[instance->object_name_len] = '\0';
+
+ for (i=0; i<depth; i++)
+ fprintf(file, " ");
+
+ if (instance->object_handle != OBJECT_PARENT_HANDLE)
+ fprintf(file, "%s {\n", stringbuf1);
+
+ for (list = instance->key_head.next;
+ list != &instance->key_head; list = list->next) {
+
+ object_key = list_entry (list, struct object_key,
+ list);
+
+ memcpy(stringbuf1, object_key->key_name, object_key->key_len);
+ stringbuf1[object_key->key_len] = '\0';
+ memcpy(stringbuf2, object_key->value, object_key->value_len);
+ stringbuf2[object_key->value_len] = '\0';
+
+ for (i=0; i<depth+1; i++)
+ fprintf(file, " ");
+
+ fprintf(file, "%s: %s\n", stringbuf1, stringbuf2);
+ }
+
+ for (list = instance->child_head.next;
+ list != &instance->child_head; list = list->next) {
+
+ find_instance = list_entry (list, struct object_instance,
+ child_list);
+ res = _dump_object(find_instance, file, depth+1);
+ if (res)
+ return res;
+ }
+ for (i=0; i<depth; i++)
+ fprintf(file, " ");
+
+ if (instance->object_handle != OBJECT_PARENT_HANDLE)
+ fprintf(file, "}\n");
+
+ return 0;
+}
+
+
+static int object_key_iter_reset(unsigned int object_handle)
+{
+ unsigned int res;
+ struct object_instance *instance;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ instance->iter_key_list = &instance->key_head;
+
+ hdb_handle_put (&object_instance_database, object_handle);
+ return (0);
+
+error_exit:
+ return (-1);
+}
+
+static int object_key_iter(unsigned int parent_object_handle,
+ void **key_name,
+ int *key_len,
+ void **value,
+ int *value_len)
+{
+ unsigned int res;
+ struct object_instance *instance;
+ struct object_key *find_key = NULL;
+ struct list_head *list;
+ unsigned int found = 0;
+
+ res = hdb_handle_get (&object_instance_database,
+ parent_object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ res = -ENOENT;
+ list = instance->iter_key_list->next;
+ if (list != &instance->key_head) {
+ find_key = list_entry (list, struct object_key, list);
+ found = 1;
+ }
+ instance->iter_key_list = list;
+ if (found) {
+ *key_name = find_key->key_name;
+ if (key_len)
+ *key_len = find_key->key_len;
+ *value = find_key->value;
+ if (value_len)
+ *value_len = find_key->value_len;
+ res = 0;
+ }
+
+ hdb_handle_put (&object_instance_database, parent_object_handle);
+ return (res);
+
+error_exit:
+ return (-1);
+}
+
+static int object_parent_get(unsigned int object_handle,
+ unsigned int *parent_handle)
+{
+ struct object_instance *instance;
+ unsigned int res;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ return (res);
+ }
+
+ if (object_handle == OBJECT_PARENT_HANDLE)
+ *parent_handle = 0;
+ else
+ *parent_handle = instance->parent_handle;
+
+ hdb_handle_put (&object_instance_database, object_handle);
+
+ return (0);
+}
+
+
+static int object_dump(unsigned int object_handle,
+ FILE *file)
+{
+ struct object_instance *instance;
+ unsigned int res;
+
+ res = hdb_handle_get (&object_instance_database,
+ object_handle, (void *)&instance);
+ if (res != 0) {
+ return (res);
+ }
+
+ res = _dump_object(instance, file, -1);
+
+ hdb_handle_put (&object_instance_database, object_handle);
+
+ return (res);
+}
+
struct objdb_iface_ver0 objdb_iface = {
.objdb_init = objdb_init,
.object_create = object_create,
.object_priv_set = object_priv_set,
.object_key_create = object_key_create,
+ .object_key_delete = object_key_delete,
+ .object_key_replace = object_key_replace,
.object_destroy = object_destroy,
.object_valid_set = object_valid_set,
.object_key_valid_set = object_key_valid_set,
.object_find_reset = object_find_reset,
.object_find = object_find,
.object_key_get = object_key_get,
- .object_priv_get = object_priv_get
+ .object_key_iter = object_key_iter,
+ .object_key_iter_reset = object_key_iter_reset,
+ .object_priv_get = object_priv_get,
+ .object_parent_get = object_parent_get,
+ .object_dump = object_dump
};
struct lcr_iface objdb_iface_ver0[1] = {
Index: exec/objdb.h
===================================================================
--- exec/objdb.h (revision 1504)
+++ exec/objdb.h (working copy)
@@ -37,6 +37,8 @@
#define OBJECT_PARENT_HANDLE 0
+#include <stdio.h>
+
struct object_valid {
char *object_name;
int object_len;
@@ -68,6 +70,22 @@
void *value,
int value_len);
+ int (*object_key_replace) (
+ unsigned int object_handle,
+ void *key_name,
+ int key_len,
+ void *old_value,
+ int old_value_len,
+ void *new_value,
+ int new_value_len);
+
+ int (*object_key_delete) (
+ unsigned int object_handle,
+ void *key_name,
+ int key_len,
+ void *value,
+ int value_len);
+
int (*object_destroy) (
unsigned int object_handle);
@@ -90,6 +108,16 @@
int object_name_len,
unsigned int *object_handle);
+ int (*object_key_iter_reset) (
+ unsigned int object_handle);
+
+ int (*object_key_iter) (
+ unsigned int parent_object_handle,
+ void **key_name,
+ int *key_len,
+ void **value,
+ int *value_len);
+
int (*object_key_get) (
unsigned int object_handle,
void *key_name,
@@ -97,9 +125,17 @@
void **value,
int *value_len);
+ int (*object_parent_get) (
+ unsigned int object_handle,
+ unsigned int *parent_handle);
+
int (*object_priv_get) (
unsigned int jobject_handle,
void **priv);
+
+ int (*object_dump) (
+ unsigned int object_handle,
+ FILE *file);
};
#endif /* OBJDB_H_DEFINED */
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais