[pulseaudio-commits] 9 commits - src/modules src/pulse src/pulsecore src/tests

Peter Meerwald pmeerw at kemper.freedesktop.org
Thu Feb 26 14:28:28 PST 2015


 src/modules/module-card-restore.c   |    4 +-
 src/modules/module-device-manager.c |    8 ++--
 src/modules/module-device-restore.c |   12 +++---
 src/modules/module-stream-restore.c |    8 ++--
 src/modules/module-tunnel.c         |   26 ++++++-------
 src/pulse/context.c                 |    6 +--
 src/pulsecore/packet.c              |   55 ++++++++++++++++++++++++++---
 src/pulsecore/packet.h              |   20 ++++++----
 src/pulsecore/pdispatch.c           |    9 ++--
 src/pulsecore/protocol-native.c     |   34 +++++++++---------
 src/pulsecore/pstream-util.c        |   13 ++++--
 src/pulsecore/pstream.c             |   15 ++++----
 src/pulsecore/tagstruct.c           |   67 +++++++++++++++++++++++-------------
 src/pulsecore/tagstruct.h           |    4 +-
 src/tests/srbchannel-test.c         |   21 ++++++++---
 15 files changed, 193 insertions(+), 109 deletions(-)

New commits:
commit 6a55df78aaff7b29d352d2e89fa3273ab5524d93
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Thu Oct 23 14:19:44 2014 +0200

    packet: Use flist to save calls to malloc()/free()
    
    a separate free-list is used to recycle memory of fixed-sized packets
    with up to MAX_APPENDED_SIZE of data
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/pulsecore/packet.c b/src/pulsecore/packet.c
index 9dc8868..e275d23 100644
--- a/src/pulsecore/packet.c
+++ b/src/pulsecore/packet.c
@@ -26,6 +26,7 @@
 #include <pulse/xmalloc.h>
 #include <pulsecore/macro.h>
 #include <pulsecore/refcnt.h>
+#include <pulsecore/flist.h>
 
 #include "packet.h"
 
@@ -41,12 +42,15 @@ typedef struct pa_packet {
     } per_type;
 } pa_packet;
 
