]>
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
24 #include <librb_config.h>
26 #include <commio-int.h>
27 #define RAWBUF_SIZE 1024
32 uint8_t data
[RAWBUF_SIZE
];
44 static rb_bh
*rawbuf_heap
;
51 t
= rb_bh_alloc(rawbuf_heap
);
56 rb_rawbuf_newbuf(rawbuf_head_t
* rb
)
59 buf
= rb_rawbuf_alloc();
60 rb_dlinkAddTail(buf
, &buf
->node
, &rb
->list
);
65 rb_rawbuf_done(rawbuf_head_t
* rb
, rawbuf_t
* buf
)
68 rb_dlinkDelete(&buf
->node
, &rb
->list
);
69 rb_bh_free(rawbuf_heap
, ptr
);
73 rb_rawbuf_flush_writev(rawbuf_head_t
* rb
, rb_fde_t
*F
)
75 rb_dlink_node
*ptr
, *next
;
79 struct rb_iovec vec
[RB_UIO_MAXIOV
];
80 memset(vec
, 0, sizeof(vec
));
82 if(rb
->list
.head
== NULL
)
88 RB_DLINK_FOREACH(ptr
, rb
->list
.head
)
90 if(x
>= RB_UIO_MAXIOV
)
96 vec
[x
].iov_base
= buf
->data
+ rb
->written
;
97 vec
[x
++].iov_len
= buf
->len
- rb
->written
;
100 vec
[x
].iov_base
= buf
->data
;
101 vec
[x
++].iov_len
= buf
->len
;
110 xret
= retval
= rb_writev(F
, vec
, x
);
114 RB_DLINK_FOREACH_SAFE(ptr
, next
, rb
->list
.head
)
121 if(xret
>= buf
->len
- rb
->written
)
123 xret
-= buf
->len
- rb
->written
;
124 rb
->len
-= buf
->len
- rb
->written
;
125 rb_rawbuf_done(rb
, buf
);
134 rb_rawbuf_done(rb
, buf
);
149 rb_rawbuf_flush(rawbuf_head_t
* rb
, rb_fde_t
*F
)
153 if(rb
->list
.head
== NULL
)
160 return rb_rawbuf_flush_writev(rb
, F
);
162 buf
= rb
->list
.head
->data
;
169 retval
= rb_write(F
, buf
->data
+ rb
->written
, buf
->len
- rb
->written
);
173 rb
->written
+= retval
;
174 if(rb
->written
== buf
->len
)
177 rb_dlinkDelete(&buf
->node
, &rb
->list
);
178 rb_bh_free(rawbuf_heap
, buf
);
181 lrb_assert(rb
->len
>= 0);
187 rb_rawbuf_append(rawbuf_head_t
* rb
, void *data
, int len
)
189 rawbuf_t
*buf
= NULL
;
192 if(rb
->list
.tail
!= NULL
)
193 buf
= rb
->list
.tail
->data
;
195 if(buf
!= NULL
&& buf
->len
< RAWBUF_SIZE
&& !buf
->flushing
)
197 buf
= (rawbuf_t
*) rb
->list
.tail
->data
;
198 clen
= RAWBUF_SIZE
- buf
->len
;
199 ptr
= (void *)(buf
->data
+ buf
->len
);
203 memcpy(ptr
, data
, clen
);
209 data
= (char *)data
+ clen
;
215 buf
= rb_rawbuf_newbuf(rb
);
217 if(len
>= RAWBUF_SIZE
)
222 memcpy(buf
->data
, data
, clen
);
225 data
= (char *)data
+ clen
;
232 rb_rawbuf_get(rawbuf_head_t
* rb
, void *data
, int len
)
237 if(rb
->list
.head
== NULL
)
240 buf
= rb
->list
.head
->data
;
243 ptr
= (void *)(buf
->data
+ rb
->written
);
252 memcpy(data
, ptr
, cpylen
);
254 if(cpylen
== buf
->len
)
257 rb_rawbuf_done(rb
, buf
);
265 rb
->written
+= cpylen
;
270 rb_rawbuf_length(rawbuf_head_t
* rb
)
272 if (rb_dlink_list_length(&rb
->list
) == 0 && lrb_assert(rb
->len
== 0))
278 rb_new_rawbuffer(void)
280 return rb_malloc(sizeof(rawbuf_head_t
));
285 rb_free_rawbuffer(rawbuf_head_t
* rb
)
287 rb_dlink_node
*ptr
, *next
;
288 RB_DLINK_FOREACH_SAFE(ptr
, next
, rb
->list
.head
)
290 rb_rawbuf_done(rb
, ptr
->data
);
297 rb_init_rawbuffers(int heap_size
)
299 if(rawbuf_heap
== NULL
)
300 rawbuf_heap
= rb_bh_create(sizeof(rawbuf_t
), heap_size
, "librb_rawbuf_heap");