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 <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 *
TextInputStream::ReadLine()
{
char *src, *p;
char *line = ReadBufferedLine();
if (line != nullptr)
return line;
do {
size_t nbytes;
while (true) {
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;
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;
auto src_p = buffer.Read();
if (src_p.IsEmpty())
return nullptr;
src = src_p.data;
p = reinterpret_cast<char*>(memchr(src, '\n', src_p.size));
if (p == nullptr && nbytes == 0) {
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;
}
}

View File

@ -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