fixes #9026 adds a readLineImpl to streams so that FileStreams can be fast (#12234)

This commit is contained in:
Ray Imber 2019-09-22 23:25:26 -07:00 • committed by Andreas Rumpf
commit 6e681b546f

View file

@ -122,6 +122,9 @@ type
readDataStrImpl*: proc (s: Stream, buffer: var string, slice: Slice[int]): int readDataStrImpl*: proc (s: Stream, buffer: var string, slice: Slice[int]): int
{.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.} {.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
readLineImpl*: proc(s: Stream, line: var TaintedString): bool
{.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
readDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int readDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int
{.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.} {.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
peekDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int peekDataImpl*: proc (s: Stream, buffer: pointer, bufLen: int): int
@ -876,19 +879,23 @@ proc readLine*(s: Stream, line: var TaintedString): bool =
doAssert strm.readLine(line) == false doAssert strm.readLine(line) == false
doAssert line == "" doAssert line == ""
strm.close() strm.close()
line.string.setLen(0) if s.readLineImpl != nil:
while true: result = s.readLineImpl(s, line)
var c = readChar(s) else:
if c == '\c': # fallback
c = readChar(s) line.string.setLen(0)
break while true:
elif c == '\L': break var c = readChar(s)
elif c == '\0': if c == '\c':
if line.len > 0: break c = readChar(s)
else: return false break
line.string.add(c) elif c == '\L': break
result = true elif c == '\0':
if line.len > 0: break
else: return false
line.string.add(c)
result = true
proc peekLine*(s: Stream, line: var TaintedString): bool = proc peekLine*(s: Stream, line: var TaintedString): bool =
## Peeks a line of text from the stream `s` into `line`. `line` must not be ## Peeks a line of text from the stream `s` into `line`. `line` must not be
@ -1131,6 +1138,9 @@ when not defined(js):
if writeBuffer(FileStream(s).f, buffer, bufLen) != bufLen: if writeBuffer(FileStream(s).f, buffer, bufLen) != bufLen:
raise newEIO("cannot write to stream") raise newEIO("cannot write to stream")
proc fsReadLine(s: Stream, line: var TaintedString): bool =
result = readLine(FileStream(s).f, line)
proc newFileStream*(f: File): owned FileStream = proc newFileStream*(f: File): owned FileStream =
## Creates a new stream from the file `f`. ## Creates a new stream from the file `f`.
## ##
@ -1169,6 +1179,7 @@ when not defined(js):
result.getPositionImpl = fsGetPosition result.getPositionImpl = fsGetPosition
result.readDataStrImpl = fsReadDataStr result.readDataStrImpl = fsReadDataStr
result.readDataImpl = fsReadData result.readDataImpl = fsReadData
result.readLineImpl = fsReadLine
result.peekDataImpl = fsPeekData result.peekDataImpl = fsPeekData
result.writeDataImpl = fsWriteData result.writeDataImpl = fsWriteData
result.flushImpl = fsFlush result.flushImpl = fsFlush