[pulseaudio-commits] [SCM] PulseAudio Sound Server branch, master, updated. v0.9.13-493-gf6ec971
Lennart Poettering
gitmailer-noreply at 0pointer.de
Wed Feb 4 08:21:27 PST 2009
This is an automated email from the git hooks/post-receive script. It was
generated because of a push to the "PulseAudio Sound Server" repository.
The master branch has been updated
from 921882de548e17bbdd79bd8eb2c2ce7d36412cf4 (commit)
- Log -----------------------------------------------------------------
f6ec971... clarify things a bit
12b7359... add a few additional validity checks
83ddc09... add new calls pa_replace() and pa_unescape()
a625ca7... make gcc shut up
078a8d5... rearrange a few things
d6dd907... simplify code a bit by using pa_sample_size_of_format()
a6fe991... beef up proplist test a bit
9a27b8f... in addition to per-property env vars PULSE_PROP_xxx look for for a stringified PULSE_PROP env var
b445741... fix up parser in pa_proplist_from_string() to handle escapes correctly; make pa_proplist_to_string() escape quotes properly
0fc59e4... add new API pa_ascii_valid(), pa_ascii_filter()
ce76216... add pa_sample_size_of_format()
32e5e64... add a lot of validity checking
b51ed38... add a bit of missing i18n
543115a... add new API pa_cvolume_compatible_with_channel_map()
-----------------------------------------------------------------------
Summary of changes:
src/map-file | 4 +
src/pulse/channelmap.c | 49 ++++--
src/pulse/ext-stream-restore.c | 48 +++++-
src/pulse/ext-stream-restore.h | 8 +-
src/pulse/operation.c | 1 +
src/pulse/proplist.c | 384 ++++++++++++++++++++++++++++++++--------
src/pulse/proplist.h | 2 +-
src/pulse/sample.c | 38 +++-
src/pulse/sample.h | 4 +
src/pulse/utf8.c | 26 +++
src/pulse/utf8.h | 6 +
src/pulse/volume.c | 62 ++++++--
src/pulse/volume.h | 8 +-
src/pulsecore/core-util.c | 47 +++++
src/pulsecore/core-util.h | 4 +
src/pulsecore/envelope.c | 7 +
src/pulsecore/modargs.c | 179 ++++++++++---------
src/pulsecore/proplist-util.c | 10 +
src/pulsecore/resampler.c | 12 +--
src/tests/proplist-test.c | 19 ++-
20 files changed, 692 insertions(+), 226 deletions(-)
-----------------------------------------------------------------------
commit 543115ae1726e853624a6214ad58187f6d84c95a
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Feb 3 21:15:32 2009 +0100
add new API pa_cvolume_compatible_with_channel_map()
diff --git a/src/map-file b/src/map-file
index 3aa1d7a..d7addfe 100644
--- a/src/map-file
+++ b/src/map-file
@@ -109,6 +109,7 @@ pa_context_unref;
pa_cvolume_avg;
pa_cvolume_channels_equal_to;
pa_cvolume_compatible;
+pa_cvolume_compatible_with_channel_map;
pa_cvolume_equal;
pa_cvolume_get_balance;
pa_cvolume_get_fade;
diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index 01a28e8..e920288 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -428,6 +428,19 @@ int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) {
return v->channels == ss->channels;
}
+int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel_map *cm) {
+ pa_assert(v);
+ pa_assert(cm);
+
+ if (!pa_cvolume_valid(v))
+ return 0;
+
+ if (!pa_channel_map_valid(cm))
+ return 0;
+
+ return v->channels == cm->channels;
+}
+
static void get_avg_lr(const pa_channel_map *map, const pa_cvolume *v, pa_volume_t *l, pa_volume_t *r) {
int c;
pa_volume_t left = 0, right = 0;
diff --git a/src/pulse/volume.h b/src/pulse/volume.h
index 9ad3e9b..8bfd068 100644
--- a/src/pulse/volume.h
+++ b/src/pulse/volume.h
@@ -230,10 +230,14 @@ double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST;
/** Remap a volume from one channel mapping to a different channel mapping. \since 0.9.12 */
pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa_channel_map *to);
-/** Return non-zero if the specified volume is compatible with
- * the specified sample spec. \since 0.9.13 */
+/** Return non-zero if the specified volume is compatible with the
+ * specified sample spec. \since 0.9.13 */
int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) PA_GCC_PURE;
+/** Return non-zero if the specified volume is compatible with the
+ * specified sample spec. \since 0.9.15 */
+int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel_map *cm) PA_GCC_PURE;
+
/** Calculate a 'balance' value for the specified volume with the
* specified channel map. The return value will range from -1.0f
* (left) to +1.0f (right). If no balance value is applicable to this
commit b51ed381162b43e55c665dbdb61e2ce4a796a4df
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Feb 3 21:56:52 2009 +0100
add a bit of missing i18n
diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c
index 6ff30c2..43e5f83 100644
--- a/src/pulse/channelmap.c
+++ b/src/pulse/channelmap.c
@@ -434,11 +434,11 @@ const char* pa_channel_position_to_string(pa_channel_position_t pos) {
const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos) {
- pa_init_i18n();
-
if (pos < 0 || pos >= PA_CHANNEL_POSITION_MAX)
return NULL;
+ pa_init_i18n();
+
return _(pretty_table[pos]);
}
@@ -502,19 +502,19 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
* "mono" here explicitly, because that can be understood as
* listing with one channel called "mono". */
- if (strcmp(s, "stereo") == 0) {
+ if (pa_streq(s, "stereo")) {
map.channels = 2;
map.map[0] = PA_CHANNEL_POSITION_LEFT;
map.map[1] = PA_CHANNEL_POSITION_RIGHT;
goto finish;
- } else if (strcmp(s, "surround-40") == 0) {
+ } else if (pa_streq(s, "surround-40")) {
map.channels = 4;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
map.map[2] = PA_CHANNEL_POSITION_REAR_LEFT;
map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
goto finish;
- } else if (strcmp(s, "surround-41") == 0) {
+ } else if (pa_streq(s, "surround-41")) {
map.channels = 5;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
@@ -522,7 +522,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
map.map[4] = PA_CHANNEL_POSITION_LFE;
goto finish;
- } else if (strcmp(s, "surround-50") == 0) {
+ } else if (pa_streq(s, "surround-50")) {
map.channels = 5;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
@@ -530,7 +530,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
map.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT;
map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
goto finish;
- } else if (strcmp(s, "surround-51") == 0) {
+ } else if (pa_streq(s, "surround-51")) {
map.channels = 6;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
@@ -539,7 +539,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
map.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER;
map.map[5] = PA_CHANNEL_POSITION_LFE;
goto finish;
- } else if (strcmp(s, "surround-71") == 0) {
+ } else if (pa_streq(s, "surround-71")) {
map.channels = 8;
map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
@@ -563,13 +563,13 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
}
/* Some special aliases */
- if (strcmp(p, "left") == 0)
+ if (pa_streq(p, "left"))
map.map[map.channels++] = PA_CHANNEL_POSITION_LEFT;
- else if (strcmp(p, "right") == 0)
+ else if (pa_streq(p, "right"))
map.map[map.channels++] = PA_CHANNEL_POSITION_RIGHT;
- else if (strcmp(p, "center") == 0)
+ else if (pa_streq(p, "center"))
map.map[map.channels++] = PA_CHANNEL_POSITION_CENTER;
- else if (strcmp(p, "subwoofer") == 0)
+ else if (pa_streq(p, "subwoofer"))
map.map[map.channels++] = PA_CHANNEL_POSITION_SUBWOOFER;
else {
pa_channel_position_t i;
@@ -784,6 +784,8 @@ const char* pa_channel_map_to_pretty_name(const pa_channel_map *map) {
for (c = 0; c < map->channels; c++)
pa_bitset_set(in_map, map->map[c], TRUE);
+ pa_init_i18n();
+
if (pa_bitset_equals(in_map, PA_CHANNEL_POSITION_MAX,
PA_CHANNEL_POSITION_MONO, -1))
return _("Mono");
diff --git a/src/pulse/sample.c b/src/pulse/sample.c
index a6c7734..5528a59 100644
--- a/src/pulse/sample.c
+++ b/src/pulse/sample.c
@@ -151,22 +151,25 @@ char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) {
if (!pa_sample_spec_valid(spec))
pa_snprintf(s, l, _("(invalid)"));
else
- pa_snprintf(s, l, "%s %uch %uHz", pa_sample_format_to_string(spec->format), spec->channels, spec->rate);
+ pa_snprintf(s, l, _("%s %uch %uHz"), pa_sample_format_to_string(spec->format), spec->channels, spec->rate);
return s;
}
char* pa_bytes_snprint(char *s, size_t l, unsigned v) {
pa_assert(s);
+ pa_assert(l > 0);
+
+ pa_init_i18n();
if (v >= ((unsigned) 1024)*1024*1024)
- pa_snprintf(s, l, "%0.1f GiB", ((double) v)/1024/1024/1024);
+ pa_snprintf(s, l, _("%0.1f GiB"), ((double) v)/1024/1024/1024);
else if (v >= ((unsigned) 1024)*1024)
- pa_snprintf(s, l, "%0.1f MiB", ((double) v)/1024/1024);
+ pa_snprintf(s, l, _("%0.1f MiB"), ((double) v)/1024/1024);
else if (v >= (unsigned) 1024)
- pa_snprintf(s, l, "%0.1f KiB", ((double) v)/1024);
+ pa_snprintf(s, l, _("%0.1f KiB"), ((double) v)/1024);
else
- pa_snprintf(s, l, "%u B", (unsigned) v);
+ pa_snprintf(s, l, _("%u B"), (unsigned) v);
return s;
}
commit 32e5e64921febb219c0b7ed8ca7da141b4ad0f23
Author: Lennart Poettering <lennart at poettering.net>
Date: Tue Feb 3 21:57:58 2009 +0100
add a lot of validity checking
diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c
index 43e5f83..983b897 100644
--- a/src/pulse/channelmap.c
+++ b/src/pulse/channelmap.c
@@ -448,6 +448,9 @@ int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) {
pa_assert(a);
pa_assert(b);
+ pa_return_val_if_fail(pa_channel_map_valid(a), 0);
+ pa_return_val_if_fail(pa_channel_map_valid(b), 0);
+
if (a->channels != b->channels)
return 0;
@@ -617,11 +620,8 @@ int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *s
pa_assert(map);
pa_assert(ss);
- if (!pa_channel_map_valid(map))
- return 0;
-
- if (!pa_sample_spec_valid(ss))
- return 0;
+ pa_return_val_if_fail(pa_channel_map_valid(map), 0);
+ pa_return_val_if_fail(pa_sample_spec_valid(ss), 0);
return map->channels == ss->channels;
}
@@ -633,6 +633,9 @@ int pa_channel_map_superset(const pa_channel_map *a, const pa_channel_map *b) {
pa_assert(a);
pa_assert(b);
+ pa_return_val_if_fail(pa_channel_map_valid(a), 0);
+ pa_return_val_if_fail(pa_channel_map_valid(b), 0);
+
memset(in_a, 0, sizeof(in_a));
for (i = 0; i < a->channels; i++)
@@ -651,6 +654,8 @@ int pa_channel_map_can_balance(const pa_channel_map *map) {
pa_assert(map);
+ pa_return_val_if_fail(pa_channel_map_valid(map), 0);
+
for (c = 0; c < map->channels; c++) {
switch (map->map[c]) {
@@ -687,6 +692,10 @@ int pa_channel_map_can_fade(const pa_channel_map *map) {
unsigned c;
pa_bool_t front = FALSE, rear = FALSE;
+ pa_assert(map);
+
+ pa_return_val_if_fail(pa_channel_map_valid(map), 0);
+
for (c = 0; c < map->channels; c++) {
switch (map->map[c]) {
@@ -727,6 +736,8 @@ const char* pa_channel_map_to_name(const pa_channel_map *map) {
pa_assert(map);
+ pa_return_val_if_fail(pa_channel_map_valid(map), NULL);
+
memset(in_map, 0, sizeof(in_map));
for (c = 0; c < map->channels; c++)
@@ -779,6 +790,8 @@ const char* pa_channel_map_to_pretty_name(const pa_channel_map *map) {
pa_assert(map);
+ pa_return_val_if_fail(pa_channel_map_valid(map), NULL);
+
memset(in_map, 0, sizeof(in_map));
for (c = 0; c < map->channels; c++)
diff --git a/src/pulse/sample.c b/src/pulse/sample.c
index 5528a59..ff86d0b 100644
--- a/src/pulse/sample.c
+++ b/src/pulse/sample.c
@@ -55,31 +55,35 @@ size_t pa_sample_size(const pa_sample_spec *spec) {
};
pa_assert(spec);
- pa_assert(spec->format >= 0);
- pa_assert(spec->format < PA_SAMPLE_MAX);
+ pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
return table[spec->format];
}
size_t pa_frame_size(const pa_sample_spec *spec) {
pa_assert(spec);
+ pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
return pa_sample_size(spec) * spec->channels;
}
size_t pa_bytes_per_second(const pa_sample_spec *spec) {
pa_assert(spec);
+ pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
+
return spec->rate*pa_frame_size(spec);
}
pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) {
pa_assert(spec);
+ pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
return (((pa_usec_t) (length / pa_frame_size(spec)) * PA_USEC_PER_SEC) / spec->rate);
}
size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) {
pa_assert(spec);
+ pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
return (size_t) (((t * spec->rate) / PA_USEC_PER_SEC)) * pa_frame_size(spec);
}
@@ -112,6 +116,9 @@ int pa_sample_spec_equal(const pa_sample_spec*a, const pa_sample_spec*b) {
pa_assert(a);
pa_assert(b);
+ pa_return_val_if_fail(pa_sample_spec_valid(a), 0);
+ pa_return_val_if_fail(pa_sample_spec_valid(b), 0);
+
return
(a->format == b->format) &&
(a->rate == b->rate) &&
@@ -143,7 +150,7 @@ const char *pa_sample_format_to_string(pa_sample_format_t f) {
char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) {
pa_assert(s);
- pa_assert(l);
+ pa_assert(l > 0);
pa_assert(spec);
pa_init_i18n();
diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index e920288..54838e8 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -37,6 +37,9 @@ int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) {
pa_assert(a);
pa_assert(b);
+ pa_return_val_if_fail(pa_cvolume_valid(a), 0);
+ pa_return_val_if_fail(pa_cvolume_valid(b), 0);
+
if (a->channels != b->channels)
return 0;
@@ -78,7 +81,9 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) {
pa_volume_t pa_cvolume_avg(const pa_cvolume *a) {
uint64_t sum = 0;
int i;
+
pa_assert(a);
+ pa_return_val_if_fail(pa_cvolume_valid(a), PA_VOLUME_MUTED);
for (i = 0; i < a->channels; i++)
sum += a->values[i];
@@ -91,7 +96,9 @@ pa_volume_t pa_cvolume_avg(const pa_cvolume *a) {
pa_volume_t pa_cvolume_max(const pa_cvolume *a) {
pa_volume_t m = 0;
int i;
+
pa_assert(a);
+ pa_return_val_if_fail(pa_cvolume_valid(a), PA_VOLUME_MUTED);
for (i = 0; i < a->channels; i++)
if (a->values[i] > m)
@@ -247,11 +254,12 @@ char *pa_sw_volume_snprint_dB(char *s, size_t l, pa_volume_t v) {
return s;
}
-/** Return non-zero if the volume of all channels is equal to the specified value */
int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) {
unsigned c;
pa_assert(a);
+ pa_return_val_if_fail(pa_cvolume_valid(a), 0);
+
for (c = 0; c < a->channels; c++)
if (a->values[c] != v)
return 0;
@@ -266,6 +274,9 @@ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const
pa_assert(a);
pa_assert(b);
+ pa_return_val_if_fail(pa_cvolume_valid(a), NULL);
+ pa_return_val_if_fail(pa_cvolume_valid(b), NULL);
+
for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++)
dest->values[i] = pa_sw_volume_multiply(a->values[i], b->values[i]);
@@ -281,6 +292,9 @@ pa_cvolume *pa_sw_cvolume_divide(pa_cvolume *dest, const pa_cvolume *a, const pa
pa_assert(a);
pa_assert(b);
+ pa_return_val_if_fail(pa_cvolume_valid(a), NULL);
+ pa_return_val_if_fail(pa_cvolume_valid(b), NULL);
+
for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++)
dest->values[i] = pa_sw_volume_divide(a->values[i], b->values[i]);
@@ -373,7 +387,11 @@ pa_cvolume *pa_cvolume_remap(pa_cvolume *v, const pa_channel_map *from, const pa
pa_assert(v);
pa_assert(from);
pa_assert(to);
- pa_assert(v->channels == from->channels);
+
+ pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
+ pa_return_val_if_fail(pa_channel_map_valid(from), NULL);
+ pa_return_val_if_fail(pa_channel_map_valid(to), NULL);
+ pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, from), NULL);
if (pa_channel_map_equal(from, to))
return v;
@@ -419,11 +437,8 @@ int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) {
pa_assert(v);
pa_assert(ss);
- if (!pa_cvolume_valid(v))
- return 0;
-
- if (!pa_sample_spec_valid(ss))
- return 0;
+ pa_return_val_if_fail(pa_cvolume_valid(v), 0);
+ pa_return_val_if_fail(pa_sample_spec_valid(ss), 0);
return v->channels == ss->channels;
}
@@ -432,11 +447,8 @@ int pa_cvolume_compatible_with_channel_map(const pa_cvolume *v, const pa_channel
pa_assert(v);
pa_assert(cm);
- if (!pa_cvolume_valid(v))
- return 0;
-
- if (!pa_channel_map_valid(cm))
- return 0;
+ pa_return_val_if_fail(pa_cvolume_valid(v), 0);
+ pa_return_val_if_fail(pa_channel_map_valid(cm), 0);
return v->channels == cm->channels;
}
@@ -478,7 +490,10 @@ float pa_cvolume_get_balance(const pa_cvolume *v, const pa_channel_map *map) {
pa_assert(v);
pa_assert(map);
- pa_assert(map->channels == v->channels);
+
+ pa_return_val_if_fail(pa_cvolume_valid(v), 0.0f);
+ pa_return_val_if_fail(pa_channel_map_valid(map), 0.0f);
+ pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), 0.0f);
if (!pa_channel_map_can_balance(map))
return 0.0f;
@@ -507,12 +522,15 @@ pa_cvolume* pa_cvolume_set_balance(pa_cvolume *v, const pa_channel_map *map, flo
pa_volume_t left, nleft, right, nright, m;
unsigned c;
- pa_assert(map->channels == v->channels);
pa_assert(map);
pa_assert(v);
pa_assert(new_balance >= -1.0f);
pa_assert(new_balance <= 1.0f);
+ pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
+ pa_return_val_if_fail(pa_channel_map_valid(map), NULL);
+ pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL);
+
if (!pa_channel_map_can_balance(map))
return v;
@@ -551,6 +569,9 @@ pa_cvolume* pa_cvolume_scale(pa_cvolume *v, pa_volume_t max) {
pa_assert(v);
+ pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
+ pa_return_val_if_fail(max != (pa_volume_t) -1, NULL);
+
for (c = 0; c < v->channels; c++)
if (v->values[c] > t)
t = v->values[c];
@@ -601,7 +622,10 @@ float pa_cvolume_get_fade(const pa_cvolume *v, const pa_channel_map *map) {
pa_assert(v);
pa_assert(map);
- pa_assert(map->channels == v->channels);
+
+ pa_return_val_if_fail(pa_cvolume_valid(v), 0.0f);
+ pa_return_val_if_fail(pa_channel_map_valid(map), 0.0f);
+ pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), 0.0f);
if (!pa_channel_map_can_fade(map))
return 0.0f;
@@ -621,12 +645,15 @@ pa_cvolume* pa_cvolume_set_fade(pa_cvolume *v, const pa_channel_map *map, float
pa_volume_t front, nfront, rear, nrear, m;
unsigned c;
- pa_assert(map->channels == v->channels);
pa_assert(map);
pa_assert(v);
pa_assert(new_fade >= -1.0f);
pa_assert(new_fade <= 1.0f);
+ pa_return_val_if_fail(pa_cvolume_valid(v), NULL);
+ pa_return_val_if_fail(pa_channel_map_valid(map), NULL);
+ pa_return_val_if_fail(pa_cvolume_compatible_with_channel_map(v, map), NULL);
+
if (!pa_channel_map_can_fade(map))
return v;
commit ce76216bce9981c31ebab2ca5a97d6c5c0509edd
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:10:15 2009 +0100
add pa_sample_size_of_format()
diff --git a/src/map-file b/src/map-file
index d7addfe..cdb9deb 100644
--- a/src/map-file
+++ b/src/map-file
@@ -181,6 +181,7 @@ pa_proplist_unset_many;
pa_proplist_update;
pa_sample_format_to_string;
pa_sample_size;
+pa_sample_size_of_format;
pa_sample_spec_equal;
pa_sample_spec_init;
pa_sample_spec_snprint;
diff --git a/src/pulse/sample.c b/src/pulse/sample.c
index ff86d0b..4b13a33 100644
--- a/src/pulse/sample.c
+++ b/src/pulse/sample.c
@@ -36,7 +36,7 @@
#include "sample.h"
-size_t pa_sample_size(const pa_sample_spec *spec) {
+size_t pa_sample_size_of_format(pa_sample_format_t f) {
static const size_t table[] = {
[PA_SAMPLE_U8] = 1,
@@ -54,10 +54,18 @@ size_t pa_sample_size(const pa_sample_spec *spec) {
[PA_SAMPLE_S24_32BE] = 4
};
+ pa_assert(f >= 0);
+ pa_assert(f < PA_SAMPLE_MAX);
+
+ return table[f];
+}
+
+size_t pa_sample_size(const pa_sample_spec *spec) {
+
pa_assert(spec);
pa_return_val_if_fail(pa_sample_spec_valid(spec), 0);
- return table[spec->format];
+ return pa_sample_size_of_format(spec->format);
}
size_t pa_frame_size(const pa_sample_spec *spec) {
diff --git a/src/pulse/sample.h b/src/pulse/sample.h
index 45a481f..3c05b54 100644
--- a/src/pulse/sample.h
+++ b/src/pulse/sample.h
@@ -261,6 +261,10 @@ size_t pa_frame_size(const pa_sample_spec *spec) PA_GCC_PURE;
/** Return the size of a sample with the specific sample type */
size_t pa_sample_size(const pa_sample_spec *spec) PA_GCC_PURE;
+/** Similar to pa_sample_size() but take a sample format instead of a
+ * full sample spec. \since 0.9.15 */
+size_t pa_sample_size_of_format(pa_sample_format_t f) PA_GCC_PURE;
+
/** Calculate the time the specified bytes take to play with the
* specified sample type. The return value will always be rounded
* down for non-integral return values. */
commit 0fc59e4585937b155125ef01b0e8c2ae9e5f6cee
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:11:56 2009 +0100
add new API pa_ascii_valid(), pa_ascii_filter()
diff --git a/src/map-file b/src/map-file
index cdb9deb..ca4e7a7 100644
--- a/src/map-file
+++ b/src/map-file
@@ -1,5 +1,7 @@
PULSE_0 {
global:
+pa_ascii_filter;
+pa_ascii_valid;
pa_browser_new;
pa_browser_new_full;
pa_browser_ref;
diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c
index 7671be4..6b58bde 100644
--- a/src/pulse/utf8.c
+++ b/src/pulse/utf8.c
@@ -263,3 +263,29 @@ char* pa_locale_to_utf8 (const char *str) {
}
#endif
+
+char *pa_ascii_valid(const char *str) {
+ const char *p;
+ pa_assert(str);
+
+ for (p = str; *p; p++)
+ if ((unsigned char) *p >= 128)
+ return NULL;
+
+ return (char*) str;
+}
+
+char *pa_ascii_filter(const char *str) {
+ char *r, *s, *d;
+ pa_assert(str);
+
+ r = pa_xstrdup(str);
+
+ for (s = r, d = r; *s; s++)
+ if ((unsigned char) *s < 128)
+ *(d++) = *s;
+
+ *d = 0;
+
+ return r;
+}
diff --git a/src/pulse/utf8.h b/src/pulse/utf8.h
index 4d75195..b9f7495 100644
--- a/src/pulse/utf8.h
+++ b/src/pulse/utf8.h
@@ -36,9 +36,15 @@ PA_C_DECL_BEGIN
/** Test if the specified strings qualifies as valid UTF8. Return the string if so, otherwise NULL */
char *pa_utf8_valid(const char *str) PA_GCC_PURE;
+/** Test if the specified strings qualifies as valid 7-bit ASCII. Return the string if so, otherwise NULL. \since 0.9.15 */
+char *pa_ascii_valid(const char *str) PA_GCC_PURE;
+
/** Filter all invalid UTF8 characters from the specified string, returning a new fully UTF8 valid string. Don't forget to free the returned string with pa_xfree() */
char *pa_utf8_filter(const char *str);
+/** Filter all invalid ASCII characters from the specified string, returning a new fully ASCII valid string. Don't forget to free the returned string with pa_xfree(). \since 0.9.15 */
+char *pa_ascii_filter(const char *str);
+
/** Convert a UTF-8 string to the current locale. Free the string using pa_xfree(). */
char* pa_utf8_to_locale (const char *str);
commit b445741ddf61de662eddbbe9fc90817ac0e24c5b
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:14:59 2009 +0100
fix up parser in pa_proplist_from_string() to handle escapes correctly; make pa_proplist_to_string() escape quotes properly
diff --git a/src/pulse/proplist.c b/src/pulse/proplist.c
index 282fe5c..db4c934 100644
--- a/src/pulse/proplist.c
+++ b/src/pulse/proplist.c
@@ -24,6 +24,7 @@
#endif
#include <string.h>
+#include <ctype.h>
#include <pulse/xmalloc.h>
#include <pulse/utf8.h>
@@ -46,7 +47,7 @@ struct property {
static pa_bool_t property_name_valid(const char *key) {
- if (!pa_utf8_valid(key))
+ if (!pa_ascii_valid(key))
return FALSE;
if (strlen(key) <= 0)
@@ -64,8 +65,6 @@ static void property_free(struct property *prop) {
}
pa_proplist* pa_proplist_new(void) {
- pa_init_i18n();
-
return MAKE_PROPLIST(pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func));
}
@@ -83,6 +82,7 @@ int pa_proplist_sets(pa_proplist *p, const char *key, const char *value) {
pa_assert(p);
pa_assert(key);
+ pa_assert(value);
if (!property_name_valid(key) || !pa_utf8_valid(value))
return -1;
@@ -104,25 +104,130 @@ int pa_proplist_sets(pa_proplist *p, const char *key, const char *value) {
}
/** Will accept only valid UTF-8 */
+static int proplist_setn(pa_proplist *p, const char *key, size_t key_length, const char *value, size_t value_length) {
+ struct property *prop;
+ pa_bool_t add = FALSE;
+ char *k, *v;
+
+ pa_assert(p);
+ pa_assert(key);
+ pa_assert(value);
+
+ k = pa_xstrndup(key, key_length);
+ v = pa_xstrndup(value, value_length);
+
+ if (!property_name_valid(k) || !pa_utf8_valid(v)) {
+ pa_xfree(k);
+ pa_xfree(v);
+ return -1;
+ }
+
+ if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), k))) {
+ prop = pa_xnew(struct property, 1);
+ prop->key = k;
+ add = TRUE;
+ } else {
+ pa_xfree(prop->value);
+ pa_xfree(k);
+ }
+
+ prop->value = v;
+ prop->nbytes = strlen(v)+1;
+
+ if (add)
+ pa_hashmap_put(MAKE_HASHMAP(p), prop->key, prop);
+
+ return 0;
+}
+
+static int proplist_sethex(pa_proplist *p, const char *key, size_t key_length, const char *value, size_t value_length) {
+ struct property *prop;
+ pa_bool_t add = FALSE;
+ char *k, *v;
+ uint8_t *d;
+ size_t dn;
+
+ pa_assert(p);
+ pa_assert(key);
+ pa_assert(value);
+
+ k = pa_xstrndup(key, key_length);
+
+ if (!property_name_valid(k)) {
+ pa_xfree(k);
+ return -1;
+ }
+
+ v = pa_xstrndup(value, value_length);
+ d = pa_xmalloc(value_length*2+1);
+
+ if ((dn = pa_parsehex(v, d, value_length*2)) == (size_t) -1) {
+ pa_xfree(k);
+ pa_xfree(v);
+ pa_xfree(d);
+ return -1;
+ }
+
+ pa_xfree(v);
+
+ if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), k))) {
+ prop = pa_xnew(struct property, 1);
+ prop->key = k;
+ add = TRUE;
+ } else {
+ pa_xfree(prop->value);
+ pa_xfree(k);
+ }
+
+ d[dn] = 0;
+ prop->value = d;
+ prop->nbytes = dn;
+
+ if (add)
+ pa_hashmap_put(MAKE_HASHMAP(p), prop->key, prop);
+
+ return 0;
+}
+
+/** Will accept only valid UTF-8 */
int pa_proplist_setf(pa_proplist *p, const char *key, const char *format, ...) {
+ struct property *prop;
+ pa_bool_t add = FALSE;
va_list ap;
- int r;
- char *t;
+ char *v;
pa_assert(p);
pa_assert(key);
+ pa_assert(format);
if (!property_name_valid(key) || !pa_utf8_valid(format))
return -1;
va_start(ap, format);
- t = pa_vsprintf_malloc(format, ap);
+ v = pa_vsprintf_malloc(format, ap);
va_end(ap);
- r = pa_proplist_sets(p, key, t);
+ if (!pa_utf8_valid(v))
+ goto fail;
- pa_xfree(t);
- return r;
+ if (!(prop = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
+ prop = pa_xnew(struct property, 1);
+ prop->key = pa_xstrdup(key);
+ add = TRUE;
+ } else
+ pa_xfree(prop->value);
+
+ prop->value = v;
+ prop->nbytes = strlen(v)+1;
+
+ if (add)
+ pa_hashmap_put(MAKE_HASHMAP(p), prop->key, prop);
+
+ return 0;
+
+fail:
+ pa_xfree(v);
+ return -1;
}
int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nbytes) {
@@ -131,6 +236,7 @@ int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nb
pa_assert(p);
pa_assert(key);
+ pa_assert(data);
if (!property_name_valid(key))
return -1;
@@ -142,7 +248,9 @@ int pa_proplist_set(pa_proplist *p, const char *key, const void *data, size_t nb
} else
pa_xfree(prop->value);
- prop->value = pa_xmemdup(data, nbytes);
+ prop->value = pa_xmalloc(nbytes+1);
+ memcpy(prop->value, data, nbytes);
+ ((char*) prop->value)[nbytes] = 0;
prop->nbytes = nbytes;
if (add)
@@ -183,6 +291,8 @@ int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t *
pa_assert(p);
pa_assert(key);
+ pa_assert(data);
+ pa_assert(nbytes);
if (!property_name_valid(key))
return -1;
@@ -275,9 +385,32 @@ char *pa_proplist_to_string_sep(pa_proplist *p, const char *sep) {
if (!pa_strbuf_isempty(buf))
pa_strbuf_puts(buf, sep);
- if ((v = pa_proplist_gets(p, key)))
- pa_strbuf_printf(buf, "%s = \"%s\"", key, v);
- else {
+ if ((v = pa_proplist_gets(p, key))) {
+ const char *t;
+
+ pa_strbuf_printf(buf, "%s = \"", key);
+
+ for (t = v;;) {
+ size_t h;
+
+ h = strcspn(t, "\"");
+
+ if (h > 0)
+ pa_strbuf_putsn(buf, t, h);
+
+ t += h;
+
+ if (*t == 0)
+ break;
+
+ pa_assert(*t == '"');
+ pa_strbuf_puts(buf, "\\\"");
+
+ t++;
+ }
+
+ pa_strbuf_puts(buf, "\"");
+ } else {
const void *value;
size_t nbytes;
char *c;
@@ -304,88 +437,189 @@ char *pa_proplist_to_string(pa_proplist *p) {
return t;
}
-/* Remove all whitepsapce from the beginning and the end of *s. *s may
- * be modified. (from conf-parser.c) */
-#define WHITESPACE " \t\n"
-#define in_string(c,s) (strchr(s,c) != NULL)
-
-static char *strip(char *s) {
- char *b = s+strspn(s, WHITESPACE);
- char *e, *l = NULL;
-
- for (e = b; *e; e++)
- if (!in_string(*e, WHITESPACE))
- l = e;
+pa_proplist *pa_proplist_from_string(const char *s) {
+ enum {
+ WHITESPACE,
+ KEY,
+ AFTER_KEY,
+ VALUE_START,
+ VALUE_SIMPLE,
+ VALUE_DOUBLE_QUOTES,
+ VALUE_DOUBLE_QUOTES_ESCAPE,
+ VALUE_TICKS,
+ VALUE_TICKS_ESCAPED,
+ VALUE_HEX
+ } state;
+
+ pa_proplist *pl;
+ const char *p, *key = NULL, *value = NULL;
+ size_t key_len = 0, value_len = 0;
+
+ pa_assert(s);
+
+ pl = pa_proplist_new();
+
+ state = WHITESPACE;
+
+ for (p = s;; p++) {
+ switch (state) {
+
+ case WHITESPACE:
+ if (*p == 0)
+ goto success;
+ else if (*p == '=')
+ goto fail;
+ else if (!isspace(*p)) {
+ key = p;
+ state = KEY;
+ key_len = 1;
+ }
+ break;
- if (l)
- *(l+1) = 0;
+ case KEY:
+ if (*p == 0)
+ goto fail;
+ else if (*p == '=')
+ state = VALUE_START;
+ else if (isspace(*p))
+ state = AFTER_KEY;
+ else
+ key_len++;
+ break;
- return b;
-}
+ case AFTER_KEY:
+ if (*p == 0)
+ goto fail;
+ else if (*p == '=')
+ state = VALUE_START;
+ else if (!isspace(*p))
+ goto fail;
+ break;
-pa_proplist *pa_proplist_from_string(const char *str) {
- pa_proplist *p;
- char *s, *v, *k, *e;
+ case VALUE_START:
+ if (*p == 0)
+ goto fail;
+ else if (strncmp(p, "hex:", 4) == 0) {
+ state = VALUE_HEX;
+ value = p+4;
+ value_len = 0;
+ p += 3;
+ } else if (*p == '\'') {
+ state = VALUE_TICKS;
+ value = p+1;
+ value_len = 0;
+ } else if (*p == '"') {
+ state = VALUE_DOUBLE_QUOTES;
+ value = p+1;
+ value_len = 0;
+ } else if (!isspace(*p)) {
+ state = VALUE_SIMPLE;
+ value = p;
+ value_len = 1;
+ }
+ break;
- pa_assert(str);
- pa_assert_se(p = pa_proplist_new());
- pa_assert_se(s = strdup(str));
+ case VALUE_SIMPLE:
+ if (*p == 0 || isspace(*p)) {
+ if (proplist_setn(pl, key, key_len, value, value_len) < 0)
+ goto fail;
- for (k = s; *k; k = e) {
- k = k+strspn(k, WHITESPACE);
+ if (*p == 0)
+ goto success;
- if (!*k)
- break;
+ state = WHITESPACE;
+ } else
+ value_len++;
+ break;
- if (!(v = strchr(k, '='))) {
- pa_log("Missing '='.");
- break;
- }
+ case VALUE_DOUBLE_QUOTES:
+ if (*p == 0)
+ goto fail;
+ else if (*p == '"') {
+ char *v;
+
+ v = pa_unescape(pa_xstrndup(value, value_len));
+
+ if (proplist_setn(pl, key, key_len, v, strlen(v)) < 0) {
+ pa_xfree(v);
+ goto fail;
+ }
+
+ pa_xfree(v);
+ state = WHITESPACE;
+ } else if (*p == '\\') {
+ state = VALUE_DOUBLE_QUOTES_ESCAPE;
+ value_len++;
+ } else
+ value_len++;
+ break;
- *v++ = '\0';
- k = strip(k);
+ case VALUE_DOUBLE_QUOTES_ESCAPE:
+ if (*p == 0)
+ goto fail;
+ else {
+ state = VALUE_DOUBLE_QUOTES;
+ value_len++;
+ }
+ break;
- v = v+strspn(v, WHITESPACE);
- if (*v == '"') {
- v++;
- if (!(e = strchr(v, '"'))) { /* FIXME: handle escape */
- pa_log("Missing '\"' at end of string value.");
+ case VALUE_TICKS:
+ if (*p == 0)
+ goto fail;
+ else if (*p == '\'') {
+ char *v;
+
+ v = pa_unescape(pa_xstrndup(value, value_len));
+
+ if (proplist_setn(pl, key, key_len, v, strlen(v)) < 0) {
+ pa_xfree(v);
+ goto fail;
+ }
+
+ pa_xfree(v);
+ state = WHITESPACE;
+ } else if (*p == '\\') {
+ state = VALUE_TICKS_ESCAPED;
+ value_len++;
+ } else
+ value_len++;
break;
- }
- *e++ = '\0';
- pa_proplist_sets(p, k, v);
- } else {
- uint8_t *blob;
- if (*v++ != 'h' || *v++ != 'e' || *v++ != 'x' || *v++ != ':') {
- pa_log("Value must be a string or \"hex:\"");
+ case VALUE_TICKS_ESCAPED:
+ if (*p == 0)
+ goto fail;
+ else {
+ state = VALUE_TICKS;
+ value_len++;
+ }
break;
- }
- e = v;
- while (in_string(*e, "0123456789abcdefABCDEF"))
- ++e;
+ case VALUE_HEX:
+ if ((*p >= '0' && *p <= '9') ||
+ (*p >= 'A' && *p <= 'F') ||
+ (*p >= 'a' && *p <= 'f')) {
+ value_len++;
+ } else if (*p == 0 || isspace(*p)) {
- if ((e - v) % 2) {
- pa_log("Invalid \"hex:\" value data");
- break;
- }
+ if (proplist_sethex(pl, key, key_len, value, value_len) < 0)
+ goto fail;
- blob = pa_xmalloc((size_t)(e-v)/2);
- if (pa_parsehex(v, blob, (e-v)/2) != (size_t)((e-v)/2)) {
- pa_log("Invalid \"hex:\" value data");
- pa_xfree(blob);
- break;
- }
+ if (*p == 0)
+ goto success;
- pa_proplist_set(p, k, blob, (e-v)/2);
- pa_xfree(blob);
+ state = WHITESPACE;
+ } else
+ goto fail;
+ break;
}
}
- pa_xfree(s);
+success:
+ return MAKE_PROPLIST(pl);
- return p;
+fail:
+ pa_proplist_free(pl);
+ return NULL;
}
int pa_proplist_contains(pa_proplist *p, const char *key) {
diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h
index 990ffd1..d611406 100644
--- a/src/pulse/proplist.h
+++ b/src/pulse/proplist.h
@@ -136,7 +136,7 @@ PA_C_DECL_BEGIN
#define PA_PROP_MODULE_USAGE "module.usage"
#define PA_PROP_MODULE_VERSION "module.version"
-/** A property list object. Basically a dictionary with UTF-8 strings
+/** A property list object. Basically a dictionary with ASCII strings
* as keys and arbitrary data as values. \since 0.9.11 */
typedef struct pa_proplist pa_proplist;
commit 9a27b8f0e8a6cd1863c95770777aa2536ec5fbb2
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:16:13 2009 +0100
in addition to per-property env vars PULSE_PROP_xxx look for for a stringified PULSE_PROP env var
diff --git a/src/pulsecore/proplist-util.c b/src/pulsecore/proplist-util.c
index 4920c27..522c7af 100644
--- a/src/pulsecore/proplist-util.c
+++ b/src/pulsecore/proplist-util.c
@@ -41,6 +41,7 @@ void pa_init_proplist(pa_proplist *p) {
extern char **environ;
#endif
char **e;
+ const char *pp;
pa_assert(p);
@@ -75,6 +76,15 @@ void pa_init_proplist(pa_proplist *p) {
}
}
+ if ((pp = getenv("PULSE_PROP"))) {
+ pa_proplist *t;
+
+ if ((t = pa_proplist_from_string(pp))) {
+ pa_proplist_update(p, PA_UPDATE_MERGE, t);
+ pa_proplist_free(t);
+ }
+ }
+
if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_ID)) {
char t[32];
pa_snprintf(t, sizeof(t), "%lu", (unsigned long) getpid());
commit a6fe99171669ae03fd5453cc8fa924f21dc9a050
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:16:32 2009 +0100
beef up proplist test a bit
diff --git a/src/tests/proplist-test.c b/src/tests/proplist-test.c
index f69fa68..5526bb7 100644
--- a/src/tests/proplist-test.c
+++ b/src/tests/proplist-test.c
@@ -29,8 +29,9 @@
#include <pulsecore/core-util.h>
int main(int argc, char*argv[]) {
- pa_proplist *a, *b, *c;
- char *s, *t, *u;
+ pa_proplist *a, *b, *c, *d;
+ char *s, *t, *u, *v;
+ const char *text;
a = pa_proplist_new();
pa_assert_se(pa_proplist_sets(a, PA_PROP_MEDIA_TITLE, "Brandenburgische Konzerte") == 0);
@@ -63,5 +64,19 @@ int main(int argc, char*argv[]) {
pa_proplist_free(b);
pa_proplist_free(c);
+ text = " eins = zwei drei = \"\\\"vier\\\"\" fuenf=sechs sieben ='\\a\\c\\h\\t\\'\\\"' neun= hex:0123456789abCDef ";
+
+ printf("%s\n", text);
+ d = pa_proplist_from_string(text);
+ v = pa_proplist_to_string(d);
+ pa_proplist_free(d);
+ printf("%s\n", v);
+ d = pa_proplist_from_string(v);
+ pa_xfree(v);
+ v = pa_proplist_to_string(d);
+ pa_proplist_free(d);
+ printf("%s\n", v);
+ pa_xfree(v);
+
return 0;
}
commit d6dd907cc87e3c6c86ec4d05a2f533bb8fcf677b
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:16:53 2009 +0100
simplify code a bit by using pa_sample_size_of_format()
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index be390db..78ad553 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -156,16 +156,6 @@ static int (* const init_table[])(pa_resampler*r) = {
[PA_RESAMPLER_PEAKS] = peaks_init,
};
-static inline size_t sample_size(pa_sample_format_t f) {
- pa_sample_spec ss = {
- .format = f,
- .rate = 0,
- .channels = 1
- };
-
- return pa_sample_size(&ss);
-}
-
pa_resampler* pa_resampler_new(
pa_mempool *pool,
const pa_sample_spec *a,
@@ -275,7 +265,7 @@ pa_resampler* pa_resampler_new(
pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format));
- r->w_sz = sample_size(r->work_format);
+ r->w_sz = pa_sample_size_of_format(r->work_format);
if (r->i_ss.format == r->work_format)
r->to_work_format_func = NULL;
commit 078a8d583f205f57b99b32fe12d33e04742c07f6
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:17:32 2009 +0100
rearrange a few things
diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c
index 9e60125..866e6e0 100644
--- a/src/pulsecore/modargs.c
+++ b/src/pulsecore/modargs.c
@@ -79,106 +79,111 @@ static int add_key_value(pa_hashmap *map, char *key, char *value, const char* co
}
pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) {
- pa_hashmap *map = NULL;
+ enum {
+ WHITESPACE,
+ KEY,
+ VALUE_START,
+ VALUE_SIMPLE,
+ VALUE_DOUBLE_QUOTES,
+ VALUE_TICKS
+ } state;
+
+ const char *p, *key = NULL, *value = NULL;
+ size_t key_len = 0, value_len = 0;
+ pa_hashmap *map;
map = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
- if (args) {
- enum {
- WHITESPACE,
- KEY,
- VALUE_START,
- VALUE_SIMPLE,
- VALUE_DOUBLE_QUOTES,
- VALUE_TICKS
- } state;
-
- const char *p, *key, *value;
- size_t key_len = 0, value_len = 0;
-
- key = value = NULL;
- state = WHITESPACE;
- for (p = args; *p; p++) {
- switch (state) {
- case WHITESPACE:
- if (*p == '=')
+ if (!args)
+ return (pa_modargs*) map;
+
+ state = WHITESPACE;
+
+ for (p = args; *p; p++) {
+ switch (state) {
+
+ case WHITESPACE:
+ if (*p == '=')
+ goto fail;
+ else if (!isspace(*p)) {
+ key = p;
+ state = KEY;
+ key_len = 1;
+ }
+ break;
+
+ case KEY:
+ if (*p == '=')
+ state = VALUE_START;
+ else if (isspace(*p))
+ goto fail;
+ else
+ key_len++;
+ break;
+
+ case VALUE_START:
+ if (*p == '\'') {
+ state = VALUE_TICKS;
+ value = p+1;
+ value_len = 0;
+ } else if (*p == '"') {
+ state = VALUE_DOUBLE_QUOTES;
+ value = p+1;
+ value_len = 0;
+ } else if (isspace(*p)) {
+ if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0)
goto fail;
- else if (!isspace(*p)) {
- key = p;
- state = KEY;
- key_len = 1;
- }
- break;
- case KEY:
- if (*p == '=')
- state = VALUE_START;
- else if (isspace(*p))
+ state = WHITESPACE;
+ } else {
+ state = VALUE_SIMPLE;
+ value = p;
+ value_len = 1;
+ }
+ break;
+
+ case VALUE_SIMPLE:
+ if (isspace(*p)) {
+ if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
goto fail;
- else
- key_len++;
- break;
- case VALUE_START:
- if (*p == '\'') {
- state = VALUE_TICKS;
- value = p+1;
- value_len = 0;
- } else if (*p == '"') {
- state = VALUE_DOUBLE_QUOTES;
- value = p+1;
- value_len = 0;
- } else if (isspace(*p)) {
- if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0)
- goto fail;
- state = WHITESPACE;
- } else {
- state = VALUE_SIMPLE;
- value = p;
- value_len = 1;
- }
- break;
- case VALUE_SIMPLE:
- if (isspace(*p)) {
- if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
- goto fail;
- state = WHITESPACE;
- } else
- value_len++;
- break;
- case VALUE_DOUBLE_QUOTES:
- if (*p == '"') {
- if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
- goto fail;
- state = WHITESPACE;
- } else
- value_len++;
- break;
- case VALUE_TICKS:
- if (*p == '\'') {
- if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
- goto fail;
- state = WHITESPACE;
- } else
- value_len++;
- break;
- }
+ state = WHITESPACE;
+ } else
+ value_len++;
+ break;
+
+ case VALUE_DOUBLE_QUOTES:
+ if (*p == '"') {
+ if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
+ goto fail;
+ state = WHITESPACE;
+ } else
+ value_len++;
+ break;
+
+ case VALUE_TICKS:
+ if (*p == '\'') {
+ if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0)
+ goto fail;
+ state = WHITESPACE;
+ } else
+ value_len++;
+ break;
}
+ }
- if (state == VALUE_START) {
- if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0)
- goto fail;
- } else if (state == VALUE_SIMPLE) {
- if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(value), valid_keys) < 0)
- goto fail;
- } else if (state != WHITESPACE)
+ if (state == VALUE_START) {
+ if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0)
goto fail;
- }
+ } else if (state == VALUE_SIMPLE) {
+ if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(value), valid_keys) < 0)
+ goto fail;
+ } else if (state != WHITESPACE)
+ goto fail;
return (pa_modargs*) map;
fail:
- if (map)
- pa_modargs_free((pa_modargs*) map);
+ pa_modargs_free((pa_modargs*) map);
return NULL;
}
commit a625ca7c74d8a21b36527c06524ac281e67308f3
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:17:48 2009 +0100
make gcc shut up
diff --git a/src/pulsecore/envelope.c b/src/pulsecore/envelope.c
index b57b643..fd6a948 100644
--- a/src/pulsecore/envelope.c
+++ b/src/pulsecore/envelope.c
@@ -744,6 +744,13 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {
break;
}
+ case PA_SAMPLE_S24LE:
+ case PA_SAMPLE_S24BE:
+ case PA_SAMPLE_S24_32LE:
+ case PA_SAMPLE_S24_32BE:
+ /* FIXME */
+ pa_assert_not_reached();
+
case PA_SAMPLE_MAX:
case PA_SAMPLE_INVALID:
pa_assert_not_reached();
commit 83ddc0936e52120f2af86a552f3adb240a4f0ac4
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:19:15 2009 +0100
add new calls pa_replace() and pa_unescape()
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index e65b179..b7ebdeb 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -97,6 +97,7 @@
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include <pulsecore/thread.h>
+#include <pulsecore/strbuf.h>
#include "core-util.h"
@@ -2553,3 +2554,49 @@ unsigned pa_ncpus(void) {
return ncpus <= 0 ? 1 : (unsigned) ncpus;
}
+
+char *pa_replace(const char*s, const char*a, const char *b) {
+ pa_strbuf *sb;
+ size_t an;
+
+ pa_assert(s);
+ pa_assert(a);
+ pa_assert(b);
+
+ an = strlen(a);
+ sb = pa_strbuf_new();
+
+ for (;;) {
+ const char *p;
+
+ if (!(p = strstr(s, a)))
+ break;
+
+ pa_strbuf_putsn(sb, s, p-s);
+ pa_strbuf_puts(sb, b);
+ s = p + an;
+ }
+
+ pa_strbuf_puts(sb, s);
+
+ return pa_strbuf_tostring_free(sb);
+}
+
+char *pa_unescape(char *p) {
+ char *s, *d;
+ pa_bool_t escaped = FALSE;
+
+ for (s = p, d = p; *s; s++) {
+ if (!escaped && *s == '\\') {
+ escaped = TRUE;
+ continue;
+ }
+
+ *(d++) = *s;
+ escaped = FALSE;
+ }
+
+ *d = 0;
+
+ return p;
+}
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index 18901f4..442815f 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -215,4 +215,8 @@ void pa_reduce(unsigned *num, unsigned *den);
unsigned pa_ncpus(void);
+char *pa_replace(const char*s, const char*a, const char *b);
+
+char *pa_unescape(char *p);
+
#endif
commit 12b735962a3794f1e64c7bf54d67dc7d8c4b8643
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:20:36 2009 +0100
add a few additional validity checks
diff --git a/src/pulse/ext-stream-restore.c b/src/pulse/ext-stream-restore.c
index 703179c..469c822 100644
--- a/src/pulse/ext-stream-restore.c
+++ b/src/pulse/ext-stream-restore.c
@@ -30,6 +30,7 @@
#include <pulsecore/pstream-util.h>
#include "internal.h"
+#include "operation.h"
#include "ext-stream-restore.h"
@@ -191,8 +192,8 @@ pa_operation *pa_ext_stream_restore_write(
void *userdata) {
uint32_t tag;
- pa_operation *o;
- pa_tagstruct *t;
+ pa_operation *o = NULL;
+ pa_tagstruct *t = NULL;
pa_assert(c);
pa_assert(PA_REFCNT_VALUE(c) >= 1);
@@ -213,7 +214,15 @@ pa_operation *pa_ext_stream_restore_write(
pa_tagstruct_put_boolean(t, apply_immediately);
for (; n > 0; n--, data++) {
+ if (!data->name || !*data->name)
+ goto fail;
+
pa_tagstruct_puts(t, data->name);
+
+ if (data->volume.channels > 0 &&
+ !pa_cvolume_compatible_with_channel_map(&data->volume, &data->channel_map))
+ goto fail;
+
pa_tagstruct_put_channel_map(t, &data->channel_map);
pa_tagstruct_put_cvolume(t, &data->volume);
pa_tagstruct_puts(t, data->device);
@@ -224,6 +233,18 @@ pa_operation *pa_ext_stream_restore_write(
pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
return o;
+
+fail:
+ if (o) {
+ pa_operation_cancel(o);
+ pa_operation_unref(o);
+ }
+
+ if (t)
+ pa_tagstruct_free(t);
+
+ pa_context_set_error(c, PA_ERR_INVALID);
+ return NULL;
}
pa_operation *pa_ext_stream_restore_delete(
@@ -233,8 +254,8 @@ pa_operation *pa_ext_stream_restore_delete(
void *userdata) {
uint32_t tag;
- pa_operation *o;
- pa_tagstruct *t;
+ pa_operation *o = NULL;
+ pa_tagstruct *t = NULL;
const char *const *k;
pa_assert(c);
@@ -251,13 +272,29 @@ pa_operation *pa_ext_stream_restore_delete(
pa_tagstruct_puts(t, "module-stream-restore");
pa_tagstruct_putu32(t, SUBCOMMAND_DELETE);
- for (k = s; *k; k++)
+ for (k = s; *k; k++) {
+ if (!*k || !**k)
+ goto fail;
+
pa_tagstruct_puts(t, *k);
+ }
pa_pstream_send_tagstruct(c->pstream, t);
pa_pdispatch_register_reply(c->pdispatch, tag, DEFAULT_TIMEOUT, pa_context_simple_ack_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
return o;
+
+fail:
+ if (o) {
+ pa_operation_cancel(o);
+ pa_operation_unref(o);
+ }
+
+ if (t)
+ pa_tagstruct_free(t);
+
+ pa_context_set_error(c, PA_ERR_INVALID);
+ return NULL;
}
pa_operation *pa_ext_stream_restore_subscribe(
@@ -322,5 +359,4 @@ void pa_ext_stream_restore_command(pa_context *c, uint32_t tag, pa_tagstruct *t)
if (c->ext_stream_restore.callback)
c->ext_stream_restore.callback(c, c->ext_stream_restore.userdata);
-
}
diff --git a/src/pulse/operation.c b/src/pulse/operation.c
index 13b470a..aa2bbc0 100644
--- a/src/pulse/operation.c
+++ b/src/pulse/operation.c
@@ -62,6 +62,7 @@ pa_operation *pa_operation_ref(pa_operation *o) {
PA_REFCNT_INC(o);
return o;
}
+
void pa_operation_unref(pa_operation *o) {
pa_assert(o);
pa_assert(PA_REFCNT_VALUE(o) >= 1);
commit f6ec971e887e68ba74fb7132dcedddc9b6f2b2db
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Feb 4 17:20:58 2009 +0100
clarify things a bit
diff --git a/src/pulse/ext-stream-restore.h b/src/pulse/ext-stream-restore.h
index ac01d23..cf9f4cc 100644
--- a/src/pulse/ext-stream-restore.h
+++ b/src/pulse/ext-stream-restore.h
@@ -36,10 +36,10 @@ PA_C_DECL_BEGIN
* maintained by module-stream-restore. \since 0.9.12 */
typedef struct pa_ext_stream_restore_info {
const char *name; /**< Identifier string of the stream. A string like "sink-input-by-role:" or similar followed by some arbitrary property value. */
- pa_channel_map channel_map; /**< The channel map for the volume field */
- pa_cvolume volume; /**< The volume of the stream when it was seen last, if applicable */
- const char *device; /**< The sink/source of the stream when it was last seen */
- int mute; /**< The boolean mute state of the stream when it was last seen, if applicable */
+ pa_channel_map channel_map; /**< The channel map for the volume field, if applicable */
+ pa_cvolume volume; /**< The volume of the stream when it was seen last, if applicable and saved */
+ const char *device; /**< The sink/source of the stream when it was last seen, if applicable and saved */
+ int mute; /**< The boolean mute state of the stream when it was last seen, if applicable and saved */
} pa_ext_stream_restore_info;
/** Callback prototype for pa_ext_stream_restore_test(). \since 0.9.12 */
--
hooks/post-receive
PulseAudio Sound Server
More information about the pulseaudio-commits
mailing list