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.
This commit is contained in:
Max Kellermann 2014-08-07 12:41:39 +02:00
parent 59d38f876a
commit 36ff991960
2 changed files with 46 additions and 35 deletions

View File

@ -27,52 +27,60 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
char *
TextInputStream::ReadBufferedLine()
{
auto r = buffer.Read();
char *newline = reinterpret_cast<char*>(memchr(r.data, '\n', r.size));
if (newline == nullptr)
return nullptr;
buffer.Consume(newline + 1 - r.data);
char *end = StripRight(r.data, newline);
*end = 0;
return r.data;
}
char * char *
TextInputStream::ReadLine() TextInputStream::ReadLine()
{ {
char *src, *p; char *line = ReadBufferedLine();
if (line != nullptr)
return line;
do { while (true) {
size_t nbytes;
auto dest = buffer.Write(); auto dest = buffer.Write();
if (dest.size >= 2) { if (dest.size < 2) {
/* reserve one byte for the null terminator if /* end of file (or line too long): terminate
the last line is not terminated by a the current line */
newline character */
assert(!dest.IsEmpty());
dest[0] = 0;
line = buffer.Read().data;
buffer.Clear();
return line;
}
/* reserve one byte for the null terminator if the
last line is not terminated by a newline
character */
--dest.size; --dest.size;
Error error; Error error;
nbytes = is.LockRead(dest.data, dest.size, error); size_t nbytes = is.LockRead(dest.data, dest.size, error);
if (nbytes > 0) if (nbytes > 0)
buffer.Append(nbytes); buffer.Append(nbytes);
else if (error.IsDefined()) { else if (error.IsDefined()) {
LogError(error); LogError(error);
return nullptr; return nullptr;
} }
} else
nbytes = 0;
auto src_p = buffer.Read(); line = ReadBufferedLine();
if (src_p.IsEmpty()) if (line != nullptr)
return line;
if (nbytes == 0)
return nullptr; return nullptr;
src = src_p.data;
p = reinterpret_cast<char*>(memchr(src, '\n', src_p.size));
if (p == nullptr && nbytes == 0) {
/* end of file (or line too long): terminate
the current line */
dest = buffer.Write();
assert(!dest.IsEmpty());
dest[0] = 0;
buffer.Clear();
return src;
} }
} while (p == nullptr);
buffer.Consume(p - src + 1);
char *end = StripRight(src, p);
*end = 0;
return src;
} }

View File

@ -47,6 +47,9 @@ public:
* @return a pointer to the line, or nullptr on end-of-file or error * @return a pointer to the line, or nullptr on end-of-file or error
*/ */
char *ReadLine(); char *ReadLine();
private:
char *ReadBufferedLine();
}; };
#endif #endif