[tor-commits] [tor/master] Add a generic_buffer_t to use the best buffer type we have on hand

nickm at torproject.org nickm at torproject.org
Wed Jul 20 13:51:20 UTC 2011


commit 34a52534bb43b30e19267968807a540ba33abe3b
Author: Nick Mathewson <nickm at torproject.org>
Date:   Mon Jul 18 15:36:20 2011 -0400

    Add a generic_buffer_t to use the best buffer type we have on hand
    
    Also add a quick function to copy all the data in a buffer.  (This
    one could be done much better, but let's see if it matters.)
---
 src/or/buffers.c |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/or/buffers.h |   19 ++++++++++++++
 src/or/or.h      |    5 ++++
 3 files changed, 94 insertions(+), 0 deletions(-)

diff --git a/src/or/buffers.c b/src/or/buffers.c
index 256b507..63132db 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -557,6 +557,39 @@ buf_free(buf_t *buf)
   tor_free(buf);
 }
 
+/** Return a new copy of <b>in_chunk</b> */
+static chunk_t *
+chunk_copy(const chunk_t *in_chunk)
+{
+  chunk_t *newch = tor_memdup(in_chunk, CHUNK_ALLOC_SIZE(in_chunk->memlen));
+  newch->next = NULL;
+  if (in_chunk->data) {
+    off_t offset = in_chunk->data - in_chunk->mem;
+    newch->data = newch->mem + offset;
+  }
+  return newch;
+}
+
+/** Return a new copy of <b>buf</b> */
+buf_t *
+buf_copy(const buf_t *buf)
+{
+  chunk_t *ch;
+  buf_t *out = buf_new();
+  out->default_chunk_size = buf->default_chunk_size;
+  for (ch = buf->head; ch; ch = ch->next) {
+    chunk_t *newch = chunk_copy(ch);
+    if (out->tail) {
+      out->tail->next = newch;
+      out->tail = newch;
+    } else {
+      out->head = out->tail = newch;
+    }
+  }
+  out->datalen = buf->datalen;
+  return out;
+}
+
 /** Append a new chunk with enough capacity to hold <b>capacity</b> bytes to
  * the tail of <b>buf</b>.  If <b>capped</b>, don't allocate a chunk bigger
  * than MAX_CHUNK_ALLOC. */
@@ -2374,6 +2407,43 @@ write_to_evbuffer_zlib(struct evbuffer *buf, tor_zlib_state_t *state,
 }
 #endif
 
+/** Set *<b>output</b> to contain a copy of the data in *<b>input</b> */
+int
+generic_buffer_set_to_copy(generic_buffer_t **output,
+                           const generic_buffer_t *input)
+{
+#ifdef USE_BUFFEREVENTS
+  struct evbuffer_ptr ptr;
+  size_t remaining = evbuffer_get_length(input);
+  if (*output) {
+    evbuffer_drain(*output, evbuffer_get_length(*output));
+  } else {
+    if (!(*output = evbuffer_new()))
+      return -1;
+  }
+  evbuffer_ptr_set((struct evbuffer*)input, &ptr, 0, EVBUFFER_PTR_SET);
+  while (remaining) {
+    struct evbuffer_iovec v[4];
+    int n_used, i;
+    n_used = evbuffer_peek((struct evbuffer*)input, -1, &ptr, v, 4);
+    if (n_used < 0)
+      return -1;
+    for (i=0;i<n_used;++i) {
+      evbuffer_add(*output, v[i].iov_base, v[i].iov_len);
+      tor_assert(v[i].iov_len <= remaining);
+      remaining -= v[i].iov_len;
+      evbuffer_ptr_set((struct evbuffer*)input,
+                       &ptr, v[i].iov_len, EVBUFFER_PTR_ADD);
+    }
+  }
+#else
+  if (*output)
+    buf_free(*output);
+  *output = buf_copy(input);
+#endif
+  return 0;
+}
+
 /** Log an error and exit if <b>buf</b> is corrupted.
  */
 void
diff --git a/src/or/buffers.h b/src/or/buffers.h
index b0161b9..7b2a2ac 100644
--- a/src/or/buffers.h
+++ b/src/or/buffers.h
@@ -16,6 +16,7 @@ buf_t *buf_new(void);
 buf_t *buf_new_with_capacity(size_t size);
 void buf_free(buf_t *buf);
 void buf_clear(buf_t *buf);
+buf_t *buf_copy(const buf_t *buf);
 void buf_shrink(buf_t *buf);
 void buf_shrink_freelists(int free_all);
 void buf_dump_freelist_sizes(int severity);
@@ -67,6 +68,24 @@ int write_to_evbuffer_zlib(struct evbuffer *buf, tor_zlib_state_t *state,
                            int done);
 #endif
 
+#ifdef USE_BUFFEREVENTS
+#define generic_buffer_new() evbuffer_new()
+#define generic_buffer_len(b) evbuffer_get_length((b))
+#define generic_buffer_add(b,dat,len) evbuffer_add((b),(dat),(len))
+#define generic_buffer_get(b,buf,buflen) evbuffer_remove((b),(buf),(buflen))
+#define generic_buffer_clear(b) evbuffer_drain((b), evbuffer_get_length((b)))
+#define generic_buffer_free(b) evbuffer_free((b))
+#else
+#define generic_buffer_new() buf_new()
+#define generic_buffer_len(b) buf_datalen((b))
+#define generic_buffer_add(b,dat,len) write_to_buf((dat),(len),(b))
+#define generic_buffer_get(b,buf,buflen) fetch_from_buf((buf),(buflen),(b))
+#define generic_buffer_clear(b) buf_clear((b))
+#define generic_buffer_free(b) buf_free((b))
+#endif
+int generic_buffer_set_to_copy(generic_buffer_t **output,
+                               const generic_buffer_t *input);
+
 void assert_buf_ok(buf_t *buf);
 
 #ifdef BUFFERS_PRIVATE
diff --git a/src/or/or.h b/src/or/or.h
index f805215..c784267 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -930,6 +930,11 @@ typedef struct {
 
 typedef struct buf_t buf_t;
 typedef struct socks_request_t socks_request_t;
+#ifdef USE_BUFFEREVENTS
+#define generic_buffer_t struct evbuffer
+#else
+#define generic_buffer_t buf_t
+#endif
 
 /* Values for connection_t.magic: used to make sure that downcasts (casts from
 * connection_t to foo_connection_t) are safe. */





More information about the tor-commits mailing list