From: Jonathan Bastien-Filiatrault Date: Wed, 8 Sep 2010 22:34:43 +0000 (-0400) Subject: mbuffers: Add mbuffer_linearize. X-Git-Tag: gnutls_2_11_3~49 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7f1ea52b58b42541b11b10166ed5c733732d2bea;p=thirdparty%2Fgnutls.git mbuffers: Add mbuffer_linearize. Signed-off-by: Jonathan Bastien-Filiatrault Signed-off-by: Nikos Mavrogiannopoulos --- diff --git a/lib/gnutls_mbuffers.c b/lib/gnutls_mbuffers.c index 45c4b97f0d..c9af21d9e1 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 ed94824826..8f08a96f9c 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.