-- | Handle-based versions of some of the functions exported by
-- Network.Socket.SendFile. 
module Network.Socket.SendFile.Handle (
  ByteCount,
  Offset,
  Iter(..), runIter,
  -- * Handle-based sendFiles
  sendFile,
  sendFileIterWith,
  sendFile',
  sendFileIterWith'
  ) where

import System.IO (Handle, hFileSize)

import qualified Network.Socket.SendFile.Internal as Internal
import Network.Socket.SendFile.Iter (Iter(..), runIter)
import Network.Socket.SendFile (ByteCount, Offset)
import Network.Socket (Socket)

-- | Simple sendFile - give it a Socket and a Handle, and it sends the entire
-- file through the socket.
--
-- WARNING: This function will raise 'IOError' 'IllegalOperation'
-- if the 'Handle' is not for an 'Fd'.
sendFile
  :: Socket
  -> Handle
  -> IO ()
sendFile :: Socket -> Handle -> IO ()
sendFile Socket
outs Handle
inh = do
  Integer
count <- Handle -> IO Integer
hFileSize Handle
inh
  Socket -> Handle -> Integer -> Integer -> IO ()
Internal.sendFile'' Socket
outs Handle
inh Integer
0 Integer
count

-- | A more interactive version of sendFile, which accepts a callback function
-- in addition to the socket and handle.  The callback will be called for each
-- chunk of data the sendFileIterWith function acts on.
--
-- WARNING: This function will raise 'IOError' 'IllegalOperation'
-- if the 'Handle' is not for an 'Fd'.
sendFileIterWith
  :: (IO Iter -> IO a)
  -> Socket
  -> Handle
  -> ByteCount
  -> IO a
sendFileIterWith :: forall a. (IO Iter -> IO a) -> Socket -> Handle -> Integer -> IO a
sendFileIterWith IO Iter -> IO a
stepper Socket
outs Handle
inh Integer
blockSize = do
  Integer
count <- Handle -> IO Integer
hFileSize Handle
inh
  forall a.
(IO Iter -> IO a)
-> Socket -> Handle -> Integer -> Integer -> Integer -> IO a
Internal.sendFileIterWith'' IO Iter -> IO a
stepper Socket
outs Handle
inh Integer
blockSize Integer
0 Integer
count

-- | A sendFile that allows the user to send a subset of the file associated
-- with the given handle.
--
-- WARNING: This function will raise 'IOError' 'IllegalOperation'
-- if the 'Handle' is not for an 'Fd'.
sendFile'
  :: Socket
  -> Handle
  -> Offset
  -> ByteCount
  -> IO ()
sendFile' :: Socket -> Handle -> Integer -> Integer -> IO ()
sendFile' = Socket -> Handle -> Integer -> Integer -> IO ()
Internal.sendFile''

-- | A more powerful version of sendFileIterWith, which allows the sending of a
-- subset of the given file.
--
-- WARNING: This function will raise 'IOError' 'IllegalOperation'
-- if the 'Handle' is not for an 'Fd'.
sendFileIterWith'
  :: (IO Iter -> IO a)
  -> Socket
  -> Handle
  -> ByteCount
  -> Offset
  -> ByteCount
  -> IO a
sendFileIterWith' :: forall a.
(IO Iter -> IO a)
-> Socket -> Handle -> Integer -> Integer -> Integer -> IO a
sendFileIterWith' = forall a.
(IO Iter -> IO a)
-> Socket -> Handle -> Integer -> Integer -> Integer -> IO a
Internal.sendFileIterWith''