mirror of
https://github.com/dlang/phobos.git
synced 2025-05-01 07:30:33 +03:00
Improve speed of byLine() on generic I/O
This commit is contained in:
parent
8fef373c9d
commit
94b21d38d1
1 changed files with 28 additions and 4 deletions
32
std/stdio.d
32
std/stdio.d
|
@ -936,8 +936,8 @@ Range that reads one line at a time. */
|
||||||
/// Range primitive implementations.
|
/// Range primitive implementations.
|
||||||
@property bool empty() const
|
@property bool empty() const
|
||||||
{
|
{
|
||||||
if (!file.isOpen) return true;
|
|
||||||
if (line !is null) return false;
|
if (line !is null) return false;
|
||||||
|
if (!file.isOpen) return true;
|
||||||
|
|
||||||
// First read ever, must make sure stream is not empty. We
|
// First read ever, must make sure stream is not empty. We
|
||||||
// do so by reading a character and putting it back. Doing
|
// do so by reading a character and putting it back. Doing
|
||||||
|
@ -966,11 +966,13 @@ Range that reads one line at a time. */
|
||||||
/// Ditto
|
/// Ditto
|
||||||
void popFront()
|
void popFront()
|
||||||
{
|
{
|
||||||
enforce(file.isOpen);
|
assert(file.isOpen);
|
||||||
|
assumeSafeAppend(line);
|
||||||
file.readln(line, terminator);
|
file.readln(line, terminator);
|
||||||
if (line.empty)
|
if (line.empty)
|
||||||
{
|
{
|
||||||
file.detach();
|
file.detach();
|
||||||
|
line = null;
|
||||||
}
|
}
|
||||||
else if (keepTerminator == KeepTerminator.no
|
else if (keepTerminator == KeepTerminator.no
|
||||||
&& std.algorithm.endsWith(line, terminator))
|
&& std.algorithm.endsWith(line, terminator))
|
||||||
|
@ -2554,13 +2556,35 @@ private size_t readlnImpl(FILE* fps, ref char[] buf, dchar terminator = '\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Narrow stream
|
// Narrow stream
|
||||||
buf.length = 0;
|
// First, fill the existing buffer
|
||||||
|
for (size_t bufPos = 0; bufPos < buf.length; )
|
||||||
|
{
|
||||||
|
immutable c = FGETC(fp);
|
||||||
|
if (c == -1)
|
||||||
|
{
|
||||||
|
buf.length = bufPos;
|
||||||
|
goto endGame;
|
||||||
|
}
|
||||||
|
buf.ptr[bufPos++] = cast(char) c;
|
||||||
|
if (c == terminator)
|
||||||
|
{
|
||||||
|
// No need to test for errors in file
|
||||||
|
buf.length = bufPos;
|
||||||
|
return bufPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Then, append to it
|
||||||
for (int c; (c = FGETC(fp)) != -1; )
|
for (int c; (c = FGETC(fp)) != -1; )
|
||||||
{
|
{
|
||||||
buf ~= cast(char)c;
|
buf ~= cast(char)c;
|
||||||
if (c == terminator)
|
if (c == terminator)
|
||||||
break;
|
{
|
||||||
|
// No need to test for errors in file
|
||||||
|
return buf.length;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endGame:
|
||||||
if (ferror(fps))
|
if (ferror(fps))
|
||||||
StdioException();
|
StdioException();
|
||||||
return buf.length;
|
return buf.length;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue