merge glitch-free branch back into trunk
[profile/ivi/pulseaudio.git] / src / pulsecore / tagstruct.c
index 556fe80..7616cd1 100644 (file)
 
 #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();
         }