added mapMem/unmapMem to memfiles; untested

This commit is contained in:
Araq 2014-03-22 02:51:03 +01:00
commit fb5ece805f

View file

@ -1,7 +1,7 @@
# #
# #
# Nimrod's Runtime Library # Nimrod's Runtime Library
# (c) Copyright 2012 Nimrod Contributors # (c) Copyright 2014 Nimrod Contributors
# #
# See the file "copying.txt", included in this # See the file "copying.txt", included in this
# distribution, for details about the copyright. # distribution, for details about the copyright.
@ -34,6 +34,43 @@ type
else: else:
handle: cint handle: cint
proc mapMem*(m: var TMemFile, mode: TFileMode = fmRead,
mappedSize = -1, offset = 0): pointer =
var readonly = mode == fmRead
when defined(windows):
result = mapViewOfFileEx(
m.mapHandle,
if readonly: FILE_MAP_READ else: FILE_MAP_WRITE,
int32(offset shr 32),
int32(offset and 0xffffffff),
if mappedSize == -1: 0 else: mappedSize,
nil)
if result == nil:
osError(osLastError())
else:
assert mappedSize > 0
result = mmap(
nil,
mappedSize,
if readonly: PROT_READ else: PROT_READ or PROT_WRITE,
if readonly: MAP_PRIVATE else: MAP_SHARED,
m.handle, offset)
if result == cast[pointer](MAP_FAILED):
osError(osLastError())
proc unmapMem*(f: var TMemFile, p: pointer, size: int) =
## unmaps the memory region ``(p, <p+size)`` of the mapped file `f`.
## All changes are written back to the file system, if `f` was opened
## with write access. ``size`` must be of exactly the size that was requested
## via ``mapMem``.
when defined(windows):
if unmapViewOfFile(p) == 0: osError(osLastError())
else:
if munmap(p, size) != 0: osError(osLastError())
proc open*(filename: string, mode: TFileMode = fmRead, proc open*(filename: string, mode: TFileMode = fmRead,
mappedSize = -1, offset = 0, newFileSize = -1): TMemFile = mappedSize = -1, offset = 0, newFileSize = -1): TMemFile =
## opens a memory mapped file. If this fails, ``EOS`` is raised. ## opens a memory mapped file. If this fails, ``EOS`` is raised.
@ -71,7 +108,7 @@ proc open*(filename: string, mode: TFileMode = fmRead,
when useWinUnicode: when useWinUnicode:
result.fHandle = callCreateFile(createFileW, newWideCString(filename)) result.fHandle = callCreateFile(createFileW, newWideCString(filename))
else: else:
result.fHandle = callCreateFile(CreateFileA, filename) result.fHandle = callCreateFile(createFileA, filename)
if result.fHandle == INVALID_HANDLE_VALUE: if result.fHandle == INVALID_HANDLE_VALUE:
fail(osLastError(), "error opening file") fail(osLastError(), "error opening file")
@ -170,14 +207,14 @@ proc close*(f: var TMemFile) =
when defined(windows): when defined(windows):
if f.fHandle != INVALID_HANDLE_VALUE: if f.fHandle != INVALID_HANDLE_VALUE:
lastErr = osLastError()
error = unmapViewOfFile(f.mem) == 0 error = unmapViewOfFile(f.mem) == 0
lastErr = osLastError()
error = (closeHandle(f.mapHandle) == 0) or error error = (closeHandle(f.mapHandle) == 0) or error
error = (closeHandle(f.fHandle) == 0) or error error = (closeHandle(f.fHandle) == 0) or error
else: else:
if f.handle != 0: if f.handle != 0:
lastErr = osLastError()
error = munmap(f.mem, f.size) != 0 error = munmap(f.mem, f.size) != 0
lastErr = osLastError()
error = (close(f.handle) != 0) or error error = (close(f.handle) != 0) or error
f.size = 0 f.size = 0