aboutsummaryrefslogtreecommitdiffstats
path: root/src/audio_parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_parser.c')
-rw-r--r--src/audio_parser.c132
1 files changed, 102 insertions, 30 deletions
diff --git a/src/audio_parser.c b/src/audio_parser.c
index 906b0f819..7c0d45ddc 100644
--- a/src/audio_parser.c
+++ b/src/audio_parser.c
@@ -36,64 +36,136 @@ audio_parser_quark(void)
return g_quark_from_static_string("audio_parser");
}
-bool
-audio_format_parse(struct audio_format *dest, const char *src, GError **error)
+static bool
+parse_sample_rate(const char *src, bool mask, uint32_t *sample_rate_r,
+ const char **endptr_r, GError **error_r)
{
- char *endptr;
unsigned long value;
+ char *endptr;
- audio_format_clear(dest);
-
- /* parse sample rate */
+ if (mask && *src == '*') {
+ *sample_rate_r = 0;
+ *endptr_r = src + 1;
+ return true;
+ }
value = strtoul(src, &endptr, 10);
if (endptr == src) {
- g_set_error(error, audio_parser_quark(), 0,
- "Sample rate missing");
- return false;
- } else if (*endptr != ':') {
- g_set_error(error, audio_parser_quark(), 0,
- "Sample format missing");
+ g_set_error(error_r, audio_parser_quark(), 0,
+ "Failed to parse the sample rate");
return false;
} else if (!audio_valid_sample_rate(value)) {
- g_set_error(error, audio_parser_quark(), 0,
+ g_set_error(error_r, audio_parser_quark(), 0,
"Invalid sample rate: %lu", value);
return false;
}
- dest->sample_rate = value;
+ *sample_rate_r = value;
+ *endptr_r = endptr;
+ return true;
+}
- /* parse sample format */
+static bool
+parse_sample_format(const char *src, bool mask, uint8_t *bits_r,
+ const char **endptr_r, GError **error_r)
+{
+ unsigned long value;
+ char *endptr;
+
+ if (mask && *src == '*') {
+ *bits_r = 0;
+ *endptr_r = src + 1;
+ return true;
+ }
- src = endptr + 1;
value = strtoul(src, &endptr, 10);
if (endptr == src) {
- g_set_error(error, audio_parser_quark(), 0,
- "Sample format missing");
- return false;
- } else if (*endptr != ':') {
- g_set_error(error, audio_parser_quark(), 0,
- "Channel count missing");
+ g_set_error(error_r, audio_parser_quark(), 0,
+ "Failed to parse the sample format");
return false;
} else if (!audio_valid_sample_format(value)) {
- g_set_error(error, audio_parser_quark(), 0,
+ g_set_error(error_r, audio_parser_quark(), 0,
"Invalid sample format: %lu", value);
return false;
}
- dest->bits = value;
+ *bits_r = value;
+ *endptr_r = endptr;
+ return true;
+}
- /* parse channel count */
+static bool
+parse_channel_count(const char *src, bool mask, uint8_t *channels_r,
+ const char **endptr_r, GError **error_r)
+{
+ unsigned long value;
+ char *endptr;
+
+ if (mask && *src == '*') {
+ *channels_r = 0;
+ *endptr_r = src + 1;
+ return true;
+ }
- src = endptr + 1;
value = strtoul(src, &endptr, 10);
- if (*endptr != 0 || !audio_valid_channel_count(value)) {
- g_set_error(error, audio_parser_quark(), 0,
- "Invalid channel count: %s", src);
+ if (endptr == src) {
+ g_set_error(error_r, audio_parser_quark(), 0,
+ "Failed to parse the channel count");
+ return false;
+ } else if (!audio_valid_channel_count(value)) {
+ g_set_error(error_r, audio_parser_quark(), 0,
+ "Invalid channel count: %lu", value);
+ return false;
+ }
+
+ *channels_r = value;
+ *endptr_r = endptr;
+ return true;
+}
+
+bool
+audio_format_parse(struct audio_format *dest, const char *src,
+ bool mask, GError **error_r)
+{
+ uint32_t rate;
+ uint8_t bits, channels;
+
+ audio_format_clear(dest);
+
+ /* parse sample rate */
+
+ if (!parse_sample_rate(src, mask, &rate, &src, error_r))
+ return false;
+
+ if (*src++ != ':') {
+ g_set_error(error_r, audio_parser_quark(), 0,
+ "Sample format missing");
+ return false;
+ }
+
+ /* parse sample format */
+
+ if (!parse_sample_format(src, mask, &bits, &src, error_r))
+ return false;
+
+ if (*src++ != ':') {
+ g_set_error(error_r, audio_parser_quark(), 0,
+ "Channel count missing");
+ return false;
+ }
+
+ /* parse channel count */
+
+ if (!parse_channel_count(src, mask, &channels, &src, error_r))
+ return false;
+
+ if (*src != 0) {
+ g_set_error(error_r, audio_parser_quark(), 0,
+ "Extra data after channel count: %s", src);
return false;
}
- dest->channels = value;
+ audio_format_init(dest, rate, bits, channels);
return true;
}