[PATCH 4/8] mbuffers: Add mbuffer_linearize.

Jonathan Bastien-Filiatrault joe at x2a.org
Thu Sep 9 00:34:43 CEST 2010


Signed-off-by: Jonathan Bastien-Filiatrault <joe at x2a.org>

diff --git a/lib/gnutls_mbuffers.c b/lib/gnutls_mbuffers.c
index 45c4b97..c9af21d 100644
--- a/lib/gnutls_mbuffers.c
+++ b/lib/gnutls_mbuffers.c
@@ -272,3 +272,42 @@ _mbuffer_append_data (mbuffer_st *bufel, void* newdata, size_t newdata_size)
 
   return 0;
 }
+
+/* Takes a buffer in multiple chunks and puts all the data in a single
+ * contiguous segment.
+ *
+ * Returns 0 on success or an error code otherwise.
+ *
+ * Cost: O(n)
+ * n: number of segments initially in the buffer
+ */
+int
+_mbuffer_linearize (mbuffer_head_st *buf)
+{
+  mbuffer_st *bufel, *cur;
+  gnutls_datum_t msg;
+  size_t pos=0;
+
+  if (buf->length <= 1)
+    /* Nothing to do */
+    return 0;
+
+  bufel = _mbuffer_alloc (buf->byte_length, buf->byte_length);
+  if (!bufel) {
+    gnutls_assert ();
+    return GNUTLS_E_MEMORY_ERROR;
+  }
+
+  for (cur = _mbuffer_get_first(buf, &msg);
+       msg.data != NULL;
+       cur = _mbuffer_get_next(cur, &msg))
+    {
+      memcpy (&bufel->msg.data[pos], msg.data, cur->msg.size);
+      pos += cur->msg.size;
+    }
+
+  _mbuffer_clear (buf);
+  _mbuffer_enqueue (buf, bufel);
+
+  return 0;
+}
diff --git a/lib/gnutls_mbuffers.h b/lib/gnutls_mbuffers.h
index ed94824..8f08a96 100644
--- a/lib/gnutls_mbuffers.h
+++ b/lib/gnutls_mbuffers.h
@@ -40,6 +40,7 @@ mbuffer_st* _mbuffer_get_next (mbuffer_st * cur, gnutls_datum_t *msg);
  * one.
  */
 int _mbuffer_append_data (mbuffer_st *bufel, void* newdata, size_t newdata_size);
+int _mbuffer_linearize (mbuffer_head_st *buf);
 
 
 /* For "user" use. One can have buffer data and header.
-- 
1.7.1





More information about the Gnutls-devel mailing list