[pulseaudio-discuss] [PATCH v4 7/7] message-params: Add read/write functions for various simple data types
Georg Chini
georg at chini.tk
Sun Jan 28 17:40:29 UTC 2018
See doc/messaging_api.txt for the added functions. All read functions return
1 on success, 0 if an empty string or end of string is found and -1 on parse
error.
---
doc/messaging_api.txt | 9 +++
src/map-file | 9 +++
src/pulse/message-params.c | 163 ++++++++++++++++++++++++++++++++++++++++++++-
src/pulse/message-params.h | 27 ++++++++
4 files changed, 207 insertions(+), 1 deletion(-)
diff --git a/doc/messaging_api.txt b/doc/messaging_api.txt
index 0e6be53f..3c56dd97 100644
--- a/doc/messaging_api.txt
+++ b/doc/messaging_api.txt
@@ -27,6 +27,11 @@ the structure
pa_message_param_begin_list() - starts a list
pa_message_param_end_list() - ends a list
pa_message_param_write_string() - writes a string to a pa_message_param structure
+pa_message_param_write_double() - writes a double to a pa_message_param structure
+pa_message_param_write_int64() - writes an integer to a pa_message_param structure
+pa_message_param_write_uint64() - writes an unsigned to a pa_message_param structure
+pa_message_param_write_bool() - writes a boolean to a pa_message_param structure
+pa_message_param_write_raw() - writes raw a string to a pa_message_param structure
For string parameters that contain curly braces, those braces must be escaped
by adding a "\" before them. This however means that a trailing backslash would
@@ -44,6 +49,10 @@ Other strings can be passed without modification.
For reading, the following functions are available:
pa_message_param_split_list() - parse message parameter string
pa_message_param_read_string() - read a string from a parameter list
+pa_message_param_read_double() - read a double from a parameter list
+pa_message_param_read_int64() - read an integer from a parameter list
+pa_message_param_read_uint64() - read an unsigned from a parameter list
+pa_message_param_read_bool() - read a boolean from a parameter list
pa_message_param_read_string() also reverts the changes that
pa_message_param_write_string() might have introduced.
diff --git a/src/map-file b/src/map-file
index 372d190d..ab8c21c6 100644
--- a/src/map-file
+++ b/src/map-file
@@ -228,10 +228,19 @@ pa_mainloop_wakeup;
pa_message_param_begin_list;
pa_message_param_end_list;
pa_message_param_new;
+pa_message_param_read_bool;
+pa_message_param_read_double;
+pa_message_param_read_int64;
pa_message_param_read_string;
+pa_message_param_read_uint64;
pa_message_param_split_list;
pa_message_param_to_string;
+pa_message_param_write_bool;
+pa_message_param_write_double;
+pa_message_param_write_int64;
+pa_message_param_write_raw;
pa_message_param_write_string;
+pa_message_param_write_uint64;
pa_msleep;
pa_operation_cancel;
pa_operation_get_state;
diff --git a/src/pulse/message-params.c b/src/pulse/message-params.c
index c1abf62b..078e784b 100644
--- a/src/pulse/message-params.c
+++ b/src/pulse/message-params.c
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <locale.h>
#include <sys/types.h>
#include <pulse/xmalloc.h>
@@ -121,7 +122,7 @@ int pa_message_param_split_list(char *c, char **result, void **state) {
}
/* Read a string from the parameter list. The state pointer is
- * advanced to the next element of the list Escaping is removed
+ * advanced to the next element of the list. Escaping is removed
* from the string. */
int pa_message_param_read_string(char *c, char **result, void **state) {
char *start_pos;
@@ -161,6 +162,114 @@ int pa_message_param_read_string(char *c, char **result, void **state) {
return err;
}
+/* Read a double from the parameter list. The state pointer is
+ * advanced to the next element of the list. */
+int pa_message_param_read_double(char *c, double *result, void **state) {
+ char *start_pos, *s;
+ int err;
+ struct lconv *locale;
+
+ pa_assert(result);
+
+ *result = 0;
+
+ if ((err = pa_message_param_split_list(c, &start_pos, state)) <= 0)
+ return err;
+
+ /* Empty element */
+ if (strlen(start_pos) == 0)
+ return 0;
+
+ locale = localeconv();
+
+ /* Replace decimal point with the correct character for the
+ * current locale. This assumes that no thousand separator
+ * is used. */
+ for (s = start_pos; *s; s++) {
+ if (*s == '.' || *s == ',')
+ *s = *locale->decimal_point;
+ }
+
+ errno = 0;
+ *result = strtod(start_pos, NULL);
+
+ if (errno != 0)
+ return -1;
+
+ return 1;
+}
+
+/* Read an integer from the parameter list. The state pointer is
+ * advanced to the next element of the list. */
+int pa_message_param_read_int64(char *c, int64_t *result, void **state) {
+ char *start_pos;
+ int err;
+
+ pa_assert(result);
+
+ *result = 0;
+
+ if ((err = pa_message_param_split_list(c, &start_pos, state)) <= 0)
+ return err;
+
+ /* Empty element */
+ if (strlen(start_pos) == 0)
+ return 0;
+
+ errno = 0;
+ *result = strtol(start_pos, NULL, 0);
+
+ if (errno != 0)
+ return -1;
+
+ return 1;
+}
+
+/* Read an unsigned integer from the parameter list. The state pointer is
+ * advanced to the next element of the list. */
+int pa_message_param_read_uint64(char *c, uint64_t *result, void **state) {
+ char *start_pos;
+ int err;
+
+ pa_assert(result);
+
+ *result = 0;
+
+ if ((err = pa_message_param_split_list(c, &start_pos, state)) <= 0)
+ return err;
+
+ /* Empty element */
+ if (strlen(start_pos) == 0)
+ return 0;
+
+ errno = 0;
+ *result = strtoul(start_pos, NULL, 0);
+
+ if (errno != 0)
+ return -1;
+
+ return 1;
+}
+
+/* Read a boolean from the parameter list. The state pointer is
+ * advanced to the next element of the list. */
+int pa_message_param_read_bool(char *c, bool *result, void **state) {
+ int err;
+ uint64_t value;
+
+ pa_assert(result);
+
+ *result = false;
+
+ if ((err = pa_message_param_read_uint64(c, &value, state)) <= 0)
+ return err;
+
+ if (value)
+ *result = true;
+
+ return 1;
+}
+
/* Write functions. The functions are wrapper functions around pa_strbuf,
* so that the client does not need to use pa_strbuf directly. */
@@ -259,3 +368,55 @@ void pa_message_param_write_string(pa_message_param *param, const char *value, b
pa_strbuf_puts(param->buffer, output);
pa_xfree(output);
}
+
+/* Writes a raw string to the pa_message_param structure. This is needed
+ * if a string cannot be written in one step. */
+void pa_message_param_write_raw(pa_message_param *param, const char *value) {
+ pa_assert(param);
+
+ /* Null value is not written */
+ if (!value)
+ return;
+
+ pa_strbuf_puts(param->buffer, value);
+}
+
+/* Writes a double to a message_param structure, adding curly braces.
+ * precision gives the number of significant digits, not digits after
+ * the decimal point. */
+void pa_message_param_write_double(pa_message_param *param, double value, int precision) {
+
+ pa_assert(param);
+
+ /* We do not care about locale because we do not know which locale is
+ * used on the server side. The decimal point character is converted
+ * to the server locale by the read function. */
+ pa_strbuf_printf(param->buffer, "{%.*g}", precision, value);
+}
+
+/* Writes an integer to a message_param structure, adding curly braces. */
+void pa_message_param_write_int64(pa_message_param *param, int64_t value) {
+
+ pa_assert(param);
+
+ pa_strbuf_printf(param->buffer, "{%li}", value);
+}
+
+/* Writes an unsigned integer to a message_param structure, adding curly braces. */
+void pa_message_param_write_uint64(pa_message_param *param, uint64_t value) {
+
+ pa_assert(param);
+
+ pa_strbuf_printf(param->buffer, "{%lu}", value);
+}
+
+/* Writes a boolean to a message_param structure, adding curly braces. */
+void pa_message_param_write_bool(pa_message_param *param, bool value) {
+
+ pa_assert(param);
+
+ if (value)
+ pa_strbuf_puts(param->buffer, "{1}");
+ else
+ pa_strbuf_puts(param->buffer, "{0}");
+}
diff --git a/src/pulse/message-params.h b/src/pulse/message-params.h
index d24b4a54..c4b3554b 100644
--- a/src/pulse/message-params.h
+++ b/src/pulse/message-params.h
@@ -40,6 +40,18 @@ int pa_message_param_split_list(char *c, char **result, void **state);
/** Read a string from the parameter list. */
int pa_message_param_read_string(char *c, char **result, void **state);
+/** Read a double from the parameter list. */
+int pa_message_param_read_double(char *c, double *result, void **state);
+
+/** Read an integer from the parameter list. */
+int pa_message_param_read_int64(char *c, int64_t *result, void **state);
+
+/** Read an unsigned integer from the parameter list. */
+int pa_message_param_read_uint64(char *c, uint64_t *result, void **state);
+
+/** Read a boolean from the parameter list. */
+int pa_message_param_read_bool(char *c, bool *result, void **state);
+
/** Write functions */
/** Create a new pa_message_param structure */
@@ -57,6 +69,21 @@ void pa_message_param_end_list(pa_message_param *param);
/** Append string to parameter list */
void pa_message_param_write_string(pa_message_param *param, const char *value, bool do_escape);
+/** Append a double to parameter list */
+void pa_message_param_write_double(pa_message_param *param, double value, int precision);
+
+/** Append an integer to parameter list */
+void pa_message_param_write_int64(pa_message_param *param, int64_t value);
+
+/** Append an unsigned integer to parameter list */
+void pa_message_param_write_uint64(pa_message_param *param, uint64_t value);
+
+/** Append a boolean to parameter list */
+void pa_message_param_write_bool(pa_message_param *param, bool value);
+
+/** Append a raw string to parameter list */
+void pa_message_param_write_raw(pa_message_param *param, const char *value);
+
PA_C_DECL_END
#endif
--
2.14.1
More information about the pulseaudio-discuss
mailing list