2 * Copyright (c) 2003-2007 Niels Provos <provos@citi.umich.edu>
3 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "util-internal.h"
34 #include "event2/event-config.h"
36 #include <sys/types.h>
38 #ifdef EVENT__HAVE_SYS_TIME_H
41 #include <sys/queue.h>
43 #include <sys/socket.h>
55 #include "event2/event.h"
56 #include "event2/buffer.h"
57 #include "event2/buffer_compat.h"
58 #include "event2/util.h"
60 #include "defer-internal.h"
61 #include "evbuffer-internal.h"
62 #include "log-internal.h"
66 /* Validates that an evbuffer is good. Returns false if it isn't, true if it
69 evbuffer_validate_(struct evbuffer *buf)
71 struct evbuffer_chain *chain;
73 int found_last_with_datap = 0;
75 if (buf->first == NULL) {
76 tt_assert(buf->last == NULL);
77 tt_assert(buf->total_len == 0);
82 tt_assert(buf->last_with_datap);
83 if (buf->last_with_datap == &buf->first)
84 found_last_with_datap = 1;
86 while (chain != NULL) {
87 if (&chain->next == buf->last_with_datap)
88 found_last_with_datap = 1;
90 if (chain->next == NULL) {
91 tt_assert(buf->last == chain);
93 tt_assert(chain->buffer_len >= chain->misalign + chain->off);
98 tt_assert(*buf->last_with_datap);
100 if (*buf->last_with_datap) {
101 chain = *buf->last_with_datap;
102 if (chain->off == 0 || buf->total_len == 0) {
103 tt_assert(chain->off == 0)
104 tt_assert(chain == buf->first);
105 tt_assert(buf->total_len == 0);
108 while (chain != NULL) {
109 tt_assert(chain->off == 0);
113 tt_assert(buf->last_with_datap == &buf->first);
115 tt_assert(found_last_with_datap);
117 tt_assert(sum == buf->total_len);
124 evbuffer_get_waste(struct evbuffer *buf, size_t *allocatedp, size_t *wastedp, size_t *usedp)
126 struct evbuffer_chain *chain;
132 /* skip empty at start */
133 while (chain && chain->off==0) {
135 a += chain->buffer_len;
138 /* first nonempty chain: stuff at the end only is wasted. */
141 a += chain->buffer_len;
143 if (chain->next && chain->next->off)
144 w += (size_t)(chain->buffer_len - (chain->misalign + chain->off));
147 /* subsequent nonempty chains */
148 while (chain && chain->off) {
150 a += chain->buffer_len;
151 w += (size_t)chain->misalign;
153 if (chain->next && chain->next->off)
154 w += (size_t) (chain->buffer_len - (chain->misalign + chain->off));
157 /* subsequent empty chains */
160 a += chain->buffer_len;
167 #define evbuffer_validate(buf) \
168 TT_STMT_BEGIN if (!evbuffer_validate_(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
171 test_evbuffer(void *ptr)
173 static char buffer[512], *tmp;
174 struct evbuffer *evb = evbuffer_new();
175 struct evbuffer *evb_two = evbuffer_new();
179 evbuffer_validate(evb);
180 evbuffer_add_printf(evb, "%s/%d", "hello", 1);
181 evbuffer_validate(evb);
183 tt_assert(evbuffer_get_length(evb) == 7);
184 tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "hello/1", 1));
186 evbuffer_add_buffer(evb, evb_two);
187 evbuffer_validate(evb);
189 evbuffer_drain(evb, strlen("hello/"));
190 evbuffer_validate(evb);
191 tt_assert(evbuffer_get_length(evb) == 1);
192 tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1", 1));
194 evbuffer_add_printf(evb_two, "%s", "/hello");
195 evbuffer_validate(evb);
196 evbuffer_add_buffer(evb, evb_two);
197 evbuffer_validate(evb);
199 tt_assert(evbuffer_get_length(evb_two) == 0);
200 tt_assert(evbuffer_get_length(evb) == 7);
201 tt_assert(!memcmp((char*)EVBUFFER_DATA(evb), "1/hello", 7));
203 memset(buffer, 0, sizeof(buffer));
204 evbuffer_add(evb, buffer, sizeof(buffer));
205 evbuffer_validate(evb);
206 tt_assert(evbuffer_get_length(evb) == 7 + 512);
208 tmp = (char *)evbuffer_pullup(evb, 7 + 512);
210 tt_assert(!strncmp(tmp, "1/hello", 7));
211 tt_assert(!memcmp(tmp + 7, buffer, sizeof(buffer)));
212 evbuffer_validate(evb);
214 evbuffer_prepend(evb, "something", 9);
215 evbuffer_validate(evb);
216 evbuffer_prepend(evb, "else", 4);
217 evbuffer_validate(evb);
219 tmp = (char *)evbuffer_pullup(evb, 4 + 9 + 7);
220 tt_assert(!strncmp(tmp, "elsesomething1/hello", 4 + 9 + 7));
221 evbuffer_validate(evb);
223 evbuffer_drain(evb, -1);
224 evbuffer_validate(evb);
225 evbuffer_drain(evb_two, -1);
226 evbuffer_validate(evb);
228 for (i = 0; i < 3; ++i) {
229 evbuffer_add(evb_two, buffer, sizeof(buffer));
230 evbuffer_validate(evb_two);
231 evbuffer_add_buffer(evb, evb_two);
232 evbuffer_validate(evb);
233 evbuffer_validate(evb_two);
236 tt_assert(evbuffer_get_length(evb_two) == 0);
237 tt_assert(evbuffer_get_length(evb) == i * sizeof(buffer));
239 /* test remove buffer */
240 sz_tmp = (size_t)(sizeof(buffer)*2.5);
241 evbuffer_remove_buffer(evb, evb_two, sz_tmp);
242 tt_assert(evbuffer_get_length(evb_two) == sz_tmp);
243 tt_assert(evbuffer_get_length(evb) == sizeof(buffer) / 2);
244 evbuffer_validate(evb);
246 if (memcmp(evbuffer_pullup(
247 evb, -1), buffer, sizeof(buffer) / 2) != 0 ||
248 memcmp(evbuffer_pullup(
249 evb_two, -1), buffer, sizeof(buffer)) != 0)
250 tt_abort_msg("Pullup did not preserve content");
252 evbuffer_validate(evb);
255 /* testing one-vector reserve and commit */
257 struct evbuffer_iovec v[1];
261 for (i = 0; i < 3; ++i) {
262 r = evbuffer_reserve_space(evb, 10000, v, 1);
264 tt_assert(v[0].iov_len >= 10000);
265 tt_assert(v[0].iov_base != NULL);
267 evbuffer_validate(evb);
269 for (j = 0; j < 10000; ++j) {
272 evbuffer_validate(evb);
274 tt_int_op(evbuffer_commit_space(evb, v, 1), ==, 0);
275 evbuffer_validate(evb);
277 tt_assert(evbuffer_get_length(evb) >= 10000);
279 evbuffer_drain(evb, j * 5000);
280 evbuffer_validate(evb);
286 evbuffer_free(evb_two);
290 no_cleanup(const void *data, size_t datalen, void *extra)
295 test_evbuffer_remove_buffer_with_empty(void *ptr)
297 struct evbuffer *src = evbuffer_new();
298 struct evbuffer *dst = evbuffer_new();
301 evbuffer_validate(src);
302 evbuffer_validate(dst);
304 /* setup the buffers */
305 /* we need more data in src than we will move later */
306 evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
307 evbuffer_add_reference(src, buf, sizeof(buf), no_cleanup, NULL);
308 /* we need one buffer in dst and one empty buffer at the end */
309 evbuffer_add(dst, buf, sizeof(buf));
310 evbuffer_add_reference(dst, buf, 0, no_cleanup, NULL);
312 evbuffer_validate(src);
313 evbuffer_validate(dst);
315 /* move three bytes over */
316 evbuffer_remove_buffer(src, dst, 3);
318 evbuffer_validate(src);
319 evbuffer_validate(dst);
327 test_evbuffer_remove_buffer_with_empty2(void *ptr)
329 struct evbuffer *src = evbuffer_new();
330 struct evbuffer *dst = evbuffer_new();
331 struct evbuffer *buf = evbuffer_new();
333 evbuffer_add(buf, "foo", 3);
334 evbuffer_add_reference(buf, "foo", 3, NULL, NULL);
336 evbuffer_add_reference(src, "foo", 3, NULL, NULL);
337 evbuffer_add_reference(src, NULL, 0, NULL, NULL);
338 evbuffer_add_buffer(src, buf);
340 evbuffer_add(buf, "foo", 3);
341 evbuffer_add_reference(buf, "foo", 3, NULL, NULL);
343 evbuffer_add_reference(dst, "foo", 3, NULL, NULL);
344 evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
345 evbuffer_add_buffer(dst, buf);
347 tt_int_op(evbuffer_get_length(src), ==, 9);
348 tt_int_op(evbuffer_get_length(dst), ==, 9);
350 evbuffer_validate(src);
351 evbuffer_validate(dst);
353 evbuffer_remove_buffer(src, dst, 8);
355 evbuffer_validate(src);
356 evbuffer_validate(dst);
358 tt_int_op(evbuffer_get_length(src), ==, 1);
359 tt_int_op(evbuffer_get_length(dst), ==, 17);
368 test_evbuffer_remove_buffer_with_empty3(void *ptr)
370 struct evbuffer *src = evbuffer_new();
371 struct evbuffer *dst = evbuffer_new();
372 struct evbuffer *buf = evbuffer_new();
374 evbuffer_add(buf, "foo", 3);
375 evbuffer_add_reference(buf, NULL, 0, NULL, NULL);
377 evbuffer_add_reference(src, "foo", 3, NULL, NULL);
378 evbuffer_add_reference(src, NULL, 0, NULL, NULL);
379 evbuffer_prepend_buffer(src, buf);
381 evbuffer_add(buf, "foo", 3);
382 evbuffer_add_reference(buf, NULL, 0, NULL, NULL);
384 evbuffer_add_reference(dst, "foo", 3, NULL, NULL);
385 evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
386 evbuffer_prepend_buffer(dst, buf);
388 tt_int_op(evbuffer_get_length(src), ==, 6);
389 tt_int_op(evbuffer_get_length(dst), ==, 6);
391 evbuffer_validate(src);
392 evbuffer_validate(dst);
394 evbuffer_remove_buffer(src, dst, 5);
396 evbuffer_validate(src);
397 evbuffer_validate(dst);
399 tt_int_op(evbuffer_get_length(src), ==, 1);
400 tt_int_op(evbuffer_get_length(dst), ==, 11);
409 test_evbuffer_add_buffer_with_empty(void *ptr)
411 struct evbuffer *src = evbuffer_new();
412 struct evbuffer *dst = evbuffer_new();
413 struct evbuffer *buf = evbuffer_new();
415 evbuffer_add(buf, "foo", 3);
417 evbuffer_add_reference(src, "foo", 3, NULL, NULL);
418 evbuffer_add_reference(src, NULL, 0, NULL, NULL);
419 evbuffer_add_buffer(src, buf);
421 evbuffer_add(buf, "foo", 3);
423 evbuffer_add_reference(dst, "foo", 3, NULL, NULL);
424 evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
425 evbuffer_add_buffer(dst, buf);
427 tt_int_op(evbuffer_get_length(src), ==, 6);
428 tt_int_op(evbuffer_get_length(dst), ==, 6);
430 evbuffer_validate(src);
431 evbuffer_validate(dst);
440 test_evbuffer_add_buffer_with_empty2(void *ptr)
442 struct evbuffer *src = evbuffer_new();
443 struct evbuffer *dst = evbuffer_new();
444 struct evbuffer *buf = evbuffer_new();
446 evbuffer_add(buf, "foo", 3);
448 evbuffer_add_reference(src, NULL, 0, NULL, NULL);
449 evbuffer_add_buffer(src, buf);
451 evbuffer_add(buf, "foo", 3);
453 evbuffer_add_reference(dst, NULL, 0, NULL, NULL);
454 evbuffer_add_buffer(dst, buf);
456 tt_int_op(evbuffer_get_length(src), ==, 3);
457 tt_int_op(evbuffer_get_length(dst), ==, 3);
459 evbuffer_validate(src);
460 evbuffer_validate(dst);
469 test_evbuffer_reserve2(void *ptr)
471 /* Test the two-vector cases of reserve/commit. */
472 struct evbuffer *buf = evbuffer_new();
474 struct evbuffer_iovec v[2];
478 /* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
479 n = evbuffer_reserve_space(buf, 1024, v, 2);
481 tt_int_op(evbuffer_get_length(buf), ==, 0);
482 tt_assert(v[0].iov_base != NULL);
483 tt_int_op(v[0].iov_len, >=, 1024);
484 memset(v[0].iov_base, 'X', 512);
486 remaining = v[0].iov_len - 512;
488 evbuffer_validate(buf);
489 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
490 tt_int_op(evbuffer_get_length(buf), ==, 512);
491 evbuffer_validate(buf);
493 /* Ask for another same-chunk request, in an existing chunk. Use 8
495 n = evbuffer_reserve_space(buf, 32, v, 2);
497 tt_assert(cp + 512 == v[0].iov_base);
498 tt_int_op(remaining, ==, v[0].iov_len);
499 memset(v[0].iov_base, 'Y', 8);
501 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
502 tt_int_op(evbuffer_get_length(buf), ==, 520);
504 evbuffer_validate(buf);
506 /* Now ask for a request that will be split. Use only one byte of it,
508 n = evbuffer_reserve_space(buf, remaining+64, v, 2);
510 tt_assert(cp + 520 == v[0].iov_base);
511 tt_int_op(remaining, ==, v[0].iov_len);
512 tt_assert(v[1].iov_base);
513 tt_assert(v[1].iov_len >= 64);
515 memset(v[0].iov_base, 'Z', 1);
517 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 1));
518 tt_int_op(evbuffer_get_length(buf), ==, 521);
520 evbuffer_validate(buf);
522 /* Now ask for a request that will be split. Use some of the first
523 * part and some of the second. */
524 n = evbuffer_reserve_space(buf, remaining+64, v, 2);
525 evbuffer_validate(buf);
527 tt_assert(cp + 521 == v[0].iov_base);
528 tt_int_op(remaining, ==, v[0].iov_len);
529 tt_assert(v[1].iov_base == cp2);
530 tt_assert(v[1].iov_len >= 64);
531 memset(v[0].iov_base, 'W', 400);
533 memset(v[1].iov_base, 'x', 60);
535 tt_int_op(0, ==, evbuffer_commit_space(buf, v, 2));
536 tt_int_op(evbuffer_get_length(buf), ==, 981);
537 evbuffer_validate(buf);
539 /* Now peek to make sure stuff got made how we like. */
540 memset(v,0,sizeof(v));
541 n = evbuffer_peek(buf, -1, NULL, v, 2);
543 tt_int_op(v[0].iov_len, ==, 921);
544 tt_int_op(v[1].iov_len, ==, 60);
547 for (i=0; i<512; ++i)
548 tt_int_op(cp[i], ==, 'X');
549 for (i=512; i<520; ++i)
550 tt_int_op(cp[i], ==, 'Y');
551 for (i=520; i<521; ++i)
552 tt_int_op(cp[i], ==, 'Z');
553 for (i=521; i<921; ++i)
554 tt_int_op(cp[i], ==, 'W');
558 tt_int_op(cp[i], ==, 'x');
565 test_evbuffer_reserve_many(void *ptr)
567 /* This is a glass-box test to handle expanding a buffer with more
568 * chunks and reallocating chunks as needed */
569 struct evbuffer *buf = evbuffer_new();
570 struct evbuffer_iovec v[8];
573 int add_data = ptr && !strcmp(ptr, "add");
574 int fill_first = ptr && !strcmp(ptr, "fill");
577 /* When reserving the the first chunk, we just allocate it */
578 n = evbuffer_reserve_space(buf, 128, v, 2);
579 evbuffer_validate(buf);
581 tt_assert(v[0].iov_len >= 128);
585 *(char*)v[0].iov_base = 'X';
587 n = evbuffer_commit_space(buf, v, 1);
589 } else if (fill_first) {
590 memset(v[0].iov_base, 'X', v[0].iov_len);
591 n = evbuffer_commit_space(buf, v, 1);
593 n = evbuffer_reserve_space(buf, 128, v, 2);
596 tt_assert(v[0].iov_base != cp1);
600 /* Make another chunk get added. */
601 n = evbuffer_reserve_space(buf, sz+128, v, 2);
602 evbuffer_validate(buf);
604 sz = v[0].iov_len + v[1].iov_len;
605 tt_int_op(sz, >=, v[0].iov_len+128);
607 tt_assert(v[0].iov_base == cp1 + 1);
609 tt_assert(v[0].iov_base == cp1);
614 /* And a third chunk. */
615 n = evbuffer_reserve_space(buf, sz+128, v, 3);
616 evbuffer_validate(buf);
618 tt_assert(cp1 == v[0].iov_base);
619 tt_assert(cp2 == v[1].iov_base);
620 sz = v[0].iov_len + v[1].iov_len + v[2].iov_len;
622 /* Now force a reallocation by asking for more space in only 2
624 n = evbuffer_reserve_space(buf, sz+128, v, 2);
625 evbuffer_validate(buf);
628 tt_assert(cp1 == v[0].iov_base);
638 test_evbuffer_expand(void *ptr)
641 struct evbuffer *buf;
645 memset(data, 'X', sizeof(data));
647 /* Make sure that expand() works on an empty buffer */
648 buf = evbuffer_new();
649 tt_int_op(evbuffer_expand(buf, 20000), ==, 0);
650 evbuffer_validate(buf);
652 evbuffer_get_waste(buf, &a,&w,&u);
655 tt_assert(a >= 20000);
656 tt_assert(buf->first);
657 tt_assert(buf->first == buf->last);
658 tt_assert(buf->first->off == 0);
659 tt_assert(buf->first->buffer_len >= 20000);
661 /* Make sure that expand() works as a no-op when there's enough
662 * contiguous space already. */
663 buffer = buf->first->buffer;
664 evbuffer_add(buf, data, 1024);
665 tt_int_op(evbuffer_expand(buf, 1024), ==, 0);
666 tt_assert(buf->first->buffer == buffer);
667 evbuffer_validate(buf);
670 /* Make sure that expand() can work by moving misaligned data
671 * when it makes sense to do so. */
672 buf = evbuffer_new();
673 evbuffer_add(buf, data, 400);
675 int n = (int)(buf->first->buffer_len - buf->first->off - 1);
676 tt_assert(n < (int)sizeof(data));
677 evbuffer_add(buf, data, n);
679 tt_assert(buf->first == buf->last);
680 tt_assert(buf->first->off == buf->first->buffer_len - 1);
681 evbuffer_drain(buf, buf->first->off - 1);
682 tt_assert(1 == evbuffer_get_length(buf));
683 tt_assert(buf->first->misalign > 0);
684 tt_assert(buf->first->off == 1);
685 buffer = buf->first->buffer;
686 tt_assert(evbuffer_expand(buf, 40) == 0);
687 tt_assert(buf->first == buf->last);
688 tt_assert(buf->first->off == 1);
689 tt_assert(buf->first->buffer == buffer);
690 tt_assert(buf->first->misalign == 0);
691 evbuffer_validate(buf);
694 /* add, expand, pull-up: This used to crash libevent. */
695 buf = evbuffer_new();
697 evbuffer_add(buf, data, sizeof(data));
698 evbuffer_add(buf, data, sizeof(data));
699 evbuffer_add(buf, data, sizeof(data));
701 evbuffer_validate(buf);
702 evbuffer_expand(buf, 1024);
703 evbuffer_validate(buf);
704 evbuffer_pullup(buf, -1);
705 evbuffer_validate(buf);
712 test_evbuffer_expand_overflow(void *ptr)
714 struct evbuffer *buf;
716 buf = evbuffer_new();
717 evbuffer_add(buf, "1", 1);
718 evbuffer_expand(buf, EVBUFFER_CHAIN_MAX);
719 evbuffer_validate(buf);
721 evbuffer_expand(buf, EV_SIZE_MAX);
722 evbuffer_validate(buf);
729 test_evbuffer_add1(void *ptr)
731 struct evbuffer *buf;
734 buf = evbuffer_new();
735 evbuffer_add(buf, "1", 1);
736 evbuffer_validate(buf);
737 evbuffer_expand(buf, 2048);
738 evbuffer_validate(buf);
739 evbuffer_add(buf, "2", 1);
740 evbuffer_validate(buf);
741 evbuffer_add_printf(buf, "3");
742 evbuffer_validate(buf);
744 tt_assert(evbuffer_get_length(buf) == 3);
745 str = (char *)evbuffer_pullup(buf, -1);
746 tt_assert(str[0] == '1');
747 tt_assert(str[1] == '2');
748 tt_assert(str[2] == '3');
754 test_evbuffer_add2(void *ptr)
756 struct evbuffer *buf;
757 static char data[4096];
758 int data_len = MIN_BUFFER_SIZE-EVBUFFER_CHAIN_SIZE-10;
762 memset(data, 'P', sizeof(data));
763 buf = evbuffer_new();
764 evbuffer_add(buf, data, data_len);
765 evbuffer_validate(buf);
766 evbuffer_expand(buf, 100);
767 evbuffer_validate(buf);
768 evbuffer_add(buf, "2", 1);
769 evbuffer_validate(buf);
770 evbuffer_add_printf(buf, "3");
771 evbuffer_validate(buf);
773 len = evbuffer_get_length(buf);
774 tt_assert(len == data_len+2);
775 str = (char *)evbuffer_pullup(buf, -1);
776 tt_assert(str[len-3] == 'P');
777 tt_assert(str[len-2] == '2');
778 tt_assert(str[len-1] == '3');
783 static int reference_cb_called;
785 reference_cb(const void *data, size_t len, void *extra)
787 tt_str_op(data, ==, "this is what we add as read-only memory.");
788 tt_int_op(len, ==, strlen(data));
789 tt_want(extra == (void *)0xdeadaffe);
790 ++reference_cb_called;
796 test_evbuffer_reference(void *ptr)
798 struct evbuffer *src = evbuffer_new();
799 struct evbuffer *dst = evbuffer_new();
800 struct evbuffer_iovec v[1];
801 const char *data = "this is what we add as read-only memory.";
802 reference_cb_called = 0;
804 tt_assert(evbuffer_add_reference(src, data, strlen(data),
805 reference_cb, (void *)0xdeadaffe) != -1);
807 evbuffer_reserve_space(dst, strlen(data), v, 1);
808 tt_assert(evbuffer_remove(src, v[0].iov_base, 10) != -1);
810 evbuffer_validate(src);
811 evbuffer_validate(dst);
813 /* make sure that we don't write data at the beginning */
814 evbuffer_prepend(src, "aaaaa", 5);
815 evbuffer_validate(src);
816 evbuffer_drain(src, 5);
818 tt_assert(evbuffer_remove(src, ((char*)(v[0].iov_base)) + 10,
819 strlen(data) - 10) != -1);
821 v[0].iov_len = strlen(data);
823 evbuffer_commit_space(dst, v, 1);
824 evbuffer_validate(src);
825 evbuffer_validate(dst);
827 tt_int_op(reference_cb_called, ==, 1);
829 tt_assert(!memcmp(evbuffer_pullup(dst, strlen(data)),
830 data, strlen(data)));
831 evbuffer_validate(dst);
839 test_evbuffer_reference2(void *ptr)
841 struct evbuffer *buf;
842 static char data[4096];
843 int data_len = MIN_BUFFER_SIZE-EVBUFFER_CHAIN_SIZE-10;
847 memset(data, 'P', sizeof(data));
848 buf = evbuffer_new();
849 evbuffer_add(buf, data, data_len);
850 evbuffer_validate(buf);
851 evbuffer_expand(buf, 100);
852 evbuffer_validate(buf);
853 evbuffer_add_reference(buf, "2", 1, no_cleanup, NULL);
854 evbuffer_validate(buf);
855 evbuffer_add_printf(buf, "3");
856 evbuffer_validate(buf);
858 len = evbuffer_get_length(buf);
859 tt_assert(len == data_len+2);
860 str = (char *)evbuffer_pullup(buf, -1);
861 tt_assert(str[len-3] == 'P');
862 tt_assert(str[len-2] == '2');
863 tt_assert(str[len-1] == '3');
868 static struct event_base *addfile_test_event_base;
869 static int addfile_test_done_writing;
870 static int addfile_test_total_written;
871 static int addfile_test_total_read;
874 addfile_test_writecb(evutil_socket_t fd, short what, void *arg)
876 struct evbuffer *b = arg;
878 evbuffer_validate(b);
879 while (evbuffer_get_length(b)) {
880 r = evbuffer_write(b, fd);
882 addfile_test_total_written += r;
883 TT_BLATHER(("Wrote %d/%d bytes", r, addfile_test_total_written));
885 int e = evutil_socket_geterror(fd);
886 if (EVUTIL_ERR_RW_RETRIABLE(e))
888 tt_fail_perror("write");
889 event_base_loopexit(addfile_test_event_base,NULL);
891 evbuffer_validate(b);
893 addfile_test_done_writing = 1;
896 event_base_loopexit(addfile_test_event_base,NULL);
900 addfile_test_readcb(evutil_socket_t fd, short what, void *arg)
902 struct evbuffer *b = arg;
905 r = evbuffer_read(b, fd, 1024);
907 addfile_test_total_read += r;
908 TT_BLATHER(("Read %d/%d bytes", r, addfile_test_total_read));
912 e = evutil_socket_geterror(fd);
913 if (! EVUTIL_ERR_RW_RETRIABLE(e)) {
914 tt_fail_perror("read");
915 event_base_loopexit(addfile_test_event_base,NULL);
918 if (addfile_test_done_writing &&
919 addfile_test_total_read >= addfile_test_total_written) {
920 event_base_loopexit(addfile_test_event_base,NULL);
925 test_evbuffer_add_file(void *ptr)
927 struct basic_test_data *testdata = ptr;
928 const char *impl = testdata->setup_data;
929 struct evbuffer *src = evbuffer_new(), *dest = evbuffer_new();
930 char *tmpfilename = NULL;
932 const char *expect_data;
933 size_t datalen, expect_len;
936 int want_ismapping = -1, want_cansendfile = -1;
938 int use_segment = 1, use_bigfile = 0, map_from_offset = 0,
939 view_from_offset = 0;
940 struct evbuffer_file_segment *seg = NULL;
941 ev_off_t starting_offset = 0, mapping_len = -1;
942 ev_off_t segment_offset = 0, segment_len = -1;
943 struct event *rev=NULL, *wev=NULL;
944 struct event_base *base = testdata->base;
945 evutil_socket_t pair[2] = {-1, -1};
946 struct evutil_weakrand_state seed = { 123456789U };
948 /* This test is highly parameterized based on substrings of its
949 * argument. The strings are: */
951 if (strstr(impl, "nosegment")) {
952 /* If nosegment is set, use the older evbuffer_add_file
956 if (strstr(impl, "bigfile")) {
957 /* If bigfile is set, use a 512K file. Else use a smaller
961 if (strstr(impl, "map_offset")) {
962 /* If map_offset is set, we build the file segment starting
963 * from a point other than byte 0 and ending somewhere other
964 * than the last byte. Otherwise we map the whole thing */
967 if (strstr(impl, "offset_in_segment")) {
968 /* If offset_in_segment is set, we add a subsection of the
969 * file semgment starting from a point other than byte 0 of
971 view_from_offset = 1;
973 if (strstr(impl, "sendfile")) {
974 /* If sendfile is set, we try to use a sendfile/splice style
976 flags = EVBUF_FS_DISABLE_MMAP;
977 want_cansendfile = 1;
979 } else if (strstr(impl, "mmap")) {
980 /* If sendfile is set, we try to use a mmap/CreateFileMapping
982 flags = EVBUF_FS_DISABLE_SENDFILE;
984 want_cansendfile = 0;
985 } else if (strstr(impl, "linear")) {
986 /* If linear is set, we try to use a read-the-whole-thing
988 flags = EVBUF_FS_DISABLE_SENDFILE|EVBUF_FS_DISABLE_MMAP;
990 want_cansendfile = 0;
991 } else if (strstr(impl, "default")) {
992 /* The caller doesn't care which backend we use. */
995 /* The caller must choose a backend. */
996 TT_DIE(("Didn't recognize the implementation"));
1002 data = malloc(1024*512);
1004 for (i = 0; i < datalen; ++i)
1005 data[i] = (char)evutil_weakrand_(&seed);
1007 data = strdup("here is a relatively small string.");
1009 datalen = strlen(data);
1012 fd = regress_make_tmpfile(data, datalen, &tmpfilename);
1014 if (map_from_offset) {
1015 starting_offset = datalen/4 + 1;
1016 mapping_len = datalen / 2 - 1;
1017 expect_data = data + starting_offset;
1018 expect_len = mapping_len;
1021 expect_len = datalen;
1023 if (view_from_offset) {
1024 tt_assert(use_segment); /* Can't do this with add_file*/
1025 segment_offset = expect_len / 3;
1026 segment_len = expect_len / 2;
1027 expect_data = expect_data + segment_offset;
1028 expect_len = segment_len;
1032 seg = evbuffer_file_segment_new(fd, starting_offset,
1033 mapping_len, flags);
1035 if (want_ismapping >= 0) {
1036 if (seg->is_mapping != (unsigned)want_ismapping)
1039 if (want_cansendfile >= 0) {
1040 if (seg->can_sendfile != (unsigned)want_cansendfile)
1045 /* Say that it drains to a fd so that we can use sendfile. */
1046 evbuffer_set_flags(src, EVBUFFER_FLAG_DRAINS_TO_FD);
1048 #if defined(EVENT__HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
1049 /* We need to use a pair of AF_INET sockets, since Solaris
1050 doesn't support sendfile() over AF_UNIX. */
1051 if (evutil_ersatz_socketpair_(AF_INET, SOCK_STREAM, 0, pair) == -1)
1052 tt_abort_msg("ersatz_socketpair failed");
1054 if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
1055 tt_abort_msg("socketpair failed");
1057 evutil_make_socket_nonblocking(pair[0]);
1058 evutil_make_socket_nonblocking(pair[1]);
1060 tt_assert(fd != -1);
1063 tt_assert(evbuffer_add_file_segment(src, seg,
1064 segment_offset, segment_len)!=-1);
1066 tt_assert(evbuffer_add_file(src, fd, starting_offset,
1067 mapping_len) != -1);
1070 evbuffer_validate(src);
1072 addfile_test_event_base = base;
1073 addfile_test_done_writing = 0;
1074 addfile_test_total_written = 0;
1075 addfile_test_total_read = 0;
1077 wev = event_new(base, pair[0], EV_WRITE|EV_PERSIST,
1078 addfile_test_writecb, src);
1079 rev = event_new(base, pair[1], EV_READ|EV_PERSIST,
1080 addfile_test_readcb, dest);
1082 event_add(wev, NULL);
1083 event_add(rev, NULL);
1084 event_base_dispatch(base);
1086 evbuffer_validate(src);
1087 evbuffer_validate(dest);
1089 tt_assert(addfile_test_done_writing);
1090 tt_int_op(addfile_test_total_written, ==, expect_len);
1091 tt_int_op(addfile_test_total_read, ==, expect_len);
1093 compare = (char *)evbuffer_pullup(dest, expect_len);
1094 tt_assert(compare != NULL);
1095 if (memcmp(compare, expect_data, expect_len)) {
1096 tt_abort_msg("Data from add_file differs.");
1099 evbuffer_validate(dest);
1104 evbuffer_file_segment_free(seg);
1108 evbuffer_free(dest);
1110 evutil_closesocket(pair[0]);
1112 evutil_closesocket(pair[1]);
1118 unlink(tmpfilename);
1123 static int file_segment_cleanup_cb_called_count = 0;
1124 static struct evbuffer_file_segment const* file_segment_cleanup_cb_called_with = NULL;
1125 static int file_segment_cleanup_cb_called_with_flags = 0;
1126 static void* file_segment_cleanup_cb_called_with_arg = NULL;
1128 file_segment_cleanup_cp(struct evbuffer_file_segment const* seg, int flags, void* arg)
1130 ++file_segment_cleanup_cb_called_count;
1131 file_segment_cleanup_cb_called_with = seg;
1132 file_segment_cleanup_cb_called_with_flags = flags;
1133 file_segment_cleanup_cb_called_with_arg = arg;
1137 test_evbuffer_file_segment_add_cleanup_cb(void* ptr)
1139 char *tmpfilename = NULL;
1141 struct evbuffer *evb = NULL;
1142 struct evbuffer_file_segment *seg = NULL, *segptr;
1143 char const* arg = "token";
1145 fd = regress_make_tmpfile("file_segment_test_file", 22, &tmpfilename);
1146 tt_int_op(fd, >=, 0);
1148 evb = evbuffer_new();
1151 segptr = seg = evbuffer_file_segment_new(fd, 0, -1, 0);
1154 evbuffer_file_segment_add_cleanup_cb(
1155 seg, &file_segment_cleanup_cp, (void*)arg);
1157 tt_assert(fd != -1);
1159 tt_assert(evbuffer_add_file_segment(evb, seg, 0, -1)!=-1);
1161 evbuffer_validate(evb);
1163 tt_int_op(file_segment_cleanup_cb_called_count, ==, 0);
1164 evbuffer_file_segment_free(seg);
1165 seg = NULL; /* Prevent double-free. */
1167 tt_int_op(file_segment_cleanup_cb_called_count, ==, 0);
1169 evb = NULL; /* pevent double-free */
1171 tt_int_op(file_segment_cleanup_cb_called_count, ==, 1);
1172 tt_assert(file_segment_cleanup_cb_called_with == segptr);
1173 tt_assert(file_segment_cleanup_cb_called_with_flags == 0);
1174 tt_assert(file_segment_cleanup_cb_called_with_arg == (void*)arg);
1180 evbuffer_file_segment_free(seg);
1182 unlink(tmpfilename);
1187 #ifndef EVENT__DISABLE_MM_REPLACEMENT
1189 failing_malloc(size_t how_much)
1197 test_evbuffer_readln(void *ptr)
1199 struct evbuffer *evb = evbuffer_new();
1200 struct evbuffer *evb_tmp = evbuffer_new();
1205 #define tt_line_eq(content) \
1207 if (!cp || sz != strlen(content) || strcmp(cp, content)) { \
1208 TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
1213 s = "complex silly newline\r\n\n\r\n\n\rmore\0\n";
1214 evbuffer_add(evb, s, strlen(s)+2);
1215 evbuffer_validate(evb);
1216 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
1217 tt_line_eq("complex silly newline");
1219 evbuffer_validate(evb);
1220 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
1221 if (!cp || sz != 5 || memcmp(cp, "more\0\0", 6))
1222 tt_abort_msg("Not as expected");
1223 tt_uint_op(evbuffer_get_length(evb), ==, 0);
1224 evbuffer_validate(evb);
1226 evbuffer_add(evb, s, strlen(s));
1228 evbuffer_validate(evb);
1229 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
1232 evbuffer_validate(evb);
1233 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_ANY);
1235 evbuffer_validate(evb);
1236 evbuffer_drain(evb, evbuffer_get_length(evb));
1237 tt_assert(evbuffer_get_length(evb) == 0);
1238 evbuffer_validate(evb);
1241 s = "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n";
1242 evbuffer_add(evb, s, strlen(s));
1243 evbuffer_validate(evb);
1244 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1245 tt_line_eq("Line with\rin the middle");
1247 evbuffer_validate(evb);
1249 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1250 tt_line_eq("Line with good crlf");
1252 evbuffer_validate(evb);
1254 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1257 evbuffer_validate(evb);
1259 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1260 tt_line_eq("final");
1262 evbuffer_validate(evb);
1263 evbuffer_add(evb, s, 1);
1264 evbuffer_validate(evb);
1266 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF);
1268 evbuffer_validate(evb);
1270 /* Test CRLF_STRICT */
1271 s = " and a bad crlf\nand a good one\r\n\r\nMore\r";
1272 evbuffer_add(evb, s, strlen(s));
1273 evbuffer_validate(evb);
1274 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1275 tt_line_eq("x and a bad crlf\nand a good one");
1277 evbuffer_validate(evb);
1279 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1282 evbuffer_validate(evb);
1284 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1286 evbuffer_validate(evb);
1287 evbuffer_add(evb, "\n", 1);
1288 evbuffer_validate(evb);
1290 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1293 tt_assert(evbuffer_get_length(evb) == 0);
1294 evbuffer_validate(evb);
1296 s = "An internal CR\r is not an eol\r\nNor is a lack of one";
1297 evbuffer_add(evb, s, strlen(s));
1298 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1299 tt_line_eq("An internal CR\r is not an eol");
1301 evbuffer_validate(evb);
1303 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1305 evbuffer_validate(evb);
1307 evbuffer_add(evb, "\r\n", 2);
1308 evbuffer_validate(evb);
1309 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1310 tt_line_eq("Nor is a lack of one");
1312 tt_assert(evbuffer_get_length(evb) == 0);
1313 evbuffer_validate(evb);
1316 s = "An\rand a nl\n\nText";
1317 evbuffer_add(evb, s, strlen(s));
1318 evbuffer_validate(evb);
1320 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1321 tt_line_eq("An\rand a nl");
1323 evbuffer_validate(evb);
1325 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1328 evbuffer_validate(evb);
1330 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1333 evbuffer_add(evb, "\n", 1);
1334 evbuffer_validate(evb);
1335 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1338 evbuffer_validate(evb);
1341 tt_int_op(evbuffer_get_length(evb), ==, 0);
1345 "The all-zeros character which may serve\0"
1346 "to accomplish time fill\0and media fill";
1347 /* Add all but the final NUL of x. */
1348 evbuffer_add(evb, x, sizeof(x)-1);
1350 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1351 tt_line_eq("NUL\n");
1353 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1356 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1357 tt_line_eq("The all-zeros character which may serve");
1359 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1360 tt_line_eq("to accomplish time fill");
1362 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_NUL);
1363 tt_ptr_op(cp, ==, NULL);
1364 evbuffer_drain(evb, -1);
1366 /* Test CRLF_STRICT - across boundaries*/
1367 s = " and a bad crlf\nand a good one\r";
1368 evbuffer_add(evb_tmp, s, strlen(s));
1369 evbuffer_validate(evb);
1370 evbuffer_add_buffer(evb, evb_tmp);
1371 evbuffer_validate(evb);
1373 evbuffer_add(evb_tmp, s, strlen(s));
1374 evbuffer_validate(evb);
1375 evbuffer_add_buffer(evb, evb_tmp);
1376 evbuffer_validate(evb);
1378 evbuffer_add(evb_tmp, s, strlen(s));
1379 evbuffer_validate(evb);
1380 evbuffer_add_buffer(evb, evb_tmp);
1381 evbuffer_validate(evb);
1383 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1384 tt_line_eq(" and a bad crlf\nand a good one");
1386 evbuffer_validate(evb);
1388 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1391 evbuffer_validate(evb);
1393 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1396 evbuffer_validate(evb);
1397 evbuffer_add(evb, "\n", 1);
1398 evbuffer_validate(evb);
1399 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_CRLF_STRICT);
1401 free(cp); cp = NULL;
1402 evbuffer_validate(evb);
1403 tt_assert(evbuffer_get_length(evb) == 0);
1405 /* Test memory problem*/
1406 s = "one line\ntwo line\nblue line";
1407 evbuffer_add(evb_tmp, s, strlen(s));
1408 evbuffer_validate(evb);
1409 evbuffer_add_buffer(evb, evb_tmp);
1410 evbuffer_validate(evb);
1412 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1413 tt_line_eq("one line");
1414 free(cp); cp = NULL;
1415 evbuffer_validate(evb);
1417 /* the next call to readline should fail */
1418 #ifndef EVENT__DISABLE_MM_REPLACEMENT
1419 event_set_mem_functions(failing_malloc, realloc, free);
1420 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1421 tt_assert(cp == NULL);
1422 evbuffer_validate(evb);
1424 /* now we should get the next line back */
1425 event_set_mem_functions(malloc, realloc, free);
1427 cp = evbuffer_readln(evb, &sz, EVBUFFER_EOL_LF);
1428 tt_line_eq("two line");
1429 free(cp); cp = NULL;
1430 evbuffer_validate(evb);
1434 evbuffer_free(evb_tmp);
1439 test_evbuffer_search_eol(void *ptr)
1441 struct evbuffer *buf = evbuffer_new();
1442 struct evbuffer_ptr ptr1, ptr2;
1446 s = "string! \r\n\r\nx\n";
1447 evbuffer_add(buf, s, strlen(s));
1449 ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_CRLF);
1450 tt_int_op(ptr1.pos, ==, 8);
1451 tt_int_op(eol_len, ==, 2);
1454 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
1455 tt_int_op(ptr2.pos, ==, 8);
1456 tt_int_op(eol_len, ==, 2);
1458 evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
1460 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF);
1461 tt_int_op(ptr2.pos, ==, 9);
1462 tt_int_op(eol_len, ==, 1);
1465 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_CRLF_STRICT);
1466 tt_int_op(ptr2.pos, ==, 10);
1467 tt_int_op(eol_len, ==, 2);
1470 ptr1 = evbuffer_search_eol(buf, NULL, &eol_len, EVBUFFER_EOL_LF);
1471 tt_int_op(ptr1.pos, ==, 9);
1472 tt_int_op(eol_len, ==, 1);
1475 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1476 tt_int_op(ptr2.pos, ==, 9);
1477 tt_int_op(eol_len, ==, 1);
1479 evbuffer_ptr_set(buf, &ptr1, 1, EVBUFFER_PTR_ADD);
1481 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1482 tt_int_op(ptr2.pos, ==, 11);
1483 tt_int_op(eol_len, ==, 1);
1485 tt_assert(evbuffer_ptr_set(buf, &ptr1, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0);
1487 ptr2 = evbuffer_search_eol(buf, &ptr1, &eol_len, EVBUFFER_EOL_LF);
1488 tt_int_op(ptr2.pos, ==, -1);
1489 tt_int_op(eol_len, ==, 0);
1496 test_evbuffer_iterative(void *ptr)
1498 struct evbuffer *buf = evbuffer_new();
1499 const char *abc = "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz";
1500 unsigned i, j, sum, n;
1504 for (i = 0; i < 1000; ++i) {
1505 for (j = 1; j < strlen(abc); ++j) {
1507 evutil_snprintf(format, sizeof(format), "%%%u.%us", j, j);
1508 evbuffer_add_printf(buf, format, abc);
1510 /* Only check for rep violations every so often.
1511 Walking over the whole list of chains can get
1512 pretty expensive as it gets long.
1515 evbuffer_validate(buf);
1521 evbuffer_validate(buf);
1523 tt_uint_op(sum, ==, evbuffer_get_length(buf));
1528 evbuffer_get_waste(buf, &a, &w, &u);
1530 printf("Allocated: %u.\nWasted: %u.\nUsed: %u.",
1531 (unsigned)a, (unsigned)w, (unsigned)u);
1532 tt_assert( ((double)w)/a < .125);
1540 test_evbuffer_find(void *ptr)
1543 const char* test1 = "1234567890\r\n";
1544 const char* test2 = "1234567890\r";
1545 #define EVBUFFER_INITIAL_LENGTH 256
1546 char test3[EVBUFFER_INITIAL_LENGTH];
1548 struct evbuffer * buf = evbuffer_new();
1552 /* make sure evbuffer_find doesn't match past the end of the buffer */
1553 evbuffer_add(buf, (unsigned char*)test1, strlen(test1));
1554 evbuffer_validate(buf);
1555 evbuffer_drain(buf, strlen(test1));
1556 evbuffer_validate(buf);
1557 evbuffer_add(buf, (unsigned char*)test2, strlen(test2));
1558 evbuffer_validate(buf);
1559 p = evbuffer_find(buf, (unsigned char*)"\r\n", 2);
1563 * drain the buffer and do another find; in r309 this would
1564 * read past the allocated buffer causing a valgrind error.
1566 evbuffer_drain(buf, strlen(test2));
1567 evbuffer_validate(buf);
1568 for (i = 0; i < EVBUFFER_INITIAL_LENGTH; ++i)
1570 test3[EVBUFFER_INITIAL_LENGTH - 1] = 'x';
1571 evbuffer_add(buf, (unsigned char *)test3, EVBUFFER_INITIAL_LENGTH);
1572 evbuffer_validate(buf);
1573 p = evbuffer_find(buf, (unsigned char *)"xy", 2);
1576 /* simple test for match at end of allocated buffer */
1577 p = evbuffer_find(buf, (unsigned char *)"ax", 2);
1578 tt_assert(p != NULL);
1579 tt_want(strncmp((char*)p, "ax", 2) == 0);
1587 test_evbuffer_ptr_set(void *ptr)
1589 struct evbuffer *buf = evbuffer_new();
1590 struct evbuffer_ptr pos;
1591 struct evbuffer_iovec v[1];
1595 tt_int_op(evbuffer_get_length(buf), ==, 0);
1597 tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1598 tt_assert(pos.pos == 0);
1599 tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_ADD) == -1);
1600 tt_assert(pos.pos == -1);
1601 tt_assert(evbuffer_ptr_set(buf, &pos, 1, EVBUFFER_PTR_SET) == -1);
1602 tt_assert(pos.pos == -1);
1604 /* create some chains */
1605 evbuffer_reserve_space(buf, 5000, v, 1);
1606 v[0].iov_len = 5000;
1607 memset(v[0].iov_base, 1, v[0].iov_len);
1608 evbuffer_commit_space(buf, v, 1);
1609 evbuffer_validate(buf);
1611 evbuffer_reserve_space(buf, 4000, v, 1);
1612 v[0].iov_len = 4000;
1613 memset(v[0].iov_base, 2, v[0].iov_len);
1614 evbuffer_commit_space(buf, v, 1);
1616 evbuffer_reserve_space(buf, 3000, v, 1);
1617 v[0].iov_len = 3000;
1618 memset(v[0].iov_base, 3, v[0].iov_len);
1619 evbuffer_commit_space(buf, v, 1);
1620 evbuffer_validate(buf);
1622 tt_int_op(evbuffer_get_length(buf), ==, 12000);
1624 tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_SET) == -1);
1625 tt_assert(pos.pos == -1);
1626 tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1627 tt_assert(pos.pos == 0);
1628 tt_assert(evbuffer_ptr_set(buf, &pos, 13000, EVBUFFER_PTR_ADD) == -1);
1630 tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1631 tt_assert(pos.pos == 0);
1632 tt_assert(evbuffer_ptr_set(buf, &pos, 10000, EVBUFFER_PTR_ADD) == 0);
1633 tt_assert(pos.pos == 10000);
1634 tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1635 tt_assert(pos.pos == 11000);
1636 tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == 0);
1637 tt_assert(pos.pos == 12000);
1638 tt_assert(evbuffer_ptr_set(buf, &pos, 1000, EVBUFFER_PTR_ADD) == -1);
1639 tt_assert(pos.pos == -1);
1647 test_evbuffer_search(void *ptr)
1649 struct evbuffer *buf = evbuffer_new();
1650 struct evbuffer *tmp = evbuffer_new();
1651 struct evbuffer_ptr pos, end;
1656 pos = evbuffer_search(buf, "x", 1, NULL);
1657 tt_int_op(pos.pos, ==, -1);
1658 tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1659 pos = evbuffer_search(buf, "x", 1, &pos);
1660 tt_int_op(pos.pos, ==, -1);
1661 tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1662 pos = evbuffer_search_range(buf, "x", 1, &pos, &pos);
1663 tt_int_op(pos.pos, ==, -1);
1664 tt_assert(evbuffer_ptr_set(buf, &pos, 0, EVBUFFER_PTR_SET) == 0);
1665 pos = evbuffer_search_range(buf, "x", 1, &pos, NULL);
1666 tt_int_op(pos.pos, ==, -1);
1668 /* set up our chains */
1669 evbuffer_add_printf(tmp, "hello"); /* 5 chars */
1670 evbuffer_add_buffer(buf, tmp);
1671 evbuffer_add_printf(tmp, "foo"); /* 3 chars */
1672 evbuffer_add_buffer(buf, tmp);
1673 evbuffer_add_printf(tmp, "cat"); /* 3 chars */
1674 evbuffer_add_buffer(buf, tmp);
1675 evbuffer_add_printf(tmp, "attack");
1676 evbuffer_add_buffer(buf, tmp);
1678 pos = evbuffer_search(buf, "attack", 6, NULL);
1679 tt_int_op(pos.pos, ==, 11);
1680 pos = evbuffer_search(buf, "attacker", 8, NULL);
1681 tt_int_op(pos.pos, ==, -1);
1683 /* test continuing search */
1684 pos = evbuffer_search(buf, "oc", 2, NULL);
1685 tt_int_op(pos.pos, ==, 7);
1686 pos = evbuffer_search(buf, "cat", 3, &pos);
1687 tt_int_op(pos.pos, ==, 8);
1688 pos = evbuffer_search(buf, "tacking", 7, &pos);
1689 tt_int_op(pos.pos, ==, -1);
1691 evbuffer_ptr_set(buf, &pos, 5, EVBUFFER_PTR_SET);
1692 pos = evbuffer_search(buf, "foo", 3, &pos);
1693 tt_int_op(pos.pos, ==, 5);
1695 evbuffer_ptr_set(buf, &pos, 2, EVBUFFER_PTR_ADD);
1696 pos = evbuffer_search(buf, "tat", 3, &pos);
1697 tt_int_op(pos.pos, ==, 10);
1699 /* test bounded search. */
1700 /* Set "end" to the first t in "attack". */
1701 evbuffer_ptr_set(buf, &end, 12, EVBUFFER_PTR_SET);
1702 pos = evbuffer_search_range(buf, "foo", 3, NULL, &end);
1703 tt_int_op(pos.pos, ==, 5);
1704 pos = evbuffer_search_range(buf, "foocata", 7, NULL, &end);
1705 tt_int_op(pos.pos, ==, 5);
1706 pos = evbuffer_search_range(buf, "foocatat", 8, NULL, &end);
1707 tt_int_op(pos.pos, ==, -1);
1708 pos = evbuffer_search_range(buf, "ack", 3, NULL, &end);
1709 tt_int_op(pos.pos, ==, -1);
1711 /* Set "end" after the last byte in the buffer. */
1712 tt_assert(evbuffer_ptr_set(buf, &end, 17, EVBUFFER_PTR_SET) == 0);
1714 pos = evbuffer_search_range(buf, "attack", 6, NULL, &end);
1715 tt_int_op(pos.pos, ==, 11);
1716 tt_assert(evbuffer_ptr_set(buf, &pos, 11, EVBUFFER_PTR_SET) == 0);
1717 pos = evbuffer_search_range(buf, "attack", 6, &pos, &end);
1718 tt_int_op(pos.pos, ==, 11);
1719 tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0);
1720 pos = evbuffer_search_range(buf, "attack", 6, &pos, &end);
1721 tt_int_op(pos.pos, ==, -1);
1722 tt_assert(evbuffer_ptr_set(buf, &pos, 17, EVBUFFER_PTR_SET) == 0);
1723 pos = evbuffer_search_range(buf, "attack", 6, &pos, NULL);
1724 tt_int_op(pos.pos, ==, -1);
1734 log_change_callback(struct evbuffer *buffer,
1735 const struct evbuffer_cb_info *cbinfo,
1739 size_t old_len = cbinfo->orig_size;
1740 size_t new_len = old_len + cbinfo->n_added - cbinfo->n_deleted;
1741 struct evbuffer *out = arg;
1742 evbuffer_add_printf(out, "%lu->%lu; ", (unsigned long)old_len,
1743 (unsigned long)new_len);
1746 self_draining_callback(struct evbuffer *evbuffer, size_t old_len,
1747 size_t new_len, void *arg)
1749 if (new_len > old_len)
1750 evbuffer_drain(evbuffer, new_len);
1754 test_evbuffer_callbacks(void *ptr)
1756 struct evbuffer *buf = evbuffer_new();
1757 struct evbuffer *buf_out1 = evbuffer_new();
1758 struct evbuffer *buf_out2 = evbuffer_new();
1759 struct evbuffer_cb_entry *cb1, *cb2;
1762 tt_assert(buf_out1);
1763 tt_assert(buf_out2);
1765 cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1766 cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1768 /* Let's run through adding and deleting some stuff from the buffer
1769 * and turning the callbacks on and off and removing them. The callback
1770 * adds a summary of length changes to buf_out1/buf_out2 when called. */
1772 evbuffer_add_printf(buf, "The %d magic words are spotty pudding", 2);
1773 evbuffer_validate(buf);
1774 evbuffer_cb_clear_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1775 evbuffer_drain(buf, 10); /*36->26*/
1776 evbuffer_validate(buf);
1777 evbuffer_prepend(buf, "Hello", 5);/*26->31*/
1778 evbuffer_cb_set_flags(buf, cb2, EVBUFFER_CB_ENABLED);
1779 evbuffer_add_reference(buf, "Goodbye", 7, NULL, NULL); /*31->38*/
1780 evbuffer_remove_cb_entry(buf, cb1);
1781 evbuffer_validate(buf);
1782 evbuffer_drain(buf, evbuffer_get_length(buf)); /*38->0*/;
1783 tt_assert(-1 == evbuffer_remove_cb(buf, log_change_callback, NULL));
1784 evbuffer_add(buf, "X", 1); /* 0->1 */
1785 tt_assert(!evbuffer_remove_cb(buf, log_change_callback, buf_out2));
1786 evbuffer_validate(buf);
1788 tt_str_op((const char *) evbuffer_pullup(buf_out1, -1), ==,
1789 "0->36; 36->26; 26->31; 31->38; ");
1790 tt_str_op((const char *) evbuffer_pullup(buf_out2, -1), ==,
1791 "0->36; 31->38; 38->0; 0->1; ");
1792 evbuffer_drain(buf_out1, evbuffer_get_length(buf_out1));
1793 evbuffer_drain(buf_out2, evbuffer_get_length(buf_out2));
1794 /* Let's test the obsolete buffer_setcb function too. */
1795 cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1796 tt_assert(cb1 != NULL);
1797 cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1798 tt_assert(cb2 != NULL);
1799 evbuffer_setcb(buf, self_draining_callback, NULL);
1800 evbuffer_add_printf(buf, "This should get drained right away.");
1801 tt_uint_op(evbuffer_get_length(buf), ==, 0);
1802 tt_uint_op(evbuffer_get_length(buf_out1), ==, 0);
1803 tt_uint_op(evbuffer_get_length(buf_out2), ==, 0);
1804 evbuffer_setcb(buf, NULL, NULL);
1805 evbuffer_add_printf(buf, "This will not.");
1806 tt_str_op((const char *) evbuffer_pullup(buf, -1), ==, "This will not.");
1807 evbuffer_validate(buf);
1808 evbuffer_drain(buf, evbuffer_get_length(buf));
1809 evbuffer_validate(buf);
1811 /* Now let's try a suspended callback. */
1812 cb1 = evbuffer_add_cb(buf, log_change_callback, buf_out1);
1813 cb2 = evbuffer_add_cb(buf, log_change_callback, buf_out2);
1814 evbuffer_cb_suspend(buf,cb2);
1815 evbuffer_prepend(buf,"Hello world",11); /*0->11*/
1816 evbuffer_validate(buf);
1817 evbuffer_cb_suspend(buf,cb1);
1818 evbuffer_add(buf,"more",4); /* 11->15 */
1819 evbuffer_cb_unsuspend(buf,cb2);
1820 evbuffer_drain(buf, 4); /* 15->11 */
1821 evbuffer_cb_unsuspend(buf,cb1);
1822 evbuffer_drain(buf, evbuffer_get_length(buf)); /* 11->0 */
1824 tt_str_op(evbuffer_pullup(buf_out1, -1), ==,
1825 "0->11; 11->11; 11->0; ");
1826 tt_str_op(evbuffer_pullup(buf_out2, -1), ==,
1827 "0->15; 15->11; 11->0; ");
1834 evbuffer_free(buf_out1);
1836 evbuffer_free(buf_out2);
1839 static int ref_done_cb_called_count = 0;
1840 static void *ref_done_cb_called_with = NULL;
1841 static const void *ref_done_cb_called_with_data = NULL;
1842 static size_t ref_done_cb_called_with_len = 0;
1843 static void ref_done_cb(const void *data, size_t len, void *info)
1845 ++ref_done_cb_called_count;
1846 ref_done_cb_called_with = info;
1847 ref_done_cb_called_with_data = data;
1848 ref_done_cb_called_with_len = len;
1852 test_evbuffer_add_reference(void *ptr)
1854 const char chunk1[] = "If you have found the answer to such a problem";
1855 const char chunk2[] = "you ought to write it up for publication";
1856 /* -- Knuth's "Notes on the Exercises" from TAOCP */
1858 size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1860 struct evbuffer *buf1 = NULL, *buf2 = NULL;
1862 buf1 = evbuffer_new();
1865 evbuffer_add_reference(buf1, chunk1, len1, ref_done_cb, (void*)111);
1866 evbuffer_add(buf1, ", ", 2);
1867 evbuffer_add_reference(buf1, chunk2, len2, ref_done_cb, (void*)222);
1868 tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1870 /* Make sure we can drain a little from a reference. */
1871 tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
1872 tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1873 tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
1874 tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1876 /* Make sure that prepending does not meddle with immutable data */
1877 tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
1878 tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1879 evbuffer_validate(buf1);
1881 /* Make sure that when the chunk is over, the callback is invoked. */
1882 evbuffer_drain(buf1, 7); /* Remove prepended stuff. */
1883 evbuffer_drain(buf1, len1-11-1); /* remove all but one byte of chunk1 */
1884 tt_int_op(ref_done_cb_called_count, ==, 0);
1885 evbuffer_remove(buf1, tmp, 1);
1886 tt_int_op(tmp[0], ==, 'm');
1887 tt_assert(ref_done_cb_called_with == (void*)111);
1888 tt_assert(ref_done_cb_called_with_data == chunk1);
1889 tt_assert(ref_done_cb_called_with_len == len1);
1890 tt_int_op(ref_done_cb_called_count, ==, 1);
1891 evbuffer_validate(buf1);
1893 /* Drain some of the remaining chunk, then add it to another buffer */
1894 evbuffer_drain(buf1, 6); /* Remove the ", you ". */
1895 buf2 = evbuffer_new();
1897 tt_int_op(ref_done_cb_called_count, ==, 1);
1898 evbuffer_add(buf2, "I ", 2);
1900 evbuffer_add_buffer(buf2, buf1);
1901 tt_int_op(ref_done_cb_called_count, ==, 1);
1902 evbuffer_remove(buf2, tmp, 16);
1903 tt_int_op(memcmp("I ought to write", tmp, 16), ==, 0);
1904 evbuffer_drain(buf2, evbuffer_get_length(buf2));
1905 tt_int_op(ref_done_cb_called_count, ==, 2);
1906 tt_assert(ref_done_cb_called_with == (void*)222);
1907 evbuffer_validate(buf2);
1909 /* Now add more stuff to buf1 and make sure that it gets removed on
1911 evbuffer_add(buf1, "You shake and shake the ", 24);
1912 evbuffer_add_reference(buf1, "ketchup bottle", 14, ref_done_cb,
1914 evbuffer_add(buf1, ". Nothing comes and then a lot'll.", 35);
1915 evbuffer_free(buf1);
1917 tt_int_op(ref_done_cb_called_count, ==, 3);
1918 tt_assert(ref_done_cb_called_with == (void*)3333);
1922 evbuffer_free(buf1);
1924 evbuffer_free(buf2);
1928 test_evbuffer_multicast(void *ptr)
1930 const char chunk1[] = "If you have found the answer to such a problem";
1931 const char chunk2[] = "you ought to write it up for publication";
1932 /* -- Knuth's "Notes on the Exercises" from TAOCP */
1934 size_t len1 = strlen(chunk1), len2=strlen(chunk2);
1936 struct evbuffer *buf1 = NULL, *buf2 = NULL;
1938 buf1 = evbuffer_new();
1941 evbuffer_add(buf1, chunk1, len1);
1942 evbuffer_add(buf1, ", ", 2);
1943 evbuffer_add(buf1, chunk2, len2);
1944 tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
1946 buf2 = evbuffer_new();
1949 tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0);
1950 /* nested references are not allowed */
1951 tt_int_op(evbuffer_add_buffer_reference(buf2, buf2), ==, -1);
1952 tt_int_op(evbuffer_add_buffer_reference(buf1, buf2), ==, -1);
1954 /* both buffers contain the same amount of data */
1955 tt_int_op(evbuffer_get_length(buf1), ==, evbuffer_get_length(buf1));
1957 /* Make sure we can drain a little from the first buffer. */
1958 tt_int_op(evbuffer_remove(buf1, tmp, 6), ==, 6);
1959 tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1960 tt_int_op(evbuffer_remove(buf1, tmp, 5), ==, 5);
1961 tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1963 /* Make sure that prepending does not meddle with immutable data */
1964 tt_int_op(evbuffer_prepend(buf1, "I have ", 7), ==, 0);
1965 tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1966 evbuffer_validate(buf1);
1968 /* Make sure we can drain a little from the second buffer. */
1969 tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
1970 tt_int_op(memcmp(tmp, "If you", 6), ==, 0);
1971 tt_int_op(evbuffer_remove(buf2, tmp, 5), ==, 5);
1972 tt_int_op(memcmp(tmp, " have", 5), ==, 0);
1974 /* Make sure that prepending does not meddle with immutable data */
1975 tt_int_op(evbuffer_prepend(buf2, "I have ", 7), ==, 0);
1976 tt_int_op(memcmp(chunk1, "If you", 6), ==, 0);
1977 evbuffer_validate(buf2);
1979 /* Make sure the data can be read from the second buffer when the first is freed */
1980 evbuffer_free(buf1);
1983 tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
1984 tt_int_op(memcmp(tmp, "I have", 6), ==, 0);
1986 tt_int_op(evbuffer_remove(buf2, tmp, 6), ==, 6);
1987 tt_int_op(memcmp(tmp, " foun", 6), ==, 0);
1991 evbuffer_free(buf1);
1993 evbuffer_free(buf2);
1997 test_evbuffer_multicast_drain(void *ptr)
1999 const char chunk1[] = "If you have found the answer to such a problem";
2000 const char chunk2[] = "you ought to write it up for publication";
2001 /* -- Knuth's "Notes on the Exercises" from TAOCP */
2002 size_t len1 = strlen(chunk1), len2=strlen(chunk2);
2004 struct evbuffer *buf1 = NULL, *buf2 = NULL;
2006 buf1 = evbuffer_new();
2009 evbuffer_add(buf1, chunk1, len1);
2010 evbuffer_add(buf1, ", ", 2);
2011 evbuffer_add(buf1, chunk2, len2);
2012 tt_int_op(evbuffer_get_length(buf1), ==, len1+len2+2);
2014 buf2 = evbuffer_new();
2017 tt_int_op(evbuffer_add_buffer_reference(buf2, buf1), ==, 0);
2018 tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2);
2019 tt_int_op(evbuffer_drain(buf1, evbuffer_get_length(buf1)), ==, 0);
2020 tt_int_op(evbuffer_get_length(buf2), ==, len1+len2+2);
2021 tt_int_op(evbuffer_drain(buf2, evbuffer_get_length(buf2)), ==, 0);
2022 evbuffer_validate(buf1);
2023 evbuffer_validate(buf2);
2027 evbuffer_free(buf1);
2029 evbuffer_free(buf2);
2033 check_prepend(struct evbuffer *buffer,
2034 const struct evbuffer_cb_info *cbinfo,
2037 tt_int_op(cbinfo->orig_size, ==, 3);
2038 tt_int_op(cbinfo->n_added, ==, 8096);
2039 tt_int_op(cbinfo->n_deleted, ==, 0);
2043 /* Some cases that we didn't get in test_evbuffer() above, for more coverage. */
2045 test_evbuffer_prepend(void *ptr)
2047 struct evbuffer *buf1 = NULL, *buf2 = NULL;
2048 char tmp[128], *buffer = malloc(8096);
2051 buf1 = evbuffer_new();
2054 /* Case 0: The evbuffer is entirely empty. */
2055 evbuffer_prepend(buf1, "This string has 29 characters", 29);
2056 evbuffer_validate(buf1);
2058 /* Case 1: Prepend goes entirely in new chunk. */
2059 evbuffer_prepend(buf1, "Short.", 6);
2060 evbuffer_validate(buf1);
2062 /* Case 2: prepend goes entirely in first chunk. */
2063 evbuffer_drain(buf1, 6+11);
2064 evbuffer_prepend(buf1, "it", 2);
2065 evbuffer_validate(buf1);
2066 tt_assert(!memcmp(buf1->first->buffer+buf1->first->misalign,
2069 /* Case 3: prepend is split over multiple chunks. */
2070 evbuffer_prepend(buf1, "It is no longer true to say ", 28);
2071 evbuffer_validate(buf1);
2072 n = evbuffer_remove(buf1, tmp, sizeof(tmp)-1);
2073 tt_int_op(n, >=, 0);
2075 tt_str_op(tmp,==,"It is no longer true to say it has 29 characters");
2077 buf2 = evbuffer_new();
2080 /* Case 4: prepend a buffer to an empty buffer. */
2082 evbuffer_add_printf(buf1, "Here is string %d. ", n++);
2083 evbuffer_prepend_buffer(buf2, buf1);
2084 evbuffer_validate(buf2);
2086 /* Case 5: prepend a buffer to a nonempty buffer. */
2087 evbuffer_add_printf(buf1, "Here is string %d. ", n++);
2088 evbuffer_prepend_buffer(buf2, buf1);
2089 evbuffer_validate(buf2);
2090 evbuffer_validate(buf1);
2091 n = evbuffer_remove(buf2, tmp, sizeof(tmp)-1);
2092 tt_int_op(n, >=, 0);
2094 tt_str_op(tmp,==,"Here is string 1000. Here is string 999. ");
2096 /* Case 5: evbuffer_prepend() will need a new buffer, with callbacks */
2097 memset(buffer, 'A', 8096);
2098 evbuffer_free(buf2);
2099 buf2 = evbuffer_new();
2101 evbuffer_prepend(buf2, "foo", 3);
2102 evbuffer_add_cb(buf2, check_prepend, NULL);
2103 evbuffer_prepend(buf2, buffer, 8096);
2104 evbuffer_remove_cb(buf2, check_prepend, NULL);
2105 evbuffer_validate(buf2);
2106 tt_nstr_op(8096,(char *)evbuffer_pullup(buf2, 8096),==,buffer);
2107 evbuffer_drain(buf2, 8096);
2108 tt_nstr_op(3,(char *)evbuffer_pullup(buf2, 3),==,"foo");
2109 evbuffer_drain(buf2, 3);
2114 evbuffer_free(buf1);
2116 evbuffer_free(buf2);
2121 test_evbuffer_peek_first_gt(void *info)
2123 struct evbuffer *buf = NULL, *tmp_buf = NULL;
2124 struct evbuffer_ptr ptr;
2125 struct evbuffer_iovec v[2];
2127 buf = evbuffer_new();
2128 tmp_buf = evbuffer_new();
2129 evbuffer_add_printf(tmp_buf, "Contents of chunk 100\n");
2130 evbuffer_add_buffer(buf, tmp_buf);
2131 evbuffer_add_printf(tmp_buf, "Contents of chunk 1\n");
2132 evbuffer_add_buffer(buf, tmp_buf);
2134 evbuffer_ptr_set(buf, &ptr, 0, EVBUFFER_PTR_SET);
2136 /** The only case that matters*/
2137 tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2);
2139 tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2);
2141 evbuffer_ptr_set(buf, &ptr, 20, EVBUFFER_PTR_ADD);
2142 tt_int_op(evbuffer_peek(buf, -1, &ptr, NULL, 0), ==, 2);
2143 tt_int_op(evbuffer_peek(buf, -1, &ptr, v, 2), ==, 2);
2144 tt_int_op(evbuffer_peek(buf, 2, &ptr, NULL, 0), ==, 1);
2145 tt_int_op(evbuffer_peek(buf, 2, &ptr, v, 2), ==, 1);
2146 tt_int_op(evbuffer_peek(buf, 3, &ptr, NULL, 0), ==, 2);
2147 tt_int_op(evbuffer_peek(buf, 3, &ptr, v, 2), ==, 2);
2153 evbuffer_free(tmp_buf);
2157 test_evbuffer_peek(void *info)
2159 struct evbuffer *buf = NULL, *tmp_buf = NULL;
2161 struct evbuffer_iovec v[20];
2162 struct evbuffer_ptr ptr;
2164 #define tt_iov_eq(v, s) \
2165 tt_int_op((v)->iov_len, ==, strlen(s)); \
2166 tt_assert(!memcmp((v)->iov_base, (s), strlen(s)))
2168 /* Let's make a very fragmented buffer. */
2169 buf = evbuffer_new();
2170 tmp_buf = evbuffer_new();
2171 for (i = 0; i < 16; ++i) {
2172 evbuffer_add_printf(tmp_buf, "Contents of chunk [%d]\n", i);
2173 evbuffer_add_buffer(buf, tmp_buf);
2176 /* How many chunks do we need for everything? */
2177 i = evbuffer_peek(buf, -1, NULL, NULL, 0);
2178 tt_int_op(i, ==, 16);
2180 /* Simple peek: get everything. */
2181 i = evbuffer_peek(buf, -1, NULL, v, 20);
2182 tt_int_op(i, ==, 16); /* we used only 16 chunks. */
2183 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
2184 tt_iov_eq(&v[3], "Contents of chunk [3]\n");
2185 tt_iov_eq(&v[12], "Contents of chunk [12]\n");
2186 tt_iov_eq(&v[15], "Contents of chunk [15]\n");
2188 /* Just get one chunk worth. */
2189 memset(v, 0, sizeof(v));
2190 i = evbuffer_peek(buf, -1, NULL, v, 1);
2191 tt_int_op(i, ==, 1);
2192 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
2193 tt_assert(v[1].iov_base == NULL);
2195 /* Suppose we want at least the first 40 bytes. */
2196 memset(v, 0, sizeof(v));
2197 i = evbuffer_peek(buf, 40, NULL, v, 16);
2198 tt_int_op(i, ==, 2);
2199 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
2200 tt_iov_eq(&v[1], "Contents of chunk [1]\n");
2201 tt_assert(v[2].iov_base == NULL);
2203 /* How many chunks do we need for 100 bytes? */
2204 memset(v, 0, sizeof(v));
2205 i = evbuffer_peek(buf, 100, NULL, NULL, 0);
2206 tt_int_op(i, ==, 5);
2207 tt_assert(v[0].iov_base == NULL);
2209 /* Now we ask for more bytes than we provide chunks for */
2210 memset(v, 0, sizeof(v));
2211 i = evbuffer_peek(buf, 60, NULL, v, 1);
2212 tt_int_op(i, ==, 3);
2213 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
2214 tt_assert(v[1].iov_base == NULL);
2216 /* Now we ask for more bytes than the buffer has. */
2217 memset(v, 0, sizeof(v));
2218 i = evbuffer_peek(buf, 65536, NULL, v, 20);
2219 tt_int_op(i, ==, 16); /* we used only 16 chunks. */
2220 tt_iov_eq(&v[0], "Contents of chunk [0]\n");
2221 tt_iov_eq(&v[3], "Contents of chunk [3]\n");
2222 tt_iov_eq(&v[12], "Contents of chunk [12]\n");
2223 tt_iov_eq(&v[15], "Contents of chunk [15]\n");
2224 tt_assert(v[16].iov_base == NULL);
2226 /* What happens if we try an empty buffer? */
2227 memset(v, 0, sizeof(v));
2228 i = evbuffer_peek(tmp_buf, -1, NULL, v, 20);
2229 tt_int_op(i, ==, 0);
2230 tt_assert(v[0].iov_base == NULL);
2231 memset(v, 0, sizeof(v));
2232 i = evbuffer_peek(tmp_buf, 50, NULL, v, 20);
2233 tt_int_op(i, ==, 0);
2234 tt_assert(v[0].iov_base == NULL);
2236 /* Okay, now time to have fun with pointers. */
2237 memset(v, 0, sizeof(v));
2238 evbuffer_ptr_set(buf, &ptr, 30, EVBUFFER_PTR_SET);
2239 i = evbuffer_peek(buf, 50, &ptr, v, 20);
2240 tt_int_op(i, ==, 3);
2241 tt_iov_eq(&v[0], " of chunk [1]\n");
2242 tt_iov_eq(&v[1], "Contents of chunk [2]\n");
2243 tt_iov_eq(&v[2], "Contents of chunk [3]\n"); /*more than we asked for*/
2245 /* advance to the start of another chain. */
2246 memset(v, 0, sizeof(v));
2247 evbuffer_ptr_set(buf, &ptr, 14, EVBUFFER_PTR_ADD);
2248 i = evbuffer_peek(buf, 44, &ptr, v, 20);
2249 tt_int_op(i, ==, 2);
2250 tt_iov_eq(&v[0], "Contents of chunk [2]\n");
2251 tt_iov_eq(&v[1], "Contents of chunk [3]\n"); /*more than we asked for*/
2253 /* peek at the end of the buffer */
2254 memset(v, 0, sizeof(v));
2255 tt_assert(evbuffer_ptr_set(buf, &ptr, evbuffer_get_length(buf), EVBUFFER_PTR_SET) == 0);
2256 i = evbuffer_peek(buf, 44, &ptr, v, 20);
2257 tt_int_op(i, ==, 0);
2258 tt_assert(v[0].iov_base == NULL);
2264 evbuffer_free(tmp_buf);
2267 /* Check whether evbuffer freezing works right. This is called twice,
2268 once with the argument "start" and once with the argument "end".
2269 When we test "start", we freeze the start of an evbuffer and make sure
2270 that modifying the start of the buffer doesn't work. When we test
2271 "end", we freeze the end of an evbuffer and make sure that modifying
2272 the end of the buffer doesn't work.
2275 test_evbuffer_freeze(void *ptr)
2277 struct evbuffer *buf = NULL, *tmp_buf=NULL;
2278 const char string[] = /* Year's End, Richard Wilbur */
2279 "I've known the wind by water banks to shake\n"
2280 "The late leaves down, which frozen where they fell\n"
2281 "And held in ice as dancers in a spell\n"
2282 "Fluttered all winter long into a lake...";
2283 const int start = !strcmp(ptr, "start");
2288 struct evbuffer_iovec v[1];
2291 tt_str_op(ptr, ==, "end");
2293 buf = evbuffer_new();
2294 tmp_buf = evbuffer_new();
2297 evbuffer_add(buf, string, strlen(string));
2298 evbuffer_freeze(buf, start); /* Freeze the start or the end.*/
2300 #define FREEZE_EQ(a, startcase, endcase) \
2303 tt_int_op((a), ==, (startcase)); \
2305 tt_int_op((a), ==, (endcase)); \
2310 orig_length = evbuffer_get_length(buf);
2312 /* These functions all manipulate the end of buf. */
2313 r = evbuffer_add(buf, "abc", 0);
2314 FREEZE_EQ(r, 0, -1);
2315 r = evbuffer_reserve_space(buf, 10, v, 1);
2316 FREEZE_EQ(r, 1, -1);
2318 memset(v[0].iov_base, 'X', 10);
2321 r = evbuffer_commit_space(buf, v, 1);
2322 FREEZE_EQ(r, 0, -1);
2323 r = evbuffer_add_reference(buf, string, 5, NULL, NULL);
2324 FREEZE_EQ(r, 0, -1);
2325 r = evbuffer_add_printf(buf, "Hello %s", "world");
2326 FREEZE_EQ(r, 11, -1);
2327 /* TODO: test add_buffer, add_file, read */
2330 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
2332 orig_length = evbuffer_get_length(buf);
2334 /* These functions all manipulate the start of buf. */
2335 r = evbuffer_remove(buf, charbuf, 1);
2336 FREEZE_EQ(r, -1, 1);
2337 r = evbuffer_drain(buf, 3);
2338 FREEZE_EQ(r, -1, 0);
2339 r = evbuffer_prepend(buf, "dummy", 5);
2340 FREEZE_EQ(r, -1, 0);
2341 cp = evbuffer_readln(buf, NULL, EVBUFFER_EOL_LF);
2342 FREEZE_EQ(cp==NULL, 1, 0);
2345 /* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */
2348 tt_int_op(orig_length, ==, evbuffer_get_length(buf));
2355 evbuffer_free(tmp_buf);
2359 test_evbuffer_add_iovec(void * ptr)
2361 struct evbuffer * buf = NULL;
2362 struct evbuffer_iovec vec[4];
2363 const char * data[] = {
2364 "Guilt resembles a sword with two edges.",
2365 "On the one hand, it cuts for Justice, imposing practical morality upon those who fear it.",
2366 "Conscience does not always adhere to rational judgment.",
2367 "Guilt is always a self-imposed burden, but it is not always rightly imposed."
2368 /* -- R.A. Salvatore, _Sojurn_ */
2370 size_t expected_length = 0;
2371 size_t returned_length = 0;
2374 buf = evbuffer_new();
2378 for (i = 0; i < 4; i++) {
2379 vec[i].iov_len = strlen(data[i]);
2380 vec[i].iov_base = (char*) data[i];
2381 expected_length += vec[i].iov_len;
2384 returned_length = evbuffer_add_iovec(buf, vec, 4);
2386 tt_int_op(returned_length, ==, evbuffer_get_length(buf));
2387 tt_int_op(evbuffer_get_length(buf), ==, expected_length);
2389 for (i = 0; i < 4; i++) {
2392 memset(charbuf, 0, 1024);
2393 evbuffer_remove(buf, charbuf, strlen(data[i]));
2394 tt_assert(strcmp(charbuf, data[i]) == 0);
2397 tt_assert(evbuffer_get_length(buf) == 0);
2405 test_evbuffer_copyout(void *dummy)
2407 const char string[] =
2408 "Still they skirmish to and fro, men my messmates on the snow "
2409 "When we headed off the aurochs turn for turn; "
2410 "When the rich Allobrogenses never kept amanuenses, "
2411 "And our only plots were piled in lakes at Berne.";
2412 /* -- Kipling, "In The Neolithic Age" */
2414 struct evbuffer_ptr ptr;
2415 struct evbuffer *buf;
2419 buf = evbuffer_new();
2422 tt_int_op(strlen(string), ==, 206);
2424 /* Ensure separate chains */
2425 evbuffer_add_reference(buf, string, 80, no_cleanup, NULL);
2426 evbuffer_add_reference(buf, string+80, 80, no_cleanup, NULL);
2427 evbuffer_add(buf, string+160, strlen(string)-160);
2429 tt_int_op(206, ==, evbuffer_get_length(buf));
2431 /* First, let's test plain old copyout. */
2433 /* Copy a little from the beginning. */
2434 tt_int_op(10, ==, evbuffer_copyout(buf, tmp, 10));
2435 tt_int_op(0, ==, memcmp(tmp, "Still they", 10));
2437 /* Now copy more than a little from the beginning */
2438 memset(tmp, 0, sizeof(tmp));
2439 tt_int_op(100, ==, evbuffer_copyout(buf, tmp, 100));
2440 tt_int_op(0, ==, memcmp(tmp, string, 100));
2442 /* Copy too much; ensure truncation. */
2443 memset(tmp, 0, sizeof(tmp));
2444 tt_int_op(206, ==, evbuffer_copyout(buf, tmp, 230));
2445 tt_int_op(0, ==, memcmp(tmp, string, 206));
2447 /* That was supposed to be nondestructive, btw */
2448 tt_int_op(206, ==, evbuffer_get_length(buf));
2450 /* Now it's time to test copyout_from! First, let's start in the
2452 evbuffer_ptr_set(buf, &ptr, 15, EVBUFFER_PTR_SET);
2453 memset(tmp, 0, sizeof(tmp));
2454 tt_int_op(10, ==, evbuffer_copyout_from(buf, &ptr, tmp, 10));
2455 tt_int_op(0, ==, memcmp(tmp, "mish to an", 10));
2457 /* Right up to the end of the first chain */
2458 memset(tmp, 0, sizeof(tmp));
2459 tt_int_op(65, ==, evbuffer_copyout_from(buf, &ptr, tmp, 65));
2460 tt_int_op(0, ==, memcmp(tmp, string+15, 65));
2462 /* Span into the second chain */
2463 memset(tmp, 0, sizeof(tmp));
2464 tt_int_op(90, ==, evbuffer_copyout_from(buf, &ptr, tmp, 90));
2465 tt_int_op(0, ==, memcmp(tmp, string+15, 90));
2467 /* Span into the third chain */
2468 memset(tmp, 0, sizeof(tmp));
2469 tt_int_op(160, ==, evbuffer_copyout_from(buf, &ptr, tmp, 160));
2470 tt_int_op(0, ==, memcmp(tmp, string+15, 160));
2473 memset(tmp, 0, sizeof(tmp));
2474 tt_int_op(206-15, ==, evbuffer_copyout_from(buf, &ptr, tmp, 999));
2475 tt_int_op(0, ==, memcmp(tmp, string+15, 206-15));
2477 /* That was supposed to be nondestructive, too */
2478 tt_int_op(206, ==, evbuffer_get_length(buf));
2486 setup_passthrough(const struct testcase_t *testcase)
2488 return testcase->setup_data;
2491 cleanup_passthrough(const struct testcase_t *testcase, void *ptr)
2497 static const struct testcase_setup_t nil_setup = {
2502 struct testcase_t evbuffer_testcases[] = {
2503 { "evbuffer", test_evbuffer, 0, NULL, NULL },
2504 { "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty, 0, NULL, NULL },
2505 { "remove_buffer_with_empty2", test_evbuffer_remove_buffer_with_empty2, 0, NULL, NULL },
2506 { "remove_buffer_with_empty3", test_evbuffer_remove_buffer_with_empty3, 0, NULL, NULL },
2507 { "add_buffer_with_empty", test_evbuffer_add_buffer_with_empty, 0, NULL, NULL },
2508 { "add_buffer_with_empty2", test_evbuffer_add_buffer_with_empty2, 0, NULL, NULL },
2509 { "reserve2", test_evbuffer_reserve2, 0, NULL, NULL },
2510 { "reserve_many", test_evbuffer_reserve_many, 0, NULL, NULL },
2511 { "reserve_many2", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"add" },
2512 { "reserve_many3", test_evbuffer_reserve_many, 0, &nil_setup, (void*)"fill" },
2513 { "expand", test_evbuffer_expand, 0, NULL, NULL },
2514 { "expand_overflow", test_evbuffer_expand_overflow, 0, NULL, NULL },
2515 { "add1", test_evbuffer_add1, 0, NULL, NULL },
2516 { "add2", test_evbuffer_add2, 0, NULL, NULL },
2517 { "reference", test_evbuffer_reference, 0, NULL, NULL },
2518 { "reference2", test_evbuffer_reference2, 0, NULL, NULL },
2519 { "iterative", test_evbuffer_iterative, 0, NULL, NULL },
2520 { "readln", test_evbuffer_readln, TT_NO_LOGS, &basic_setup, NULL },
2521 { "search_eol", test_evbuffer_search_eol, 0, NULL, NULL },
2522 { "find", test_evbuffer_find, 0, NULL, NULL },
2523 { "ptr_set", test_evbuffer_ptr_set, 0, NULL, NULL },
2524 { "search", test_evbuffer_search, 0, NULL, NULL },
2525 { "callbacks", test_evbuffer_callbacks, 0, NULL, NULL },
2526 { "add_reference", test_evbuffer_add_reference, 0, NULL, NULL },
2527 { "multicast", test_evbuffer_multicast, 0, NULL, NULL },
2528 { "multicast_drain", test_evbuffer_multicast_drain, 0, NULL, NULL },
2529 { "prepend", test_evbuffer_prepend, TT_FORK, NULL, NULL },
2530 { "peek", test_evbuffer_peek, 0, NULL, NULL },
2531 { "peek_first_gt", test_evbuffer_peek_first_gt, 0, NULL, NULL },
2532 { "freeze_start", test_evbuffer_freeze, 0, &nil_setup, (void*)"start" },
2533 { "freeze_end", test_evbuffer_freeze, 0, &nil_setup, (void*)"end" },
2534 { "add_iovec", test_evbuffer_add_iovec, 0, NULL, NULL},
2535 { "copyout", test_evbuffer_copyout, 0, NULL, NULL},
2536 { "file_segment_add_cleanup_cb", test_evbuffer_file_segment_add_cleanup_cb, 0, NULL, NULL },
2538 #define ADDFILE_TEST(name, parameters) \
2539 { name, test_evbuffer_add_file, TT_FORK|TT_NEED_BASE, \
2540 &basic_setup, (void*)(parameters) }
2542 #define ADDFILE_TEST_GROUP(name, parameters) \
2543 ADDFILE_TEST(name "_sendfile", "sendfile " parameters), \
2544 ADDFILE_TEST(name "_mmap", "mmap " parameters), \
2545 ADDFILE_TEST(name "_linear", "linear " parameters)
2547 ADDFILE_TEST_GROUP("add_file", ""),
2548 ADDFILE_TEST("add_file_nosegment", "default nosegment"),
2550 ADDFILE_TEST_GROUP("add_big_file", "bigfile"),
2551 ADDFILE_TEST("add_big_file_nosegment", "default nosegment bigfile"),
2553 ADDFILE_TEST_GROUP("add_file_offset", "bigfile map_offset"),
2554 ADDFILE_TEST("add_file_offset_nosegment",
2555 "default nosegment bigfile map_offset"),
2557 ADDFILE_TEST_GROUP("add_file_offset2", "bigfile offset_in_segment"),
2559 ADDFILE_TEST_GROUP("add_file_offset3",
2560 "bigfile offset_in_segment map_offset"),