From 045c1d602dcba57868845ba3270510593c39480f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 15 May 2008 23:34:41 +0000 Subject: merge glitch-free branch back into trunk git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@2445 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/tagstruct.c | 94 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 6 deletions(-) (limited to 'src/pulsecore/tagstruct.c') diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c index 556fe806..7616cd16 100644 --- a/src/pulsecore/tagstruct.c +++ b/src/pulsecore/tagstruct.c @@ -42,12 +42,14 @@ #include "tagstruct.h" +#define MAX_TAG_SIZE (64*1024) + struct pa_tagstruct { uint8_t *data; size_t length, allocated; size_t rindex; - int dynamic; + pa_bool_t dynamic; }; pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length) { @@ -161,7 +163,7 @@ void pa_tagstruct_put_arbitrary(pa_tagstruct *t, const void *p, size_t length) { t->length += 5+length; } -void pa_tagstruct_put_boolean(pa_tagstruct*t, int b) { +void pa_tagstruct_put_boolean(pa_tagstruct*t, pa_bool_t b) { pa_assert(t); extend(t, 1); @@ -254,6 +256,32 @@ void pa_tagstruct_put_cvolume(pa_tagstruct *t, const pa_cvolume *cvolume) { } } +void pa_tagstruct_put_proplist(pa_tagstruct *t, pa_proplist *p) { + void *state = NULL; + pa_assert(t); + pa_assert(p); + + extend(t, 1); + + t->data[t->length++] = PA_TAG_PROPLIST; + + for (;;) { + const char *k; + const void *d; + size_t l; + + if (!(k = pa_proplist_iterate(p, &state))) + break; + + pa_tagstruct_puts(t, k); + pa_assert_se(pa_proplist_get(p, k, &d, &l) >= 0); + pa_tagstruct_putu32(t, (uint32_t) l); + pa_tagstruct_put_arbitrary(t, d, l); + } + + pa_tagstruct_puts(t, NULL); +} + int pa_tagstruct_gets(pa_tagstruct*t, const char **s) { int error = 0; size_t n; @@ -379,7 +407,7 @@ const uint8_t* pa_tagstruct_data(pa_tagstruct*t, size_t *l) { return t->data; } -int pa_tagstruct_get_boolean(pa_tagstruct*t, int *b) { +int pa_tagstruct_get_boolean(pa_tagstruct*t, pa_bool_t *b) { pa_assert(t); pa_assert(b); @@ -387,9 +415,9 @@ int pa_tagstruct_get_boolean(pa_tagstruct*t, int *b) { return -1; if (t->data[t->rindex] == PA_TAG_BOOLEAN_TRUE) - *b = 1; + *b = TRUE; else if (t->data[t->rindex] == PA_TAG_BOOLEAN_FALSE) - *b = 0; + *b = FALSE; else return -1; @@ -529,6 +557,52 @@ int pa_tagstruct_get_cvolume(pa_tagstruct *t, pa_cvolume *cvolume) { return 0; } +int pa_tagstruct_get_proplist(pa_tagstruct *t, pa_proplist *p) { + size_t saved_rindex; + + pa_assert(t); + pa_assert(p); + + if (t->rindex+1 > t->length) + return -1; + + if (t->data[t->rindex] != PA_TAG_PROPLIST) + return -1; + + saved_rindex = t->rindex; + t->rindex++; + + for (;;) { + const char *k; + const void *d; + uint32_t length; + + if (pa_tagstruct_gets(t, &k) < 0) + goto fail; + + if (!k) + break; + + if (pa_tagstruct_getu32(t, &length) < 0) + goto fail; + + if (length > MAX_TAG_SIZE) + goto fail; + + if (pa_tagstruct_get_arbitrary(t, &d, length) < 0) + goto fail; + + if (pa_proplist_set(p, k, d, length) < 0) + goto fail; + } + + return 0; + +fail: + t->rindex = saved_rindex; + return -1; +} + void pa_tagstruct_put(pa_tagstruct *t, ...) { va_list va; pa_assert(t); @@ -591,6 +665,10 @@ void pa_tagstruct_put(pa_tagstruct *t, ...) { pa_tagstruct_put_cvolume(t, va_arg(va, pa_cvolume *)); break; + case PA_TAG_PROPLIST: + pa_tagstruct_put_proplist(t, va_arg(va, pa_proplist *)); + break; + default: pa_assert_not_reached(); } @@ -643,7 +721,7 @@ int pa_tagstruct_get(pa_tagstruct *t, ...) { case PA_TAG_BOOLEAN_TRUE: case PA_TAG_BOOLEAN_FALSE: - ret = pa_tagstruct_get_boolean(t, va_arg(va, int*)); + ret = pa_tagstruct_get_boolean(t, va_arg(va, pa_bool_t*)); break; case PA_TAG_TIMEVAL: @@ -662,6 +740,10 @@ int pa_tagstruct_get(pa_tagstruct *t, ...) { ret = pa_tagstruct_get_cvolume(t, va_arg(va, pa_cvolume *)); break; + case PA_TAG_PROPLIST: + ret = pa_tagstruct_get_proplist(t, va_arg(va, pa_proplist *)); + break; + default: pa_assert_not_reached(); } -- cgit