utils: add some utility functions for working with strv

Add function to parse strv from relaxed json syntax.
Add some functions to find a string or the first common string.
This commit is contained in:
Wim Taymans 2023-10-31 10:57:25 +01:00
parent 9cdb3607e1
commit 72fa74ff57
2 changed files with 93 additions and 1 deletions

View file

@ -13,6 +13,8 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <spa/utils/json.h>
#include <pipewire/array.h> #include <pipewire/array.h>
#include <pipewire/log.h> #include <pipewire/log.h>
#include <pipewire/utils.h> #include <pipewire/utils.h>
@ -74,6 +76,7 @@ char **pw_split_strv(const char *str, const char *delimiter, int max_tokens, int
} }
pw_array_add_ptr(&arr, NULL); pw_array_add_ptr(&arr, NULL);
if (n_tokens != NULL)
*n_tokens = n; *n_tokens = n;
return arr.data; return arr.data;
@ -110,6 +113,89 @@ int pw_split_ip(char *str, const char *delimiter, int max_tokens, char *tokens[]
return n; return n;
} }
/** Parse an array of strings
* \param val a string to parse
* \param len the length of \a val
* \param max_tokens the max number of tokens to split
* \param[out] n_tokens the number of tokens, may be NULL
* \return a NULL terminated array of strings that should be
* freed with \ref pw_free_strv.
*
* \a val is parsed using relaxed json syntax.
*
* \since 0.3.84
*/
SPA_EXPORT
char **pw_strv_parse(const char *val, size_t len, int max_tokens, int *n_tokens)
{
struct pw_array arr;
struct spa_json it[2];
char v[256];
int n = 0;
if (val == NULL)
return NULL;
pw_array_init(&arr, 16);
spa_json_init(&it[0], val, len);
if (spa_json_enter_array(&it[0], &it[1]) <= 0)
spa_json_init(&it[1], val, len);
while (spa_json_get_string(&it[1], v, sizeof(v)) > 0 && n + 1 < max_tokens) {
pw_array_add_ptr(&arr, strdup(v));
n++;
}
pw_array_add_ptr(&arr, NULL);
if (n_tokens != NULL)
*n_tokens = n;
return arr.data;
}
/** Find a string in a NULL terminated array of strings.
* \param a a strv to check
* \param b the string to find
* \return the index in \a a where \a b is found or < 0 if not.
*
* \since 0.3.84
*/
SPA_EXPORT
int pw_strv_find(char **a, char *b)
{
int i;
if (a == NULL || b == NULL)
return -EINVAL;
for (i = 0; a[i]; i++) {
if (spa_streq(a[i], b))
return i;
}
return -ENOENT;
}
/** Check if two NULL terminated arrays of strings have a common string.
* \param a a strv to check
* \param b another strv to check
* \return the index in \a a of the first common string or < 0 if not.
*
* \since 0.3.84
*/
SPA_EXPORT
int pw_strv_find_common(char **a, char **b)
{
int i;
if (a == NULL || b == NULL)
return -EINVAL;
for (i = 0; a[i]; i++) {
if (pw_strv_find(b, a[i]) >= 0)
return i;
}
return -ENOENT;
}
/** Free a NULL terminated array of strings /** Free a NULL terminated array of strings
* \param str a NULL terminated array of string * \param str a NULL terminated array of string
* *

View file

@ -46,6 +46,12 @@ pw_split_strv(const char *str, const char *delimiter, int max_tokens, int *n_tok
int int
pw_split_ip(char *str, const char *delimiter, int max_tokens, char *tokens[]); pw_split_ip(char *str, const char *delimiter, int max_tokens, char *tokens[]);
char **pw_strv_parse(const char *val, size_t len, int max_tokens, int *n_tokens);
int pw_strv_find(char **a, char *b);
int pw_strv_find_common(char **a, char **b);
void void
pw_free_strv(char **str); pw_free_strv(char **str);