|
Packit |
3ae693 |
/*-*- Mode: C; c-basic-offset: 8 -*-*/
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/***
|
|
Packit |
3ae693 |
This file is part of libcanberra.
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
Copyright 2008 Lennart Poettering
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
libcanberra is free software; you can redistribute it and/or modify
|
|
Packit |
3ae693 |
it under the terms of the GNU Lesser General Public License as
|
|
Packit |
3ae693 |
published by the Free Software Foundation, either version 2.1 of the
|
|
Packit |
3ae693 |
License, or (at your option) any later version.
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
libcanberra is distributed in the hope that it will be useful, but
|
|
Packit |
3ae693 |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
3ae693 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
3ae693 |
Lesser General Public License for more details.
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
3ae693 |
License along with libcanberra. If not, see
|
|
Packit |
3ae693 |
<http://www.gnu.org/licenses/>.
|
|
Packit |
3ae693 |
***/
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
3ae693 |
#include <config.h>
|
|
Packit |
3ae693 |
#endif
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#include <stdarg.h>
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#include "canberra.h"
|
|
Packit |
3ae693 |
#include "proplist.h"
|
|
Packit |
3ae693 |
#include "macro.h"
|
|
Packit |
3ae693 |
#include "malloc.h"
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static unsigned calc_hash(const char *c) {
|
|
Packit |
3ae693 |
unsigned hash = 0;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
for (; *c; c++)
|
|
Packit |
3ae693 |
hash = 31 * hash + (unsigned) *c;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return hash;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/**
|
|
Packit |
3ae693 |
* ca_proplist_create:
|
|
Packit |
3ae693 |
* @p: A pointer where to fill in a pointer for the new property list.
|
|
Packit |
3ae693 |
*
|
|
Packit |
3ae693 |
* Allocate a new empty property list.
|
|
Packit |
3ae693 |
*
|
|
Packit |
3ae693 |
* Returns: 0 on success, negative error code on error.
|
|
Packit |
3ae693 |
*/
|
|
Packit |
3ae693 |
int ca_proplist_create(ca_proplist **_p) {
|
|
Packit |
3ae693 |
ca_proplist *p;
|
|
Packit |
3ae693 |
ca_return_val_if_fail(_p, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(p = ca_new0(ca_proplist, 1)))
|
|
Packit |
3ae693 |
return CA_ERROR_OOM;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(p->mutex = ca_mutex_new())) {
|
|
Packit |
3ae693 |
ca_free(p);
|
|
Packit |
3ae693 |
return CA_ERROR_OOM;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
*_p = p;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return CA_SUCCESS;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static int _unset(ca_proplist *p, const char *key) {
|
|
Packit |
3ae693 |
ca_prop *prop, *nprop;
|
|
Packit |
3ae693 |
unsigned i;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(key, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
i = calc_hash(key) % N_HASHTABLE;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
nprop = NULL;
|
|
Packit |
3ae693 |
for (prop = p->prop_hashtable[i]; prop; nprop = prop, prop = prop->next_in_slot)
|
|
Packit |
3ae693 |
if (strcmp(prop->key, key) == 0)
|
|
Packit |
3ae693 |
break;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (prop) {
|
|
Packit |
3ae693 |
if (nprop)
|
|
Packit |
3ae693 |
nprop->next_in_slot = prop->next_in_slot;
|
|
Packit |
3ae693 |
else
|
|
Packit |
3ae693 |
p->prop_hashtable[i] = prop->next_in_slot;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (prop->prev_item)
|
|
Packit |
3ae693 |
prop->prev_item->next_item = prop->next_item;
|
|
Packit |
3ae693 |
else
|
|
Packit |
3ae693 |
p->first_item = prop->next_item;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (prop->next_item)
|
|
Packit |
3ae693 |
prop->next_item->prev_item = prop->prev_item;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_free(prop->key);
|
|
Packit |
3ae693 |
ca_free(prop);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return CA_SUCCESS;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/**
|
|
Packit |
3ae693 |
* ca_proplist_sets:
|
|
Packit |
3ae693 |
* @p: The property list to add this key/value pair to
|
|
Packit |
3ae693 |
* @key: The key for this key/value pair
|
|
Packit |
3ae693 |
* @value: The value for this key/value pair
|
|
Packit |
3ae693 |
*
|
|
Packit |
3ae693 |
* Add a new string key/value pair to the property list.
|
|
Packit |
3ae693 |
*
|
|
Packit |
3ae693 |
* Returns: 0 on success, negative error code on error.
|
|
Packit |
3ae693 |
*/
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int ca_proplist_sets(ca_proplist *p, const char *key, const char *value) {
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(key, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(value, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return ca_proplist_set(p, key, value, strlen(value)+1);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/**
|
|
Packit |
3ae693 |
* ca_proplist_setf:
|
|
Packit |
3ae693 |
* @p: The property list to add this key/value pair to
|
|
Packit |
3ae693 |
* @key: The key for this key/value pair
|
|
Packit |
3ae693 |
* @format: The format string for the value for this key/value pair
|
|
Packit |
3ae693 |
* @...: The parameters for the format string
|
|
Packit |
3ae693 |
*
|
|
Packit |
3ae693 |
* Much like ca_proplist_sets(): add a new string key/value pair to
|
|
Packit |
3ae693 |
* the property list. Takes a standard C format string plus arguments
|
|
Packit |
3ae693 |
* and formats a string of it.
|
|
Packit |
3ae693 |
*
|
|
Packit |
3ae693 |
* Returns: 0 on success, negative error code on error.
|
|
Packit |
3ae693 |
*/
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int ca_proplist_setf(ca_proplist *p, const char *key, const char *format, ...) {
|
|
Packit |
3ae693 |
int ret;
|
|
Packit |
3ae693 |
char *k;
|
|
Packit |
3ae693 |
ca_prop *prop;
|
|
Packit |
3ae693 |
size_t size = 100;
|
|
Packit |
3ae693 |
unsigned h;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(key, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(format, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(k = ca_strdup(key)))
|
|
Packit |
3ae693 |
return CA_ERROR_OOM;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
for (;;) {
|
|
Packit |
3ae693 |
va_list ap;
|
|
Packit |
3ae693 |
int r;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(prop = ca_malloc(CA_ALIGN(sizeof(ca_prop)) + size))) {
|
|
Packit |
3ae693 |
ca_free(k);
|
|
Packit |
3ae693 |
return CA_ERROR_OOM;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
va_start(ap, format);
|
|
Packit |
3ae693 |
r = vsnprintf(CA_PROP_DATA(prop), size, format, ap);
|
|
Packit |
3ae693 |
va_end(ap);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
((char*) CA_PROP_DATA(prop))[size-1] = 0;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (r > -1 && (size_t) r < size) {
|
|
Packit |
3ae693 |
prop->nbytes = (size_t) r+1;
|
|
Packit |
3ae693 |
break;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (r > -1) /* glibc 2.1 */
|
|
Packit |
3ae693 |
size = (size_t) r+1;
|
|
Packit |
3ae693 |
else /* glibc 2.0 */
|
|
Packit |
3ae693 |
size *= 2;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_free(prop);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
prop->key = k;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_mutex_lock(p->mutex);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((ret = _unset(p, key)) < 0) {
|
|
Packit |
3ae693 |
ca_free(prop);
|
|
Packit |
3ae693 |
ca_free(k);
|
|
Packit |
3ae693 |
goto finish;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
h = calc_hash(key) % N_HASHTABLE;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
prop->next_in_slot = p->prop_hashtable[h];
|
|
Packit |
3ae693 |
p->prop_hashtable[h] = prop;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
prop->prev_item = NULL;
|
|
Packit |
3ae693 |
if ((prop->next_item = p->first_item))
|
|
Packit |
3ae693 |
prop->next_item->prev_item = prop;
|
|
Packit |
3ae693 |
p->first_item = prop;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
finish:
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_mutex_unlock(p->mutex);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/**
|
|
Packit |
3ae693 |
* ca_proplist_set:
|
|
Packit |
3ae693 |
* @p: The property list to add this key/value pair to
|
|
Packit |
3ae693 |
* @key: The key for this key/value pair
|
|
Packit |
3ae693 |
* @data: The binary value for this key value pair
|
|
Packit |
3ae693 |
* @nbytes: The size of thebinary value for this key value pair.
|
|
Packit |
3ae693 |
*
|
|
Packit |
3ae693 |
* Add a new binary key/value pair to the property list.
|
|
Packit |
3ae693 |
*
|
|
Packit |
3ae693 |
* Returns: 0 on success, negative error code on error.
|
|
Packit |
3ae693 |
*/
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int ca_proplist_set(ca_proplist *p, const char *key, const void *data, size_t nbytes) {
|
|
Packit |
3ae693 |
int ret;
|
|
Packit |
3ae693 |
char *k;
|
|
Packit |
3ae693 |
ca_prop *prop;
|
|
Packit |
3ae693 |
unsigned h;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(key, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(!nbytes || data, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(k = ca_strdup(key)))
|
|
Packit |
3ae693 |
return CA_ERROR_OOM;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(prop = ca_malloc(CA_ALIGN(sizeof(ca_prop)) + nbytes))) {
|
|
Packit |
3ae693 |
ca_free(k);
|
|
Packit |
3ae693 |
return CA_ERROR_OOM;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
prop->key = k;
|
|
Packit |
3ae693 |
prop->nbytes = nbytes;
|
|
Packit |
3ae693 |
memcpy(CA_PROP_DATA(prop), data, nbytes);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_mutex_lock(p->mutex);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((ret = _unset(p, key)) < 0) {
|
|
Packit |
3ae693 |
ca_free(prop);
|
|
Packit |
3ae693 |
ca_free(k);
|
|
Packit |
3ae693 |
goto finish;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
h = calc_hash(key) % N_HASHTABLE;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
prop->next_in_slot = p->prop_hashtable[h];
|
|
Packit |
3ae693 |
p->prop_hashtable[h] = prop;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
prop->prev_item = NULL;
|
|
Packit |
3ae693 |
if ((prop->next_item = p->first_item))
|
|
Packit |
3ae693 |
prop->next_item->prev_item = prop;
|
|
Packit |
3ae693 |
p->first_item = prop;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
finish:
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_mutex_unlock(p->mutex);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/* Not exported, not self-locking */
|
|
Packit |
3ae693 |
ca_prop* ca_proplist_get_unlocked(ca_proplist *p, const char *key) {
|
|
Packit |
3ae693 |
ca_prop *prop;
|
|
Packit |
3ae693 |
unsigned i;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p, NULL);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(key, NULL);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
i = calc_hash(key) % N_HASHTABLE;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
for (prop = p->prop_hashtable[i]; prop; prop = prop->next_in_slot)
|
|
Packit |
3ae693 |
if (strcmp(prop->key, key) == 0)
|
|
Packit |
3ae693 |
return prop;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return NULL;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/* Not exported, not self-locking */
|
|
Packit |
3ae693 |
const char* ca_proplist_gets_unlocked(ca_proplist *p, const char *key) {
|
|
Packit |
3ae693 |
ca_prop *prop;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p, NULL);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(key, NULL);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(prop = ca_proplist_get_unlocked(p, key)))
|
|
Packit |
3ae693 |
return NULL;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!memchr(CA_PROP_DATA(prop), 0, prop->nbytes))
|
|
Packit |
3ae693 |
return NULL;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return CA_PROP_DATA(prop);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/**
|
|
Packit |
3ae693 |
* ca_proplist_destroy:
|
|
Packit |
3ae693 |
* @p: The property list to destroy
|
|
Packit |
3ae693 |
*
|
|
Packit |
3ae693 |
* Destroys a property list that was created with ca_proplist_create() earlier.
|
|
Packit |
3ae693 |
*
|
|
Packit |
3ae693 |
* Returns: 0 on success, negative error code on error.
|
|
Packit |
3ae693 |
*/
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int ca_proplist_destroy(ca_proplist *p) {
|
|
Packit |
3ae693 |
ca_prop *prop, *nprop;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
for (prop = p->first_item; prop; prop = nprop) {
|
|
Packit |
3ae693 |
nprop = prop->next_item;
|
|
Packit |
3ae693 |
ca_free(prop->key);
|
|
Packit |
3ae693 |
ca_free(prop);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_mutex_free(p->mutex);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_free(p);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return CA_SUCCESS;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static int merge_into(ca_proplist *a, ca_proplist *b) {
|
|
Packit |
3ae693 |
int ret = CA_SUCCESS;
|
|
Packit |
3ae693 |
ca_prop *prop;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(a, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(b, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_mutex_lock(b->mutex);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
for (prop = b->first_item; prop; prop = prop->next_item)
|
|
Packit |
3ae693 |
if ((ret = ca_proplist_set(a, prop->key, CA_PROP_DATA(prop), prop->nbytes)) < 0)
|
|
Packit |
3ae693 |
break;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_mutex_unlock(b->mutex);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int ca_proplist_merge(ca_proplist **_a, ca_proplist *b, ca_proplist *c) {
|
|
Packit |
3ae693 |
ca_proplist *a;
|
|
Packit |
3ae693 |
int ret;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(_a, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(b, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((ret = ca_proplist_create(&a)) < 0)
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((ret = merge_into(a, b)) < 0 ||
|
|
Packit |
3ae693 |
(ret = merge_into(a, c)) < 0) {
|
|
Packit |
3ae693 |
ca_proplist_destroy(a);
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
*_a = a;
|
|
Packit |
3ae693 |
return CA_SUCCESS;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_bool_t ca_proplist_contains(ca_proplist *p, const char *key) {
|
|
Packit |
3ae693 |
ca_bool_t b;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p, FALSE);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(key, FALSE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_mutex_lock(p->mutex);
|
|
Packit |
3ae693 |
b = !!ca_proplist_get_unlocked(p, key);
|
|
Packit |
3ae693 |
ca_mutex_unlock(p->mutex);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return b;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int ca_proplist_merge_ap(ca_proplist *p, va_list ap) {
|
|
Packit |
3ae693 |
int ret;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
for (;;) {
|
|
Packit |
3ae693 |
const char *key, *value;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(key = va_arg(ap, const char*)))
|
|
Packit |
3ae693 |
break;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(value = va_arg(ap, const char*)))
|
|
Packit |
3ae693 |
return CA_ERROR_INVALID;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((ret = ca_proplist_sets(p, key, value)) < 0)
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return CA_SUCCESS;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int ca_proplist_from_ap(ca_proplist **_p, va_list ap) {
|
|
Packit |
3ae693 |
int ret;
|
|
Packit |
3ae693 |
ca_proplist *p;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(_p, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((ret = ca_proplist_create(&p)) < 0)
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((ret = ca_proplist_merge_ap(p, ap)) < 0)
|
|
Packit |
3ae693 |
goto fail;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
*_p = p;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return CA_SUCCESS;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
fail:
|
|
Packit |
3ae693 |
ca_assert_se(ca_proplist_destroy(p) == CA_SUCCESS);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|