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.
19 FILE_LICENCE ( GPL2_OR_LATER
);
32 #include <gpxe/linebuf.h>
35 * Retrieve buffered-up line
37 * @v linebuf Line buffer
38 * @ret line Buffered line, or NULL if no line ready to read
40 char * buffered_line ( struct line_buffer
*linebuf
) {
41 return ( linebuf
->ready
? linebuf
->data
: NULL
);
45 * Discard line buffer contents
47 * @v linebuf Line buffer
49 void empty_line_buffer ( struct line_buffer
*linebuf
) {
50 free ( linebuf
->data
);
57 * Buffer up received data by lines
59 * @v linebuf Line buffer
60 * @v data New data to add
61 * @v len Length of new data to add
62 * @ret len Consumed length, or negative error number
64 * After calling line_buffer(), use buffered_line() to determine
65 * whether or not a complete line is available. Carriage returns and
66 * newlines will have been stripped, and the line will be
67 * NUL-terminated. This buffered line is valid only until the next
68 * call to line_buffer() (or to empty_line_buffer()).
70 * Note that line buffers use dynamically allocated storage; you
71 * should call empty_line_buffer() before freeing a @c struct @c
74 ssize_t
line_buffer ( struct line_buffer
*linebuf
,
75 const char *data
, size_t len
) {
81 /* Free any completed line from previous iteration */
83 empty_line_buffer ( linebuf
);
85 /* Search for line terminator */
86 if ( ( eol
= memchr ( data
, '\n', len
) ) ) {
87 consume
= ( eol
- data
+ 1 );
92 /* Reallocate data buffer and copy in new data */
93 new_len
= ( linebuf
->len
+ consume
);
94 new_data
= realloc ( linebuf
->data
, ( new_len
+ 1 ) );
97 memcpy ( ( new_data
+ linebuf
->len
), data
, consume
);
98 new_data
[new_len
] = '\0';
99 linebuf
->data
= new_data
;
100 linebuf
->len
= new_len
;
102 /* If we have reached end of line, trim the line and mark as ready */
104 linebuf
->data
[--linebuf
->len
] = '\0'; /* trim NL */
105 if ( linebuf
->data
[linebuf
->len
- 1] == '\r' )
106 linebuf
->data
[--linebuf
->len
] = '\0'; /* trim CR */