2 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 #include <gpxe/linebuf.h>
33 * Retrieve buffered-up line
35 * @v linebuf Line buffer
36 * @ret line Buffered line, or NULL if no line ready to read
38 char * buffered_line ( struct line_buffer
*linebuf
) {
39 return ( linebuf
->ready
? linebuf
->data
: NULL
);
43 * Discard line buffer contents
45 * @v linebuf Line buffer
47 void empty_line_buffer ( struct line_buffer
*linebuf
) {
48 free ( linebuf
->data
);
55 * Buffer up received data by lines
57 * @v linebuf Line buffer
58 * @v data New data to add
59 * @v len Length of new data to add
60 * @ret len Consumed length, or negative error number
62 * After calling line_buffer(), use buffered_line() to determine
63 * whether or not a complete line is available. Carriage returns and
64 * newlines will have been stripped, and the line will be
65 * NUL-terminated. This buffered line is valid only until the next
66 * call to line_buffer() (or to empty_line_buffer()).
68 * Note that line buffers use dynamically allocated storage; you
69 * should call empty_line_buffer() before freeing a @c struct @c
72 ssize_t
line_buffer ( struct line_buffer
*linebuf
,
73 const char *data
, size_t len
) {
79 /* Free any completed line from previous iteration */
81 empty_line_buffer ( linebuf
);
83 /* Search for line terminator */
84 if ( ( eol
= memchr ( data
, '\n', len
) ) ) {
85 consume
= ( eol
- data
+ 1 );
90 /* Reallocate data buffer and copy in new data */
91 new_len
= ( linebuf
->len
+ consume
);
92 new_data
= realloc ( linebuf
->data
, ( new_len
+ 1 ) );
95 memcpy ( ( new_data
+ linebuf
->len
), data
, consume
);
96 new_data
[new_len
] = '\0';
97 linebuf
->data
= new_data
;
98 linebuf
->len
= new_len
;
100 /* If we have reached end of line, trim the line and mark as ready */
102 linebuf
->data
[--linebuf
->len
] = '\0'; /* trim NL */
103 if ( linebuf
->data
[linebuf
->len
- 1] == '\r' )
104 linebuf
->data
[--linebuf
->len
] = '\0'; /* trim CR */