mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	message-params: Add read functions for arrays
The following new functions have been added: pa_message_params_read_double_array() - read an array of double from list pa_message_params_read_int64_array() - read an array of int64 from list pa_message_params_read_uint64_array() - read an array of uint64 from list pa_message_params_read_string_array() - read an array of strings from list Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/51>
This commit is contained in:
		
							parent
							
								
									8140932afd
								
							
						
					
					
						commit
						ff64defc13
					
				
					 3 changed files with 204 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -235,10 +235,14 @@ pa_message_params_free;
 | 
			
		|||
pa_message_params_new;
 | 
			
		||||
pa_message_params_read_bool;
 | 
			
		||||
pa_message_params_read_double;
 | 
			
		||||
pa_message_params_read_double_array;
 | 
			
		||||
pa_message_params_read_int64;
 | 
			
		||||
pa_message_params_read_int64_array;
 | 
			
		||||
pa_message_params_read_raw;
 | 
			
		||||
pa_message_params_read_string;
 | 
			
		||||
pa_message_params_read_string_array;
 | 
			
		||||
pa_message_params_read_uint64;
 | 
			
		||||
pa_message_params_read_uint64_array;
 | 
			
		||||
pa_message_params_to_string_free;
 | 
			
		||||
pa_message_params_write_bool;
 | 
			
		||||
