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.
33 #include "event2/event-config.h"
35 #include <sys/types.h>
37 #ifdef _EVENT_HAVE_SYS_TIME_H
40 #include <sys/queue.h>
42 #include <sys/socket.h>
54 #include "event2/event.h"
55 #include "event2/buffer.h"
56 #include "event2/buffer_compat.h"
57 #include "event2/util.h"
59 #include "evbuffer-internal.h"
60 #include "log-internal.h"
64 /* Validates that an evbuffer is good. Returns false if it isn't, true if it
67 _evbuffer_validate(struct evbuffer
*buf
)
69 struct evbuffer_chain
*chain
;
71 int found_last_with_datap
= 0;
73 if (buf
->first
== NULL
) {
74 tt_assert(buf
->last
== NULL
);
75 tt_assert(buf
->total_len
== 0);
80 tt_assert(buf
->last_with_datap
);
81 if (buf
->last_with_datap
== &buf
->first
)
82 found_last_with_datap
= 1;
84 while (chain
!= NULL
) {
85 if (&chain
->next
== buf
->last_with_datap
)
86 found_last_with_datap
= 1;
88 if (chain
->next
== NULL
) {
89 tt_assert(buf
->last
== chain
);
91 tt_assert(chain
->buffer_len
>= chain
->misalign
+ chain
->off
);
96 tt_assert(*buf
->last_with_datap
);
98 if (*buf
->last_with_datap
) {
99 chain
= *buf
->last_with_datap
;
100 if (chain
->off
== 0 || buf
->total_len
== 0) {
101 tt_assert(chain
->off
== 0)
102 tt_assert(chain
== buf
->first
);
103 tt_assert(buf
->total_len
== 0);
106 while (chain
!= NULL
) {
107 tt_assert(chain
->off
== 0);
111 tt_assert(buf
->last_with_datap
== &buf
->first
);
113 tt_assert(found_last_with_datap
);
115 tt_assert(sum
== buf
->total_len
);
122 evbuffer_get_waste(struct evbuffer
*buf
, size_t *allocatedp
, size_t *wastedp
, size_t *usedp
)
124 struct evbuffer_chain
*chain
;
130 /* skip empty at start */
131 while (chain
&& chain
->off
==0) {
133 a
+= chain
->buffer_len
;
136 /* first nonempty chain: stuff at the end only is wasted. */
139 a
+= chain
->buffer_len
;
141 if (chain
->next
&& chain
->next
->off
)
142 w
+= (size_t)(chain
->buffer_len
- (chain
->misalign
+ chain
->off
));
145 /* subsequent nonempty chains */
146 while (chain
&& chain
->off
) {
148 a
+= chain
->buffer_len
;
149 w
+= (size_t)chain
->misalign
;
151 if (chain
->next
&& chain
->next
->off
)
152 w
+= (size_t) (chain
->buffer_len
- (chain
->misalign
+ chain
->off
));
155 /* subsequent empty chains */
158 a
+= chain
->buffer_len
;
165 #define evbuffer_validate(buf) \
166 TT_STMT_BEGIN if (!_evbuffer_validate(buf)) TT_DIE(("Buffer format invalid")); TT_STMT_END
169 test_evbuffer(void *ptr
)
171 static char buffer
[512], *tmp
;
172 struct evbuffer
*evb
= evbuffer_new();
173 struct evbuffer
*evb_two
= evbuffer_new();
177 evbuffer_validate(evb
);
178 evbuffer_add_printf(evb
, "%s/%d", "hello", 1);
179 evbuffer_validate(evb
);
181 tt_assert(evbuffer_get_length(evb
) == 7);
182 tt_assert(!memcmp((char*)EVBUFFER_DATA(evb
), "hello/1", 1));
184 evbuffer_add_buffer(evb
, evb_two
);
185 evbuffer_validate(evb
);
187 evbuffer_drain(evb
, strlen("hello/"));
188 evbuffer_validate(evb
);
189 tt_assert(evbuffer_get_length(evb
) == 1);
190 tt_assert(!memcmp((char*)EVBUFFER_DATA(evb
), "1", 1));
192 evbuffer_add_printf(evb_two
, "%s", "/hello");
193 evbuffer_validate(evb
);
194 evbuffer_add_buffer(evb
, evb_two
);
195 evbuffer_validate(evb
);
197 tt_assert(evbuffer_get_length(evb_two
) == 0);
198 tt_assert(evbuffer_get_length(evb
) == 7);
199 tt_assert(!memcmp((char*)EVBUFFER_DATA(evb
), "1/hello", 7) != 0);
201 memset(buffer
, 0, sizeof(buffer
));
202 evbuffer_add(evb
, buffer
, sizeof(buffer
));
203 evbuffer_validate(evb
);
204 tt_assert(evbuffer_get_length(evb
) == 7 + 512);
206 tmp
= (char *)evbuffer_pullup(evb
, 7 + 512);
208 tt_assert(!strncmp(tmp
, "1/hello", 7));
209 tt_assert(!memcmp(tmp
+ 7, buffer
, sizeof(buffer
)));
210 evbuffer_validate(evb
);
212 evbuffer_prepend(evb
, "something", 9);
213 evbuffer_validate(evb
);
214 evbuffer_prepend(evb
, "else", 4);
215 evbuffer_validate(evb
);
217 tmp
= (char *)evbuffer_pullup(evb
, 4 + 9 + 7);
218 tt_assert(!strncmp(tmp
, "elsesomething1/hello", 4 + 9 + 7));
219 evbuffer_validate(evb
);
221 evbuffer_drain(evb
, -1);
222 evbuffer_validate(evb
);
223 evbuffer_drain(evb_two
, -1);
224 evbuffer_validate(evb
);
226 for (i
= 0; i
< 3; ++i
) {
227 evbuffer_add(evb_two
, buffer
, sizeof(buffer
));
228 evbuffer_validate(evb_two
);
229 evbuffer_add_buffer(evb
, evb_two
);
230 evbuffer_validate(evb
);
231 evbuffer_validate(evb_two
);
234 tt_assert(evbuffer_get_length(evb_two
) == 0);
235 tt_assert(evbuffer_get_length(evb
) == i
* sizeof(buffer
));
237 /* test remove buffer */
238 sz_tmp
= (size_t)(sizeof(buffer
)*2.5);
239 evbuffer_remove_buffer(evb
, evb_two
, sz_tmp
);
240 tt_assert(evbuffer_get_length(evb_two
) == sz_tmp
);
241 tt_assert(evbuffer_get_length(evb
) == sizeof(buffer
) / 2);
242 evbuffer_validate(evb
);
244 if (memcmp(evbuffer_pullup(
245 evb
, -1), buffer
, sizeof(buffer
) / 2) != 0 ||
246 memcmp(evbuffer_pullup(
247 evb_two
, -1), buffer
, sizeof(buffer
)) != 0)
248 tt_abort_msg("Pullup did not preserve content");
250 evbuffer_validate(evb
);
253 /* testing one-vector reserve and commit */
255 struct evbuffer_iovec v
[1];
259 for (i
= 0; i
< 3; ++i
) {
260 r
= evbuffer_reserve_space(evb
, 10000, v
, 1);
262 tt_assert(v
[0].iov_len
>= 10000);
263 tt_assert(v
[0].iov_base
!= NULL
);
265 evbuffer_validate(evb
);
267 for (j
= 0; j
< 10000; ++j
) {
270 evbuffer_validate(evb
);
272 tt_int_op(evbuffer_commit_space(evb
, v
, 1), ==, 0);
273 evbuffer_validate(evb
);
275 tt_assert(evbuffer_get_length(evb
) >= 10000);
277 evbuffer_drain(evb
, j
* 5000);
278 evbuffer_validate(evb
);
284 evbuffer_free(evb_two
);
288 no_cleanup(const void *data
, size_t datalen
, void *extra
)
293 test_evbuffer_remove_buffer_with_empty(void *ptr
)
295 struct evbuffer
*src
= evbuffer_new();
296 struct evbuffer
*dst
= evbuffer_new();
299 evbuffer_validate(src
);
300 evbuffer_validate(dst
);
302 /* setup the buffers */
303 /* we need more data in src than we will move later */
304 evbuffer_add_reference(src
, buf
, sizeof(buf
), no_cleanup
, NULL
);
305 evbuffer_add_reference(src
, buf
, sizeof(buf
), no_cleanup
, NULL
);
306 /* we need one buffer in dst and one empty buffer at the end */
307 evbuffer_add(dst
, buf
, sizeof(buf
));
308 evbuffer_add_reference(dst
, buf
, 0, no_cleanup
, NULL
);
310 evbuffer_validate(src
);
311 evbuffer_validate(dst
);
313 /* move three bytes over */
314 evbuffer_remove_buffer(src
, dst
, 3);
316 evbuffer_validate(src
);
317 evbuffer_validate(dst
);
325 test_evbuffer_reserve2(void *ptr
)
327 /* Test the two-vector cases of reserve/commit. */
328 struct evbuffer
*buf
= evbuffer_new();
330 struct evbuffer_iovec v
[2];
334 /* First chunk will necessarily be one chunk. Use 512 bytes of it.*/
335 n
= evbuffer_reserve_space(buf
, 1024, v
, 2);
337 tt_int_op(evbuffer_get_length(buf
), ==, 0);
338 tt_assert(v
[0].iov_base
!= NULL
);
339 tt_int_op(v
[0].iov_len
, >=, 1024);
340 memset(v
[0].iov_base
, 'X', 512);
342 remaining
= v
[0].iov_len
- 512;
344 evbuffer_validate(buf
);
345 tt_int_op(0, ==, evbuffer_commit_space(buf
, v
, 1));
346 tt_int_op(evbuffer_get_length(buf
), ==, 512);
347 evbuffer_validate(buf
);
349 /* Ask for another same-chunk request, in an existing chunk. Use 8
351 n
= evbuffer_reserve_space(buf
, 32, v
, 2);
353 tt_assert(cp
+ 512 == v
[0].iov_base
);
354 tt_int_op(remaining
, ==, v
[0].iov_len
);
355 memset(v
[0].iov_base
, 'Y', 8);
357 tt_int_op(0, ==, evbuffer_commit_space(buf
, v
, 1));
358 tt_int_op(evbuffer_get_length(buf
), ==, 520);
360 evbuffer_validate(buf
);
362 /* Now ask for a request that will be split. Use only one byte of it,
364 n
= evbuffer_reserve_space(buf
, remaining
+64, v
, 2);
366 tt_assert(cp
+ 520 == v
[0].iov_base
);
367 tt_int_op(remaining
, ==, v
[0].iov_len
);
368 tt_assert(v
[1].iov_base
);
369 tt_assert(v
[1].iov_len
>= 64);
371 memset(v
[0].iov_base
, 'Z', 1);
373 tt_int_op(0, ==, evbuffer_commit_space(buf
, v
, 1));
374 tt_int_op(evbuffer_get_length(buf
), ==, 521);
376 evbuffer_validate(buf
);
378 /* Now ask for a request that will be split. Use some of the first
379 * part and some of the second. */
380 n
= evbuffer_reserve_space(buf
, remaining
+64, v
, 2);
381 evbuffer_validate(buf
);
383 tt_assert(cp
+ 521 == v
[0].iov_base
);
384 tt_int_op(remaining
, ==, v
[0].iov_len
);
385 tt_assert(v
[1].iov_base
== cp2
);
386 tt_assert(v
[1].iov_len
>= 64);
387 memset(v
[0].iov_base
, 'W', 400);
389 memset(v
[1].iov_base
, 'x', 60);
391 tt_int_op(0, ==, evbuffer_commit_space(buf
, v
, 2));
392 tt_int_op(evbuffer_get_length(buf
), ==, 981);
393 evbuffer_validate(buf
);
395 /* Now peek to make sure stuff got made how we like. */
396 memset(v
,0,sizeof(v
));
397 n
= evbuffer_peek(buf
, -1, NULL
, v
, 2);
399 tt_int_op(v
[0].iov_len
, ==, 921);
400 tt_int_op(v
[1].iov_len
, ==, 60);
403 for (i
=0; i
<512; ++i
)
404 tt_int_op(cp
[i
], ==, 'X');
405 for (i
=512; i
<520; ++i
)
406 tt_int_op(cp
[i
], ==, 'Y');
407 for (i
=520; i
<521; ++i
)
408 tt_int_op(cp
[i
], ==, 'Z');
409 for (i
=521; i
<921; ++i
)
410 tt_int_op(cp
[i
], ==, 'W');
414 tt_int_op(cp
[i
], ==, 'x');
421 test_evbuffer_reserve_many(void *ptr
)
423 /* This is a glass-box test to handle expanding a buffer with more
424 * chunks and reallocating chunks as needed */
425 struct evbuffer
*buf
= evbuffer_new();
426 struct evbuffer_iovec v
[8];
429 int add_data
= ptr
&& !strcmp(ptr
, "add");
430 int fill_first
= ptr
&& !strcmp(ptr
, "fill");
433 /* When reserving the the first chunk, we just allocate it */
434 n
= evbuffer_reserve_space(buf
, 128, v
, 2);
435 evbuffer_validate(buf
);
437 tt_assert(v
[0].iov_len
>= 128);
441 *(char*)v
[0].iov_base
= 'X';
443 n
= evbuffer_commit_space(buf
, v
, 1);
445 } else if (fill_first
) {
446 memset(v
[0].iov_base
, 'X', v
[0].iov_len
);
447 n
= evbuffer_commit_space(buf
, v
, 1);
449 n
= evbuffer_reserve_space(buf
, 128, v
, 2);
452 tt_assert(v
[0].iov_base
!= cp1
);
456 /* Make another chunk get added. */
457 n
= evbuffer_reserve_space(buf
, sz
+128, v
, 2);
458 evbuffer_validate(buf
);
460 sz
= v
[0].iov_len
+ v
[1].iov_len
;
461 tt_int_op(sz
, >=, v
[0].iov_len
+128);
463 tt_assert(v
[0].iov_base
== cp1
+ 1);
465 tt_assert(v
[0].iov_base
== cp1
);
470 /* And a third chunk. */
471 n
= evbuffer_reserve_space(buf
, sz
+128, v
, 3);
472 evbuffer_validate(buf
);
474 tt_assert(cp1
== v
[0].iov_base
);
475 tt_assert(cp2
== v
[1].iov_base
);
476 sz
= v
[0].iov_len
+ v
[1].iov_len
+ v
[2].iov_len
;
478 /* Now force a reallocation by asking for more space in only 2
480 n
= evbuffer_reserve_space(buf
, sz
+128, v
, 2);
481 evbuffer_validate(buf
);
484 tt_assert(cp1
== v
[0].iov_base
);
494 test_evbuffer_expand(void *ptr
)
497 struct evbuffer
*buf
;
501 memset(data
, 'X', sizeof(data
));
503 /* Make sure that expand() works on an empty buffer */
504 buf
= evbuffer_new();
505 tt_int_op(evbuffer_expand(buf
, 20000), ==, 0);
506 evbuffer_validate(buf
);
508 evbuffer_get_waste(buf
, &a
,&w
,&u
);
511 tt_assert(a
>= 20000);
512 tt_assert(buf
->first
);
513 tt_assert(buf
->first
== buf
->last
);
514 tt_assert(buf
->first
->off
== 0);
515 tt_assert(buf
->first
->buffer_len
>= 20000);
517 /* Make sure that expand() works as a no-op when there's enough
518 * contiguous space already. */
519 buffer
= buf
->first
->buffer
;
520 evbuffer_add(buf
, data
, 1024);
521 tt_int_op(evbuffer_expand(buf
, 1024), ==, 0);
522 tt_assert(buf
->first
->buffer
== buffer
);
523 evbuffer_validate(buf
);
526 /* Make sure that expand() can work by moving misaligned data
527 * when it makes sense to do so. */
528 buf
= evbuffer_new();
529 evbuffer_add(buf
, data
, 400);
531 int n
= (int)(buf
->first
->buffer_len
- buf
->first
->off
- 1);
532 tt_assert(n
< (int)sizeof(data
));
533 evbuffer_add(buf
, data
, n
);
535 tt_assert(buf
->first
== buf
->last
);
536 tt_assert(buf
->first
->off
== buf
->first
->buffer_len
- 1);
537 evbuffer_drain(buf
, buf
->first
->off
- 1);
538 tt_assert(1 == evbuffer_get_length(buf
));
539 tt_assert(buf
->first
->misalign
> 0);
540 tt_assert(buf
->first
->off
== 1);
541 buffer
= buf
->first
->buffer
;
542 tt_assert(evbuffer_expand(buf
, 40) == 0);
543 tt_assert(buf
->first
== buf
->last
);
544 tt_assert(buf
->first
->off
== 1);
545 tt_assert(buf
->first
->buffer
== buffer
);
546 tt_assert(buf
->first
->misalign
== 0);
547 evbuffer_validate(buf
);
550 /* add, expand, pull-up: This used to crash libevent. */
551 buf
= evbuffer_new();
553 evbuffer_add(buf
, data
, sizeof(data
));
554 evbuffer_add(buf
, data
, sizeof(data
));
555 evbuffer_add(buf
, data
, sizeof(data
));
557 evbuffer_validate(buf
);
558 evbuffer_expand(buf
, 1024);
559 evbuffer_validate(buf
);
560 evbuffer_pullup(buf
, -1);
561 evbuffer_validate(buf
);
568 static int reference_cb_called
;
570 reference_cb(const void *data
, size_t len
, void *extra
)
572 tt_str_op(data
, ==, "this is what we add as read-only memory.");
573 tt_int_op(len
, ==, strlen(data
));
574 tt_want(extra
== (void *)0xdeadaffe);
575 ++reference_cb_called
;
581 test_evbuffer_reference(void *ptr
)
583 struct evbuffer
*src
= evbuffer_new();
584 struct evbuffer
*dst
= evbuffer_new();
585 struct evbuffer_iovec v
[1];
586 const char *data
= "this is what we add as read-only memory.";
587 reference_cb_called
= 0;
589 tt_assert(evbuffer_add_reference(src
, data
, strlen(data
),
590 reference_cb
, (void *)0xdeadaffe) != -1);
592 evbuffer_reserve_space(dst
, strlen(data
), v
, 1);
593 tt_assert(evbuffer_remove(src
, v
[0].iov_base
, 10) != -1);
595 evbuffer_validate(src
);
596 evbuffer_validate(dst
);
598 /* make sure that we don't write data at the beginning */
599 evbuffer_prepend(src
, "aaaaa", 5);
600 evbuffer_validate(src
);
601 evbuffer_drain(src
, 5);
603 tt_assert(evbuffer_remove(src
, ((char*)(v
[0].iov_base
)) + 10,
604 strlen(data
) - 10) != -1);
606 v
[0].iov_len
= strlen(data
);
608 evbuffer_commit_space(dst
, v
, 1);
609 evbuffer_validate(src
);
610 evbuffer_validate(dst
);
612 tt_int_op(reference_cb_called
, ==, 1);
614 tt_assert(!memcmp(evbuffer_pullup(dst
, strlen(data
)),
615 data
, strlen(data
)));
616 evbuffer_validate(dst
);
623 int _evbuffer_testing_use_sendfile(void);
624 int _evbuffer_testing_use_mmap(void);
625 int _evbuffer_testing_use_linear_file_access(void);
628 test_evbuffer_add_file(void *ptr
)
630 const char *impl
= ptr
;
631 struct evbuffer
*src
= evbuffer_new();
632 const char *data
= "this is what we add as file system data.";
636 evutil_socket_t pair
[2] = {-1, -1};
637 int r
=0, n_written
=0;
639 /* Add a test for a big file. XXXX */
642 if (!strcmp(impl
, "sendfile")) {
643 if (!_evbuffer_testing_use_sendfile())
645 TT_BLATHER(("Using sendfile-based implementaion"));
646 } else if (!strcmp(impl
, "mmap")) {
647 if (!_evbuffer_testing_use_mmap())
649 TT_BLATHER(("Using mmap-based implementaion"));
650 } else if (!strcmp(impl
, "linear")) {
651 if (!_evbuffer_testing_use_linear_file_access())
653 TT_BLATHER(("Using read-based implementaion"));
655 TT_DIE(("Didn't recognize the implementation"));
658 /* Say that it drains to a fd so that we can use sendfile. */
659 evbuffer_set_flags(src
, EVBUFFER_FLAG_DRAINS_TO_FD
);
661 #if defined(_EVENT_HAVE_SENDFILE) && defined(__sun__) && defined(__svr4__)
662 /* We need to use a pair of AF_INET sockets, since Solaris
663 doesn't support sendfile() over AF_UNIX. */
664 if (evutil_ersatz_socketpair(AF_INET
, SOCK_STREAM
, 0, pair
) == -1)
665 tt_abort_msg("ersatz_socketpair failed");
667 if (evutil_socketpair(AF_UNIX
, SOCK_STREAM
, 0, pair
) == -1)
668 tt_abort_msg("socketpair failed");
671 datalen
= strlen(data
);
672 fd
= regress_make_tmpfile(data
, datalen
);
676 tt_assert(evbuffer_add_file(src
, fd
, 0, datalen
) != -1);
678 evbuffer_validate(src
);
680 while (evbuffer_get_length(src
) &&
681 (r
= evbuffer_write(src
, pair
[0])) > 0) {
682 evbuffer_validate(src
);
685 tt_int_op(r
, !=, -1);
686 tt_int_op(n_written
, ==, datalen
);
688 evbuffer_validate(src
);
689 tt_int_op(evbuffer_read(src
, pair
[1], (int)strlen(data
)), ==, datalen
);
690 evbuffer_validate(src
);
691 compare
= (char *)evbuffer_pullup(src
, datalen
);
692 tt_assert(compare
!= NULL
);
693 if (memcmp(compare
, data
, datalen
))
694 tt_abort_msg("Data from add_file differs.");
696 evbuffer_validate(src
);
699 evutil_closesocket(pair
[0]);
701 evutil_closesocket(pair
[1]);
705 #ifndef _EVENT_DISABLE_MM_REPLACEMENT
707 failing_malloc(size_t how_much
)
715 test_evbuffer_readln(void *ptr
)
717 struct evbuffer
*evb
= evbuffer_new();
718 struct evbuffer
*evb_tmp
= evbuffer_new();
723 #define tt_line_eq(content) \
725 if (!cp || sz != strlen(content) || strcmp(cp, content)) { \
726 TT_DIE(("Wanted %s; got %s [%d]", content, cp, (int)sz)); \
731 s
= "complex silly newline\r\n\n\r\n\n\rmore\0\n";
732 evbuffer_add(evb
, s
, strlen(s
)+2);
733 evbuffer_validate(evb
);
734 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_ANY
);
735 tt_line_eq("complex silly newline");
737 evbuffer_validate(evb
);
738 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_ANY
);
739 if (!cp
|| sz
!= 5 || memcmp(cp
, "more\0\0", 6))
740 tt_abort_msg("Not as expected");
741 tt_uint_op(evbuffer_get_length(evb
), ==, 0);
742 evbuffer_validate(evb
);
744 evbuffer_add(evb
, s
, strlen(s
));
746 evbuffer_validate(evb
);
747 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_ANY
);
750 evbuffer_validate(evb
);
751 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_ANY
);
753 evbuffer_validate(evb
);
754 evbuffer_drain(evb
, evbuffer_get_length(evb
));
755 tt_assert(evbuffer_get_length(evb
) == 0);
756 evbuffer_validate(evb
);
759 s
= "Line with\rin the middle\nLine with good crlf\r\n\nfinal\n";
760 evbuffer_add(evb
, s
, strlen(s
));
761 evbuffer_validate(evb
);
762 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF
);
763 tt_line_eq("Line with\rin the middle");
765 evbuffer_validate(evb
);
767 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF
);
768 tt_line_eq("Line with good crlf");
770 evbuffer_validate(evb
);
772 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF
);
775 evbuffer_validate(evb
);
777 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF
);
780 evbuffer_validate(evb
);
781 evbuffer_add(evb
, s
, 1);
782 evbuffer_validate(evb
);
784 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF
);
786 evbuffer_validate(evb
);
788 /* Test CRLF_STRICT */
789 s
= " and a bad crlf\nand a good one\r\n\r\nMore\r";
790 evbuffer_add(evb
, s
, strlen(s
));
791 evbuffer_validate(evb
);
792 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
793 tt_line_eq("x and a bad crlf\nand a good one");
795 evbuffer_validate(evb
);
797 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
800 evbuffer_validate(evb
);
802 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
804 evbuffer_validate(evb
);
805 evbuffer_add(evb
, "\n", 1);
806 evbuffer_validate(evb
);
808 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
811 tt_assert(evbuffer_get_length(evb
) == 0);
812 evbuffer_validate(evb
);
814 s
= "An internal CR\r is not an eol\r\nNor is a lack of one";
815 evbuffer_add(evb
, s
, strlen(s
));
816 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
817 tt_line_eq("An internal CR\r is not an eol");
819 evbuffer_validate(evb
);
821 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
823 evbuffer_validate(evb
);
825 evbuffer_add(evb
, "\r\n", 2);
826 evbuffer_validate(evb
);
827 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
828 tt_line_eq("Nor is a lack of one");
830 tt_assert(evbuffer_get_length(evb
) == 0);
831 evbuffer_validate(evb
);
834 s
= "An\rand a nl\n\nText";
835 evbuffer_add(evb
, s
, strlen(s
));
836 evbuffer_validate(evb
);
838 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_LF
);
839 tt_line_eq("An\rand a nl");
841 evbuffer_validate(evb
);
843 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_LF
);
846 evbuffer_validate(evb
);
848 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_LF
);
851 evbuffer_add(evb
, "\n", 1);
852 evbuffer_validate(evb
);
853 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_LF
);
856 evbuffer_validate(evb
);
858 /* Test CRLF_STRICT - across boundaries*/
859 s
= " and a bad crlf\nand a good one\r";
860 evbuffer_add(evb_tmp
, s
, strlen(s
));
861 evbuffer_validate(evb
);
862 evbuffer_add_buffer(evb
, evb_tmp
);
863 evbuffer_validate(evb
);
865 evbuffer_add(evb_tmp
, s
, strlen(s
));
866 evbuffer_validate(evb
);
867 evbuffer_add_buffer(evb
, evb_tmp
);
868 evbuffer_validate(evb
);
870 evbuffer_add(evb_tmp
, s
, strlen(s
));
871 evbuffer_validate(evb
);
872 evbuffer_add_buffer(evb
, evb_tmp
);
873 evbuffer_validate(evb
);
875 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
876 tt_line_eq(" and a bad crlf\nand a good one");
878 evbuffer_validate(evb
);
880 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
883 evbuffer_validate(evb
);
885 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
888 evbuffer_validate(evb
);
889 evbuffer_add(evb
, "\n", 1);
890 evbuffer_validate(evb
);
891 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_CRLF_STRICT
);
894 evbuffer_validate(evb
);
895 tt_assert(evbuffer_get_length(evb
) == 0);
897 /* Test memory problem*/
898 s
= "one line\ntwo line\nblue line";
899 evbuffer_add(evb_tmp
, s
, strlen(s
));
900 evbuffer_validate(evb
);
901 evbuffer_add_buffer(evb
, evb_tmp
);
902 evbuffer_validate(evb
);
904 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_LF
);
905 tt_line_eq("one line");
907 evbuffer_validate(evb
);
909 /* the next call to readline should fail */
910 #ifndef _EVENT_DISABLE_MM_REPLACEMENT
911 event_set_mem_functions(failing_malloc
, realloc
, free
);
912 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_LF
);
913 tt_assert(cp
== NULL
);
914 evbuffer_validate(evb
);
916 /* now we should get the next line back */
917 event_set_mem_functions(malloc
, realloc
, free
);
919 cp
= evbuffer_readln(evb
, &sz
, EVBUFFER_EOL_LF
);
920 tt_line_eq("two line");
922 evbuffer_validate(evb
);
926 evbuffer_free(evb_tmp
);
931 test_evbuffer_search_eol(void *ptr
)
933 struct evbuffer
*buf
= evbuffer_new();
934 struct evbuffer_ptr ptr1
, ptr2
;
938 s
= "string! \r\n\r\nx\n";
939 evbuffer_add(buf
, s
, strlen(s
));
941 ptr1
= evbuffer_search_eol(buf
, NULL
, &eol_len
, EVBUFFER_EOL_CRLF
);
942 tt_int_op(ptr1
.pos
, ==, 8);
943 tt_int_op(eol_len
, ==, 2);
946 ptr2
= evbuffer_search_eol(buf
, &ptr1
, &eol_len
, EVBUFFER_EOL_CRLF
);
947 tt_int_op(ptr2
.pos
, ==, 8);
948 tt_int_op(eol_len
, ==, 2);
950 evbuffer_ptr_set(buf
, &ptr1
, 1, EVBUFFER_PTR_ADD
);
952 ptr2
= evbuffer_search_eol(buf
, &ptr1
, &eol_len
, EVBUFFER_EOL_CRLF
);
953 tt_int_op(ptr2
.pos
, ==, 9);
954 tt_int_op(eol_len
, ==, 1);
957 ptr2
= evbuffer_search_eol(buf
, &ptr1
, &eol_len
, EVBUFFER_EOL_CRLF_STRICT
);
958 tt_int_op(ptr2
.pos
, ==, 10);
959 tt_int_op(eol_len
, ==, 2);
962 ptr1
= evbuffer_search_eol(buf
, NULL
, &eol_len
, EVBUFFER_EOL_LF
);
963 tt_int_op(ptr1
.pos
, ==, 9);
964 tt_int_op(eol_len
, ==, 1);
967 ptr2
= evbuffer_search_eol(buf
, &ptr1
, &eol_len
, EVBUFFER_EOL_LF
);
968 tt_int_op(ptr2
.pos
, ==, 9);
969 tt_int_op(eol_len
, ==, 1);
971 evbuffer_ptr_set(buf
, &ptr1
, 1, EVBUFFER_PTR_ADD
);
973 ptr2
= evbuffer_search_eol(buf
, &ptr1
, &eol_len
, EVBUFFER_EOL_LF
);
974 tt_int_op(ptr2
.pos
, ==, 11);
975 tt_int_op(eol_len
, ==, 1);
982 test_evbuffer_iterative(void *ptr
)
984 struct evbuffer
*buf
= evbuffer_new();
985 const char *abc
= "abcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyzabcdefghijklmnopqrstvuwxyz";
986 unsigned i
, j
, sum
, n
;
990 for (i
= 0; i
< 1000; ++i
) {
991 for (j
= 1; j
< strlen(abc
); ++j
) {
993 evutil_snprintf(format
, sizeof(format
), "%%%u.%us", j
, j
);
994 evbuffer_add_printf(buf
, format
, abc
);
996 /* Only check for rep violations every so often.
997 Walking over the whole list of chains can get
998 pretty expensive as it gets long.
1001 evbuffer_validate(buf
);
1007 evbuffer_validate(buf
);
1009 tt_uint_op(sum
, ==, evbuffer_get_length(buf
));
1014 evbuffer_get_waste(buf
, &a
, &w
, &u
);
1016 printf("Allocated: %u.\nWasted: %u.\nUsed: %u.",
1017 (unsigned)a
, (unsigned)w
, (unsigned)u
);
1018 tt_assert( ((double)w
)/a
< .125);
1026 test_evbuffer_find(void *ptr
)
1029 const char* test1
= "1234567890\r\n";
1030 const char* test2
= "1234567890\r";
1031 #define EVBUFFER_INITIAL_LENGTH 256
1032 char test3
[EVBUFFER_INITIAL_LENGTH
];
1034 struct evbuffer
* buf
= evbuffer_new();
1038 /* make sure evbuffer_find doesn't match past the end of the buffer */
1039 evbuffer_add(buf
, (u_char
*)test1
, strlen(test1
));
1040 evbuffer_validate(buf
);
1041 evbuffer_drain(buf
, strlen(test1
));
1042 evbuffer_validate(buf
);
1043 evbuffer_add(buf
, (u_char
*)test2
, strlen(test2
));
1044 evbuffer_validate(buf
);
1045 p
= evbuffer_find(buf
, (u_char
*)"\r\n", 2);
1049 * drain the buffer and do another find; in r309 this would
1050 * read past the allocated buffer causing a valgrind error.
1052 evbuffer_drain(buf
, strlen(test2
));
1053 evbuffer_validate(buf
);
1054 for (i
= 0; i
< EVBUFFER_INITIAL_LENGTH
; ++i
)
1056 test3
[EVBUFFER_INITIAL_LENGTH
- 1] = 'x';
1057 evbuffer_add(buf
, (u_char
*)test3
, EVBUFFER_INITIAL_LENGTH
);
1058 evbuffer_validate(buf
);
1059 p
= evbuffer_find(buf
, (u_char
*)"xy", 2);
1062 /* simple test for match at end of allocated buffer */
1063 p
= evbuffer_find(buf
, (u_char
*)"ax", 2);
1064 tt_assert(p
!= NULL
);
1065 tt_want(strncmp((char*)p
, "ax", 2) == 0);
1073 test_evbuffer_ptr_set(void *ptr
)
1075 struct evbuffer
*buf
= evbuffer_new();
1076 struct evbuffer_ptr pos
;
1077 struct evbuffer_iovec v
[1];
1081 /* create some chains */
1082 evbuffer_reserve_space(buf
, 5000, v
, 1);
1083 v
[0].iov_len
= 5000;
1084 memset(v
[0].iov_base
, 1, v
[0].iov_len
);
1085 evbuffer_commit_space(buf
, v
, 1);
1086 evbuffer_validate(buf
);
1088 evbuffer_reserve_space(buf
, 4000, v
, 1);
1089 v
[0].iov_len
= 4000;
1090 memset(v
[0].iov_base
, 2, v
[0].iov_len
);
1091 evbuffer_commit_space(buf
, v
, 1);
1093 evbuffer_reserve_space(buf
, 3000, v
, 1);
1094 v
[0].iov_len
= 3000;
1095 memset(v
[0].iov_base
, 3, v
[0].iov_len
);
1096 evbuffer_commit_space(buf
, v
, 1);
1097 evbuffer_validate(buf
);
1099 tt_int_op(evbuffer_get_length(buf
), ==, 12000);
1101 tt_assert(evbuffer_ptr_set(buf
, &pos
, 13000, EVBUFFER_PTR_SET
) == -1);
1102 tt_assert(pos
.pos
== -1);
1103 tt_assert(evbuffer_ptr_set(buf
, &pos
, 0, EVBUFFER_PTR_SET
) == 0);
1104 tt_assert(pos
.pos
== 0);
1105 tt_assert(evbuffer_ptr_set(buf
, &pos
, 13000, EVBUFFER_PTR_ADD
) == -1);
1107 tt_assert(evbuffer_ptr_set(buf
, &pos
, 0, EVBUFFER_PTR_SET
) == 0);
1108 tt_assert(pos
.pos
== 0);
1109 tt_assert(evbuffer_ptr_set(buf
, &pos
, 10000, EVBUFFER_PTR_ADD
) == 0);
1110 tt_assert(pos
.pos
== 10000);
1111 tt_assert(evbuffer_ptr_set(buf
, &pos
, 1000, EVBUFFER_PTR_ADD
) == 0);
1112 tt_assert(pos
.pos
== 11000);
1113 tt_assert(evbuffer_ptr_set(buf
, &pos
, 1000, EVBUFFER_PTR_ADD
) == -1);
1114 tt_assert(pos
.pos
== -1);
1122 test_evbuffer_search(void *ptr
)
1124 struct evbuffer
*buf
= evbuffer_new();
1125 struct evbuffer
*tmp
= evbuffer_new();
1126 struct evbuffer_ptr pos
, end
;
1131 /* set up our chains */
1132 evbuffer_add_printf(tmp
, "hello"); /* 5 chars */
1133 evbuffer_add_buffer(buf
, tmp
);
1134 evbuffer_add_printf(tmp
, "foo"); /* 3 chars */
1135 evbuffer_add_buffer(buf
, tmp
);
1136 evbuffer_add_printf(tmp
, "cat"); /* 3 chars */
1137 evbuffer_add_buffer(buf
, tmp
);
1138 evbuffer_add_printf(tmp
, "attack");
1139 evbuffer_add_buffer(buf
, tmp
);
1141 pos
= evbuffer_search(buf
, "attack", 6, NULL
);
1142 tt_int_op(pos
.pos
, ==, 11);
1143 pos
= evbuffer_search(buf
, "attacker", 8, NULL
);
1144 tt_int_op(pos
.pos
, ==, -1);
1146 /* test continuing search */
1147 pos
= evbuffer_search(buf
, "oc", 2, NULL
);
1148 tt_int_op(pos
.pos
, ==, 7);
1149 pos
= evbuffer_search(buf
, "cat", 3, &pos
);
1150 tt_int_op(pos
.pos
, ==, 8);
1151 pos
= evbuffer_search(buf
, "tacking", 7, &pos
);
1152 tt_int_op(pos
.pos
, ==, -1);
1154 evbuffer_ptr_set(buf
, &pos
, 5, EVBUFFER_PTR_SET
);
1155 pos
= evbuffer_search(buf
, "foo", 3, &pos
);
1156 tt_int_op(pos
.pos
, ==, 5);
1158 evbuffer_ptr_set(buf
, &pos
, 2, EVBUFFER_PTR_ADD
);
1159 pos
= evbuffer_search(buf
, "tat", 3, &pos
);
1160 tt_int_op(pos
.pos
, ==, 10);
1162 /* test bounded search. */
1163 /* Set "end" to the first t in "attack". */
1164 evbuffer_ptr_set(buf
, &end
, 12, EVBUFFER_PTR_SET
);
1165 pos
= evbuffer_search_range(buf
, "foo", 3, NULL
, &end
);
1166 tt_int_op(pos
.pos
, ==, 5);
1167 pos
= evbuffer_search_range(buf
, "foocata", 7, NULL
, &end
);
1168 tt_int_op(pos
.pos
, ==, 5);
1169 pos
= evbuffer_search_range(buf
, "foocatat", 8, NULL
, &end
);
1170 tt_int_op(pos
.pos
, ==, -1);
1171 pos
= evbuffer_search_range(buf
, "ack", 3, NULL
, &end
);
1172 tt_int_op(pos
.pos
, ==, -1);
1183 log_change_callback(struct evbuffer
*buffer
,
1184 const struct evbuffer_cb_info
*cbinfo
,
1188 size_t old_len
= cbinfo
->orig_size
;
1189 size_t new_len
= old_len
+ cbinfo
->n_added
- cbinfo
->n_deleted
;
1190 struct evbuffer
*out
= arg
;
1191 evbuffer_add_printf(out
, "%lu->%lu; ", (unsigned long)old_len
,
1192 (unsigned long)new_len
);
1195 self_draining_callback(struct evbuffer
*evbuffer
, size_t old_len
,
1196 size_t new_len
, void *arg
)
1198 if (new_len
> old_len
)
1199 evbuffer_drain(evbuffer
, new_len
);
1203 test_evbuffer_callbacks(void *ptr
)
1205 struct evbuffer
*buf
= evbuffer_new();
1206 struct evbuffer
*buf_out1
= evbuffer_new();
1207 struct evbuffer
*buf_out2
= evbuffer_new();
1208 struct evbuffer_cb_entry
*cb1
, *cb2
;
1211 tt_assert(buf_out1
);
1212 tt_assert(buf_out2
);
1214 cb1
= evbuffer_add_cb(buf
, log_change_callback
, buf_out1
);
1215 cb2
= evbuffer_add_cb(buf
, log_change_callback
, buf_out2
);
1217 /* Let's run through adding and deleting some stuff from the buffer
1218 * and turning the callbacks on and off and removing them. The callback
1219 * adds a summary of length changes to buf_out1/buf_out2 when called. */
1221 evbuffer_add_printf(buf
, "The %d magic words are spotty pudding", 2);
1222 evbuffer_validate(buf
);
1223 evbuffer_cb_clear_flags(buf
, cb2
, EVBUFFER_CB_ENABLED
);
1224 evbuffer_drain(buf
, 10); /*36->26*/
1225 evbuffer_validate(buf
);
1226 evbuffer_prepend(buf
, "Hello", 5);/*26->31*/
1227 evbuffer_cb_set_flags(buf
, cb2
, EVBUFFER_CB_ENABLED
);
1228 evbuffer_add_reference(buf
, "Goodbye", 7, NULL
, NULL
); /*31->38*/
1229 evbuffer_remove_cb_entry(buf
, cb1
);
1230 evbuffer_validate(buf
);
1231 evbuffer_drain(buf
, evbuffer_get_length(buf
)); /*38->0*/;
1232 tt_assert(-1 == evbuffer_remove_cb(buf
, log_change_callback
, NULL
));
1233 evbuffer_add(buf
, "X", 1); /* 0->1 */
1234 tt_assert(!evbuffer_remove_cb(buf
, log_change_callback
, buf_out2
));
1235 evbuffer_validate(buf
);
1237 tt_str_op(evbuffer_pullup(buf_out1
, -1), ==,
1238 "0->36; 36->26; 26->31; 31->38; ");
1239 tt_str_op(evbuffer_pullup(buf_out2
, -1), ==,
1240 "0->36; 31->38; 38->0; 0->1; ");
1241 evbuffer_drain(buf_out1
, evbuffer_get_length(buf_out1
));
1242 evbuffer_drain(buf_out2
, evbuffer_get_length(buf_out2
));
1243 /* Let's test the obsolete buffer_setcb function too. */
1244 cb1
= evbuffer_add_cb(buf
, log_change_callback
, buf_out1
);
1245 tt_assert(cb1
!= NULL
);
1246 cb2
= evbuffer_add_cb(buf
, log_change_callback
, buf_out2
);
1247 tt_assert(cb2
!= NULL
);
1248 evbuffer_setcb(buf
, self_draining_callback
, NULL
);
1249 evbuffer_add_printf(buf
, "This should get drained right away.");
1250 tt_uint_op(evbuffer_get_length(buf
), ==, 0);
1251 tt_uint_op(evbuffer_get_length(buf_out1
), ==, 0);
1252 tt_uint_op(evbuffer_get_length(buf_out2
), ==, 0);
1253 evbuffer_setcb(buf
, NULL
, NULL
);
1254 evbuffer_add_printf(buf
, "This will not.");
1255 tt_str_op(evbuffer_pullup(buf
, -1), ==, "This will not.");
1256 evbuffer_validate(buf
);
1257 evbuffer_drain(buf
, evbuffer_get_length(buf
));
1258 evbuffer_validate(buf
);
1260 /* Now let's try a suspended callback. */
1261 cb1
= evbuffer_add_cb(buf
, log_change_callback
, buf_out1
);
1262 cb2
= evbuffer_add_cb(buf
, log_change_callback
, buf_out2
);
1263 evbuffer_cb_suspend(buf
,cb2
);
1264 evbuffer_prepend(buf
,"Hello world",11); /*0->11*/
1265 evbuffer_validate(buf
);
1266 evbuffer_cb_suspend(buf
,cb1
);
1267 evbuffer_add(buf
,"more",4); /* 11->15 */
1268 evbuffer_cb_unsuspend(buf
,cb2
);
1269 evbuffer_drain(buf
, 4); /* 15->11 */
1270 evbuffer_cb_unsuspend(buf
,cb1
);
1271 evbuffer_drain(buf
, evbuffer_get_length(buf
)); /* 11->0 */
1273 tt_str_op(evbuffer_pullup(buf_out1
, -1), ==,
1274 "0->11; 11->11; 11->0; ");
1275 tt_str_op(evbuffer_pullup(buf_out2
, -1), ==,
1276 "0->15; 15->11; 11->0; ");
1283 evbuffer_free(buf_out1
);
1285 evbuffer_free(buf_out2
);
1288 static int ref_done_cb_called_count
= 0;
1289 static void *ref_done_cb_called_with
= NULL
;
1290 static const void *ref_done_cb_called_with_data
= NULL
;
1291 static size_t ref_done_cb_called_with_len
= 0;
1292 static void ref_done_cb(const void *data
, size_t len
, void *info
)
1294 ++ref_done_cb_called_count
;
1295 ref_done_cb_called_with
= info
;
1296 ref_done_cb_called_with_data
= data
;
1297 ref_done_cb_called_with_len
= len
;
1301 test_evbuffer_add_reference(void *ptr
)
1303 const char chunk1
[] = "If you have found the answer to such a problem";
1304 const char chunk2
[] = "you ought to write it up for publication";
1305 /* -- Knuth's "Notes on the Exercises" from TAOCP */
1307 size_t len1
= strlen(chunk1
), len2
=strlen(chunk2
);
1309 struct evbuffer
*buf1
= NULL
, *buf2
= NULL
;
1311 buf1
= evbuffer_new();
1314 evbuffer_add_reference(buf1
, chunk1
, len1
, ref_done_cb
, (void*)111);
1315 evbuffer_add(buf1
, ", ", 2);
1316 evbuffer_add_reference(buf1
, chunk2
, len2
, ref_done_cb
, (void*)222);
1317 tt_int_op(evbuffer_get_length(buf1
), ==, len1
+len2
+2);
1319 /* Make sure we can drain a little from a reference. */
1320 tt_int_op(evbuffer_remove(buf1
, tmp
, 6), ==, 6);
1321 tt_int_op(memcmp(tmp
, "If you", 6), ==, 0);
1322 tt_int_op(evbuffer_remove(buf1
, tmp
, 5), ==, 5);
1323 tt_int_op(memcmp(tmp
, " have", 5), ==, 0);
1325 /* Make sure that prepending does not meddle with immutable data */
1326 tt_int_op(evbuffer_prepend(buf1
, "I have ", 7), ==, 0);
1327 tt_int_op(memcmp(chunk1
, "If you", 6), ==, 0);
1328 evbuffer_validate(buf1
);
1330 /* Make sure that when the chunk is over, the callback is invoked. */
1331 evbuffer_drain(buf1
, 7); /* Remove prepended stuff. */
1332 evbuffer_drain(buf1
, len1
-11-1); /* remove all but one byte of chunk1 */
1333 tt_int_op(ref_done_cb_called_count
, ==, 0);
1334 evbuffer_remove(buf1
, tmp
, 1);
1335 tt_int_op(tmp
[0], ==, 'm');
1336 tt_assert(ref_done_cb_called_with
== (void*)111);
1337 tt_assert(ref_done_cb_called_with_data
== chunk1
);
1338 tt_assert(ref_done_cb_called_with_len
== len1
);
1339 tt_int_op(ref_done_cb_called_count
, ==, 1);
1340 evbuffer_validate(buf1
);
1342 /* Drain some of the remaining chunk, then add it to another buffer */
1343 evbuffer_drain(buf1
, 6); /* Remove the ", you ". */
1344 buf2
= evbuffer_new();
1346 tt_int_op(ref_done_cb_called_count
, ==, 1);
1347 evbuffer_add(buf2
, "I ", 2);
1349 evbuffer_add_buffer(buf2
, buf1
);
1350 tt_int_op(ref_done_cb_called_count
, ==, 1);
1351 evbuffer_remove(buf2
, tmp
, 16);
1352 tt_int_op(memcmp("I ought to write", tmp
, 16), ==, 0);
1353 evbuffer_drain(buf2
, evbuffer_get_length(buf2
));
1354 tt_int_op(ref_done_cb_called_count
, ==, 2);
1355 tt_assert(ref_done_cb_called_with
== (void*)222);
1356 evbuffer_validate(buf2
);
1358 /* Now add more stuff to buf1 and make sure that it gets removed on
1360 evbuffer_add(buf1
, "You shake and shake the ", 24);
1361 evbuffer_add_reference(buf1
, "ketchup bottle", 14, ref_done_cb
,
1363 evbuffer_add(buf1
, ". Nothing comes and then a lot'll.", 42);
1364 evbuffer_free(buf1
);
1366 tt_int_op(ref_done_cb_called_count
, ==, 3);
1367 tt_assert(ref_done_cb_called_with
== (void*)3333);
1371 evbuffer_free(buf1
);
1373 evbuffer_free(buf2
);
1376 /* Some cases that we didn't get in test_evbuffer() above, for more coverage. */
1378 test_evbuffer_prepend(void *ptr
)
1380 struct evbuffer
*buf1
= NULL
, *buf2
= NULL
;
1384 buf1
= evbuffer_new();
1387 /* Case 0: The evbuffer is entirely empty. */
1388 evbuffer_prepend(buf1
, "This string has 29 characters", 29);
1389 evbuffer_validate(buf1
);
1391 /* Case 1: Prepend goes entirely in new chunk. */
1392 evbuffer_prepend(buf1
, "Short.", 6);
1393 evbuffer_validate(buf1
);
1395 /* Case 2: prepend goes entirely in first chunk. */
1396 evbuffer_drain(buf1
, 6+11);
1397 evbuffer_prepend(buf1
, "it", 2);
1398 evbuffer_validate(buf1
);
1399 tt_assert(!memcmp(buf1
->first
->buffer
+buf1
->first
->misalign
,
1402 /* Case 3: prepend is split over multiple chunks. */
1403 evbuffer_prepend(buf1
, "It is no longer true to say ", 28);
1404 evbuffer_validate(buf1
);
1405 n
= evbuffer_remove(buf1
, tmp
, sizeof(tmp
)-1);
1407 tt_str_op(tmp
,==,"It is no longer true to say it has 29 characters");
1409 buf2
= evbuffer_new();
1412 /* Case 4: prepend a buffer to an empty buffer. */
1414 evbuffer_add_printf(buf1
, "Here is string %d. ", n
++);
1415 evbuffer_prepend_buffer(buf2
, buf1
);
1416 evbuffer_validate(buf2
);
1418 /* Case 5: prepend a buffer to a nonempty buffer. */
1419 evbuffer_add_printf(buf1
, "Here is string %d. ", n
++);
1420 evbuffer_prepend_buffer(buf2
, buf1
);
1421 evbuffer_validate(buf2
);
1422 evbuffer_validate(buf1
);
1423 n
= evbuffer_remove(buf2
, tmp
, sizeof(tmp
)-1);
1425 tt_str_op(tmp
,==,"Here is string 1000. Here is string 999. ");
1429 evbuffer_free(buf1
);
1431 evbuffer_free(buf2
);
1436 test_evbuffer_peek(void *info
)
1438 struct evbuffer
*buf
= NULL
, *tmp_buf
= NULL
;
1440 struct evbuffer_iovec v
[20];
1441 struct evbuffer_ptr ptr
;
1443 #define tt_iov_eq(v, s) \
1444 tt_int_op((v)->iov_len, ==, strlen(s)); \
1445 tt_assert(!memcmp((v)->iov_base, (s), strlen(s)))
1447 /* Let's make a very fragmented buffer. */
1448 buf
= evbuffer_new();
1449 tmp_buf
= evbuffer_new();
1450 for (i
= 0; i
< 16; ++i
) {
1451 evbuffer_add_printf(tmp_buf
, "Contents of chunk [%d]\n", i
);
1452 evbuffer_add_buffer(buf
, tmp_buf
);
1455 /* How many chunks do we need for everything? */
1456 i
= evbuffer_peek(buf
, -1, NULL
, NULL
, 0);
1457 tt_int_op(i
, ==, 16);
1459 /* Simple peek: get everything. */
1460 i
= evbuffer_peek(buf
, -1, NULL
, v
, 20);
1461 tt_int_op(i
, ==, 16); /* we used only 16 chunks. */
1462 tt_iov_eq(&v
[0], "Contents of chunk [0]\n");
1463 tt_iov_eq(&v
[3], "Contents of chunk [3]\n");
1464 tt_iov_eq(&v
[12], "Contents of chunk [12]\n");
1465 tt_iov_eq(&v
[15], "Contents of chunk [15]\n");
1467 /* Just get one chunk worth. */
1468 memset(v
, 0, sizeof(v
));
1469 i
= evbuffer_peek(buf
, -1, NULL
, v
, 1);
1470 tt_int_op(i
, ==, 1);
1471 tt_iov_eq(&v
[0], "Contents of chunk [0]\n");
1472 tt_assert(v
[1].iov_base
== NULL
);
1474 /* Suppose we want at least the first 40 bytes. */
1475 memset(v
, 0, sizeof(v
));
1476 i
= evbuffer_peek(buf
, 40, NULL
, v
, 16);
1477 tt_int_op(i
, ==, 2);
1478 tt_iov_eq(&v
[0], "Contents of chunk [0]\n");
1479 tt_iov_eq(&v
[1], "Contents of chunk [1]\n");
1480 tt_assert(v
[2].iov_base
== NULL
);
1482 /* How many chunks do we need for 100 bytes? */
1483 memset(v
, 0, sizeof(v
));
1484 i
= evbuffer_peek(buf
, 100, NULL
, NULL
, 0);
1485 tt_int_op(i
, ==, 5);
1486 tt_assert(v
[0].iov_base
== NULL
);
1488 /* Now we ask for more bytes than we provide chunks for */
1489 memset(v
, 0, sizeof(v
));
1490 i
= evbuffer_peek(buf
, 60, NULL
, v
, 1);
1491 tt_int_op(i
, ==, 3);
1492 tt_iov_eq(&v
[0], "Contents of chunk [0]\n");
1493 tt_assert(v
[1].iov_base
== NULL
);
1495 /* Now we ask for more bytes than the buffer has. */
1496 memset(v
, 0, sizeof(v
));
1497 i
= evbuffer_peek(buf
, 65536, NULL
, v
, 20);
1498 tt_int_op(i
, ==, 16); /* we used only 16 chunks. */
1499 tt_iov_eq(&v
[0], "Contents of chunk [0]\n");
1500 tt_iov_eq(&v
[3], "Contents of chunk [3]\n");
1501 tt_iov_eq(&v
[12], "Contents of chunk [12]\n");
1502 tt_iov_eq(&v
[15], "Contents of chunk [15]\n");
1503 tt_assert(v
[16].iov_base
== NULL
);
1505 /* What happens if we try an empty buffer? */
1506 memset(v
, 0, sizeof(v
));
1507 i
= evbuffer_peek(tmp_buf
, -1, NULL
, v
, 20);
1508 tt_int_op(i
, ==, 0);
1509 tt_assert(v
[0].iov_base
== NULL
);
1510 memset(v
, 0, sizeof(v
));
1511 i
= evbuffer_peek(tmp_buf
, 50, NULL
, v
, 20);
1512 tt_int_op(i
, ==, 0);
1513 tt_assert(v
[0].iov_base
== NULL
);
1515 /* Okay, now time to have fun with pointers. */
1516 memset(v
, 0, sizeof(v
));
1517 evbuffer_ptr_set(buf
, &ptr
, 30, EVBUFFER_PTR_SET
);
1518 i
= evbuffer_peek(buf
, 50, &ptr
, v
, 20);
1519 tt_int_op(i
, ==, 3);
1520 tt_iov_eq(&v
[0], " of chunk [1]\n");
1521 tt_iov_eq(&v
[1], "Contents of chunk [2]\n");
1522 tt_iov_eq(&v
[2], "Contents of chunk [3]\n"); /*more than we asked for*/
1524 /* advance to the start of another chain. */
1525 memset(v
, 0, sizeof(v
));
1526 evbuffer_ptr_set(buf
, &ptr
, 14, EVBUFFER_PTR_ADD
);
1527 i
= evbuffer_peek(buf
, 44, &ptr
, v
, 20);
1528 tt_int_op(i
, ==, 2);
1529 tt_iov_eq(&v
[0], "Contents of chunk [2]\n");
1530 tt_iov_eq(&v
[1], "Contents of chunk [3]\n"); /*more than we asked for*/
1536 evbuffer_free(tmp_buf
);
1539 /* Check whether evbuffer freezing works right. This is called twice,
1540 once with the argument "start" and once with the argument "end".
1541 When we test "start", we freeze the start of an evbuffer and make sure
1542 that modifying the start of the buffer doesn't work. When we test
1543 "end", we freeze the end of an evbuffer and make sure that modifying
1544 the end of the buffer doesn't work.
1547 test_evbuffer_freeze(void *ptr
)
1549 struct evbuffer
*buf
= NULL
, *tmp_buf
=NULL
;
1550 const char string
[] = /* Year's End, Richard Wilbur */
1551 "I've known the wind by water banks to shake\n"
1552 "The late leaves down, which frozen where they fell\n"
1553 "And held in ice as dancers in a spell\n"
1554 "Fluttered all winter long into a lake...";
1555 const int start
= !strcmp(ptr
, "start");
1560 struct evbuffer_iovec v
[1];
1563 tt_str_op(ptr
, ==, "end");
1565 buf
= evbuffer_new();
1566 tmp_buf
= evbuffer_new();
1569 evbuffer_add(buf
, string
, strlen(string
));
1570 evbuffer_freeze(buf
, start
); /* Freeze the start or the end.*/
1572 #define FREEZE_EQ(a, startcase, endcase) \
1575 tt_int_op((a), ==, (startcase)); \
1577 tt_int_op((a), ==, (endcase)); \
1582 orig_length
= evbuffer_get_length(buf
);
1584 /* These functions all manipulate the end of buf. */
1585 r
= evbuffer_add(buf
, "abc", 0);
1586 FREEZE_EQ(r
, 0, -1);
1587 r
= evbuffer_reserve_space(buf
, 10, v
, 1);
1588 FREEZE_EQ(r
, 1, -1);
1590 memset(v
[0].iov_base
, 'X', 10);
1593 r
= evbuffer_commit_space(buf
, v
, 1);
1594 FREEZE_EQ(r
, 0, -1);
1595 r
= evbuffer_add_reference(buf
, string
, 5, NULL
, NULL
);
1596 FREEZE_EQ(r
, 0, -1);
1597 r
= evbuffer_add_printf(buf
, "Hello %s", "world");
1598 FREEZE_EQ(r
, 11, -1);
1599 /* TODO: test add_buffer, add_file, read */
1602 tt_int_op(orig_length
, ==, evbuffer_get_length(buf
));
1604 orig_length
= evbuffer_get_length(buf
);
1606 /* These functions all manipulate the start of buf. */
1607 r
= evbuffer_remove(buf
, charbuf
, 1);
1608 FREEZE_EQ(r
, -1, 1);
1609 r
= evbuffer_drain(buf
, 3);
1610 FREEZE_EQ(r
, -1, 0);
1611 r
= evbuffer_prepend(buf
, "dummy", 5);
1612 FREEZE_EQ(r
, -1, 0);
1613 cp
= evbuffer_readln(buf
, NULL
, EVBUFFER_EOL_LF
);
1614 FREEZE_EQ(cp
==NULL
, 1, 0);
1617 /* TODO: Test remove_buffer, add_buffer, write, prepend_buffer */
1620 tt_int_op(orig_length
, ==, evbuffer_get_length(buf
));
1627 evbuffer_free(tmp_buf
);
1631 setup_passthrough(const struct testcase_t
*testcase
)
1633 return testcase
->setup_data
;
1636 cleanup_passthrough(const struct testcase_t
*testcase
, void *ptr
)
1642 static const struct testcase_setup_t nil_setup
= {
1647 struct testcase_t evbuffer_testcases
[] = {
1648 { "evbuffer", test_evbuffer
, 0, NULL
, NULL
},
1649 { "remove_buffer_with_empty", test_evbuffer_remove_buffer_with_empty
, 0, NULL
, NULL
},
1650 { "reserve2", test_evbuffer_reserve2
, 0, NULL
, NULL
},
1651 { "reserve_many", test_evbuffer_reserve_many
, 0, NULL
, NULL
},
1652 { "reserve_many2", test_evbuffer_reserve_many
, 0, &nil_setup
, (void*)"add" },
1653 { "reserve_many3", test_evbuffer_reserve_many
, 0, &nil_setup
, (void*)"fill" },
1654 { "expand", test_evbuffer_expand
, 0, NULL
, NULL
},
1655 { "reference", test_evbuffer_reference
, 0, NULL
, NULL
},
1656 { "iterative", test_evbuffer_iterative
, 0, NULL
, NULL
},
1657 { "readln", test_evbuffer_readln
, TT_NO_LOGS
, &basic_setup
, NULL
},
1658 { "search_eol", test_evbuffer_search_eol
, 0, NULL
, NULL
},
1659 { "find", test_evbuffer_find
, 0, NULL
, NULL
},
1660 { "ptr_set", test_evbuffer_ptr_set
, 0, NULL
, NULL
},
1661 { "search", test_evbuffer_search
, 0, NULL
, NULL
},
1662 { "callbacks", test_evbuffer_callbacks
, 0, NULL
, NULL
},
1663 { "add_reference", test_evbuffer_add_reference
, 0, NULL
, NULL
},
1664 { "prepend", test_evbuffer_prepend
, TT_FORK
, NULL
, NULL
},
1665 { "peek", test_evbuffer_peek
, 0, NULL
, NULL
},
1666 { "freeze_start", test_evbuffer_freeze
, 0, &nil_setup
, (void*)"start" },
1667 { "freeze_end", test_evbuffer_freeze
, 0, &nil_setup
, (void*)"end" },
1668 /* TODO: need a temp file implementation for Windows */
1669 { "add_file_sendfile", test_evbuffer_add_file
, TT_FORK
, &nil_setup
,
1670 (void*)"sendfile" },
1671 { "add_file_mmap", test_evbuffer_add_file
, TT_FORK
, &nil_setup
,
1673 { "add_file_linear", test_evbuffer_add_file
, TT_FORK
, &nil_setup
,