aboutsummaryrefslogtreecommitdiffstats
path: root/src/input
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-08-07 12:41:39 +0200
committerMax Kellermann <max@duempel.org>2014-08-07 16:08:02 +0200
commit36ff991960f4d298a97cee3f8f0ffcaa30686466 (patch)
tree005d598b9157c31ff6e27f3d217405f9fa8cc708 /src/input
parent59d38f876a22ef520c6b897a356e8fb8677481aa (diff)
downloadmpd-36ff991960f4d298a97cee3f8f0ffcaa30686466.tar.gz
mpd-36ff991960f4d298a97cee3f8f0ffcaa30686466.tar.xz
mpd-36ff991960f4d298a97cee3f8f0ffcaa30686466.zip
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.
Diffstat (limited to 'src/input')
-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