2 * Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 * Distributed under the terms of the MIT License.
7 #include "line_buffer.h"
9 #include <KernelExport.h>
14 clear_line_buffer(struct line_buffer
&buffer
)
23 init_line_buffer(struct line_buffer
&buffer
, size_t size
)
25 clear_line_buffer(buffer
);
27 buffer
.buffer
= (char *)malloc(size
);
28 if (buffer
.buffer
== NULL
)
38 uninit_line_buffer(struct line_buffer
&buffer
)
46 line_buffer_readable(struct line_buffer
&buffer
)
53 line_buffer_readable_line(struct line_buffer
&buffer
, char eol
, char eof
)
55 size_t size
= buffer
.in
;
59 // find EOL or EOF char
60 for (size_t i
= 0; i
< size
; i
++) {
61 char c
= buffer
.buffer
[(buffer
.first
+ i
) % buffer
.size
];
62 if (c
== eol
|| c
== '\n' || c
== '\r' || c
== eof
)
66 // If the buffer is full, but doesn't contain a EOL or EOF, we report the
67 // full size anyway, since otherwise the reader would wait forever.
68 return buffer
.in
== buffer
.size
? buffer
.in
: 0;
73 line_buffer_writable(struct line_buffer
&buffer
)
75 return buffer
.size
- buffer
.in
;
80 line_buffer_user_read(struct line_buffer
&buffer
, char *data
, size_t length
,
81 char eof
, bool* hitEOF
)
83 size_t available
= buffer
.in
;
85 if (length
> available
)
91 // check for EOF, if the caller asked us to
94 for (size_t i
= 0; i
< available
; i
++) {
95 char c
= buffer
.buffer
[(buffer
.first
+ i
) % buffer
.size
];
104 ssize_t bytesRead
= length
;
106 if (buffer
.first
+ length
< buffer
.size
) {
108 if (user_memcpy(data
, buffer
.buffer
+ buffer
.first
, length
) != B_OK
)
109 bytesRead
= B_BAD_ADDRESS
;
111 // need to copy both ends
112 size_t upper
= buffer
.size
- buffer
.first
;
113 size_t lower
= length
- upper
;
115 if (user_memcpy(data
, buffer
.buffer
+ buffer
.first
, upper
) != B_OK
116 || user_memcpy(data
+ upper
, buffer
.buffer
, lower
) != B_OK
)
117 bytesRead
= B_BAD_ADDRESS
;
121 buffer
.first
= (buffer
.first
+ bytesRead
) % buffer
.size
;
122 buffer
.in
-= bytesRead
;
125 // dispose of EOF char
126 if (hitEOF
&& *hitEOF
) {
127 buffer
.first
= (buffer
.first
+ 1) % buffer
.size
;
136 line_buffer_putc(struct line_buffer
&buffer
, char c
)
138 if (buffer
.in
== buffer
.size
)
141 buffer
.buffer
[(buffer
.first
+ buffer
.in
++) % buffer
.size
] = c
;
148 line_buffer_getc(struct line_buffer
&buffer
, char *_c
)
154 line_buffer_ungetc(struct line_buffer
&buffer
, char *c
)
162 line_buffer_tail_getc(struct line_buffer
&buffer
, char *c
)
167 *c
= buffer
.buffer
[(buffer
.first
+ --buffer
.in
) % buffer
.size
];