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.
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; \
*/
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.
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:
zlib_input_filter(struct evbuffer *src, struct evbuffer *dst,
enum bufferevent_filter_state state, void *ctx)
{
- char tmp[4096];
int nread, nwrite;
int res;
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 ?
/* 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++;
zlib_output_filter(struct evbuffer *src, struct evbuffer *dst,
enum bufferevent_filter_state state, void *ctx)
{
- char tmp[4096];
int nread, nwrite;
int res;
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);
/* 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++;