@@ -92,9 +92,11 @@ import Streamly.Internal.Data.Unfold (Step(..))
9292import Streamly.Internal.Data.Unfold.Type (Unfold(..))
9393import System.FilePath ((</>))
9494#if (defined linux_HOST_OS) || (defined darwin_HOST_OS)
95−import System.Posix (openDirStream, readDirStream, closeDirStream)
95+import System.Posix (DirStream, openDirStream, readDirStream, closeDirStream)
9696#elif defined(mingw32_HOST_OS)
9797import qualified System.Win32 as Win32
98+#else
99+#error "Unsupported architecture"
98100#endif
99101import qualified Streamly.Data.Unfold as UF
100102import qualified Streamly.Internal.Data.Unfold as UF (mapM2, bracketIO)
@@ -237,57 +239,57 @@ toStreamWithBufferOf chunkSize h = AS.concat $ toChunksWithBufferOf chunkSize h
237239
238240-- XXX exception handling
239241
240−-- | Read a directory emitting a stream with names of the children. Filter out
241−-- "." and ".." entries.
242−--
243−-- /Internal/
244−--
245−{-# INLINE reader #-}
246−reader :: (MonadIO m, MonadCatch m) => Unfold m FilePath FilePath
247−reader =
248242#if (defined linux_HOST_OS) || (defined darwin_HOST_OS)
249− UF.bracketIO openDirStream closeDirStream childOf
250− & UF.filter (\x -> x /= "." && x /= "..")
243+{-# INLINE streamReader #-}
244+streamReader :: MonadIO m => Unfold m DirStream FilePath
245+streamReader = Unfold step return
251246
252247 where
253248
254− {-# INLINABLE childOf #-}
255− childOf = Unfold step inject
256−
257− where
249+ step strm = do
250+ -- XXX Use readDirStreamMaybe
251+ file <- liftIO $ readDirStream strm
252+ case file of
253+ [] -> return Stop
254+ _ -> return $ Yield file strm
258255
259− inject = return
260−
261− step strm = do
262− file <- liftIO $ readDirStream strm
263− case file of
264− [] -> return Stop
265− _ -> return $ Yield file strm
266256#elif defined(mingw32_HOST_OS)
267− UF.bracketIO
268− Win32.findFirstFile
269− (\(h, _) -> liftIO $ Win32.findClose h)
270− childOf
271− & UF.filter (\x -> x /= "." && x /= "..")
257+openDirStream :: String -> IO (Win32.HANDLE, Win32.FindData)
258+openDirStream = Win32.findFirstFile
272259
273− where
260+closeDirStream :: (Win32.HANDLE, Win32.FindData) -> IO ()
261+closeDirStream (h, _) = Win32.findClose h
274262
275− {-# INLINABLE childOf #-}
276− childOf = Unfold step inject
263+{-# INLINE streamReader #-}
264+streamReader :: MonadIO m => Unfold m (Win32.HANDLE, Win32.FindData) FilePath
265+streamReader = Unfold step return
277266
278− where
279−
280− inject = return
267+ where
281268
282− step (h, fdat) = do
283− more <- liftIO $ Win32.findNextFile h fdat
284− if more
285− then do
286− file <- liftIO $ Win32.getFindDataFileName fdat
287− return $ Yield file (h, fdat)
288− else return Stop
269+ step (h, fdat) = do
270+ more <- liftIO $ Win32.findNextFile h fdat
271+ if more
272+ then do
273+ file <- liftIO $ Win32.getFindDataFileName fdat
274+ return $ Yield file (h, fdat)
275+ else return Stop
289276#endif
290277
278+-- | Read a directory emitting a stream with names of the children. Filter out
279+-- "." and ".." entries.
280+--
281+-- /Internal/
282+--
283+{-# INLINE reader #-}
284+reader :: (MonadIO m, MonadCatch m) => Unfold m FilePath FilePath
285+reader =
286+-- XXX Instead of using bracketIO for each iteration of the loop we should
287+-- instead yield a buffer of dir entries in each iteration and then use an
288+-- unfold and concat to flatten those entries. That should improve the
289+-- performance.
290+ UF.bracketIO openDirStream closeDirStream streamReader
291+ & UF.filter (\x -> x /= "." && x /= "..")
292+
291293-- XXX We can use a more general mechanism to filter the contents of a
292294-- directory. We can just stat each child and pass on the stat information. We
293295-- can then use that info to do a general filtering. "find" like filters can be