2 * Copyright (c) 2016 Mohamed Aslan <maslan@sce.carleton.ca>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include <sys/param.h>
24 rbuffer_new(size_t capacity
)
28 rbuf
= malloc(sizeof(struct rbuffer
));
31 rbuf
->rb_capacity
= capacity
> 0 ? capacity
: BUFSIZ
;
33 rbuf
->rb_data
= reallocarray(NULL
, rbuf
->rb_capacity
, sizeof(char));
34 if (rbuf
->rb_data
== NULL
) {
38 rbuf
->rb_wp
= rbuf
->rb_data
;
39 rbuf
->rb_rp
= rbuf
->rb_data
;
45 rbuffer_free(struct rbuffer
*rbuf
)
54 rbuffer_write(struct rbuffer
*rbuf
, const char *src
, size_t len
)
57 size_t block
, n
, copied
= 0, free
, rem
= len
;
62 free
= rbuf
->rb_capacity
- rbuf
->rb_len
;
66 /* TODO: optimize, copy only what needs to be copied. */
68 block
= rbuf
->rb_capacity
- (rbuf
->rb_wp
- rbuf
->rb_data
);
70 memcpy(rbuf
->rb_wp
, src
+ copied
, n
);
75 if (rbuf
->rb_wp
>= rbuf
->rb_data
+ rbuf
->rb_capacity
)
76 rbuf
->rb_wp
= rbuf
->rb_data
;
81 /* check if wp crossed rp */
83 rbuf
->rb_rp
= rbuf
->rb_wp
;
85 rbuf
->rb_len
= MIN(rbuf
->rb_len
, rbuf
->rb_capacity
);
91 rbuffer_read(struct rbuffer
*rbuf
, size_t len
)
96 total
= MIN(len
, rbuf
->rb_len
);
99 str
= reallocarray(NULL
, total
, sizeof(char));
101 n
= MIN(len
, (rbuf
->rb_data
+ rbuf
->rb_capacity
) - rbuf
->rb_rp
);
102 memcpy(str
, rbuf
->rb_rp
, n
);
106 memcpy(str
+ n
, rbuf
->rb_data
, total
- n
);
107 rbuf
->rb_rp
= rbuf
->rb_data
+ (total
- n
);
110 rbuf
->rb_len
-= total
;
116 rbuffer_find(struct rbuffer
*rbuf
, char ch
, size_t *len
)
118 char *ptr
= rbuf
->rb_rp
;
121 n
= MIN(rbuf
->rb_len
, (rbuf
->rb_data
+ rbuf
->rb_capacity
) - rbuf
->rb_rp
);
122 m
= rbuf
->rb_len
- n
;
123 for (ptr
= rbuf
->rb_rp
; n
-- ; ptr
++) {
125 *len
= rbuf
->rb_len
- n
- m
;
129 for (ptr
= rbuf
->rb_data
; m
-- ; ptr
++) {
131 *len
= rbuf
->rb_len
- m
;
139 rbuffer_readline(struct rbuffer
*rbuf
)
146 if (rbuffer_find(rbuf
, '\n', &n
)) {
147 str
= rbuffer_read(rbuf
, n
);