mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 12:28:19 -04:00
Added evbuffer_add_iovec and unit tests.
This commit is contained in:
parent
95af043314
commit
aaec5aca01
31
buffer.c
31
buffer.c
@ -589,6 +589,37 @@ evbuffer_get_contiguous_space(const struct evbuffer *buf)
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t
|
||||
evbuffer_add_iovec(struct evbuffer * buf, struct evbuffer_iovec * vec, int n_vec) {
|
||||
int n;
|
||||
size_t res;
|
||||
size_t to_alloc;
|
||||
|
||||
EVBUFFER_LOCK(buf);
|
||||
|
||||
res = to_alloc = 0;
|
||||
|
||||
for (n = 0; n < n_vec; n++) {
|
||||
to_alloc += vec[n].iov_len;
|
||||
}
|
||||
|
||||
if (evbuffer_expand(buf, to_alloc) < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (n = 0; n < n_vec; n++) {
|
||||
if (evbuffer_add(buf, vec[n].iov_base, vec[n].iov_len) < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
res += vec[n].iov_len;
|
||||
}
|
||||
|
||||
done:
|
||||
EVBUFFER_UNLOCK(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size,
|
||||
struct evbuffer_iovec *vec, int n_vecs)
|
||||
|
@ -950,6 +950,21 @@ struct event_base;
|
||||
*/
|
||||
int evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base);
|
||||
|
||||
/**
|
||||
Append data from 1 or more iovec's to an evbuffer
|
||||
|
||||
Calculates the number of bytes needed for an iovec structure and guarantees
|
||||
all data will fit into a single chain. Can be used in lieu of functionality
|
||||
which calls evbuffer_add() constantly before being used to increase
|
||||
performance.
|
||||
|
||||
@param buffer the destination buffer
|
||||
@param vec the source iovec
|
||||
@param n_vec the number of iovec structures.
|
||||
@return the number of bytes successfully written to the output buffer.
|
||||
*/
|
||||
size_t evbuffer_add_iovec(struct evbuffer * buffer, struct evbuffer_iovec * vec, int n_vec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1827,6 +1827,49 @@ end:
|
||||
evbuffer_free(tmp_buf);
|
||||
}
|
||||
|
||||
static void
|
||||
test_evbuffer_add_iovec(void * ptr)
|
||||
{
|
||||
struct evbuffer * buf = NULL;
|
||||
struct evbuffer_iovec vec[4];
|
||||
const char * data[] = {
|
||||
"Guilt resembles a sword with two edges.",
|
||||
"On the one hand, it cuts for Justice, imposing practical morality upon those who fear it.",
|
||||
"Conscience does not always adhere to rational judgment.",
|
||||
"Guilt is always a self-imposed burden, but it is not always rightly imposed."
|
||||
};
|
||||
size_t expected_length = 0;
|
||||
size_t returned_length = 0;
|
||||
int i;
|
||||
|
||||
buf = evbuffer_new();
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
vec[i].iov_len = strlen(data[i]);
|
||||
vec[i].iov_base = data[i];
|
||||
expected_length += vec[i].iov_len;
|
||||
}
|
||||
|
||||
returned_length = evbuffer_add_iovec(buf, vec, 4);
|
||||
|
||||
tt_int_op(returned_length, ==, evbuffer_get_length(buf));
|
||||
tt_int_op(evbuffer_get_length(buf), ==, expected_length);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
char charbuf[1024];
|
||||
|
||||
memset(charbuf, 0, 1024);
|
||||
evbuffer_remove(buf, charbuf, strlen(data[i]));
|
||||
tt_assert(strcmp(charbuf, data[i]) == 0);
|
||||
}
|
||||
|
||||
tt_assert(evbuffer_get_length(buf) == 0);
|
||||
end:
|
||||
if (buf) {
|
||||
evbuffer_free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
setup_passthrough(const struct testcase_t *testcase)
|
||||
{
|
||||
@ -1865,6 +1908,7 @@ struct testcase_t evbuffer_testcases[] = {
|
||||
{ "peek", test_evbuffer_peek, 0, NULL, NULL },
|
||||
{ "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
|
||||
{ "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
|
||||
{ "add_iovec", test_evbuffer_add_iovec, 0, NULL, NULL},
|
||||
|
||||
#define ADDFILE_TEST(name, parameters) \
|
||||
{ name, test_evbuffer_add_file, TT_FORK|TT_NEED_BASE, \
|
||||
|
Loading…
x
Reference in New Issue
Block a user