Add MemFile text interface factored so users can optionally skip Nim string
construction (e.g. to filter many lines out before building strings). Only Windows and/or Unix line endings are supported by default, though fiddling with delim/eat arguments can probably support archaic MacOS9 files.
This commit is contained in:
parent
4932415742
commit
a12c9cfb9d
1 changed files with 32 additions and 0 deletions
|
|
@ -245,3 +245,35 @@ proc close*(f: var MemFile) =
|
||||||
|
|
||||||
if error: raiseOSError(lastErr)
|
if error: raiseOSError(lastErr)
|
||||||
|
|
||||||
|
type Record* {.unchecked.} = object
|
||||||
|
Beg*: cstring
|
||||||
|
Len*: int
|
||||||
|
|
||||||
|
iterator records*(mfile: MemFile, delim='\l', eat='\r'): Record {.inline.} =
|
||||||
|
proc c_memchr(cstr: cstring, c: char, n: csize): cstring {.
|
||||||
|
importc: "memchr", header: "<string.h>" .}
|
||||||
|
proc `-!`(p, q: cstring): int {.inline.} = return cast[int](p) -% cast[int](q)
|
||||||
|
var rec: Record
|
||||||
|
var End: cstring
|
||||||
|
rec.Beg = cast[cstring](mfile.mem)
|
||||||
|
var remaining = mfile.size
|
||||||
|
while remaining > 0:
|
||||||
|
End = c_memchr(rec.Beg, delim, remaining)
|
||||||
|
if End == nil: # unterminated final record
|
||||||
|
rec.Len = remaining
|
||||||
|
yield rec
|
||||||
|
break
|
||||||
|
rec.Len = End -! rec.Beg # delimiter is not included
|
||||||
|
if eat != '\0' and rec.Len > 0 and rec.Beg[rec.Len - 1] == eat:
|
||||||
|
dec(rec.Len) # exclude extra pre-delim ch
|
||||||
|
yield rec
|
||||||
|
rec.Beg = cast[cstring](cast[int](End) +% 1) # skip delimiter
|
||||||
|
remaining = mfile.size - (rec.Beg -! cast[cstring](mfile.mem))
|
||||||
|
|
||||||
|
proc toString*(rec: Record): string {.inline.} =
|
||||||
|
proc toNimStr(str: cstring, len: int): string {. importc: "toNimStr" .}
|
||||||
|
result = toNimStr(cast[cstring](rec.Beg), rec.Len)
|
||||||
|
result[result.len] = '\0'
|
||||||
|
|
||||||
|
iterator lines*(mfile: MemFile): string {.inline.} =
|
||||||
|
for rec in records(mfile): yield toString(rec)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue