This commit is contained in:
Timothee Cour 2020-11-18 03:01:43 -08:00 • committed by GitHub
commit 33d79b9e64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 34 deletions

View file

@ -38,6 +38,8 @@
- Added `asyncdispatch.activeDescriptors` that returns the number of currently - Added `asyncdispatch.activeDescriptors` that returns the number of currently
active async event handles/file descriptors active async event handles/file descriptors
- `os.FileInfo` (returned by `getFileInfo`) now contains `blockSize`,
determining preferred I/O block size for this file object.
## Language changes ## Language changes

View file

@ -1550,40 +1550,6 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1",
else: else:
result = a.st_dev == b.st_dev and a.st_ino == b.st_ino result = a.st_dev == b.st_dev and a.st_ino == b.st_ino
proc sameFileContent*(path1, path2: string): bool {.rtl, extern: "nos$1",
tags: [ReadIOEffect], noWeirdTarget.} =
## Returns true if both pathname arguments refer to files with identical
## binary content.
##
## See also:
## * `sameFile proc <#sameFile,string,string>`_
const
bufSize = 8192 # 8K buffer
var
a, b: File
if not open(a, path1): return false
if not open(b, path2):
close(a)
return false
var bufA = alloc(bufSize)
var bufB = alloc(bufSize)
while true:
var readA = readBuffer(a, bufA, bufSize)
var readB = readBuffer(b, bufB, bufSize)
if readA != readB:
result = false
break
if readA == 0:
result = true
break
result = equalMem(bufA, bufB, readA)
if not result: break
if readA != bufSize: break # end of file
dealloc(bufA)
dealloc(bufB)
close(a)
close(b)
type type
FilePermission* = enum ## File access permission, modelled after UNIX. FilePermission* = enum ## File access permission, modelled after UNIX.
## ##
@ -3074,6 +3040,8 @@ type
lastAccessTime*: times.Time ## Time file was last accessed. lastAccessTime*: times.Time ## Time file was last accessed.
lastWriteTime*: times.Time ## Time file was last modified/written to. lastWriteTime*: times.Time ## Time file was last modified/written to.
creationTime*: times.Time ## Time file was created. Not supported on all systems! creationTime*: times.Time ## Time file was created. Not supported on all systems!
blockSize*: int ## Preferred I/O block size for this object.
## In some filesystems, this may vary from file to file.
template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped = template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped =
## Transforms the native file info structure into the one nim uses. ## Transforms the native file info structure into the one nim uses.
@ -3088,6 +3056,7 @@ template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped =
formalInfo.lastAccessTime = fromWinTime(rdFileTime(rawInfo.ftLastAccessTime)) formalInfo.lastAccessTime = fromWinTime(rdFileTime(rawInfo.ftLastAccessTime))
formalInfo.lastWriteTime = fromWinTime(rdFileTime(rawInfo.ftLastWriteTime)) formalInfo.lastWriteTime = fromWinTime(rdFileTime(rawInfo.ftLastWriteTime))
formalInfo.creationTime = fromWinTime(rdFileTime(rawInfo.ftCreationTime)) formalInfo.creationTime = fromWinTime(rdFileTime(rawInfo.ftCreationTime))
formalInfo.blockSize = 8192 # xxx use windows API instead of hardcoding
# Retrieve basic permissions # Retrieve basic permissions
if (rawInfo.dwFileAttributes and FILE_ATTRIBUTE_READONLY) != 0'i32: if (rawInfo.dwFileAttributes and FILE_ATTRIBUTE_READONLY) != 0'i32:
@ -3114,6 +3083,7 @@ template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped =
formalInfo.lastAccessTime = rawInfo.st_atim.toTime formalInfo.lastAccessTime = rawInfo.st_atim.toTime
formalInfo.lastWriteTime = rawInfo.st_mtim.toTime formalInfo.lastWriteTime = rawInfo.st_mtim.toTime
formalInfo.creationTime = rawInfo.st_ctim.toTime formalInfo.creationTime = rawInfo.st_ctim.toTime
formalInfo.blockSize = rawInfo.st_blksize
formalInfo.permissions = {} formalInfo.permissions = {}
checkAndIncludeMode(S_IRUSR, fpUserRead) checkAndIncludeMode(S_IRUSR, fpUserRead)
@ -3217,6 +3187,39 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo {.noWeirdTarget.
raiseOSError(osLastError(), path) raiseOSError(osLastError(), path)
rawToFormalFileInfo(rawInfo, path, result) rawToFormalFileInfo(rawInfo, path, result)
proc sameFileContent*(path1, path2: string): bool {.rtl, extern: "nos$1",
tags: [ReadIOEffect], noWeirdTarget.} =
## Returns true if both pathname arguments refer to files with identical
## binary content.
##
## See also:
## * `sameFile proc <#sameFile,string,string>`_
var
a, b: File
if not open(a, path1): return false
if not open(b, path2):
close(a)
return false
let bufSize = getFileInfo(a).blockSize
var bufA = alloc(bufSize)
var bufB = alloc(bufSize)
while true:
var readA = readBuffer(a, bufA, bufSize)
var readB = readBuffer(b, bufB, bufSize)
if readA != readB:
result = false
break
if readA == 0:
result = true
break
result = equalMem(bufA, bufB, readA)
if not result: break
if readA != bufSize: break # end of file
dealloc(bufA)
dealloc(bufB)
close(a)
close(b)
proc isHidden*(path: string): bool {.noWeirdTarget.} = proc isHidden*(path: string): bool {.noWeirdTarget.} =
## Determines whether ``path`` is hidden or not, using `this ## Determines whether ``path`` is hidden or not, using `this
## reference <https://en.wikipedia.org/wiki/Hidden_file_and_hidden_directory>`_. ## reference <https://en.wikipedia.org/wiki/Hidden_file_and_hidden_directory>`_.