pa_message_params_write_double;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,61 @@ struct pa_message_params {
 | 
			
		|||
    pa_strbuf *buffer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Helper functions */
 | 
			
		||||
 | 
			
		||||
/* Count number of top level elements in parameter list */
 | 
			
		||||
static int count_elements(const char *c) {
 | 
			
		||||
    const char *s;
 | 
			
		||||
    uint32_t element_count;
 | 
			
		||||
    bool found_element, found_backslash;
 | 
			
		||||
    int open_braces;
 | 
			
		||||
 | 
			
		||||
    if (!c || *c == 0)
 | 
			
		||||
        return PA_MESSAGE_PARAMS_LIST_END;
 | 
			
		||||
 | 
			
		||||
    element_count = 0;
 | 
			
		||||
    open_braces = 0;
 | 
			
		||||
    found_element = false;
 | 
			
		||||
    found_backslash = false;
 | 
			
		||||
    s = c;
 | 
			
		||||
 | 
			
		||||
    /* Count elements in list */
 | 
			
		||||
    while (*s != 0) {
 | 
			
		||||
 | 
			
		||||
        /* Skip escaped curly braces. */
 | 
			
		||||
        if (*s == '\\' && !found_backslash) {
 | 
			
		||||
            found_backslash = true;
 | 
			
		||||
            s++;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (*s == '{' && !found_backslash) {
 | 
			
		||||
            found_element = true;
 | 
			
		||||
            open_braces++;
 | 
			
		||||
        }
 | 
			
		||||
        if (*s == '}' && !found_backslash)
 | 
			
		||||
            open_braces--;
 | 
			
		||||
 | 
			
		||||
        /* unexpected closing brace, parse error */
 | 
			
		||||
        if (open_braces < 0)
 | 
			
		||||
            return PA_MESSAGE_PARAMS_PARSE_ERROR;
 | 
			
		||||
 | 
			
		||||
        if (open_braces == 0 && found_element) {
 | 
			
		||||
            element_count++;
 | 
			
		||||
            found_element = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        found_backslash = false;
 | 
			
		||||
        s++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* missing closing brace, parse error */
 | 
			
		||||
    if (open_braces > 0)
 | 
			
		||||
        return PA_MESSAGE_PARAMS_PARSE_ERROR;
 | 
			
		||||
 | 
			
		||||
    return element_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Split the specified string into elements. An element is defined as
 | 
			
		||||
 * a sub-string between curly braces. The function is needed to parse
 | 
			
		||||
 * the parameters of messages. Each time it is called it returns the
 | 
			
		||||
| 
						 | 
				
			
			@ -188,7 +243,7 @@ int pa_message_params_read_double(char *c, double *result, void **state) {
 | 
			
		|||
    if (!is_unpacked)
 | 
			
		||||
        return PA_MESSAGE_PARAMS_PARSE_ERROR;
 | 
			
		||||
 | 
			
		||||
    /* Convert to double */
 | 
			
		||||
    /* Get decimal separator for current locale */
 | 
			
		||||
    locale = localeconv();
 | 
			
		||||
 | 
			
		||||
    /* Replace decimal point with the correct character for the
 | 
			
		||||
| 
						 | 
				
			
			@ -289,6 +344,122 @@ int pa_message_params_read_bool(char *c, bool *result, void **state) {
 | 
			
		|||
    return PA_MESSAGE_PARAMS_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Converts a parameter list to a string array. Escaping is removed from
 | 
			
		||||
 * the strings. Returns an array of pointers to sub-strings within c in
 | 
			
		||||
 * *results. The returned array must be freed, but not the strings
 | 
			
		||||
 * within the array. The function returns the number of strings in the
 | 
			
		||||
 * array. */
 | 
			
		||||
int pa_message_params_read_string_array(char *c, const char ***results) {
 | 
			
		||||
    void *state = NULL;
 | 
			
		||||
    uint32_t element_count, i;
 | 
			
		||||
    int err;
 | 
			
		||||
    const char **values;
 | 
			
		||||
 | 
			
		||||
    pa_assert(results);
 | 
			
		||||
 | 
			
		||||
    /* Count elements, return if no element was found or parse error. */
 | 
			
		||||
    if ((element_count = count_elements(c)) <= 0)
 | 
			
		||||
        return element_count;
 | 
			
		||||
 | 
			
		||||
    /* Allocate array */
 | 
			
		||||
    values = pa_xmalloc0(element_count * sizeof(char *));
 | 
			
		||||
 | 
			
		||||
    for (i = 0; (err = pa_message_params_read_string(c, &(values[i]), &state)) > 0; i++)
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
    if (err < 0) {
 | 
			
		||||
        pa_xfree(values);
 | 
			
		||||
        return PA_MESSAGE_PARAMS_PARSE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *results = values;
 | 
			
		||||
    return element_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Converts a parameter list to a double array. */
 | 
			
		||||
int pa_message_params_read_double_array(char *c, double **results) {
 | 
			
		||||
    double  *values;
 | 
			
		||||
    void *state = NULL;
 | 
			
		||||
    uint32_t element_count, i;
 | 
			
		||||
    int err;
 | 
			
		||||
 | 
			
		||||
    pa_assert(results);
 | 
			
		||||
 | 
			
		||||
    /* Count elements, return if no element was found or parse error. */
 | 
			
		||||
    if ((element_count = count_elements(c)) <= 0)
 | 
			
		||||
        return element_count;
 | 
			
		||||
 | 
			
		||||
    /* Allocate array */
 | 
			
		||||
    values = pa_xmalloc0(element_count * sizeof(double));
 | 
			
		||||
 | 
			
		||||
    for (i = 0; (err = pa_message_params_read_double(c, &(values[i]), &state)) > 0; i++)
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
    if (err < 0) {
 | 
			
		||||
        pa_xfree(values);
 | 
			
		||||
        return PA_MESSAGE_PARAMS_PARSE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *results = values;
 | 
			
		||||
    return element_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Converts a parameter list to an int64 array. */
 | 
			
		||||
int pa_message_params_read_int64_array(char *c, int64_t **results) {
 | 
			
		||||
    int64_t  *values;
 | 
			
		||||
    void *state = NULL;
 | 
			
		||||
    uint32_t element_count, i;
 | 
			
		||||
    int err;
 | 
			
		||||
 | 
			
		||||
    pa_assert(results);
 | 
			
		||||
 | 
			
		||||
    /* Count elements, return if no element was found or parse error. */
 | 
			
		||||
    if ((element_count = count_elements(c)) <= 0)
 | 
			
		||||
        return element_count;
 | 
			
		||||
 | 
			
		||||
    /* Allocate array */
 | 
			
		||||
    values = pa_xmalloc0(element_count * sizeof(int64_t));
 | 
			
		||||
 | 
			
		||||
    for (i = 0; (err = pa_message_params_read_int64(c, &(values[i]), &state)) > 0; i++)
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
    if (err < 0) {
 | 
			
		||||
        pa_xfree(values);
 | 
			
		||||
        return PA_MESSAGE_PARAMS_PARSE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *results = values;
 | 
			
		||||
    return element_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Converts a parameter list to an uint64 array. */
 | 
			
		||||
int pa_message_params_read_uint64_array(char *c, uint64_t **results) {
 | 
			
		||||
    uint64_t  *values;
 | 
			
		||||
    void *state = NULL;
 | 
			
		||||
    uint32_t element_count, i;
 | 
			
		||||
    int err;
 | 
			
		||||
 | 
			
		||||
    pa_assert(results);
 | 
			
		||||
 | 
			
		||||
    /* Count elements, return if no element was found or parse error. */
 | 
			
		||||
    if ((element_count = count_elements(c)) <= 0)
 | 
			
		||||
        return element_count;
 | 
			
		||||
 | 
			
		||||
    /* Allocate array */
 | 
			
		||||
    values = pa_xmalloc0(element_count * sizeof(uint64_t));
 | 
			
		||||
 | 
			
		||||
    for (i = 0; (err = pa_message_params_read_uint64(c, &(values[i]), &state)) > 0; i++)
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
    if (err < 0) {
 | 
			
		||||
        pa_xfree(values);
 | 
			
		||||
        return PA_MESSAGE_PARAMS_PARSE_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *results = values;
 | 
			
		||||
    return element_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Write functions. The functions are wrapper functions around pa_strbuf,
 | 
			
		||||
 * so that the client does not need to use pa_strbuf directly. */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,12 @@
 | 
			
		|||
 * the callback, it must be copied using pa_xstrdup().
 | 
			
		||||
 * When a read function is called, the state pointer is advanced to the
 | 
			
		||||
 * next list element. The variable state points to should be initialized
 | 
			
		||||
 * to NULL before the first call.\n
 | 
			
		||||
 * to NULL before the first call.
 | 
			
		||||
 * All read functions except read_raw() preserve a default value passed
 | 
			
		||||
 * in result if the call fails. For the array functions, results must be
 | 
			
		||||
 * initialized prior to the call either to NULL or to an array with default
 | 
			
		||||
 * values. If the function succeeds, the default array will be freed and
 | 
			
		||||
 * the number of elements in the result array is returned.\n\n
 | 
			
		||||
 * Write functions operate on a pa_message_params structure which is a
 | 
			
		||||
 * wrapper for pa_strbuf. A parameter list or sub-list is started by a
 | 
			
		||||
 * call to begin_list() and ended by a call to end_list().
 | 
			
		||||
| 
						 | 
				
			
			@ -69,9 +74,19 @@ int pa_message_params_read_bool(char *c, bool *result, void **state);
 | 
			
		|||
/** Read a double from parameter list in c. \since 15.0 */
 | 
			
		||||
int pa_message_params_read_double(char *c, double *result, void **state);
 | 
			
		||||
 | 
			
		||||
/** Converts a parameter list to a double array. Empty elements in the parameter
 | 
			
		||||
 * list are treated as error. Before the call, results must be initialized, either
 | 
			
		||||
 * to NULL or to an array with default values. \since 15.0 */
 | 
			
		||||
int pa_message_params_read_double_array(char *c, double **results);
 | 
			
		||||
 | 
			
		||||
/** Read an integer from parameter list in c. \since 15.0 */
 | 
			
		||||
int pa_message_params_read_int64(char *c, int64_t *result, void **state);
 | 
			
		||||
 | 
			
		||||
/** Converts a parameter list to an int64 array. Empty elements in the parameter
 | 
			
		||||
 * list are treated as error. Before the call, results must be initialized, either
 | 
			
		||||
 * to NULL or to an array with default values. \since 15.0 */
 | 
			
		||||
int pa_message_params_read_int64_array(char *c, int64_t **results);
 | 
			
		||||
 | 
			
		||||
/** Read raw data from parameter list in c. Used to split a message parameter
 | 
			
		||||
 * string into list elements. The string returned in *result must not be freed.  \since 15.0 */
 | 
			
		||||
int pa_message_params_read_raw(char *c, char **result, void **state);
 | 
			
		||||
| 
						 | 
				
			
			@ -80,9 +95,21 @@ int pa_message_params_read_raw(char *c, char **result, void **state);
 | 
			
		|||
 * will be unescaped. \since 15.0 */
 | 
			
		||||
int pa_message_params_read_string(char *c, const char **result, void **state);
 | 
			
		||||
 | 
			
		||||
/** Convert a parameter list to a string array. Escaping is removed from
 | 
			
		||||
 * the strings. Returns an array of pointers to sub-strings within c in
 | 
			
		||||
 * *results. The returned array must be freed, but not the strings
 | 
			
		||||
 * within the array. Before the call, results must be initialized, either
 | 
			
		||||
 * to NULL or to an array with default values. \since 15.0 */
 | 
			
		||||
int pa_message_params_read_string_array(char *c, const char ***results);
 | 
			
		||||
 | 
			
		||||
/** Read an unsigned integer from parameter list in c. \since 15.0 */
 | 
			
		||||
int pa_message_params_read_uint64(char *c, uint64_t *result, void **state);
 | 
			
		||||
 | 
			
		||||
/** Converts a parameter list to an uint64 array. Empty elements in the parameter
 | 
			
		||||
 * list are treated as error. Before the call, results must be initialized, either
 | 
			
		||||
 * to NULL or to an array with default values. \since 15.0 */
 | 
			
		||||
int pa_message_params_read_uint64_array(char *c, uint64_t **results);
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
 | 
			
		||||
/** @{ \name Write functions */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue