]> granicus.if.org Git - libevent/commitdiff
introduce evbuffer_reserve_space() and evbuffer_commit_space() to make processing...
authorNiels Provos <provos@gmail.com>
Sat, 3 May 2008 03:05:28 +0000 (03:05 +0000)
committerNiels Provos <provos@gmail.com>
Sat, 3 May 2008 03:05:28 +0000 (03:05 +0000)
svn:r757

ChangeLog
buffer.c
include/event2/buffer.h
test/regress.c
test/regress_zlib.c

index c31573ed1b3a62a9790f5b6a373fe731163b9303..d6cb1f12b56eb18ac07bf618710bed58b29796c8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -84,6 +84,7 @@ Changes in current version:
  o add new evtimer_assign, signal_assign, evtimer_new, and signal_new functions to manipulate timer and signal events, analagous to the now-recommended event_assign and event_new
  o switch internal uses of event_set over to use event_assign.
  o introduce evbuffer_contiguous_space() api that tells a user how much data is available in the first buffer chain
+ o introduce evbuffer_reserve_space() and evbuffer_commit_space() to make processing in filters more efficient.
        
 Changes in 1.4.0:
  o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
index 20dfb160fd8bca3c48273e0116a525d8b72c2d39..eec9b783bafdf85909cd71acba426aad1bc5348c 100644 (file)
--- a/buffer.c
+++ b/buffer.c
@@ -131,6 +131,34 @@ evbuffer_contiguous_space(struct evbuffer *buf)
        return (chain != NULL ? chain->off : 0);
 }
 
+u_char *
+evbuffer_reserve_space(struct evbuffer *buf, size_t size)
+{
+       struct evbuffer_chain *chain;
+
+       if (evbuffer_expand(buf, size) == -1)
+               return (NULL);
+
+       chain = buf->last;
+
+       return (chain->buffer + chain->misalign + chain->off);
+}
+
+int
+evbuffer_commit_space(struct evbuffer *buf, size_t size)
+{
+       struct evbuffer_chain *chain = buf->last;
+
+       if (chain == NULL || 
+           chain->buffer_len - chain->off - chain->misalign < size)
+               return (-1);
+
+       chain->off += size;
+       buf->total_len += size;
+
+       return (0);
+}
+
 #define ZERO_CHAIN(dst) do { \
                (dst)->first = NULL;            \
                (dst)->last = NULL;             \
index 637cc2e0ff13f1c88e68b6579921b69e13c090a9..9d70555b0cfad0d6366bb473cba34f7f5baee973 100644 (file)
@@ -118,6 +118,38 @@ size_t evbuffer_contiguous_space(struct evbuffer *buf);
 */
 int evbuffer_expand(struct evbuffer *buf, size_t datlen);
 
+/**
+   Reserves space in the last chain of an event buffer.
+
+   Makes space available in the last chain of an event buffer that can
+   be arbitrarily written to by a user.  The space does not become
+   available for reading until it has been committed.
+
+   Multiple subsequent calls to this function will make the same space
+   available until evbuffer_commit_space() has been called.
+
+   @param buf the event buffer in which to reserve space.
+   @param size how much space to make available.
+   @return the pointer to the available space or NULL on error.
+   @see evbuffer_commit_space
+*/
+
+u_char *evbuffer_reserve_space(struct evbuffer *buf, size_t size);
+
+/**
+   Commits previously reserved space.
+
+   Commits some of the space previously reserved.  It then becomes
+   available for reading.
+
+   @param buf the event buffer in which to reserve space.
+   @param size how much space to commit.
+   @return 0 on success, -1 on error
+   @see evbuffer_reserve_space
+*/
+
+int evbuffer_commit_space(struct evbuffer *buf, size_t size);
+
 
 /**
   Append data to the end of an evbuffer.
index 00dbffe9dd3275252850b87c60c9b29335fc904d..993fba540f8c69ebfbd2add7c31dc81ae0eadafd 100644 (file)
@@ -1013,6 +1013,31 @@ test_evbuffer(void)
                goto out;
        evbuffer_validate(evb);
 
+
+       /* testing reserve and commit */
+       {
+               u_char *buf;
+               int i, j;
+
+               for (i = 0; i < 3; ++i) {
+                       buf = evbuffer_reserve_space(evb, 10000);
+                       assert(buf != NULL);
+                       evbuffer_validate(evb);
+                       for (j = 0; j < 10000; ++j) {
+                               buf[j] = j;
+                       }
+                       evbuffer_validate(evb);
+
+                       assert(evbuffer_commit_space(evb, 10000) == 0);
+                       evbuffer_validate(evb);
+
+                       assert(evbuffer_length(evb) >= 10000);
+
+                       evbuffer_drain(evb, j * 5000);
+                       evbuffer_validate(evb);
+               }
+       }
+       
        test_ok = 1;
        
 out:
