4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "LineSplitter.hpp"
28 static std::pair
<unsigned, unsigned>
29 extract_line(const char *data
, unsigned length
)
31 const char *eol
= (const char *)memchr(data
, '\n', length
);
33 return std::pair
<unsigned, unsigned>(length
, length
);
35 length
= eol
+ 1 - data
;
37 /* purge trailing carriage return characters */
38 while (eol
> data
&& eol
[-1] == '\r')
41 return std::pair
<unsigned, unsigned>(eol
- data
, length
);
45 LineSplitter::ReadLine()
47 /* is there enough data left in the buffer to read another line? */
48 if (memchr(remaining
.data
, '\n', remaining
.length
) == NULL
) {
49 /* no: read more data from the Source */
50 remaining
= source
.Read();
51 if (remaining
.IsEmpty())
56 assert(!remaining
.IsEmpty());
58 Source
<char>::Range range
= remaining
;
59 std::pair
<unsigned, unsigned> bounds
=
60 extract_line(range
.data
, range
.length
);
61 source
.Consume(bounds
.second
);
62 remaining
.data
+= bounds
.second
;
63 remaining
.length
-= bounds
.second
;
65 if (bounds
.first
>= range
.length
) {
66 /* last line, not terminated by a line feed: copy to local buffer,
67 because we want to append the null byte */
68 char *line
= last
.get(range
.length
+ 1);
70 /* allocation has failed */
73 memcpy(line
, range
.data
, range
.length
);
74 line
[range
.length
] = 0;
77 /* there is space left for the null byte */
78 range
.data
[bounds
.first
] = 0;
84 LineSplitter::GetSize() const
86 return source
.GetSize();
90 LineSplitter::Tell() const