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:
parent
59d38f876a
commit
36ff991960
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user