Steven Dake wrote:
> Chrissie,
> 
> An object may have multiple keys with the same name with different
> values.
> 
> For example:
> 
> object = System
>   key = processor value = CPUTYPEA
>   key = processor value = CPUTYPEB
> 
> This is why there is no delete or replace at the moment.  I looked at
> the patches briefly and I'm not sure if it handles this condition
> properly.
> 
> Essentially you would want to pass the existing value for the key to
> delete or replace into the functions.

Oh yes, I'd forgotten about that, thank you. The attached patch adds
'value' parameters to the key replace & delete calls. If the value
pointer is NULL then the function will simply replace the first one it
finds - which is handy if you don't know the value (or don't care and
have a fair idea that there will be only one).

I have also added a return code of -1/ENOENT if the key to be
replaced/deleted can't be found.

-- 

Chrissie
Index: trunk/exec/objdb.c
===================================================================
--- trunk/exec/objdb.c	(revision 1499)
+++ trunk/exec/objdb.c	(working copy)
@@ -312,10 +312,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 +533,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 +702,91 @@
 	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, "    ");
+
+	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, "    ");
+
+	fprintf(file, "}\n");
+
+	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, 0);
+
+	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_priv_get	= object_priv_get,
+	.object_dump	        = object_dump
 };
 
 struct lcr_iface objdb_iface_ver0[1] = {
Index: trunk/exec/objdb.h
===================================================================
--- trunk/exec/objdb.h	(revision 1499)
+++ trunk/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);
 
@@ -100,6 +118,10 @@
 	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

Reply via email to