content: -- | Input and output streams for files.
  --
  -- The functions in this file use \"with*\" or \"bracket\" semantics, i.e. they
  -- open the supplied 'FilePath', run a user computation, and then close the
  -- file handle. If you need more control over the lifecycle of the underlying
  -- file descriptor resources, you are encouraged to use the functions from
  -- "System.IO.Streams.Handle" instead.
  module System.IO.Streams.File
    ( -- * File conversions
      withFileAsInput
    , withFileAsInputStartingAt
    , unsafeWithFileAsInputStartingAt
    , withFileAsOutput
    , withFileAsOutputExt
    ) where
  
  ------------------------------------------------------------------------------
  import           Control.Monad              (unless)
  import           Data.ByteString            (ByteString)
  import           Data.Int                   (Int64)
  import           System.IO                  (BufferMode (NoBuffering), IOMode (ReadMode, WriteMode), SeekMode (AbsoluteSeek), hSeek, hSetBuffering, withBinaryFile)
  ------------------------------------------------------------------------------
  import           System.IO.Streams.Handle   (handleToInputStream, handleToOutputStream)
  import           System.IO.Streams.Internal (InputStream, OutputStream)
  
  
  ------------------------------------------------------------------------------
  -- | @'withFileAsInput' name act@ opens the specified file in \"read mode\" and
  -- passes the resulting 'InputStream' to the computation @act@. The file will
  -- be closed on exit from @withFileAsInput@, whether by normal termination or
  -- by raising an exception.
  --
  -- If closing the file raises an exception, then /that/ exception will be
  -- raised by 'withFileAsInput' rather than any exception raised by @act@.
  withFileAsInput :: FilePath                          -- ^ file to open
                  -> (InputStream ByteString -> IO a)  -- ^ function to run
                  -> IO a
  withFileAsInput = withFileAsInputStartingAt 0
  
  
  ------------------------------------------------------------------------------
  -- | Like 'withFileAsInput', but seeks to the specified byte offset before
  -- attaching the given file descriptor to the 'InputStream'.
  withFileAsInputStartingAt
      :: Int64                             -- ^ starting index to seek to
      -> FilePath                          -- ^ file to open
      -> (InputStream ByteString -> IO a)  -- ^ function to run
      -> IO a
  withFileAsInputStartingAt idx fp m = withBinaryFile fp ReadMode go
    where
      go h = do
          unless (idx == 0) $ hSeek h AbsoluteSeek $ toInteger idx
          handleToInputStream h >>= m
  
  
  ------------------------------------------------------------------------------
  -- | Like 'withFileAsInputStartingAt', except that the 'ByteString' emitted by
  -- the created 'InputStream' may reuse its buffer. You may only use this
  -- function if you do not retain references to the generated bytestrings
  -- emitted.
  unsafeWithFileAsInputStartingAt
      :: Int64                             -- ^ starting index to seek to
      -> FilePath                          -- ^ file to open
      -> (InputStream ByteString -> IO a)  -- ^ function to run
      -> IO a
  unsafeWithFileAsInputStartingAt = withFileAsInputStartingAt
  
  
  ------------------------------------------------------------------------------
  -- | Open a file for writing and  attaches an 'OutputStream' for you to write
  -- to. The file will be closed on error or completion of your action.
  withFileAsOutput
      :: FilePath                           -- ^ file to open
      -> (OutputStream ByteString -> IO a)  -- ^ function to run
      -> IO a
  withFileAsOutput f = withFileAsOutputExt f WriteMode NoBuffering
  
  
  ------------------------------------------------------------------------------
  -- | Like 'withFileAsOutput', but allowing you control over the output file
  -- mode and buffering behaviour.
  withFileAsOutputExt
      :: FilePath                           -- ^ file to open
      -> IOMode                             -- ^ mode to write in
      -> BufferMode                         -- ^ should we buffer the output?
      -> (OutputStream ByteString -> IO a)  -- ^ function to run
      -> IO a
  withFileAsOutputExt fp iomode buffermode m = withBinaryFile fp iomode $ \h -> do
      hSetBuffering h buffermode
      handleToOutputStream h >>= m
  