static int object_key_delete ( hdb_handle_t object_handle, const void *key_name, size_t key_len) { unsigned int res; int ret = 0; struct object_instance *instance; struct object_key *object_key = NULL; struct list_head *list; int found = 0; objdb_rdlock(); 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)) { 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); if (ret == 0) { object_key_changed_notification(object_handle, key_name, key_len, NULL, 0, OBJECT_KEY_DELETED); } objdb_rdunlock(); return (ret); error_exit: objdb_rdunlock(); return (-1); }
static int object_key_create_typed( hdb_handle_t object_handle, const char *key_name, const void *value, size_t value_len, objdb_value_types_t value_type) { struct object_instance *instance; struct object_key *object_key; unsigned int res; struct list_head *list; int found = 0; int i; size_t key_len = strlen(key_name); size_t expected_size; int test_size_by_type = CS_TRUE; objdb_rdlock(); res = hdb_handle_get (&object_instance_database, object_handle, (void *)&instance); if (res != 0) { goto error_exit; } switch (value_type) { case OBJDB_VALUETYPE_INT16: expected_size = sizeof (int16_t); break; case OBJDB_VALUETYPE_UINT16: expected_size = sizeof (uint16_t); break; case OBJDB_VALUETYPE_INT32: expected_size = sizeof (int32_t); break; case OBJDB_VALUETYPE_UINT32: expected_size = sizeof (uint32_t); break; case OBJDB_VALUETYPE_INT64: expected_size = sizeof (int64_t); break; case OBJDB_VALUETYPE_UINT64: expected_size = sizeof (uint64_t); break; case OBJDB_VALUETYPE_FLOAT: expected_size = sizeof (float); break; case OBJDB_VALUETYPE_DOUBLE: expected_size = sizeof (double); break; case OBJDB_VALUETYPE_ANY: default: test_size_by_type = CS_FALSE; break; } if (test_size_by_type) { if (expected_size != value_len) { //printf ("%s exp:%d != len:%d\n", key_name, expected_size, value_len); goto error_put; } } /* * 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, value, value_len); if (res != 0) { goto error_put; } } } } /* See if it already exists */ found = 0; 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)) { found = 1; break; } } if (found) { free(object_key->value); } else { object_key = malloc (sizeof (struct object_key)); if (object_key == 0) { goto error_put; } object_key->key_name = malloc (key_len + 1); if (object_key->key_name == 0) { goto error_put_object; } memcpy (object_key->key_name, key_name, key_len + 1); list_init (&object_key->list); list_add_tail (&object_key->list, &instance->key_head); } object_key->value = malloc (value_len); if (object_key->value == 0) { goto error_put_key; } memcpy (object_key->value, value, value_len); object_key->key_len = key_len; object_key->value_len = value_len; object_key->value_type = value_type; object_key_changed_notification(object_handle, key_name, key_len, value, value_len, OBJECT_KEY_CREATED); hdb_handle_put (&object_instance_database, object_handle); objdb_rdunlock(); return (0); error_put_key: free (object_key->key_name); error_put_object: free (object_key); error_put: hdb_handle_put (&object_instance_database, object_handle); error_exit: objdb_rdunlock(); return (-1); }
static int object_key_replace ( hdb_handle_t object_handle, const void *key_name, size_t key_len, const void *new_value, size_t 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; objdb_rdlock(); 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)) { found = 1; break; } } if (found) { int i; int found_validator = 0; /* * 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_validator = 1; break; } } /* * Item not found in validation list */ if (found_validator == 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); if (ret == 0) { object_key_changed_notification (object_handle, key_name, key_len, new_value, new_value_len, OBJECT_KEY_REPLACED); } objdb_rdunlock(); return (ret); error_put: hdb_handle_put (&object_instance_database, object_handle); error_exit: objdb_rdunlock(); return (-1); }
static int object_key_decrement ( hdb_handle_t object_handle, const void *key_name, size_t key_len, unsigned int *value) { unsigned int res = 0; struct object_instance *instance; struct object_key *object_key = NULL; struct list_head *list; int found = 0; objdb_lock(); 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)) { found = 1; break; } } if (found) { switch (object_key->value_type) { case OBJDB_VALUETYPE_INT16: (*(int16_t *)object_key->value)--; break; case OBJDB_VALUETYPE_UINT16: (*(uint16_t *)object_key->value)--; break; case OBJDB_VALUETYPE_INT32: (*(int32_t *)object_key->value)--; break; case OBJDB_VALUETYPE_UINT32: (*(uint32_t *)object_key->value)--; break; case OBJDB_VALUETYPE_INT64: (*(int64_t *)object_key->value)--; break; case OBJDB_VALUETYPE_UINT64: (*(uint64_t *)object_key->value)--; break; case OBJDB_VALUETYPE_ANY: /* for backwards compatibilty */ if (object_key->value_len == sizeof(int)) { (*(int *)object_key->value)--; } else { res = -1; } break; default: res = -1; break; } if (res == 0) { /* nasty, not sure why we need to return this typed * instead of void* */ *value = *(int *)object_key->value; } } else { res = -1; } hdb_handle_put (&object_instance_database, object_handle); if (res == 0) { object_key_changed_notification (object_handle, key_name, key_len, object_key->value, object_key->value_len, OBJECT_KEY_REPLACED); } objdb_unlock(); return (res); error_exit: objdb_unlock(); return (-1); }