index 434054c4e82dc5293912227515c9edf9e1109a2c..48bea35d1d27e4c6846821aada895346d59a8a30 100644 (file)
@@ -103,7 +103,6 @@ static enum bufferevent_filter_result
 zlib_input_filter(struct evbuffer *src, struct evbuffer *dst,
     enum bufferevent_filter_state state, void *ctx)
 {
-       char tmp[4096];
        int nread, nwrite;
        int res;
 
@@ -114,8 +113,8 @@ zlib_input_filter(struct evbuffer *src, struct evbuffer *dst,
                p->avail_in = evbuffer_contiguous_space(src);
                p->next_in = evbuffer_pullup(src, p->avail_in);
 
-               p->next_out = (unsigned char *)tmp;
-               p->avail_out = sizeof(tmp);
+               p->next_out = evbuffer_reserve_space(dst, 4096);
+               p->avail_out = 4096;
 
                /* we need to flush zlib if we got a flush */
                res = inflate(p, state == BEV_FLUSH ?
@@ -124,10 +123,10 @@ zlib_input_filter(struct evbuffer *src, struct evbuffer *dst,
 
                /* let's figure out how much was compressed */
                nread = evbuffer_contiguous_space(src) - p->avail_in;
-               nwrite = sizeof(tmp) - p->avail_out;
+               nwrite = 4096 - p->avail_out;
 
                evbuffer_drain(src, nread);
-               evbuffer_add(dst, tmp, nwrite);
+               evbuffer_commit_space(dst, nwrite);
        } while (EVBUFFER_LENGTH(src) > 0);
 
        test_ok++;
@@ -139,7 +138,6 @@ static enum bufferevent_filter_result
 zlib_output_filter(struct evbuffer *src, struct evbuffer *dst,
     enum bufferevent_filter_state state, void *ctx)
 {
-       char tmp[4096];
        int nread, nwrite;
        int res;
 
@@ -150,8 +148,8 @@ zlib_output_filter(struct evbuffer *src, struct evbuffer *dst,
                p->avail_in = evbuffer_contiguous_space(src);
                p->next_in = evbuffer_pullup(src, p->avail_in);
 
-               p->next_out = (unsigned char *)tmp;
-               p->avail_out = sizeof(tmp);
+               p->next_out = evbuffer_reserve_space(dst, 4096);
+               p->avail_out = 4096;
 
                /* we need to flush zlib if we got a flush */
                res = deflate(p, state == BEV_FLUSH ? Z_FINISH : Z_NO_FLUSH);
@@ -159,10 +157,10 @@ zlib_output_filter(struct evbuffer *src, struct evbuffer *dst,
 
                /* let's figure out how much was compressed */
                nread = evbuffer_contiguous_space(src) - p->avail_in;
-               nwrite = sizeof(tmp) - p->avail_out;
+               nwrite = 4096 - p->avail_out;
 
                evbuffer_drain(src, nread);
-               evbuffer_add(dst, tmp, nwrite);
+               evbuffer_commit_space(dst, nwrite);
        } while (EVBUFFER_LENGTH(src) > 0);
 
        test_ok++;