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