diff options
Diffstat (limited to 'src/input')
-rw-r--r-- | src/input/TextInputStream.cxx | 76 | ||||
-rw-r--r-- | src/input/TextInputStream.hxx | 3 |
2 files changed, 45 insertions, 34 deletions
diff --git a/src/input/TextInputStream.cxx b/src/input/TextInputStream.cxx index 177606d6d..0eb5bc1a8 100644 --- a/src/input/TextInputStream.cxx +++ b/src/input/TextInputStream.cxx @@ -28,51 +28,59 @@ #include <string.h> char * -TextInputStream::ReadLine() +TextInputStream::ReadBufferedLine() { - char *src, *p; - - do { - size_t nbytes; - auto dest = buffer.Write(); - if (dest.size >= 2) { - /* reserve one byte for the null terminator if - the last line is not terminated by a - newline character */ - --dest.size; + auto r = buffer.Read(); + char *newline = reinterpret_cast<char*>(memchr(r.data, '\n', r.size)); + if (newline == nullptr) + return nullptr; - Error error; - nbytes = is.LockRead(dest.data, dest.size, error); - if (nbytes > 0) - buffer.Append(nbytes); - else if (error.IsDefined()) { - LogError(error); - return nullptr; - } - } else - nbytes = 0; + buffer.Consume(newline + 1 - r.data); - auto src_p = buffer.Read(); - if (src_p.IsEmpty()) - return nullptr; + char *end = StripRight(r.data, newline); + *end = 0; + return r.data; +} - src = src_p.data; +char * +TextInputStream::ReadLine() +{ + char *line = ReadBufferedLine(); + if (line != nullptr) + return line; - p = reinterpret_cast<char*>(memchr(src, '\n', src_p.size)); - if (p == nullptr && nbytes == 0) { + while (true) { + auto dest = buffer.Write(); + if (dest.size < 2) { /* end of file (or line too long): terminate the current line */ - dest = buffer.Write(); + assert(!dest.IsEmpty()); dest[0] = 0; + line = buffer.Read().data; buffer.Clear(); - return src; + return line; } - } while (p == nullptr); - buffer.Consume(p - src + 1); + /* reserve one byte for the null terminator if the + last line is not terminated by a newline + character */ + --dest.size; - char *end = StripRight(src, p); - *end = 0; - return src; + Error error; + size_t nbytes = is.LockRead(dest.data, dest.size, error); + if (nbytes > 0) + buffer.Append(nbytes); + else if (error.IsDefined()) { + LogError(error); + return nullptr; + } + + line = ReadBufferedLine(); + if (line != nullptr) + return line; + + if (nbytes == 0) + return nullptr; + } } diff --git a/src/input/TextInputStream.hxx b/src/input/TextInputStream.hxx index 6f39d22cf..ce1eaddff 100644 --- a/src/input/TextInputStream.hxx +++ b/src/input/TextInputStream.hxx @@ -47,6 +47,9 @@ public: * @return a pointer to the line, or nullptr on end-of-file or error */ char *ReadLine(); + +private: + char *ReadBufferedLine(); }; #endif |