2 * Copyright (c) 2002, 2003 Niels Provos <provos@citi.umich.edu>
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.
38 /* If we have vasprintf, we need to define this before we include stdio.h. */
42 #include <sys/types.h>
44 #ifdef HAVE_SYS_TIME_H
48 #ifdef HAVE_SYS_IOCTL_H
49 #include <sys/ioctl.h>
71 struct evbuffer
*buffer
;
73 buffer
= calloc(1, sizeof(struct evbuffer
));
79 evbuffer_free(struct evbuffer
*buffer
)
81 if (buffer
->orig_buffer
!= NULL
)
82 free(buffer
->orig_buffer
);
87 * This is a destructive add. The data from one buffer moves into
91 #define SWAP(x,y) do { \
92 (x)->buffer = (y)->buffer; \
93 (x)->orig_buffer = (y)->orig_buffer; \
94 (x)->misalign = (y)->misalign; \
95 (x)->totallen = (y)->totallen; \
96 (x)->off = (y)->off; \
100 evbuffer_add_buffer(struct evbuffer
*outbuf
, struct evbuffer
*inbuf
)
104 /* Short cut for better performance */
105 if (outbuf
->off
== 0) {
107 size_t oldoff
= inbuf
->off
;
109 /* Swap them directly */
115 * Optimization comes with a price; we need to notify the
116 * buffer if necessary of the changes. oldoff is the amount
117 * of data that we transfered from inbuf to outbuf
119 if (inbuf
->off
!= oldoff
&& inbuf
->cb
!= NULL
)
120 (*inbuf
->cb
)(inbuf
, oldoff
, inbuf
->off
, inbuf
->cbarg
);
121 if (oldoff
&& outbuf
->cb
!= NULL
)
122 (*outbuf
->cb
)(outbuf
, 0, oldoff
, outbuf
->cbarg
);
127 res
= evbuffer_add(outbuf
, inbuf
->buffer
, inbuf
->off
);
129 /* We drain the input buffer on success */
130 evbuffer_drain(inbuf
, inbuf
->off
);
137 evbuffer_add_vprintf(struct evbuffer
*buf
, const char *fmt
, va_list ap
)
141 size_t oldoff
= buf
->off
;
145 /* make sure that at least some space is available */
146 evbuffer_expand(buf
, 64);
148 size_t used
= buf
->misalign
+ buf
->off
;
149 buffer
= (char *)buf
->buffer
+ buf
->off
;
150 assert(buf
->totallen
>= used
);
151 space
= buf
->totallen
- used
;
154 #define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list))
158 sz
= evutil_vsnprintf(buffer
, space
, fmt
, aq
);
164 if ((size_t)sz
< space
) {
167 (*buf
->cb
)(buf
, oldoff
, buf
->off
, buf
->cbarg
);
170 if (evbuffer_expand(buf
, sz
+ 1) == -1)
178 evbuffer_add_printf(struct evbuffer
*buf
, const char *fmt
, ...)
184 res
= evbuffer_add_vprintf(buf
, fmt
, ap
);
190 /* Reads data from an event buffer and drains the bytes read */
193 evbuffer_remove(struct evbuffer
*buf
, void *data
, size_t datlen
)
195 size_t nread
= datlen
;
196 if (nread
>= buf
->off
)
199 memcpy(data
, buf
->buffer
, nread
);
200 evbuffer_drain(buf
, nread
);
206 * Reads a line terminated by either '\r\n', '\n\r' or '\r' or '\n'.
207 * The returned buffer needs to be freed by the called.
211 evbuffer_readline(struct evbuffer
*buffer
)
213 u_char
*data
= EVBUFFER_DATA(buffer
);
214 size_t len
= EVBUFFER_LENGTH(buffer
);
218 for (i
= 0; i
< len
; i
++) {
219 if (data
[i
] == '\r' || data
[i
] == '\n')
226 if ((line
= malloc(i
+ 1)) == NULL
) {
227 fprintf(stderr
, "%s: out of memory\n", __func__
);
231 memcpy(line
, data
, i
);
235 * Some protocols terminate a line with '\r\n', so check for
239 char fch
= data
[i
], sch
= data
[i
+1];
241 /* Drain one more character if needed */
242 if ( (sch
== '\r' || sch
== '\n') && sch
!= fch
)
246 evbuffer_drain(buffer
, i
+ 1);
251 /* Adds data to an event buffer */
254 evbuffer_align(struct evbuffer
*buf
)
256 memmove(buf
->orig_buffer
, buf
->buffer
, buf
->off
);
257 buf
->buffer
= buf
->orig_buffer
;
261 /* Expands the available space in the event buffer to at least datlen */
264 evbuffer_expand(struct evbuffer
*buf
, size_t datlen
)
266 size_t need
= buf
->misalign
+ buf
->off
+ datlen
;
268 /* If we can fit all the data, then we don't have to do anything */
269 if (buf
->totallen
>= need
)
273 * If the misalignment fulfills our data needs, we just force an
274 * alignment to happen. Afterwards, we have enough space.
276 if (buf
->misalign
>= datlen
) {
280 size_t length
= buf
->totallen
;
284 while (length
< need
)
287 if (buf
->orig_buffer
!= buf
->buffer
)
289 if ((newbuf
= realloc(buf
->buffer
, length
)) == NULL
)
292 buf
->orig_buffer
= buf
->buffer
= newbuf
;
293 buf
->totallen
= length
;
300 evbuffer_add(struct evbuffer
*buf
, const void *data
, size_t datlen
)
302 size_t need
= buf
->misalign
+ buf
->off
+ datlen
;
303 size_t oldoff
= buf
->off
;
305 if (buf
->totallen
< need
) {
306 if (evbuffer_expand(buf
, datlen
) == -1)
310 memcpy(buf
->buffer
+ buf
->off
, data
, datlen
);
313 if (datlen
&& buf
->cb
!= NULL
)
314 (*buf
->cb
)(buf
, oldoff
, buf
->off
, buf
->cbarg
);
320 evbuffer_drain(struct evbuffer
*buf
, size_t len
)
322 size_t oldoff
= buf
->off
;
324 if (len
>= buf
->off
) {
326 buf
->buffer
= buf
->orig_buffer
;
332 buf
->misalign
+= len
;
337 /* Tell someone about changes in this buffer */
338 if (buf
->off
!= oldoff
&& buf
->cb
!= NULL
)
339 (*buf
->cb
)(buf
, oldoff
, buf
->off
, buf
->cbarg
);
344 * Reads data from a file descriptor into a buffer.
347 #define EVBUFFER_MAX_READ 4096
350 evbuffer_read(struct evbuffer
*buf
, int fd
, int howmuch
)
353 size_t oldoff
= buf
->off
;
354 int n
= EVBUFFER_MAX_READ
;
356 #if defined(FIONREAD)
359 if (ioctlsocket(fd
, FIONREAD
, &lng
) == -1 || (n
=lng
) <= 0) {
361 if (ioctl(fd
, FIONREAD
, &n
) == -1 || n
<= 0) {
363 n
= EVBUFFER_MAX_READ
;
364 } else if (n
> EVBUFFER_MAX_READ
&& n
> howmuch
) {
366 * It's possible that a lot of data is available for
367 * reading. We do not want to exhaust resources
368 * before the reader has a chance to do something
369 * about it. If the reader does not tell us how much
370 * data we should read, we artifically limit it.
372 if ((size_t)n
> buf
->totallen
<< 2)
373 n
= buf
->totallen
<< 2;
374 if (n
< EVBUFFER_MAX_READ
)
375 n
= EVBUFFER_MAX_READ
;
378 if (howmuch
< 0 || howmuch
> n
)
381 /* If we don't have FIONREAD, we might waste some space here */
382 if (evbuffer_expand(buf
, howmuch
) == -1)
385 /* We can append new data at this point */
386 p
= buf
->buffer
+ buf
->off
;
389 n
= read(fd
, p
, howmuch
);
391 n
= recv(fd
, p
, howmuch
, 0);
400 /* Tell someone about changes in this buffer */
401 if (buf
->off
!= oldoff
&& buf
->cb
!= NULL
)
402 (*buf
->cb
)(buf
, oldoff
, buf
->off
, buf
->cbarg
);
408 evbuffer_write(struct evbuffer
*buffer
, int fd
)
413 n
= write(fd
, buffer
->buffer
, buffer
->off
);
415 n
= send(fd
, buffer
->buffer
, buffer
->off
, 0);
421 evbuffer_drain(buffer
, n
);
427 evbuffer_find(struct evbuffer
*buffer
, const u_char
*what
, size_t len
)
429 u_char
*search
= buffer
->buffer
, *end
= search
+ buffer
->off
;
432 while (search
< end
&&
433 (p
= memchr(search
, *what
, end
- search
)) != NULL
) {
436 if (memcmp(p
, what
, len
) == 0)
444 void evbuffer_setcb(struct evbuffer
*buffer
,
445 void (*cb
)(struct evbuffer
*, size_t, size_t, void *),
449 buffer
->cbarg
= cbarg
;