    {-# LANGUAGE CPP #-}
    -- | The standard @openFile@ call on Windows causing problematic file locking
    -- in some cases. This module provides a cross-platform file reading API
    -- without the file locking problems on Windows.
    --
    -- This module /always/ opens files in binary mode.
    --
    -- @readChunk@ will return an empty @ByteString@ on EOF.
    module Data.Streaming.FileRead
        ( ReadHandle
        , openFile
        , closeFile
        , readChunk
        ) where

    #if WINDOWS

    import System.Win32File

    #else

    import qualified System.IO as IO
    import qualified Data.ByteString as S
    import Data.ByteString.Lazy.Internal (defaultChunkSize)

    newtype ReadHandle = ReadHandle IO.Handle

    openFile :: FilePath -> IO ReadHandle
    openFile :: FilePath -> IO ReadHandle
    openFile fp :: FilePath
    fp = Handle -> ReadHandle
    ReadHandle (Handle -> ReadHandle) -> IO Handle -> IO ReadHandle
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` FilePath -> IOMode -> IO Handle
    IO.openBinaryFile FilePath
    fp IOMode
    IO.ReadMode

    closeFile :: ReadHandle -> IO ()
    closeFile :: ReadHandle -> IO ()
    closeFile (ReadHandle h :: Handle
    h) = Handle -> IO ()
    IO.hClose Handle
    h

    readChunk :: ReadHandle -> IO S.ByteString
    readChunk :: ReadHandle -> IO ByteString
    readChunk (ReadHandle h :: Handle
    h) = Handle -> Int -> IO ByteString
    S.hGetSome Handle
    h Int
    defaultChunkSize

    #endif