    module Network.HTTP.Semantics.File (
        -- * Position read
        PositionRead,
        PositionReadMaker,
        Sentinel (..),
        defaultPositionReadMaker,
    ) where

    import System.IO

    import Network.ByteOrder
    import Network.HTTP.Semantics

    -- | Position read for files.
    type PositionRead = FileOffset -> ByteCount -> Buffer -> IO ByteCount

    -- | Making a position read and its closer.
    type PositionReadMaker = FilePath -> IO (PositionRead, Sentinel)

    --- | Manipulating a file resource.
    data Sentinel
        = -- | Closing a file resource. Its refresher is automatiaclly generated by
          --   the internal timer.
          Closer (IO ())
        | -- | Refreshing a file resource while reading.
          --   Closing the file must be done by its own timer or something.
          Refresher (IO ())

    -- | Position read based on 'Handle'.
    defaultPositionReadMaker :: PositionReadMaker
    defaultPositionReadMaker :: PositionReadMaker
    defaultPositionReadMaker FilePath
    file = do
        hdl <- FilePath -> IOMode -> IO Handle
    openBinaryFile FilePath
    file IOMode
    ReadMode
        return (pread hdl, Closer $ hClose hdl)
      where
        pread :: Handle -> PositionRead
        pread :: Handle -> PositionRead
    pread Handle
    hdl FileOffset
    off FileOffset
    bytes Buffer
    buf = do
            Handle -> SeekMode -> Integer -> IO ()
    hSeek Handle
    hdl SeekMode
    AbsoluteSeek (Integer -> IO ()) -> Integer -> IO ()
    forall a b. (a -> b) -> a -> b
    $ FileOffset -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral FileOffset
    off
            Int -> FileOffset
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> FileOffset) -> IO Int -> IO FileOffset
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Handle -> Buffer -> Int -> IO Int
    forall a. Handle -> Ptr a -> Int -> IO Int
    hGetBufSome Handle
    hdl Buffer
    buf (FileOffset -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral FileOffset
    bytes)