]>
jfr.im git - solanum.git/blob - librb/src/rawbuf.c
2 * ircd-ratbox: A slight useful ircd
3 * rawbuf.c: raw buffer (non-line oriented buffering)
5 * Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
6 * Copyright (C) 2007 ircd-ratbox development team
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
25 #include <libratbox_config.h>
26 #include <ratbox_lib.h>
27 #include <commio-int.h>
28 #define RAWBUF_SIZE 1024
33 uint8_t data
[RAWBUF_SIZE
];
45 static rb_bh
*rawbuf_heap
;
52 t
= rb_bh_alloc(rawbuf_heap
);
57 rb_rawbuf_newbuf(rawbuf_head_t
* rb
)
60 buf
= rb_rawbuf_alloc();
61 rb_dlinkAddTail(buf
, &buf
->node
, &rb
->list
);
66 rb_rawbuf_done(rawbuf_head_t
* rb
, rawbuf_t
* buf
)
69 rb_dlinkDelete(&buf
->node
, &rb
->list
);
70 rb_bh_free(rawbuf_heap
, ptr
);
74 rb_rawbuf_flush_writev(rawbuf_head_t
* rb
, rb_fde_t
*F
)
76 rb_dlink_node
*ptr
, *next
;
80 struct rb_iovec vec
[RB_UIO_MAXIOV
];
81 memset(vec
, 0, sizeof(vec
));
83 if(rb
->list
.head
== NULL
)
89 RB_DLINK_FOREACH(ptr
, rb
->list
.head
)
91 if(x
>= RB_UIO_MAXIOV
)
97 vec
[x
].iov_base
= buf
->data
+ rb
->written
;
98 vec
[x
++].iov_len
= buf
->len
- rb
->written
;
101 vec
[x
].iov_base
= buf
->data
;
102 vec
[x
++].iov_len
= buf
->len
;
111 xret
= retval
= rb_writev(F
, vec
, x
);
115 RB_DLINK_FOREACH_SAFE(ptr
, next
, rb
->list
.head
)
122 if(xret
>= buf
->len
- rb
->written
)
124 xret
-= buf
->len
- rb
->written
;
125 rb
->len
-= buf
->len
- rb
->written
;
126 rb_rawbuf_done(rb
, buf
);
135 rb_rawbuf_done(rb
, buf
);
150 rb_rawbuf_flush(rawbuf_head_t
* rb
, rb_fde_t
*F
)
154 if(rb
->list
.head
== NULL
)
161 return rb_rawbuf_flush_writev(rb
, F
);
163 buf
= rb
->list
.head
->data
;
170 retval
= rb_write(F
, buf
->data
+ rb
->written
, buf
->len
- rb
->written
);
174 rb
->written
+= retval
;
175 if(rb
->written
== buf
->len
)
178 rb_dlinkDelete(&buf
->node
, &rb
->list
);
179 rb_bh_free(rawbuf_heap
, buf
);
182 lrb_assert(rb
->len
>= 0);
188 rb_rawbuf_append(rawbuf_head_t
* rb
, void *data
, int len
)
190 rawbuf_t
*buf
= NULL
;
193 if(rb
->list
.tail
!= NULL
)
194 buf
= rb
->list
.tail
->data
;
196 if(buf
!= NULL
&& buf
->len
< RAWBUF_SIZE
&& !buf
->flushing
)
198 buf
= (rawbuf_t
*) rb
->list
.tail
->data
;
199 clen
= RAWBUF_SIZE
- buf
->len
;
200 ptr
= (void *)(buf
->data
+ buf
->len
);
204 memcpy(ptr
, data
, clen
);
210 data
= (char *)data
+ clen
;
216 buf
= rb_rawbuf_newbuf(rb
);
218 if(len
>= RAWBUF_SIZE
)
223 memcpy(buf
->data
, data
, clen
);
226 data
= (char *)data
+ clen
;
233 rb_rawbuf_get(rawbuf_head_t
* rb
, void *data
, int len
)
238 if(rb
->list
.head
== NULL
)
241 buf
= rb
->list
.head
->data
;
244 ptr
= (void *)(buf
->data
+ rb
->written
);
253 memcpy(data
, ptr
, cpylen
);
255 if(cpylen
== buf
->len
)
258 rb_rawbuf_done(rb
, buf
);
266 rb
->written
+= cpylen
;
271 rb_rawbuf_length(rawbuf_head_t
* rb
)
273 if(rb_dlink_list_length(&rb
->list
) == 0 && rb
->len
!= 0)
279 rb_new_rawbuffer(void)
281 return rb_malloc(sizeof(rawbuf_head_t
));
286 rb_free_rawbuffer(rawbuf_head_t
* rb
)
288 rb_dlink_node
*ptr
, *next
;
289 RB_DLINK_FOREACH_SAFE(ptr
, next
, rb
->list
.head
)
291 rb_rawbuf_done(rb
, ptr
->data
);
298 rb_init_rawbuffers(int heap_size
)
300 if(rawbuf_heap
== NULL
)
301 rawbuf_heap
= rb_bh_create(sizeof(rawbuf_t
), heap_size
, "librb_rawbuf_heap");