io.directories: faster directory-entries by caching dirent structs.
parent
24d345cdd9
commit
26ff963758
|
@ -31,7 +31,7 @@ HOOK: make-directory io-backend ( path -- )
|
|||
! Listing directories
|
||||
TUPLE: directory-entry name type ;
|
||||
|
||||
HOOK: >directory-entry os ( byte-array -- directory-entry )
|
||||
C: <directory-entry> directory-entry
|
||||
|
||||
HOOK: (directory-entries) os ( path -- seq )
|
||||
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
! Copyright (C) 2009 Doug Coleman.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: alien.c-types alien.data io.directories.unix kernel libc
|
||||
system unix classes.struct unix.ffi ;
|
||||
math system unix classes.struct unix.ffi ;
|
||||
IN: io.directories.unix.linux
|
||||
|
||||
M: linux find-next-file ( DIR* -- dirent )
|
||||
dirent <struct>
|
||||
f void* <ref>
|
||||
[ [ readdir64_r ] unix-system-call 0 = [ (io-error) ] unless ] 2keep
|
||||
void* deref [ drop f ] unless ;
|
||||
: next-dirent ( DIR* dirent* -- dirent* ? )
|
||||
f void* <ref> [
|
||||
readdir64_r [ dup strerror libc-error ] unless-zero
|
||||
] 2keep void* deref ; inline
|
||||
|
||||
M: linux (directory-entries) ( path -- seq )
|
||||
[
|
||||
dirent <struct>
|
||||
'[ _ _ next-dirent ] [ >directory-entry ] produce nip
|
||||
] with-unix-directory ;
|
||||
|
|
|
@ -4,7 +4,7 @@ USING: accessors alien.c-types alien.data alien.strings
|
|||
assocs combinators continuations destructors fry io io.backend
|
||||
io.directories io.encodings.binary io.files.info.unix
|
||||
io.encodings.utf8 io.files io.pathnames io.files.types kernel
|
||||
math.bitwise sequences system unix unix.stat vocabs.loader
|
||||
math math.bitwise sequences system unix unix.stat vocabs.loader
|
||||
classes.struct unix.ffi literals libc vocabs io.files.info ;
|
||||
IN: io.directories.unix
|
||||
|
||||
|
@ -40,15 +40,6 @@ M: unix copy-file ( from to -- )
|
|||
dupd curry swap '[ _ closedir io-error ] [ ] cleanup
|
||||
] with-directory ; inline
|
||||
|
||||
HOOK: find-next-file os ( DIR* -- byte-array )
|
||||
|
||||
M: unix find-next-file ( DIR* -- byte-array )
|
||||
dirent <struct>
|
||||
f void* <ref>
|
||||
0 set-errno
|
||||
[ readdir_r 0 = [ errno 0 = [ (io-error) ] unless ] unless ] 2keep
|
||||
void* deref [ drop f ] unless ;
|
||||
|
||||
: dirent-type>file-type ( type -- file-type )
|
||||
H{
|
||||
{ $ DT_BLK +block-device+ }
|
||||
|
@ -63,25 +54,22 @@ M: unix find-next-file ( DIR* -- byte-array )
|
|||
|
||||
! An easy way to return +unknown+ is to mount a .iso on OSX and
|
||||
! call directory-entries on the mount point.
|
||||
: dirent>file-type ( dirent -- type )
|
||||
dup d_type>> dirent-type>file-type
|
||||
dup +unknown+ = [
|
||||
drop d_name>> utf8 alien>string file-info type>>
|
||||
] [
|
||||
nip
|
||||
] if ;
|
||||
|
||||
M: unix >directory-entry ( byte-array -- directory-entry )
|
||||
{
|
||||
[ d_name>> underlying>> utf8 alien>string ]
|
||||
[ dirent>file-type ]
|
||||
} cleave directory-entry boa ;
|
||||
: next-dirent ( DIR* dirent* -- dirent* ? )
|
||||
f void* <ref> [
|
||||
readdir_r [ dup strerror libc-error ] unless-zero
|
||||
] 2keep void* deref ; inline
|
||||
|
||||
: >directory-entry ( dirent* -- directory-entry )
|
||||
[ d_name>> utf8 alien>string ]
|
||||
[ d_type>> dirent-type>file-type ] bi
|
||||
dup +unknown+ = [ drop dup file-info type>> ] when
|
||||
<directory-entry> ; inline
|
||||
|
||||
M: unix (directory-entries) ( path -- seq )
|
||||
[
|
||||
'[ _ find-next-file dup ]
|
||||
[ >directory-entry ]
|
||||
produce nip
|
||||
dirent <struct>
|
||||
'[ _ _ next-dirent ] [ >directory-entry ] produce nip
|
||||
] with-unix-directory ;
|
||||
|
||||
os linux? [ "io.directories.unix.linux" require ] when
|
||||
|
|
|
@ -48,13 +48,11 @@ M: windows delete-directory ( path -- )
|
|||
normalize-path
|
||||
RemoveDirectory win32-error=0/f ;
|
||||
|
||||
: find-first-file ( path -- WIN32_FIND_DATA handle )
|
||||
WIN32_FIND_DATA <struct>
|
||||
: find-first-file ( path WIN32_FIND_DATA -- WIN32_FIND_DATA HANDLE )
|
||||
[ nip ] [ FindFirstFile ] 2bi
|
||||
[ INVALID_HANDLE_VALUE = [ win32-error-string throw ] when ] keep ;
|
||||
|
||||
: find-next-file ( path -- WIN32_FIND_DATA/f )
|
||||
WIN32_FIND_DATA <struct>
|
||||
: find-next-file ( HANDLE WIN32_FIND_DATA -- WIN32_FIND_DATA/f )
|
||||
[ nip ] [ FindNextFile ] 2bi 0 = [
|
||||
GetLastError ERROR_NO_MORE_FILES = [
|
||||
win32-error
|
||||
|
@ -63,23 +61,27 @@ M: windows delete-directory ( path -- )
|
|||
|
||||
TUPLE: windows-directory-entry < directory-entry attributes ;
|
||||
|
||||
M: windows >directory-entry ( byte-array -- directory-entry )
|
||||
C: <windows-directory-entry> windows-directory-entry
|
||||
|
||||
: >windows-directory-entry ( WIN32_FIND_DATA -- directory-entry )
|
||||
[ cFileName>> alien>native-string ]
|
||||
[
|
||||
dwFileAttributes>>
|
||||
[ win32-file-type ] [ win32-file-attributes ] bi
|
||||
] bi
|
||||
dupd remove windows-directory-entry boa ;
|
||||
dupd remove <windows-directory-entry> ; inline
|
||||
|
||||
M: windows (directory-entries) ( path -- seq )
|
||||
"\\" ?tail drop "\\*" append
|
||||
find-first-file [ >directory-entry ] dip
|
||||
WIN32_FIND_DATA <struct>
|
||||
find-first-file over
|
||||
[ >windows-directory-entry ] 2dip
|
||||
[
|
||||
'[
|
||||
[ _ find-next-file dup ]
|
||||
[ >directory-entry ]
|
||||
[ _ _ find-next-file dup ]
|
||||
[ >windows-directory-entry ]
|
||||
produce nip
|
||||
over name>> "." = [ nip ] [ swap prefix ] if
|
||||
]
|
||||
] [ '[ _ FindClose win32-error=0/f ] ] bi [ ] cleanup ;
|
||||
] [ drop '[ _ FindClose win32-error=0/f ] ] 2bi [ ] cleanup ;
|
||||
|
||||
|
|
Loading…
Reference in New Issue