{-# LANGUAGE CPP, RecordWildCards #-}
module Network.Socket.SendFile.Internal (
sendFile,
sendFileIterWith,
sendFile',
sendFileIterWith',
sendFile'',
sendFileIterWith'',
unsafeSendFile,
unsafeSendFileIterWith,
unsafeSendFile',
unsafeSendFileIterWith',
sendFileMode,
) where
#if defined(PORTABLE_SENDFILE)
import Network.Socket.SendFile.Portable (sendFileMode, sendFile'', sendFileIterWith'', unsafeSendFile'', unsafeSendFileIterWith'')
#else
import Network.Socket (fdSocket)
import Network.Socket.SendFile.Util
import System.Posix.Types (Fd(..))
#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__ >= 611
import GHC.IO.Handle.Internals (withHandle_)
import GHC.IO.Handle.Types (Handle__(..))
import qualified GHC.IO.FD as FD
import GHC.IO.Exception
import Data.Typeable (cast)
#else
import GHC.IOBase
import GHC.Handle hiding (fdToHandle)
import qualified GHC.Handle
#endif
#endif
#endif
import Network.Socket (Socket)
import Network.Socket.SendFile.Iter (Iter(..))
import System.IO (Handle, IOMode(..), hFileSize, hFlush, withBinaryFile)
#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__ >= 611
import System.IO.Error
#endif
#endif
#if defined(WIN32_SENDFILE)
import Network.Socket.SendFile.Win32 (_sendFile, sendFileIter)
sendFileMode :: String
sendFileMode = "WIN32_SENDFILE"
#endif
#if defined(LINUX_SENDFILE)
import Network.Socket.SendFile.Linux (_sendFile, sendFileIter)
sendFileMode :: String
sendFileMode = "LINUX_SENDFILE"
#endif
#if defined(FREEBSD_SENDFILE)
import Network.Socket.SendFile.FreeBSD (_sendFile, sendFileIter)
sendFileMode :: String
sendFileMode = "FREEBSD_SENDFILE"
#endif
#if defined(DARWIN_SENDFILE)
import Network.Socket.SendFile.Darwin (_sendFile, sendFileIter)
sendFileMode :: String
sendFileMode = "DARWIN_SENDFILE"
#endif
#if defined(PORTABLE_SENDFILE)
#else
sendFile'' :: Socket -> Handle -> Integer -> Integer -> IO ()
sendFile'' outs inh off count =
#if MIN_VERSION_network(3,0,0)
do out_fd <- Fd <$> (fdSocket outs)
#else
do let out_fd = Fd (fdSocket outs)
#endif
withFd inh $ \in_fd ->
wrapSendFile' (\out_fd_ in_fd_ _blockSize_ off_ count_ -> _sendFile out_fd_ in_fd_ off_ count_)
out_fd in_fd count off count
sendFileIterWith'' :: (IO Iter -> IO a) -> Socket -> Handle -> Integer -> Integer -> Integer -> IO a
sendFileIterWith'' stepper outs inp blockSize off count =
#if MIN_VERSION_network(3,0,0)
do out_fd <- Fd <$> (fdSocket outs)
#else
do let out_fd = Fd (fdSocket outs)
#endif
withFd inp $ \in_fd ->
stepper $ wrapSendFile' sendFileIter out_fd in_fd blockSize off count
unsafeSendFile'' :: Handle -> Handle -> Integer -> Integer -> IO ()
unsafeSendFile'' outp inp off count =
do hFlush outp
withFd outp $ \out_fd ->
withFd inp $ \in_fd ->
wrapSendFile' (\out_fd_ in_fd_ _blockSize_ off_ count_ -> _sendFile out_fd_ in_fd_ off_ count_)
out_fd in_fd count off count
unsafeSendFileIterWith'' :: (IO Iter -> IO a) -> Handle -> Handle -> Integer -> Integer -> Integer -> IO a
unsafeSendFileIterWith'' stepper outp inp blockSize off count =
do hFlush outp
withFd outp $ \out_fd ->
withFd inp $ \in_fd ->
stepper $ wrapSendFile' sendFileIter out_fd in_fd blockSize off count
withFd :: Handle -> (Fd -> IO a) -> IO a
#ifdef __GLASGOW_HASKELL__
#if __GLASGOW_HASKELL__ >= 611
withFd h f = withHandle_ "withFd" h $ \ Handle__{..} -> do
case cast haDevice of
Nothing -> ioError (ioeSetErrorString (mkIOError IllegalOperation
"withFd" (Just h) Nothing)
"handle is not a file descriptor")
Just fd -> f (Fd (fromIntegral (FD.fdFD fd)))
#else
withFd h f =
withHandle_ "withFd" h $ \ h_ ->
f (Fd (fromIntegral (haFD h_)))
#endif
#endif
#endif
sendFile :: Socket -> FilePath -> IO ()
sendFile outs infp =
withBinaryFile infp ReadMode $ \inp -> do
count <- hFileSize inp
sendFile'' outs inp 0 count
sendFileIterWith :: (IO Iter -> IO a) -> Socket -> FilePath -> Integer -> IO a
sendFileIterWith stepper outs infp blockSize =
withBinaryFile infp ReadMode $ \inp -> do
count <- hFileSize inp
sendFileIterWith'' stepper outs inp blockSize 0 count
sendFile' :: Socket -> FilePath -> Integer -> Integer -> IO ()
sendFile' outs infp offset count =
withBinaryFile infp ReadMode $ \inp ->
sendFile'' outs inp offset count
sendFileIterWith' :: (IO Iter -> IO a) -> Socket -> FilePath -> Integer -> Integer -> Integer -> IO a
sendFileIterWith' stepper outs infp blockSize offset count =
withBinaryFile infp ReadMode $ \inp ->
sendFileIterWith'' stepper outs inp blockSize offset count
unsafeSendFile :: Handle -> FilePath -> IO ()
unsafeSendFile outp infp =
withBinaryFile infp ReadMode $ \inp -> do
count <- hFileSize inp
unsafeSendFile'' outp inp 0 count
unsafeSendFileIterWith :: (IO Iter -> IO a) -> Handle -> FilePath -> Integer -> IO a
unsafeSendFileIterWith stepper outp infp blockSize =
withBinaryFile infp ReadMode $ \inp -> do
count <- hFileSize inp
unsafeSendFileIterWith'' stepper outp inp blockSize 0 count
unsafeSendFile'
:: Handle
-> FilePath
-> Integer
-> Integer
-> IO ()
unsafeSendFile' outp infp offset count =
withBinaryFile infp ReadMode $ \inp -> do
unsafeSendFile'' outp inp offset count
unsafeSendFileIterWith'
:: (IO Iter -> IO a)
-> Handle
-> FilePath
-> Integer
-> Integer
-> Integer
-> IO a
unsafeSendFileIterWith' stepper outp infp blockSize offset count =
withBinaryFile infp ReadMode $ \inp -> do
unsafeSendFileIterWith'' stepper outp inp blockSize offset count