aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/TextInputStream.cxx76
-rw-r--r--src/input/TextInputStream.hxx3
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