diff --git a/src/pipewire/properties.c b/src/pipewire/properties.c index 3de43e8e9..09571d45b 100644 --- a/src/pipewire/properties.c +++ b/src/pipewire/properties.c @@ -145,41 +145,64 @@ struct pw_properties *pw_properties_new_dict(const struct spa_dict *dict) return &impl->this; } -static struct pw_properties * -properties_new_string(const char *str) +SPA_EXPORT +int pw_properties_update_string(struct pw_properties *props, const char *str, size_t size) { - struct properties *impl; - const char *state = NULL, *s = NULL; - size_t len; - int res; + struct properties *impl = SPA_CONTAINER_OF(props, struct properties, this); + struct spa_json it[2]; + int count = 0; - impl = properties_new(16); - if (impl == NULL) - return NULL; + spa_json_init(&it[0], str, size); + if (spa_json_enter_object(&it[0], &it[1]) > 0) { + char key[1024], *val; - s = pw_split_walk(str, " \t\n\r", &len, &state); - while (s) { - char *val, *eq; + while (spa_json_get_string(&it[1], key, sizeof(key)-1)) { + int len; + const char *value; - if ((val = strndup(s, len)) == NULL) - goto error_errno; + if ((len = spa_json_next(&it[1], &value)) <= 0) + break; - eq = strchr(val, '='); - if (eq && eq != val) { - *eq = '\0'; - add_func(&impl->this, val, strdup(eq+1)); - } else { + if (key[0] == '#') + continue; + if (spa_json_is_null(value, len)) + val = NULL; + else { + if (spa_json_is_container(value, len)) + len = spa_json_container_len(&it[1], value, len); + + if ((val = strndup(value, len)) == NULL) + return -errno; + + if (spa_json_is_string(value, len)) + spa_json_parse_string(value, len, val); + } + count += pw_properties_set(&impl->this, key, val); free(val); } - s = pw_split_walk(str, " \t\n\r", &len, &state); - } - return &impl->this; + } else { + const char *state = NULL, *s = NULL; + size_t len; -error_errno: - res = -errno; - pw_properties_free(&impl->this); - errno = -res; - return NULL; + s = pw_split_walk(str, " \t\n\r", &len, &state); + while (s) { + char *val, *eq; + + if (s[0] == '#') + continue; + if ((val = strndup(s, len)) == NULL) + return -errno; + + eq = strchr(val, '='); + if (eq && eq != val) { + *eq = '\0'; + count += pw_properties_set(&impl->this, val, eq+1); + } + free(val); + s = pw_split_walk(str, " \t\n\r", &len, &state); + } + } + return count; } /** Make a new properties object from the given str @@ -197,39 +220,17 @@ struct pw_properties * pw_properties_new_string(const char *object) { struct properties *impl; - struct spa_json it[2]; - char key[256], *val; int res; - spa_json_init(&it[0], object, strlen(object)); - if (spa_json_enter_object(&it[0], &it[1]) < 0) - return properties_new_string(object); - impl = properties_new(16); if (impl == NULL) return NULL; - while (spa_json_get_string(&it[1], key, sizeof(key)-1)) { - int len; - const char *value; + if ((res = pw_properties_update_string(&impl->this, object, strlen(object))) < 0) + goto error; - if ((len = spa_json_next(&it[1], &value)) <= 0) - break; - - if (spa_json_is_container(value, len)) - len = spa_json_container_len(&it[1], value, len); - - if ((val = strndup(value, len)) == NULL) - goto error_errno; - - if (spa_json_is_string(value, len)) - spa_json_parse_string(value, len, val); - - add_func(&impl->this, strdup(key), val); - } return &impl->this; -error_errno: - res = errno; +error: pw_properties_free(&impl->this); errno = -res; return NULL; diff --git a/src/pipewire/properties.h b/src/pipewire/properties.h index 4574b1fcc..120bbf423 100644 --- a/src/pipewire/properties.h +++ b/src/pipewire/properties.h @@ -64,6 +64,8 @@ int pw_properties_update_keys(struct pw_properties *props, int pw_properties_update(struct pw_properties *oldprops, const struct spa_dict *dict); +int pw_properties_update_string(struct pw_properties *props, + const char *str, size_t size); int pw_properties_add(struct pw_properties *oldprops, const struct spa_dict *dict); diff --git a/src/tests/test-properties.c b/src/tests/test-properties.c index bcbf29826..5d631e40f 100644 --- a/src/tests/test-properties.c +++ b/src/tests/test-properties.c @@ -317,7 +317,7 @@ static void test_new_json(void) props = pw_properties_new_string("{ \"foo\": \"bar\\n\\t\", \"bar\": 1.8, \"empty\": [ \"foo\", \"bar\" ], \"\": \"gg\""); spa_assert(props != NULL); spa_assert(props->flags == 0); - spa_assert(props->dict.n_items == 4); + spa_assert(props->dict.n_items == 3); spa_assert(!strcmp(pw_properties_get(props, "foo"), "bar\n\t")); spa_assert(!strcmp(pw_properties_get(props, "bar"), "1.8"));