properties: don't add NULL values

NULL values should remove the key.
This commit is contained in:
Wim Taymans 2018-11-06 12:21:44 +01:00
parent 10ce1a02cf
commit d5c894cfd8

View file

@ -98,7 +98,8 @@ struct pw_properties *pw_properties_new(const char *key, ...)
va_start(varargs, key); va_start(varargs, key);
while (key != NULL) { while (key != NULL) {
value = va_arg(varargs, char *); value = va_arg(varargs, char *);
add_func(&impl->this, strdup(key), value ? strdup(value) : NULL); if (value)
add_func(&impl->this, strdup(key), strdup(value));
key = va_arg(varargs, char *); key = va_arg(varargs, char *);
} }
va_end(varargs); va_end(varargs);
@ -123,9 +124,9 @@ struct pw_properties *pw_properties_new_dict(const struct spa_dict *dict)
return NULL; return NULL;
for (i = 0; i < dict->n_items; i++) { for (i = 0; i < dict->n_items; i++) {
if (dict->items[i].key != NULL) if (dict->items[i].key != NULL && dict->items[i].value != NULL)
add_func(&impl->this, strdup(dict->items[i].key), add_func(&impl->this, strdup(dict->items[i].key),
dict->items[i].value ? strdup(dict->items[i].value) : NULL); strdup(dict->items[i].value));
} }
return &impl->this; return &impl->this;
@ -186,7 +187,7 @@ struct pw_properties *pw_properties_copy(const struct pw_properties *properties)
return NULL; return NULL;
pw_array_for_each(item, &impl->items) pw_array_for_each(item, &impl->items)
add_func(copy, strdup(item->key), item->value ? strdup(item->value) : NULL); add_func(copy, strdup(item->key), strdup(item->value));
return copy; return copy;
} }
@ -241,37 +242,45 @@ void pw_properties_free(struct pw_properties *properties)
struct spa_dict_item *item; struct spa_dict_item *item;
pw_array_for_each(item, &impl->items) pw_array_for_each(item, &impl->items)
clear_item(item); clear_item(item);
pw_array_clear(&impl->items); pw_array_clear(&impl->items);
free(impl); free(impl);
} }
static int do_replace(struct pw_properties *properties, const char *key, char *value) static int do_replace(struct pw_properties *properties, const char *key, char *value, bool copy)
{ {
struct properties *impl = SPA_CONTAINER_OF(properties, struct properties, this); struct properties *impl = SPA_CONTAINER_OF(properties, struct properties, this);
int index = find_index(properties, key); int index = find_index(properties, key);
if (index == -1) { if (index == -1) {
add_func(properties, strdup(key), value); if (value == NULL)
return 0;
add_func(properties, strdup(key), copy ? strdup(value) : value);
} else { } else {
struct spa_dict_item *item = struct spa_dict_item *item =
pw_array_get_unchecked(&impl->items, index, struct spa_dict_item); pw_array_get_unchecked(&impl->items, index, struct spa_dict_item);
clear_item(item); if (value && strcmp(item->value, value) == 0) {
if (!copy)
free(value);
return 0;
}
if (value == NULL) { if (value == NULL) {
struct spa_dict_item *other = pw_array_get_unchecked(&impl->items, struct spa_dict_item *other = pw_array_get_unchecked(&impl->items,
pw_array_get_len(&impl->items, struct spa_dict_item) - 1, pw_array_get_len(&impl->items, struct spa_dict_item) - 1,
struct spa_dict_item); struct spa_dict_item);
clear_item(item);
item->key = other->key; item->key = other->key;
item->value = other->value; item->value = other->value;
impl->items.size -= sizeof(struct spa_dict_item); impl->items.size -= sizeof(struct spa_dict_item);
} else { } else {
item->key = strdup(key); free((char *) item->value);
item->value = value; item->value = copy ? strdup(value) : value;
} }
} }
return 0; return 1;
} }
/** Set a property value /** Set a property value
@ -279,6 +288,9 @@ static int do_replace(struct pw_properties *properties, const char *key, char *v
* \param properties the properties to change * \param properties the properties to change
* \param key a key * \param key a key
* \param value a value or NULL to remove the key * \param value a value or NULL to remove the key
* \return 1 if the properties were changed. 0 if nothing was changed because
* the property already existed with the same value or because the key to remove
* did not exist.
* *
* Set the property in \a properties with \a key to \a value. Any previous value * Set the property in \a properties with \a key to \a value. Any previous value
* of \a key will be overwritten. When \a value is NULL, the key will be * of \a key will be overwritten. When \a value is NULL, the key will be
@ -288,7 +300,16 @@ static int do_replace(struct pw_properties *properties, const char *key, char *v
*/ */
int pw_properties_set(struct pw_properties *properties, const char *key, const char *value) int pw_properties_set(struct pw_properties *properties, const char *key, const char *value)
{ {
return do_replace(properties, key, value ? strdup(value) : NULL); return do_replace(properties, key, (char*)value, true);
}
int
pw_properties_setva(struct pw_properties *properties,
const char *key, const char *format, va_list args)
{
char *value;
vasprintf(&value, format, args);
return do_replace(properties, key, value, false);
} }
/** Set a property value by format /** Set a property value by format
@ -297,6 +318,8 @@ int pw_properties_set(struct pw_properties *properties, const char *key, const c
* \param key a key * \param key a key
* \param format a value * \param format a value
* \param ... extra arguments * \param ... extra arguments
* \return 1 if the properties were changed. 0 if nothing was changed because
* the property already existed with the same value.
* *
* Set the property in \a properties with \a key to the value in printf style \a format * Set the property in \a properties with \a key to the value in printf style \a format
* Any previous value of \a key will be overwritten. * Any previous value of \a key will be overwritten.
@ -305,14 +328,14 @@ int pw_properties_set(struct pw_properties *properties, const char *key, const c
*/ */
int pw_properties_setf(struct pw_properties *properties, const char *key, const char *format, ...) int pw_properties_setf(struct pw_properties *properties, const char *key, const char *format, ...)
{ {
int res;
va_list varargs; va_list varargs;
char *value;
va_start(varargs, format); va_start(varargs, format);
vasprintf(&value, format, varargs); res = pw_properties_setva(properties, key, format, varargs);
va_end(varargs); va_end(varargs);
return do_replace(properties, key, value); return res;
} }
/** Get a property /** Get a property