blob: b3ce76a14054c9477fcf879520f8341075c62d2f [file] [log] [blame]
William A. Kennington III9a512c92022-08-12 15:15:55 -07001#include <stdplus/exception.hpp>
2#include <stdplus/fd/line.hpp>
3#include <stdplus/fd/ops.hpp>
4
Patrick Williamsd1984dd2023-05-10 16:12:44 -05005#include <cstring>
6
William A. Kennington III9a512c92022-08-12 15:15:55 -07007namespace stdplus
8{
9namespace fd
10{
11
Patrick Williamsd1984dd2023-05-10 16:12:44 -050012LineReader::LineReader(Fd& fd) : fd(fd) {}
William A. Kennington III9a512c92022-08-12 15:15:55 -070013
14const std::string* LineReader::readLine()
15{
16 if (hit_eof)
17 {
18 throw exception::Eof("readLine");
19 }
20 if (line_complete)
21 {
22 line.clear();
23 }
24 while (true)
25 {
26 if (buf_data.empty())
27 {
28 try
29 {
30 buf_data = read(fd, buf);
31 if (buf_data.empty())
32 {
33 return nullptr;
34 }
35 }
36 catch (const exception::Eof&)
37 {
38 hit_eof = true;
39 return &line;
40 }
41 }
42 line_complete = false;
43 for (size_t i = 0; i < buf_data.size(); ++i)
44 {
45 if (buf_data[i] == '\n')
46 {
William A. Kennington IIIb594fc32022-08-18 01:47:48 -070047 auto oldsize = line.size();
48 line.resize(oldsize + i);
49 std::memcpy(line.data() + oldsize, buf_data.data(), i);
William A. Kennington III9a512c92022-08-12 15:15:55 -070050 buf_data = buf_data.subspan(i + 1);
51 line_complete = true;
52 return &line;
53 }
54 }
William A. Kennington IIIb594fc32022-08-18 01:47:48 -070055 auto oldsize = line.size();
56 line.resize(oldsize + buf_data.size());
57 std::memcpy(line.data() + oldsize, buf_data.data(), buf_data.size());
William A. Kennington III9a512c92022-08-12 15:15:55 -070058 buf_data = {};
59 }
60}
61
62} // namespace fd
63} // namespace stdplus