{-# LINE 1 "src/SendFile/Internal.hsc" #-}
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
{-# LINE 2 "src/SendFile/Internal.hsc" #-}
module SendFile.Internal (
    fileSize,
    sendFile,
    sendFile',
    sendFileMode
    ) where

import System.IO (
    Handle(..),
    IOMode(..),
    SeekMode(..),
    hFileSize,
    hFlush,
    hSeek,
    withBinaryFile
    )


{-# LINE 42 "src/SendFile/Internal.hsc" #-}


{-# LINE 44 "src/SendFile/Internal.hsc" #-}
import Foreign.C
import GHC.IOBase (haFD)
import GHC.Handle (withHandle_)

sendFileMode :: String
sendFileMode = "LINUX_SENDFILE"

sendFile' :: Handle -> FilePath -> Int -> Int -> IO ()
sendFile' outh infp offset count = do
    -- flush outh before handing it sendFile
    hFlush outh
    withHandle_ "sendFile" outh $ \outh' -> do 
    withCString infp $ \in_fp -> do
    let out_fd = haFD outh'
    err <- c_sendfile_linux out_fd in_fp (fromIntegral offset) (fromIntegral count)
    if err == 0
        then return ()
        else fail ("errno " ++ show err)
    
foreign import ccall
    c_sendfile_linux :: CInt -> CString -> CLong -> CLong -> IO Int

{-# LINE 66 "src/SendFile/Internal.hsc" #-}


{-# LINE 83 "src/SendFile/Internal.hsc" #-}

fileSize :: FilePath -> IO Int
fileSize fp = fmap fromIntegral (withBinaryFile fp ReadMode hFileSize)

sendFile :: Handle -> FilePath -> IO ()
sendFile outh infp = do
    count <- fileSize infp
    sendFile' outh infp 0 count