#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) {
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);
}
}
+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;
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);
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;
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);
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();
}
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:
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();
}