@@ -34,6 +34,7 @@ module System.Posix.Directory (
34
34
readDirStream ,
35
35
readDirStreamMaybe ,
36
36
readDirStreamWith ,
37
+ readDirStreamWithPtr ,
37
38
rewindDirStream ,
38
39
closeDirStream ,
39
40
DirStreamOffset ,
@@ -114,26 +115,38 @@ readDirStreamMaybe = readDirStreamWith
114
115
-- invocation of the callback and it will be freed automatically after. Do not
115
116
-- pass it to the outside world!
116
117
readDirStreamWith :: (DirEnt -> IO a ) -> DirStream -> IO (Maybe a )
117
- readDirStreamWith f (DirStream dirp) =
118
- alloca $ \ ptr_dEnt -> loop ptr_dEnt
119
- where
120
- loop ptr_dEnt = do
121
- resetErrno
122
- r <- c_readdir dirp ptr_dEnt
123
- if (r == 0 )
124
- then do dEnt <- peek ptr_dEnt
125
- if (dEnt == nullPtr)
126
- then return Nothing
127
- else do
128
- res <- f (DirEnt dEnt)
129
- c_freeDirEnt dEnt
130
- return (Just res)
131
- else do errno <- getErrno
132
- if (errno == eINTR) then loop ptr_dEnt else do
133
- let (Errno eo) = errno
134
- if (eo == 0 )
135
- then return Nothing
136
- else throwErrno " readDirStream"
118
+ readDirStreamWith f dstream = alloca
119
+ (\ ptr_dEnt -> readDirStreamWithPtr ptr_dEnt f dstream)
120
+
121
+ -- | A version of 'readDirStreamWith' that takes a pre-allocated pointer in
122
+ -- addition to the other arguments. This pointer is used to store the pointer
123
+ -- to the next directory entry, if there is any. This function is intended for
124
+ -- usecases where you need to read a lot of directory entries and want to
125
+ -- reuse the pointer for each of them. Using for example 'readDirStream' or
126
+ -- 'readDirStreamWith' in this scenario would allocate a new pointer for each
127
+ -- call of these functions.
128
+ --
129
+ -- __NOTE__: You are responsible for releasing the pointer after you are done.
130
+ readDirStreamWithPtr :: Ptr DirEnt -> (DirEnt -> IO a ) -> DirStream -> IO (Maybe a )
131
+ readDirStreamWithPtr ptr_dEnt f dstream@ (DirStream dirp) = do
132
+ resetErrno
133
+ r <- c_readdir dirp (castPtr ptr_dEnt)
134
+ if (r == 0 )
135
+ then do dEnt@ (DirEnt dEntPtr) <- peek ptr_dEnt
136
+ if (dEntPtr == nullPtr)
137
+ then return Nothing
138
+ else do
139
+ res <- f dEnt
140
+ c_freeDirEnt dEntPtr
141
+ return (Just res)
142
+ else do errno <- getErrno
143
+ if (errno == eINTR)
144
+ then readDirStreamWithPtr ptr_dEnt f dstream
145
+ else do
146
+ let (Errno eo) = errno
147
+ if (eo == 0 )
148
+ then return Nothing
149
+ else throwErrno " readDirStream"
137
150
138
151
-- traversing directories
139
152
foreign import ccall unsafe " __hscore_readdir"
0 commit comments