From 36ff991960f4d298a97cee3f8f0ffcaa30686466 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 7 Aug 2014 12:41:39 +0200 Subject: TextInputStream: move code to ReadBufferedLine() Look at the buffer first, before trying to read from the file. This reduces overhead because we don't refill the buffer after every line. --- src/input/TextInputStream.cxx | 76 ++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 34 deletions(-) (limited to 'src/input/TextInputStream.cxx') 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 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(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(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; + } } -- cgit v1.2.3