+PA_STATIC_FLIST_DECLARE(packets, 0, pa_xfree);
+
 pa_packet* pa_packet_new(size_t length) {
     pa_packet *p;
 
     pa_assert(length > 0);
 
-    p = pa_xnew(pa_packet, 1);
+    if (!(p = pa_flist_pop(PA_STATIC_FLIST_GET(packets))))
+        p = pa_xnew(pa_packet, 1);
     PA_REFCNT_INIT(p);
     p->length = length;
     if (length > MAX_APPENDED_SIZE) {
@@ -77,7 +81,8 @@ pa_packet* pa_packet_new_dynamic(void* data, size_t length) {
     pa_assert(data);
     pa_assert(length > 0);
 
-    p = pa_xnew(pa_packet, 1);
+    if (!(p = pa_flist_pop(PA_STATIC_FLIST_GET(packets))))
+        p = pa_xnew(pa_packet, 1);
     PA_REFCNT_INIT(p);
     p->length = length;
     p->data = data;
@@ -111,6 +116,7 @@ void pa_packet_unref(pa_packet *p) {
     if (PA_REFCNT_DEC(p) <= 0) {
         if (p->type == PA_PACKET_DYNAMIC)
             pa_xfree(p->data);
-        pa_xfree(p);
+        if (pa_flist_push(PA_STATIC_FLIST_GET(packets), p) < 0)
+            pa_xfree(p);
     }
 }

commit f92300cc92e5e51b9f42e75d7afc8b330d676528
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Thu Oct 23 16:51:08 2014 +0200

    packet: Introduce pa_packet_new_data() to copy data into a newly created packet
    
    v2: (thanks Alexander Patrakov)
    * turn check in pa_packet_new() into assert()
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/pulsecore/packet.c b/src/pulsecore/packet.c
index eacff9d..9dc8868 100644
--- a/src/pulsecore/packet.c
+++ b/src/pulsecore/packet.c
@@ -60,6 +60,17 @@ pa_packet* pa_packet_new(size_t length) {
     return p;
 }
 
+pa_packet* pa_packet_new_data(const void* data, size_t length) {
+    pa_packet *p = pa_packet_new(length);
+
+    pa_assert(data);
+    pa_assert(length > 0);
+
+    memcpy(p->data, data, length);
+
+    return p;
+}
+
 pa_packet* pa_packet_new_dynamic(void* data, size_t length) {
     pa_packet *p;
 
diff --git a/src/pulsecore/packet.h b/src/pulsecore/packet.h
index 6d61e02..2060987 100644
--- a/src/pulsecore/packet.h
+++ b/src/pulsecore/packet.h
@@ -29,6 +29,10 @@ typedef struct pa_packet pa_packet;
  * on length) */
 pa_packet* pa_packet_new(size_t length);
 
+/* create packet (either of type appended or dynamic depending on length)
+ * and copy data */
+pa_packet* pa_packet_new_data(const void* data, size_t length);
+
 /* data must have been malloc()ed; the packet takes ownership of the memory,
  * i.e. memory is free()d with the packet */
 pa_packet* pa_packet_new_dynamic(void* data, size_t length);
diff --git a/src/pulsecore/pstream-util.c b/src/pulsecore/pstream-util.c
index d8b9808..e874503 100644
--- a/src/pulsecore/pstream-util.c
+++ b/src/pulsecore/pstream-util.c
@@ -36,7 +36,7 @@ static void pa_pstream_send_tagstruct_with_ancil_data(pa_pstream *p, pa_tagstruc
     pa_assert(t);
 
     pa_assert_se(data = pa_tagstruct_data(t, &length));
-    pa_assert_se(packet = pa_packet_new_dynamic(pa_xmemdup(data, length), length));
+    pa_assert_se(packet = pa_packet_new_data(data, length));
     pa_tagstruct_free(t);
 
     pa_pstream_send_packet(p, packet, ancil_data);

commit c1a7f0e3264bc399d289cbeb8556f193db3ab67b
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Thu Oct 23 13:48:21 2014 +0200

    packet: Make pa_packet_new() create fixed-size packets
    
    if length exceeds maximum appended size, create a packet of
    type dynamic instead of type appended
    
    this is a preparation to use a separate free-list for packets
    
    document semantics of pa_packet_new_*() functions
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/pulsecore/packet.c b/src/pulsecore/packet.c
index a819ee3..eacff9d 100644
--- a/src/pulsecore/packet.c
+++ b/src/pulsecore/packet.c
@@ -29,11 +29,16 @@
 
 #include "packet.h"
 
+#define MAX_APPENDED_SIZE 128
+
 typedef struct pa_packet {
     PA_REFCNT_DECLARE;
     enum { PA_PACKET_APPENDED, PA_PACKET_DYNAMIC } type;
     size_t length;
     uint8_t *data;
+    union {
+        uint8_t appended[MAX_APPENDED_SIZE];
+    } per_type;
 } pa_packet;
 
 pa_packet* pa_packet_new(size_t length) {
@@ -41,11 +46,16 @@ pa_packet* pa_packet_new(size_t length) {
 
     pa_assert(length > 0);
 
-    p = pa_xmalloc(PA_ALIGN(sizeof(pa_packet)) + length);
+    p = pa_xnew(pa_packet, 1);
     PA_REFCNT_INIT(p);
     p->length = length;
-    p->data = (uint8_t*) p + PA_ALIGN(sizeof(pa_packet));
-    p->type = PA_PACKET_APPENDED;
+    if (length > MAX_APPENDED_SIZE) {
+        p->data = pa_xmalloc(length);
+        p->type = PA_PACKET_DYNAMIC;
+    } else {
+        p->data = p->per_type.appended;
+        p->type = PA_PACKET_APPENDED;
+    }
 
     return p;
 }
diff --git a/src/pulsecore/packet.h b/src/pulsecore/packet.h
index 83fa0b8..6d61e02 100644
--- a/src/pulsecore/packet.h
+++ b/src/pulsecore/packet.h
@@ -25,7 +25,12 @@
 
 typedef struct pa_packet pa_packet;
 
+/* create empty packet (either of type appended or dynamic depending
+ * on length) */
 pa_packet* pa_packet_new(size_t length);
+
+/* data must have been malloc()ed; the packet takes ownership of the memory,
+ * i.e. memory is free()d with the packet */
 pa_packet* pa_packet_new_dynamic(void* data, size_t length);
 
 const void* pa_packet_data(pa_packet *p, size_t *l);

commit 5a2c41e5bf13d16f01dce1e73de956ea9456b447
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Thu Oct 23 11:43:04 2014 +0200

    packet: Hide internals of pa_packet, introduce pa_packet_data()
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/pulsecore/packet.c b/src/pulsecore/packet.c
index 8fea4e2..a819ee3 100644
--- a/src/pulsecore/packet.c
+++ b/src/pulsecore/packet.c
@@ -25,9 +25,17 @@
 
 #include <pulse/xmalloc.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/refcnt.h>
 
 #include "packet.h"
 
+typedef struct pa_packet {
+    PA_REFCNT_DECLARE;
+    enum { PA_PACKET_APPENDED, PA_PACKET_DYNAMIC } type;
+    size_t length;
+    uint8_t *data;
+} pa_packet;
+
 pa_packet* pa_packet_new(size_t length) {
     pa_packet *p;
 
@@ -57,6 +65,16 @@ pa_packet* pa_packet_new_dynamic(void* data, size_t length) {
     return p;
 }
 
+const void* pa_packet_data(pa_packet *p, size_t *l) {
+    pa_assert(PA_REFCNT_VALUE(p) >= 1);
+    pa_assert(p->data);
+    pa_assert(l);
+
+    *l = p->length;
+
+    return p->data;
+}
+
 pa_packet* pa_packet_ref(pa_packet *p) {
     pa_assert(p);
     pa_assert(PA_REFCNT_VALUE(p) >= 1);
diff --git a/src/pulsecore/packet.h b/src/pulsecore/packet.h
index c49ca06..83fa0b8 100644
--- a/src/pulsecore/packet.h
+++ b/src/pulsecore/packet.h
@@ -23,18 +23,13 @@
 #include <sys/types.h>
 #include <inttypes.h>
 
-#include <pulsecore/refcnt.h>
-
-typedef struct pa_packet {
-    PA_REFCNT_DECLARE;
-    enum { PA_PACKET_APPENDED, PA_PACKET_DYNAMIC } type;
-    size_t length;
-    uint8_t *data;
-} pa_packet;
+typedef struct pa_packet pa_packet;
 
 pa_packet* pa_packet_new(size_t length);
 pa_packet* pa_packet_new_dynamic(void* data, size_t length);
 
+const void* pa_packet_data(pa_packet *p, size_t *l);
+
 pa_packet* pa_packet_ref(pa_packet *p);
 void pa_packet_unref(pa_packet *p);
 
diff --git a/src/pulsecore/pdispatch.c b/src/pulsecore/pdispatch.c
index 7837ee3..f136875 100644
--- a/src/pulsecore/pdispatch.c
+++ b/src/pulsecore/pdispatch.c
@@ -293,19 +293,20 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet *packet, const pa_cmsg_ancil_da
     uint32_t tag, command;
     pa_tagstruct *ts = NULL;
     int ret = -1;
+    const void *pdata;
+    size_t plen;
 
     pa_assert(pd);
     pa_assert(PA_REFCNT_VALUE(pd) >= 1);
     pa_assert(packet);
-    pa_assert(PA_REFCNT_VALUE(packet) >= 1);
-    pa_assert(packet->data);
 
     pa_pdispatch_ref(pd);
 
-    if (packet->length <= 8)
+    pdata = pa_packet_data(packet, &plen);
+    if (plen <= 8)
         goto finish;
 
-    ts = pa_tagstruct_new_fixed(packet->data, packet->length);
+    ts = pa_tagstruct_new_fixed(pdata, plen);
 
     if (pa_tagstruct_getu32(ts, &command) < 0 ||
         pa_tagstruct_getu32(ts, &tag) < 0)
diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c
index ad8eef1..b0ed5a7 100644
--- a/src/pulsecore/pstream.c
+++ b/src/pulsecore/pstream.c
@@ -491,14 +491,16 @@ static void prepare_next_write_item(pa_pstream *p) {
     p->write.descriptor[PA_PSTREAM_DESCRIPTOR_FLAGS] = 0;
 
     if (p->write.current->type == PA_PSTREAM_ITEM_PACKET) {
+        size_t plen;
 
         pa_assert(p->write.current->packet);
-        p->write.data = p->write.current->packet->data;
-        p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl((uint32_t) p->write.current->packet->length);
 
-        if (p->write.current->packet->length <= MINIBUF_SIZE - PA_PSTREAM_DESCRIPTOR_SIZE) {
-            memcpy(&p->write.minibuf[PA_PSTREAM_DESCRIPTOR_SIZE], p->write.data, p->write.current->packet->length);
-            p->write.minibuf_validsize = PA_PSTREAM_DESCRIPTOR_SIZE + p->write.current->packet->length;
+        p->write.data = (void *) pa_packet_data(p->write.current->packet, &plen);
+        p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl((uint32_t) plen);
+
+        if (plen <= MINIBUF_SIZE - PA_PSTREAM_DESCRIPTOR_SIZE) {
+            memcpy(&p->write.minibuf[PA_PSTREAM_DESCRIPTOR_SIZE], p->write.data, plen);
+            p->write.minibuf_validsize = PA_PSTREAM_DESCRIPTOR_SIZE + plen;
         }
 
     } else if (p->write.current->type == PA_PSTREAM_ITEM_SHMRELEASE) {
@@ -787,6 +789,7 @@ static int do_read(pa_pstream *p, struct pstream_read *re) {
         channel = ntohl(re->descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL]);
 
         if (channel == (uint32_t) -1) {
+            size_t plen;
 
             if (flags != 0) {
                 pa_log_warn("Received packet frame with invalid flags value.");
@@ -795,7 +798,7 @@ static int do_read(pa_pstream *p, struct pstream_read *re) {
 
             /* Frame is a packet frame */
             re->packet = pa_packet_new(length);
-            re->data = re->packet->data;
+            re->data = (void *) pa_packet_data(re->packet, &plen);
 
         } else {
 
diff --git a/src/tests/srbchannel-test.c b/src/tests/srbchannel-test.c
index ba7b8ef..cd4d397 100644
--- a/src/tests/srbchannel-test.c
+++ b/src/tests/srbchannel-test.c
@@ -35,26 +35,35 @@ static unsigned packets_checksum;
 static size_t packets_length;
 
 static void packet_received(pa_pstream *p, pa_packet *packet, const pa_cmsg_ancil_data *ancil_data, void *userdata) {
+    const uint8_t *pdata;
+    size_t plen;
     unsigned i;
-    fail_unless(packets_length == packet->length);
+
+    pdata = pa_packet_data(packet, &plen);
+    fail_unless(packets_length == plen);
+
     packets_received++;
-    for (i = 0; i < packet->length; i++)
-        packets_checksum += packet->data[i];
+    for (i = 0; i < plen; i++)
+        packets_checksum += pdata[i];
 }
 
 static void packet_test(unsigned npackets, size_t plength, pa_mainloop *ml, pa_pstream *p1, pa_pstream *p2) {
     pa_packet *packet = pa_packet_new(plength);
     unsigned i;
     unsigned psum = 0, totalsum = 0;
+    uint8_t *pdata;
+    size_t plen;
+
     pa_log_info("Sending %d packets of length %zd", npackets, plength);
     packets_received = 0;
     packets_checksum = 0;
     packets_length = plength;
     pa_pstream_set_receive_packet_callback(p2, packet_received, NULL);
 
-    for (i = 0; i < plength; i++) {
-        packet->data[i] = i;
-        psum += packet->data[i];
+    pdata = (uint8_t *) pa_packet_data(packet, &plen);
+    for (i = 0; i < plen; i++) {
+        pdata[i] = i;
+        psum += pdata[i];
     }
 
     for (i = 0; i < npackets; i++) {

commit 9f97f08f400a371e93ee6f178b5307427c79295c
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Thu Oct 23 11:52:43 2014 +0200

    tagstruct: Use flist to potentially save calls to malloc()/free()
    
    v2: (thanks David Henningson)
    * fix double assignment of data in pa_tagstruct_new_fixed(), two statements on one line
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c
index 4206509..8a29957 100644
--- a/src/pulsecore/tagstruct.c
+++ b/src/pulsecore/tagstruct.c
@@ -35,6 +35,7 @@
 
 #include <pulsecore/socket.h>
 #include <pulsecore/macro.h>
+#include <pulsecore/flist.h>
 
 #include "tagstruct.h"
 
@@ -57,10 +58,13 @@ struct pa_tagstruct {
     } per_type;
 };
 
+PA_STATIC_FLIST_DECLARE(tagstructs, 0, pa_xfree);
+
 pa_tagstruct *pa_tagstruct_new(void) {
     pa_tagstruct*t;
 
-    t = pa_xnew(pa_tagstruct, 1);
+    if (!(t = pa_flist_pop(PA_STATIC_FLIST_GET(tagstructs))))
+        t = pa_xnew(pa_tagstruct, 1);
     t->data = t->per_type.appended;
     t->allocated = MAX_APPENDED_SIZE;
     t->length = t->rindex = 0;
@@ -74,7 +78,8 @@ pa_tagstruct *pa_tagstruct_new_fixed(const uint8_t* data, size_t length) {
 
     pa_assert(data && length);
 
-    t = pa_xnew(pa_tagstruct, 1);
+    if (!(t = pa_flist_pop(PA_STATIC_FLIST_GET(tagstructs))))
+        t = pa_xnew(pa_tagstruct, 1);
     t->data = (uint8_t*) data;
     t->allocated = t->length = length;
     t->rindex = 0;
@@ -88,7 +93,8 @@ void pa_tagstruct_free(pa_tagstruct*t) {
 
     if (t->type == PA_TAGSTRUCT_DYNAMIC)
         pa_xfree(t->data);
-    pa_xfree(t);
+    if (pa_flist_push(PA_STATIC_FLIST_GET(tagstructs), t) < 0)
+        pa_xfree(t);
 }
 
 static inline void extend(pa_tagstruct*t, size_t l) {

commit adb577c905f2e930bdd2bfe630d6ca0ea286d6cb
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Wed Oct 22 14:59:11 2014 +0200

    tagstruct: Add type _APPENDED
    
    add 128 bytes of storage in each tagstruct that will initially
    be used; if this storage is exceeded the type changes to _DYNAMIC
    
    v3: (thanks David Henningson)
    * add comments explaining how memory is handled by different tagstruct types
    v2: (thanks Alexander Patrakov)
    * replace constant 100 with GROW_TAG_SIZE (the increment in with a dynamic tagstruct grows when extend()ed)
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c
index e78fb4a..4206509 100644
--- a/src/pulsecore/tagstruct.c
+++ b/src/pulsecore/tagstruct.c
@@ -39,6 +39,8 @@
 #include "tagstruct.h"
 
 #define MAX_TAG_SIZE (64*1024)
+#define MAX_APPENDED_SIZE 128
+#define GROW_TAG_SIZE 100
 
 struct pa_tagstruct {
     uint8_t *data;
@@ -46,19 +48,23 @@ struct pa_tagstruct {
     size_t rindex;
 
     enum {
-        PA_TAGSTRUCT_FIXED,
-        PA_TAGSTRUCT_DYNAMIC,
+        PA_TAGSTRUCT_FIXED, /* The tagstruct does not own the data, buffer was provided by caller. */
+        PA_TAGSTRUCT_DYNAMIC, /* Buffer owned by tagstruct, data must be freed. */
+        PA_TAGSTRUCT_APPENDED, /* Data points to appended buffer, used for small tagstructs. Will change to dynamic if needed. */
     } type;
+    union {
+        uint8_t appended[MAX_APPENDED_SIZE];
+    } per_type;
 };
 
 pa_tagstruct *pa_tagstruct_new(void) {
     pa_tagstruct*t;
 
     t = pa_xnew(pa_tagstruct, 1);
-    t->data = NULL;
-    t->allocated = t->length = 0;
-    t->rindex = 0;
-    t->type = PA_TAGSTRUCT_DYNAMIC;
+    t->data = t->per_type.appended;
+    t->allocated = MAX_APPENDED_SIZE;
+    t->length = t->rindex = 0;
+    t->type = PA_TAGSTRUCT_APPENDED;
 
     return t;
 }
@@ -92,7 +98,13 @@ static inline void extend(pa_tagstruct*t, size_t l) {
     if (t->length+l <= t->allocated)
         return;
 
-    t->data = pa_xrealloc(t->data, t->allocated = t->length+l+100);
+    if (t->type == PA_TAGSTRUCT_DYNAMIC)
+        t->data = pa_xrealloc(t->data, t->allocated = t->length + l + GROW_TAG_SIZE);
+    else if (t->type == PA_TAGSTRUCT_APPENDED) {
+        t->type = PA_TAGSTRUCT_DYNAMIC;
+        t->data = pa_xmalloc(t->allocated = t->length + l + GROW_TAG_SIZE);
+        memcpy(t->data, t->per_type.appended, t->length);
+    }
 }
 
 static void write_u8(pa_tagstruct *t, uint8_t u) {

commit ab948629d35276ffe956dc897a0b38c391eacfea
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Thu Oct 23 16:42:58 2014 +0200

    tagstruct: Get rid of pa_tagstruct_free_data()
    
    pa_tagstruct_free_data() is used in only one place
    to pass data from a tagstruct to a packet
    
    this patch is a temporary solution which introduces an extra
    malloc(); will be resolved shortly...
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/pulsecore/pstream-util.c b/src/pulsecore/pstream-util.c
index 1c39f78..d8b9808 100644
--- a/src/pulsecore/pstream-util.c
+++ b/src/pulsecore/pstream-util.c
@@ -23,19 +23,22 @@
 
 #include <pulsecore/native-common.h>
 #include <pulsecore/macro.h>
+#include <pulse/xmalloc.h>
 
 #include "pstream-util.h"
 
 static void pa_pstream_send_tagstruct_with_ancil_data(pa_pstream *p, pa_tagstruct *t, const pa_cmsg_ancil_data *ancil_data) {
     size_t length;
-    uint8_t *data;
+    const uint8_t *data;
     pa_packet *packet;
 
     pa_assert(p);
     pa_assert(t);
 
-    pa_assert_se(data = pa_tagstruct_free_data(t, &length));
-    pa_assert_se(packet = pa_packet_new_dynamic(data, length));
+    pa_assert_se(data = pa_tagstruct_data(t, &length));
+    pa_assert_se(packet = pa_packet_new_dynamic(pa_xmemdup(data, length), length));
+    pa_tagstruct_free(t);
+
     pa_pstream_send_packet(p, packet, ancil_data);
     pa_packet_unref(packet);
 }
diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c
index 84a2b82..e78fb4a 100644
--- a/src/pulsecore/tagstruct.c
+++ b/src/pulsecore/tagstruct.c
@@ -85,19 +85,6 @@ void pa_tagstruct_free(pa_tagstruct*t) {
     pa_xfree(t);
 }
 
-uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l) {
-    uint8_t *p;
-
-    pa_assert(t);
-    pa_assert(t->type == PA_TAGSTRUCT_DYNAMIC);
-    pa_assert(l);
-
-    p = t->data;
-    *l = t->length;
-    pa_xfree(t);
-    return p;
-}
-
 static inline void extend(pa_tagstruct*t, size_t l) {
     pa_assert(t);
     pa_assert(t->type != PA_TAGSTRUCT_FIXED);
diff --git a/src/pulsecore/tagstruct.h b/src/pulsecore/tagstruct.h
index e67adc1..348c65d 100644
--- a/src/pulsecore/tagstruct.h
+++ b/src/pulsecore/tagstruct.h
@@ -63,7 +63,6 @@ enum {
 pa_tagstruct *pa_tagstruct_new(void);
 pa_tagstruct *pa_tagstruct_new_fixed(const uint8_t* data, size_t length);
 void pa_tagstruct_free(pa_tagstruct*t);
-uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l);
 
 int pa_tagstruct_eof(pa_tagstruct*t);
 const uint8_t* pa_tagstruct_data(pa_tagstruct*t, size_t *l);

commit b96971941b0fcd13de9002d37e1b491811944cb6
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Wed Oct 22 14:52:23 2014 +0200

    tagstruct: Replace dynamic flag with type
    
    ... in order to prepare for a new type _APPENDED
    
    remove the assert() for dynamic in pa_tagstruct_data() as
    the function makes sense for all tagstruct types (and the returned pointer
    is const)
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c
index 251618a..84a2b82 100644
--- a/src/pulsecore/tagstruct.c
+++ b/src/pulsecore/tagstruct.c
@@ -45,7 +45,10 @@ struct pa_tagstruct {
     size_t length, allocated;
     size_t rindex;
 
-    bool dynamic;
+    enum {
+        PA_TAGSTRUCT_FIXED,
+        PA_TAGSTRUCT_DYNAMIC,
+    } type;
 };
 
 pa_tagstruct *pa_tagstruct_new(void) {
@@ -55,7 +58,7 @@ pa_tagstruct *pa_tagstruct_new(void) {
     t->data = NULL;
     t->allocated = t->length = 0;
     t->rindex = 0;
-    t->dynamic = true;
+    t->type = PA_TAGSTRUCT_DYNAMIC;
 
     return t;
 }
@@ -69,7 +72,7 @@ pa_tagstruct *pa_tagstruct_new_fixed(const uint8_t* data, size_t length) {
     t->data = (uint8_t*) data;
     t->allocated = t->length = length;
     t->rindex = 0;
-    t->dynamic = false;
+    t->type = PA_TAGSTRUCT_FIXED;
 
     return t;
 }
@@ -77,7 +80,7 @@ pa_tagstruct *pa_tagstruct_new_fixed(const uint8_t* data, size_t length) {
 void pa_tagstruct_free(pa_tagstruct*t) {
     pa_assert(t);
 
-    if (t->dynamic)
+    if (t->type == PA_TAGSTRUCT_DYNAMIC)
         pa_xfree(t->data);
     pa_xfree(t);
 }
@@ -86,7 +89,7 @@ uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l) {
     uint8_t *p;
 
     pa_assert(t);
-    pa_assert(t->dynamic);
+    pa_assert(t->type == PA_TAGSTRUCT_DYNAMIC);
     pa_assert(l);
 
     p = t->data;
@@ -97,7 +100,7 @@ uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l) {
 
 static inline void extend(pa_tagstruct*t, size_t l) {
     pa_assert(t);
-    pa_assert(t->dynamic);
+    pa_assert(t->type != PA_TAGSTRUCT_FIXED);
 
     if (t->length+l <= t->allocated)
         return;
@@ -449,7 +452,6 @@ int pa_tagstruct_eof(pa_tagstruct*t) {
 
 const uint8_t* pa_tagstruct_data(pa_tagstruct*t, size_t *l) {
     pa_assert(t);
-    pa_assert(t->dynamic);
     pa_assert(l);
 
     *l = t->length;

commit 037fdf485fd085525235ab4c9093a9a9eb73c414
Author: Peter Meerwald <p.meerwald at bct-electronic.com>
Date:   Thu Oct 23 16:09:45 2014 +0200

    tagstruct: Distinguish pa_tagstruct_new() use cases
    
    pa_tagstruct_new() is called either with no data, i.e. (NULL, 0)
    to create a dynamic tagstruct or with a pointer to fixed data
    
    introduce a new function pa_tagstruct_new_fixed() for the latter case
    
    Signed-off-by: Peter Meerwald <pmeerw at pmeerw.net>

diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c
index baa2f4f..f5577db 100644
--- a/src/modules/module-card-restore.c
+++ b/src/modules/module-card-restore.c
@@ -195,7 +195,7 @@ static bool entry_write(struct userdata *u, const char *name, const struct entry
     pa_assert(name);
     pa_assert(e);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu8(t, e->version);
     pa_tagstruct_puts(t, e->profile);
     pa_tagstruct_putu32(t, pa_hashmap_size(e->ports));
@@ -273,7 +273,7 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
         return NULL;
     }
 
-    t = pa_tagstruct_new(data.data, data.size);
+    t = pa_tagstruct_new_fixed(data.data, data.size);
     e = entry_new();
 
     if (pa_tagstruct_getu8(t, &e->version) < 0 ||
diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c
index 46a6955..f125bdd 100644
--- a/src/modules/module-device-manager.c
+++ b/src/modules/module-device-manager.c
@@ -207,7 +207,7 @@ static bool entry_write(struct userdata *u, const char *name, const struct entry
     pa_assert(name);
     pa_assert(e);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu8(t, e->version);
     pa_tagstruct_puts(t, e->description);
     pa_tagstruct_put_boolean(t, e->user_set_description);
@@ -295,7 +295,7 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
     if (!pa_database_get(u->database, &key, &data))
         goto fail;
 
-    t = pa_tagstruct_new(data.data, data.size);
+    t = pa_tagstruct_new_fixed(data.data, data.size);
     e = entry_new();
 
     if (pa_tagstruct_getu8(t, &e->version) < 0 ||
@@ -449,7 +449,7 @@ static void notify_subscribers(struct userdata *u) {
     PA_IDXSET_FOREACH(c, u->subscribed, idx) {
         pa_tagstruct *t;
 
-        t = pa_tagstruct_new(NULL, 0);
+        t = pa_tagstruct_new();
         pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION);
         pa_tagstruct_putu32(t, 0);
         pa_tagstruct_putu32(t, u->module->index);
@@ -1130,7 +1130,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
   if (pa_tagstruct_getu32(t, &command) < 0)
     goto fail;
 
-  reply = pa_tagstruct_new(NULL, 0);
+  reply = pa_tagstruct_new();
   pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
   pa_tagstruct_putu32(reply, tag);
 
diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c
index 70a6517..f515de7 100644
--- a/src/modules/module-device-restore.c
+++ b/src/modules/module-device-restore.c
@@ -151,7 +151,7 @@ static void trigger_save(struct userdata *u, pa_device_type_t type, uint32_t sin
         PA_IDXSET_FOREACH(c, u->subscribed, idx) {
             pa_tagstruct *t;
 
-            t = pa_tagstruct_new(NULL, 0);
+            t = pa_tagstruct_new();
             pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION);
             pa_tagstruct_putu32(t, 0);
             pa_tagstruct_putu32(t, u->module->index);
@@ -200,7 +200,7 @@ static bool entry_write(struct userdata *u, const char *name, const struct entry
     pa_assert(name);
     pa_assert(e);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu8(t, e->version);
     pa_tagstruct_put_boolean(t, e->port_valid);
     pa_tagstruct_puts(t, e->port);
@@ -236,7 +236,7 @@ static struct entry* entry_read(struct userdata *u, const char *name) {
         return NULL;
     }
 
-    t = pa_tagstruct_new(data.data, data.size);
+    t = pa_tagstruct_new_fixed(data.data, data.size);
     e = entry_new();
 
     if (pa_tagstruct_getu8(t, &e->version) < 0 ||
@@ -371,7 +371,7 @@ static bool perportentry_write(struct userdata *u, const char *basekeyname, cons
     n_formats = pa_idxset_size(e->formats);
     pa_assert(n_formats > 0);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu8(t, e->version);
     pa_tagstruct_put_boolean(t, e->volume_valid);
     pa_tagstruct_put_channel_map(t, &e->channel_map);
@@ -417,7 +417,7 @@ static struct perportentry* perportentry_read(struct userdata *u, const char *ba
     if (!pa_database_get(u->database, &key, &data))
         goto fail;
 
-    t = pa_tagstruct_new(data.data, data.size);
+    t = pa_tagstruct_new_fixed(data.data, data.size);
     e = perportentry_new(false);
 
     if (pa_tagstruct_getu8(t, &e->version) < 0 ||
@@ -1041,7 +1041,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
     if (pa_tagstruct_getu32(t, &command) < 0)
         goto fail;
 
-    reply = pa_tagstruct_new(NULL, 0);
+    reply = pa_tagstruct_new();
     pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
     pa_tagstruct_putu32(reply, tag);
 
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index 30c9717..397b58f 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -992,7 +992,7 @@ static bool entry_write(struct userdata *u, const char *name, const struct entry
     pa_assert(name);
     pa_assert(e);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu8(t, e->version);
     pa_tagstruct_put_boolean(t, e->volume_valid);
     pa_tagstruct_put_channel_map(t, &e->channel_map);
@@ -1124,7 +1124,7 @@ static struct entry *entry_read(struct userdata *u, const char *name) {
     if (!pa_database_get(u->database, &key, &data))
         goto fail;
 
-    t = pa_tagstruct_new(data.data, data.size);
+    t = pa_tagstruct_new_fixed(data.data, data.size);
     e = entry_new();
 
     if (pa_tagstruct_getu8(t, &e->version) < 0 ||
@@ -1201,7 +1201,7 @@ static void trigger_save(struct userdata *u) {
     PA_IDXSET_FOREACH(c, u->subscribed, idx) {
         pa_tagstruct *t;
 
-        t = pa_tagstruct_new(NULL, 0);
+        t = pa_tagstruct_new();
         pa_tagstruct_putu32(t, PA_COMMAND_EXTENSION);
         pa_tagstruct_putu32(t, 0);
         pa_tagstruct_putu32(t, u->module->index);
@@ -2016,7 +2016,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
     if (pa_tagstruct_getu32(t, &command) < 0)
         goto fail;
 
-    reply = pa_tagstruct_new(NULL, 0);
+    reply = pa_tagstruct_new();
     pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
     pa_tagstruct_putu32(reply, tag);
 
diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c
index 7c233c9..833423a 100644
--- a/src/modules/module-tunnel.c
+++ b/src/modules/module-tunnel.c
@@ -447,7 +447,7 @@ static void stream_cork(struct userdata *u, bool cork) {
     if (!u->pstream)
         return;
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
 #ifdef TUNNEL_SINK
     pa_tagstruct_putu32(t, PA_COMMAND_CORK_PLAYBACK_STREAM);
 #else
@@ -880,7 +880,7 @@ static void request_latency(struct userdata *u) {
     uint32_t tag;
     pa_assert(u);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
 #ifdef TUNNEL_SINK
     pa_tagstruct_putu32(t, PA_COMMAND_GET_PLAYBACK_LATENCY);
 #else
@@ -942,7 +942,7 @@ static void update_description(struct userdata *u) {
                           pa_get_user_name(un, sizeof(un)),
                           pa_get_host_name(hn, sizeof(hn)));
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
 #ifdef TUNNEL_SINK
     pa_tagstruct_putu32(t, PA_COMMAND_SET_PLAYBACK_STREAM_NAME);
 #else
@@ -1362,14 +1362,14 @@ static void request_info(struct userdata *u) {
     uint32_t tag;
     pa_assert(u);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_GET_SERVER_INFO);
     pa_tagstruct_putu32(t, tag = u->ctag++);
     pa_pstream_send_tagstruct(u->pstream, t);
     pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, server_info_cb, u, NULL);
 
 #ifdef TUNNEL_SINK
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INPUT_INFO);
     pa_tagstruct_putu32(t, tag = u->ctag++);
     pa_tagstruct_putu32(t, u->device_index);
@@ -1377,7 +1377,7 @@ static void request_info(struct userdata *u) {
     pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, sink_input_info_cb, u, NULL);
 
     if (u->sink_name) {
-        t = pa_tagstruct_new(NULL, 0);
+        t = pa_tagstruct_new();
         pa_tagstruct_putu32(t, PA_COMMAND_GET_SINK_INFO);
         pa_tagstruct_putu32(t, tag = u->ctag++);
         pa_tagstruct_putu32(t, PA_INVALID_INDEX);
@@ -1387,7 +1387,7 @@ static void request_info(struct userdata *u) {
     }
 #else
     if (u->source_name) {
-        t = pa_tagstruct_new(NULL, 0);
+        t = pa_tagstruct_new();
         pa_tagstruct_putu32(t, PA_COMMAND_GET_SOURCE_INFO);
         pa_tagstruct_putu32(t, tag = u->ctag++);
         pa_tagstruct_putu32(t, PA_INVALID_INDEX);
@@ -1434,7 +1434,7 @@ static void start_subscribe(struct userdata *u) {
     pa_tagstruct *t;
     pa_assert(u);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE);
     pa_tagstruct_putu32(t, u->ctag++);
     pa_tagstruct_putu32(t, PA_SUBSCRIPTION_MASK_SERVER|
@@ -1619,7 +1619,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
                 pa_get_host_name(hn, sizeof(hn)));
 #endif
 
-    reply = pa_tagstruct_new(NULL, 0);
+    reply = pa_tagstruct_new();
     pa_tagstruct_putu32(reply, PA_COMMAND_SET_CLIENT_NAME);
     pa_tagstruct_putu32(reply, u->ctag++);
 
@@ -1637,7 +1637,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
     pa_pstream_send_tagstruct(u->pstream, reply);
     /* We ignore the server's reply here */
 
-    reply = pa_tagstruct_new(NULL, 0);
+    reply = pa_tagstruct_new();
 
     if (u->version < 13)
         /* Only for older PA versions we need to fill in the maxlength */
@@ -1841,7 +1841,7 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
     pa_pstream_set_receive_memblock_callback(u->pstream, pstream_memblock_callback, u);
 #endif
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_AUTH);
     pa_tagstruct_putu32(t, tag = u->ctag++);
     pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION);
@@ -1880,7 +1880,7 @@ static void sink_set_volume(pa_sink *sink) {
     u = sink->userdata;
     pa_assert(u);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_VOLUME);
     pa_tagstruct_putu32(t, u->ctag++);
     pa_tagstruct_putu32(t, u->device_index);
@@ -1900,7 +1900,7 @@ static void sink_set_mute(pa_sink *sink) {
     if (u->version < 11)
         return;
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_SET_SINK_INPUT_MUTE);
     pa_tagstruct_putu32(t, u->ctag++);
     pa_tagstruct_putu32(t, u->device_index);
diff --git a/src/pulse/context.c b/src/pulse/context.c
index 30d3eab..738ea84 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -369,7 +369,7 @@ static void handle_srbchannel_memblock(pa_context *c, pa_memblock *memblock) {
     }
 
     /* Ack the enable command */
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_ENABLE_SRBCHANNEL);
     pa_tagstruct_putu32(t, c->srb_setup_tag);
     pa_pstream_send_tagstruct(c->pstream, t);
@@ -1305,7 +1305,7 @@ pa_tagstruct *pa_tagstruct_command(pa_context *c, uint32_t command, uint32_t *ta
     pa_assert(c);
     pa_assert(tag);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, command);
     pa_tagstruct_putu32(t, *tag = c->ctag++);
 
@@ -1479,7 +1479,7 @@ static void pa_command_disable_srbchannel(pa_pdispatch *pd, uint32_t command, ui
     }
 
     /* Send disable command back again */
-    t2 = pa_tagstruct_new(NULL, 0);
+    t2 = pa_tagstruct_new();
     pa_tagstruct_putu32(t2, PA_COMMAND_DISABLE_SRBCHANNEL);
     pa_tagstruct_putu32(t2, tag);
     pa_pstream_send_tagstruct(c->pstream, t2);
diff --git a/src/pulsecore/pdispatch.c b/src/pulsecore/pdispatch.c
index c258c0b..7837ee3 100644
--- a/src/pulsecore/pdispatch.c
+++ b/src/pulsecore/pdispatch.c
@@ -305,7 +305,7 @@ int pa_pdispatch_run(pa_pdispatch *pd, pa_packet *packet, const pa_cmsg_ancil_da
     if (packet->length <= 8)
         goto finish;
 
-    ts = pa_tagstruct_new(packet->data, packet->length);
+    ts = pa_tagstruct_new_fixed(packet->data, packet->length);
 
     if (pa_tagstruct_getu32(ts, &command) < 0 ||
         pa_tagstruct_getu32(ts, &tag) < 0)
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index f54f2a4..ba9b406 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -757,7 +757,7 @@ static void record_stream_send_killed(record_stream *r) {
     pa_tagstruct *t;
     record_stream_assert_ref(r);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_KILLED);
     pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
     pa_tagstruct_putu32(t, r->index);
@@ -818,7 +818,7 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
                     break;
             }
 
-            t = pa_tagstruct_new(NULL, 0);
+            t = pa_tagstruct_new();
             pa_tagstruct_putu32(t, PA_COMMAND_REQUEST);
             pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
             pa_tagstruct_putu32(t, s->index);
@@ -839,7 +839,7 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
 #endif
 
             /* Report that we're empty */
-            t = pa_tagstruct_new(NULL, 0);
+            t = pa_tagstruct_new();
             pa_tagstruct_putu32(t, PA_COMMAND_UNDERFLOW);
             pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
             pa_tagstruct_putu32(t, s->index);
@@ -853,7 +853,7 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
             pa_tagstruct *t;
 
             /* Notify the user we're overflowed*/
-            t = pa_tagstruct_new(NULL, 0);
+            t = pa_tagstruct_new();
             pa_tagstruct_putu32(t, PA_COMMAND_OVERFLOW);
             pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
             pa_tagstruct_putu32(t, s->index);
@@ -867,7 +867,7 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
                 pa_tagstruct *t;
 
                 /* Notify the user we started playback */
-                t = pa_tagstruct_new(NULL, 0);
+                t = pa_tagstruct_new();
                 pa_tagstruct_putu32(t, PA_COMMAND_STARTED);
                 pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
                 pa_tagstruct_putu32(t, s->index);
@@ -887,7 +887,7 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
             if (s->connection->version >= 15) {
                 pa_tagstruct *t;
 
-                t = pa_tagstruct_new(NULL, 0);
+                t = pa_tagstruct_new();
                 pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED);
                 pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
                 pa_tagstruct_putu32(t, s->index);
@@ -1285,7 +1285,7 @@ static void playback_stream_send_killed(playback_stream *p) {
     pa_tagstruct *t;
     playback_stream_assert_ref(p);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_KILLED);
     pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
     pa_tagstruct_putu32(t, p->index);
@@ -1747,7 +1747,7 @@ static void sink_input_send_event_cb(pa_sink_input *i, const char *event, pa_pro
     if (s->connection->version < 15)
       return;
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_EVENT);
     pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
     pa_tagstruct_putu32(t, s->index);
@@ -1768,7 +1768,7 @@ static void sink_input_suspend_cb(pa_sink_input *i, bool suspend) {
     if (s->connection->version < 12)
       return;
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_SUSPENDED);
     pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
     pa_tagstruct_putu32(t, s->index);
@@ -1795,7 +1795,7 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
     if (s->connection->version < 12)
       return;
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_MOVED);
     pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
     pa_tagstruct_putu32(t, s->index);
@@ -1885,7 +1885,7 @@ static void source_output_send_event_cb(pa_source_output *o, const char *event,
     if (s->connection->version < 15)
       return;
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_EVENT);
     pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
     pa_tagstruct_putu32(t, s->index);
@@ -1906,7 +1906,7 @@ static void source_output_suspend_cb(pa_source_output *o, bool suspend) {
     if (s->connection->version < 12)
       return;
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_SUSPENDED);
     pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
     pa_tagstruct_putu32(t, s->index);
@@ -1934,7 +1934,7 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
     if (s->connection->version < 12)
       return;
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_MOVED);
     pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
     pa_tagstruct_putu32(t, s->index);
@@ -1975,7 +1975,7 @@ if (!(expression)) { \
 static pa_tagstruct *reply_new(uint32_t tag) {
     pa_tagstruct *reply;
 
-    reply = pa_tagstruct_new(NULL, 0);
+    reply = pa_tagstruct_new();
     pa_tagstruct_putu32(reply, PA_COMMAND_REPLY);
     pa_tagstruct_putu32(reply, tag);
     return reply;
@@ -2619,7 +2619,7 @@ static void setup_srbchannel(pa_native_connection *c) {
     pa_srbchannel_export(srb, &srbt);
 
     /* Send enable command to client */
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_ENABLE_SRBCHANNEL);
     pa_tagstruct_putu32(t, (size_t) srb); /* tag */
     fdlist[0] = srbt.readfd;
@@ -3744,7 +3744,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint3
 
     pa_native_connection_assert_ref(c);
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE_EVENT);
     pa_tagstruct_putu32(t, (uint32_t) -1);
     pa_tagstruct_putu32(t, e);
@@ -5037,7 +5037,7 @@ static void client_send_event_cb(pa_client *client, const char*event, pa_proplis
     if (c->version < 15)
       return;
 
-    t = pa_tagstruct_new(NULL, 0);
+    t = pa_tagstruct_new();
     pa_tagstruct_putu32(t, PA_COMMAND_CLIENT_EVENT);
     pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */
     pa_tagstruct_puts(t, event);
diff --git a/src/pulsecore/pstream-util.c b/src/pulsecore/pstream-util.c
index 356d28c..1c39f78 100644
--- a/src/pulsecore/pstream-util.c
+++ b/src/pulsecore/pstream-util.c
@@ -84,7 +84,7 @@ void pa_pstream_send_tagstruct_with_fds(pa_pstream *p, pa_tagstruct *t, int nfd,
 void pa_pstream_send_error(pa_pstream *p, uint32_t tag, uint32_t error) {
     pa_tagstruct *t;
 
-    pa_assert_se(t = pa_tagstruct_new(NULL, 0));
+    pa_assert_se(t = pa_tagstruct_new());
     pa_tagstruct_putu32(t, PA_COMMAND_ERROR);
     pa_tagstruct_putu32(t, tag);
     pa_tagstruct_putu32(t, error);
@@ -94,7 +94,7 @@ void pa_pstream_send_error(pa_pstream *p, uint32_t tag, uint32_t error) {
 void pa_pstream_send_simple_ack(pa_pstream *p, uint32_t tag) {
     pa_tagstruct *t;
 
-    pa_assert_se(t = pa_tagstruct_new(NULL, 0));
+    pa_assert_se(t = pa_tagstruct_new());
     pa_tagstruct_putu32(t, PA_COMMAND_REPLY);
     pa_tagstruct_putu32(t, tag);
     pa_pstream_send_tagstruct(p, t);
diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c
index bf123d5..251618a 100644
--- a/src/pulsecore/tagstruct.c
+++ b/src/pulsecore/tagstruct.c
@@ -48,16 +48,28 @@ struct pa_tagstruct {
     bool dynamic;
 };
 
-pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length) {
+pa_tagstruct *pa_tagstruct_new(void) {
     pa_tagstruct*t;
 
-    pa_assert(!data || (data && length));
+    t = pa_xnew(pa_tagstruct, 1);
+    t->data = NULL;
+    t->allocated = t->length = 0;
+    t->rindex = 0;
+    t->dynamic = true;
+
+    return t;
+}
+
+pa_tagstruct *pa_tagstruct_new_fixed(const uint8_t* data, size_t length) {
+    pa_tagstruct*t;
+
+    pa_assert(data && length);
 
     t = pa_xnew(pa_tagstruct, 1);
     t->data = (uint8_t*) data;
-    t->allocated = t->length = data ? length : 0;
+    t->allocated = t->length = length;
     t->rindex = 0;
-    t->dynamic = !data;
+    t->dynamic = false;
 
     return t;
 }
diff --git a/src/pulsecore/tagstruct.h b/src/pulsecore/tagstruct.h
index 6319ee9..e67adc1 100644
--- a/src/pulsecore/tagstruct.h
+++ b/src/pulsecore/tagstruct.h
@@ -60,7 +60,8 @@ enum {
     PA_TAG_FORMAT_INFO = 'f',
 };
 
-pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length);
+pa_tagstruct *pa_tagstruct_new(void);
+pa_tagstruct *pa_tagstruct_new_fixed(const uint8_t* data, size_t length);
 void pa_tagstruct_free(pa_tagstruct*t);
 uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l);
 



More information about the pulseaudio-commits mailing list