Add updateFilePos() primitive and tests. (#229)

This commit is contained in:
Eugene Kabanov 2024-09-04 06:12:02 +03:00 committed by GitHub
parent 4d4dfb7b32
commit d4634c5405
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 68 additions and 0 deletions

View File

@ -1356,6 +1356,49 @@ proc setFilePos*(handle: IoHandle, offset: int64,
else:
ok()
proc updateFilePos*(handle: IoHandle, offset: int64,
whence: SeekPosition): IoResult[int64] =
## Procedure shall set the file offset for the open file associated with the
## file descriptor ``handle``, as follows:
## * If whence is ``SeekPosition.SeekBegin``, the file offset shall be set
## to ``offset`` bytes.
## * If whence is ``SeekPosition.SeekCur``, the file offset shall be set to
## its current location plus ``offset``.
## * If whence is ``SeekPosition.SeekEnd``, the file offset shall be set to
## the size of the file plus ``offset``.
##
## Returns the resulting offset location as measured in bytes from the
## beginning of the file.
when defined(windows):
var noffset = 0'i64
let pos =
case whence
of SeekBegin:
FILE_BEGIN
of SeekCurrent:
FILE_CURRENT
of SeekEnd:
FILE_END
let res = setFilePointerEx(uint(handle), offset, addr noffset, pos)
if res == 0:
err(ioLastError())
else:
ok(noffset)
else:
let pos =
case whence
of SeekBegin:
posix.SEEK_SET
of SeekCurrent:
posix.SEEK_CUR
of SeekEnd:
posix.SEEK_END
let res = int64(posix.lseek(cint(handle), Off(offset), pos))
if res == -1'i64:
err(ioLastError())
else:
ok(res)
proc truncate*(handle: IoHandle, length: int64): IoResult[void] =
## Procedure cause the regular file referenced by handle ``handle`` to be
## truncated to a size of precisely ``length`` bytes.

View File

@ -629,6 +629,31 @@ suite "OS Input/Output procedures test suite":
positions[3] == 10'i64
positions[4] == 20'i64
test "updateFilePos(handle) test":
proc performTest(path: string): IoResult[tuple[s0, s1, s2, s3, s4: int64]] =
let flags = {OpenFlags.Write, OpenFlags.Truncate, OpenFlags.Create}
let handle = ? openFile(path, flags)
let msg = "AAAAABBBBBCCCCCDDDDD"
discard ? io2.writeFile(handle, msg)
let
pos0 = ? updateFilePos(handle, 0'i64, SeekBegin)
pos1 = ? updateFilePos(handle, 5'i64, SeekCurrent)
pos2 = ? updateFilePos(handle, 5'i64, SeekCurrent)
pos3 = ? updateFilePos(handle, 0'i64, SeekEnd)
pos4 = ? updateFilePos(handle, -5'i64, SeekEnd)
? closeFile(handle)
? removeFile(path)
ok((pos0, pos1, pos2, pos3, pos4))
let res = performTest("testblob4")
check res.isOk()
let positions = res.get()
check:
positions[0] == 0'i64
positions[1] == 5'i64
positions[2] == 10'i64
positions[3] == 20'i64
positions[4] == 15'i64
test "lockFile(handle)/unlockFile(handle) test":
type
TestResult = object