Merge branch 'evbuffer_copyout'

This commit is contained in:
Nick Mathewson 2010-04-13 01:46:29 -04:00
commit ab30e553c4
2 changed files with 28 additions and 21 deletions

View File

@ -861,15 +861,28 @@ done:
} }
/* Reads data from an event buffer and drains the bytes read */ /* Reads data from an event buffer and drains the bytes read */
int int
evbuffer_remove(struct evbuffer *buf, void *data_out, size_t datlen) evbuffer_remove(struct evbuffer *buf, void *data_out, size_t datlen)
{
ev_ssize_t n;
EVBUFFER_LOCK(buf);
n = evbuffer_copyout(buf, data_out, datlen);
if (n > 0) {
if (evbuffer_drain(buf, n)<0)
n = -1;
}
EVBUFFER_UNLOCK(buf);
return (int)n;
}
ev_ssize_t
evbuffer_copyout(struct evbuffer *buf, void *data_out, size_t datlen)
{ {
/*XXX fails badly on sendfile case. */ /*XXX fails badly on sendfile case. */
struct evbuffer_chain *chain, *tmp; struct evbuffer_chain *chain;
char *data = data_out; char *data = data_out;
size_t nread; size_t nread;
int result = 0; ev_ssize_t result = 0;
EVBUFFER_LOCK(buf); EVBUFFER_LOCK(buf);
@ -893,31 +906,15 @@ evbuffer_remove(struct evbuffer *buf, void *data_out, size_t datlen)
data += chain->off; data += chain->off;
datlen -= chain->off; datlen -= chain->off;
if (buf->last_with_datap == &chain->next) {
buf->last_with_datap = &buf->first;
}
tmp = chain;
chain = chain->next; chain = chain->next;
evbuffer_chain_free(tmp); EVUTIL_ASSERT(chain || datlen==0);
} }
buf->first = chain;
if (chain == NULL)
buf->last = NULL;
if (datlen) { if (datlen) {
EVUTIL_ASSERT(chain);
memcpy(data, chain->buffer + chain->misalign, datlen); memcpy(data, chain->buffer + chain->misalign, datlen);
chain->misalign += datlen;
chain->off -= datlen;
} }
buf->total_len -= nread;
buf->n_del_for_cb += nread;
if (nread)
evbuffer_invoke_callbacks(buf);
result = nread; result = nread;
done: done:
EVBUFFER_UNLOCK(buf); EVBUFFER_UNLOCK(buf);

View File

@ -267,6 +267,16 @@ int evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen);
*/ */
int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen); int evbuffer_remove(struct evbuffer *buf, void *data, size_t datlen);
/**
Read data from an event buffer, and leave the buffer unchanged.
@param buf the event buffer to be read from
@param data the destination buffer to store the result
@param datlen the maximum size of the destination buffer
@return the number of bytes read, or -1 if we can't drain the buffer.
*/
ev_ssize_t evbuffer_copyout(struct evbuffer *buf, void *data_out, size_t datlen);
/** /**
Read data from an event buffer into another event buffer draining Read data from an event buffer into another event buffer draining
the bytes from the src buffer read. This function avoids memcpy the bytes from the src buffer read. This function avoids memcpy