Skip to content

Commit

Permalink
stdlib: minor refactorings and updates
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq committed Nov 27, 2024
1 parent e7f48cd commit 48c7e32
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 34 deletions.
62 changes: 31 additions & 31 deletions lib/pure/memfiles.nim
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,16 @@ when defined(nimPreviewSlimSystem):


proc newEIO(msg: string): ref IOError =
new(result)
result.msg = msg
result = (ref IOError)(msg: msg)

proc setFileSize(fh: FileHandle, newFileSize = -1, oldSize = -1): OSErrorCode =
## Set the size of open file pointed to by `fh` to `newFileSize` if != -1,
## allocating | freeing space from the file system. This routine returns the
## last OSErrorCode found rather than raising to support old rollback/clean-up
## code style. [ Should maybe move to std/osfiles. ]
result = OSErrorCode(0)
if newFileSize < 0 or newFileSize == oldSize:
return
return result
when defined(windows):
var sizeHigh = int32(newFileSize shr 32)
let sizeLow = int32(newFileSize and 0xffffffff)
Expand All @@ -56,7 +56,7 @@ proc setFileSize(fh: FileHandle, newFileSize = -1, oldSize = -1): OSErrorCode =
when declared(posix_fallocate):
while (e = posix_fallocate(fh, 0, newFileSize); e == EINTR):
discard
if e in [EINVAL, EOPNOTSUPP] and ftruncate(fh, newFileSize) == -1:
if (e == EINVAL or e == EOPNOTSUPP) and ftruncate(fh, newFileSize) == -1:
result = osLastError() # fallback arguable; Most portable BUT allows SEGV
elif e != 0:
result = osLastError()
Expand Down Expand Up @@ -268,10 +268,10 @@ proc open*(filename: string, mode: FileMode = fmRead,
if result.handle == -1:
fail(osLastError(), "error opening file")

if mappedSize != -1: #XXX Logic here differs from `when windows` branch ..
result.size = mappedSize #.. which always fstats&Uses min(mappedSize, st).
if mappedSize != -1: # XXX Logic here differs from `when windows` branch ..
result.size = mappedSize # .. which always fstats&Uses min(mappedSize, st).
else: # if newFileSize!=-1: result.size=newFileSize # if trust setFileSize
var stat: Stat #^^.. BUT some FSes (eg. Linux HugeTLBfs) round to 2MiB.
var stat: Stat # ^^.. BUT some FSes (eg. Linux HugeTLBfs) round to 2MiB.
if fstat(result.handle, stat) != -1:
result.size = stat.st_size.int # int may be 32-bit-unsafe for 2..<4 GiB
else:
Expand Down Expand Up @@ -336,8 +336,9 @@ proc resize*(f: var MemFile, newFileSize: int) {.raises: [IOError, OSError].} =
f.mapHandle = createFileMappingW(f.fHandle, nil, PAGE_READWRITE, 0,0,nil)
if f.mapHandle == 0: # Re-do map
raiseOSError(osLastError())
if (let m = mapViewOfFileEx(f.mapHandle, FILE_MAP_READ or FILE_MAP_WRITE,
0, 0, WinSizeT(newFileSize), nil); m != nil):
let m = mapViewOfFileEx(f.mapHandle, FILE_MAP_READ or FILE_MAP_WRITE,
0, 0, WinSizeT(newFileSize), nil)
if m != nil:
f.mem = m
f.size = newFileSize
else:
Expand All @@ -347,8 +348,8 @@ proc resize*(f: var MemFile, newFileSize: int) {.raises: [IOError, OSError].} =
raise newException(IOError,
"Cannot resize MemFile opened with allowRemap=false")
if newFileSize != f.size:
if (let e = setFileSize(f.handle.FileHandle, newFileSize, f.size);
e != 0.OSErrorCode): raiseOSError(e)
let e = setFileSize(f.handle.FileHandle, newFileSize, f.size)
if e != 0.OSErrorCode: raiseOSError(e)
when defined(linux): #Maybe NetBSD, too?
# On Linux this can be over 100 times faster than a munmap,mmap cycle.
proc mremap(old: pointer; oldSize, newSize: csize_t; flags: cint):
Expand Down Expand Up @@ -401,17 +402,18 @@ proc close*(f: var MemFile) =

if error: raiseOSError(lastErr)

type MemSlice* = object ## represent slice of a MemFile for iteration over delimited lines/records
data*: pointer
size*: int
type
MemSlice* = object ## represent slice of a MemFile for iteration over delimited lines/records
data*: pointer
size*: int

proc `==`*(x, y: MemSlice): bool =
## Compare a pair of MemSlice for strict equality.
result = (x.size == y.size and equalMem(x.data, y.data, x.size))

proc `$`*(ms: MemSlice): string {.inline.} =
## Return a Nim string built from a MemSlice.
result.setLen(ms.size)
result = newString(ms.size)
copyMem(result.cstring, ms.data, ms.size)

iterator memSlices*(mfile: MemFile, delim = '\l', eat = '\r'): MemSlice {.inline.} =
Expand Down Expand Up @@ -449,9 +451,8 @@ iterator memSlices*(mfile: MemFile, delim = '\l', eat = '\r'): MemSlice {.inline
proc c_memchr(cstr: pointer, c: char, n: csize_t): pointer {.
importc: "memchr", header: "<string.h>".}
proc `-!`(p, q: pointer): int {.inline.} = return cast[int](p) -% cast[int](q)
var ms: MemSlice
var ending: pointer
ms.data = mfile.mem
var ms = MemSlice(data: mfile.mem, size: 0)
var remaining = mfile.size
while remaining > 0:
ending = c_memchr(ms.data, delim, csize_t(remaining))
Expand Down Expand Up @@ -479,7 +480,6 @@ iterator lines*(mfile: MemFile, buf: var string, delim = '\l',
## for line in lines(memfiles.open("foo"), buffer):
## echo line
## ```

for ms in memSlices(mfile, delim, eat):
setLen(buf, ms.size)
if ms.size > 0:
Expand All @@ -497,7 +497,6 @@ iterator lines*(mfile: MemFile, delim = '\l', eat = '\r'): string {.inline.} =
## for line in lines(memfiles.open("foo")):
## echo line
## ```

var buf = newStringOfCap(80)
for line in lines(mfile, buf, delim, eat):
yield buf
Expand All @@ -507,7 +506,7 @@ type
MemMapFileStreamObj* = object of Stream
mf: MemFile
mode: FileMode
pos: ByteAddress
pos: int

proc mmsClose(s: Stream) =
MemMapFileStream(s).pos = -1
Expand Down Expand Up @@ -555,14 +554,15 @@ proc newMemMapFileStream*(filename: string, mode: FileMode = fmRead,
## `fileSize` can only be set if the file does not exist and is opened
## with write access (e.g., with fmReadWrite).
var mf: MemFile = open(filename, mode, newFileSize = fileSize)
new(result)
result.mode = mode
result.mf = mf
result.closeImpl = mmsClose
result.atEndImpl = mmsAtEnd
result.setPositionImpl = mmsSetPosition
result.getPositionImpl = mmsGetPosition
result.readDataImpl = mmsReadData
result.peekDataImpl = mmsPeekData
result.writeDataImpl = mmsWriteData
result.flushImpl = mmsFlush
result = MemMapFileStream(
mode: mode,
mf: mf,
closeImpl: mmsClose,
atEndImpl: mmsAtEnd,
setPositionImpl: mmsSetPosition,
getPositionImpl: mmsGetPosition,
readDataImpl: mmsReadData,
peekDataImpl: mmsPeekData,
writeDataImpl: mmsWriteData,
flushImpl: mmsFlush
)
6 changes: 3 additions & 3 deletions lib/pure/streams.nim
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ proc close*(s: Stream) =
let strm = newStringStream("The first line\nthe second line\nthe third line")
## do something...
strm.close()

block:
let strm = newFileStream("amissingfile.txt")
# deferring works even if newFileStream fails
Expand Down Expand Up @@ -286,9 +286,9 @@ when (NimMajor, NimMinor) >= (1, 3) or not defined(js):
strm.close()

const bufferSize = 1024
result = ""
jsOrVmBlock:
var buffer2: string
buffer2.setLen(bufferSize)
var buffer2 = newString(bufferSize)
while true:
let readBytes = readDataStr(s, buffer2, 0..<bufferSize)
if readBytes == 0:
Expand Down

0 comments on commit 48c7e32

Please sign in to comment.