mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 13:04:23 -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;
|
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
|
int
|
||||||
evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size,
|
evbuffer_reserve_space(struct evbuffer *buf, ev_ssize_t size,
|
||||||
struct evbuffer_iovec *vec, int n_vecs)
|
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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1827,6 +1827,49 @@ end:
|
|||||||
evbuffer_free(tmp_buf);
|
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 *
|
static void *
|
||||||
setup_passthrough(const struct testcase_t *testcase)
|
setup_passthrough(const struct testcase_t *testcase)
|
||||||
{
|
{
|
||||||
@ -1865,6 +1908,7 @@ struct testcase_t evbuffer_testcases[] = {
|
|||||||
{ "peek", test_evbuffer_peek, 0, NULL, NULL },
|
{ "peek", test_evbuffer_peek, 0, NULL, NULL },
|
||||||
{ "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
|
{ "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
|
||||||
{ "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
|
{ "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
|
||||||
|
{ "add_iovec", test_evbuffer_add_iovec, 0, NULL, NULL},
|
||||||
|
|
||||||
#define ADDFILE_TEST(name, parameters) \
|
#define ADDFILE_TEST(name, parameters) \
|
||||||
{ name, test_evbuffer_add_file, TT_FORK|TT_NEED_BASE, \
|
{ name, test_evbuffer_add_file, TT_FORK|TT_NEED_BASE, \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user