-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A portable sendfile library
--   
--   A library which exposes zero-copy sendfile functionality in a portable
--   way. If a platform does not support sendfile, a fallback
--   implementation in haskell is provided.
--   
--   Currently supported platforms: Windows 2000+ (Native), Linux 2.6+
--   (Native), FreeBSD (Native), OS-X 10.5+ (Native), Everything else
--   (Portable Haskell code).
@package sendfile
@version 0.7.11.6

module Network.Socket.SendFile.Iter

-- | An iteratee for sendfile
--   
--   In general, a whole file is not sent by a single call to sendfile(),
--   but a series of calls which send successive pieces.
--   
--   The high-level API in this sendfile library has calls which will send
--   the entire file (or an entire requested offset+length), before
--   returning.
--   
--   However, there are instances where you want to be a bit more involved
--   in the sending loop. For example, if you want to tickle a timeout
--   after each chunk is sent or update a progress bar.
--   
--   The <a>Iter</a> type gives you that power with out requiring you to
--   manage all the low-level details of the sendfile loop. The interface
--   is simple and consistant across all platforms.
--   
--   A call to sendfile() can result in three different states:
--   
--   <ol>
--   <li>the requested number of bytes for that iteration was sent
--   successfully, there are more bytes left to send.</li>
--   <li>some (possibly 0) bytes were sent, but the file descriptor would
--   now block if more bytes were written. There are more bytes left to
--   send.</li>
--   <li>All the bytes were sent, and there is nothing left to send.</li>
--   </ol>
--   
--   We handle these three cases by using a type with three constructors:
--   
--   <pre>
--   data Iter
--       = Sent       Int64    (IO Iter)
--       | WouldBlock Int64 Fd (IO Iter)
--       | Done       Int64             
--   </pre>
--   
--   All three constructors provide an <a>Int64</a> which represents the
--   number of bytes sent for that particular iteration. (Not the total
--   byte count).
--   
--   The <a>Sent</a> and <a>WouldBlock</a> constructors provide <a>IO</a>
--   <a>Iter</a> as their final argument. Running this IO action will send
--   the next block of data.
--   
--   The <a>WouldBlock</a> constructor also provides the <a>Fd</a> for the
--   output socket. You should not send anymore data until the <a>Fd</a>
--   would not block. The easiest way to do that is to use
--   <a>threadWaitWrite</a> to suspend the thread until the <a>Fd</a> is
--   available.
--   
--   A very simple function to drive the Iter might look like:
--   
--   <pre>
--   runIter :: IO Iter -&gt; IO ()
--   runIter iter =
--      do r &lt;- iter
--         case r of
--           (Done _n)      -&gt; return ()
--           (Sent _n cont) -&gt; runIter cont
--           (WouldBlock _n fd cont) -&gt; 
--               do threadWaitWrite fd
--                  runIter cont
--   </pre>
--   
--   You would use it as the first argument to a *IterWith function, e.g.
--   
--   <pre>
--   sendFileIterWith runIter outputSocket "/path/to/file" 2^16 
--   </pre>
--   
--   The <a>runIter</a> function provided by this module is similar, but
--   also returns the total number of bytes sent.
--   
--   NOTE: You must not use the <a>Fd</a> or the <a>IO</a> <a>Iter</a>
--   after the call to *IterWith has returned. When the *IterWith functions
--   return, the file descriptors may be closed due to finalizers running.
data Iter

-- | number of bytes sent this pass and a continuation to send more
Sent :: Int64 -> IO Iter -> Iter

-- | number of bytes sent, Fd that blocked, continuation to send more.
--   NOTE: The Fd should not be used outside the running of the Iter as it
--   may be freed when the Iter is done
WouldBlock :: Int64 -> Fd -> IO Iter -> Iter

-- | number of bytes sent, no more to send
Done :: Int64 -> Iter

-- | A simple function to drive the *IterWith functions. It returns the
--   total number of bytes sent.
runIter :: IO Iter -> IO Int64

module Network.Socket.SendFile.Portable
sendFile :: Socket -> FilePath -> IO ()
sendFileIterWith :: (IO Iter -> IO a) -> Socket -> FilePath -> Integer -> IO a
sendFile' :: Socket -> FilePath -> Integer -> Integer -> IO ()
sendFileIterWith' :: (IO Iter -> IO a) -> Socket -> FilePath -> Integer -> Integer -> Integer -> IO a
sendFile'' :: Socket -> Handle -> Integer -> Integer -> IO ()
sendFileIterWith'' :: (IO Iter -> IO a) -> Socket -> Handle -> Integer -> Integer -> Integer -> IO a
unsafeSendFile :: Handle -> FilePath -> IO ()
unsafeSendFileIterWith :: (IO Iter -> IO a) -> Handle -> FilePath -> Integer -> IO a
unsafeSendFile' :: Handle -> FilePath -> Integer -> Integer -> IO ()
unsafeSendFile'' :: Handle -> Handle -> Integer -> Integer -> IO ()
unsafeSendFileIterWith' :: (IO Iter -> IO a) -> Handle -> FilePath -> Integer -> Integer -> Integer -> IO a
unsafeSendFileIterWith'' :: (IO Iter -> IO a) -> Handle -> Handle -> Integer -> Integer -> Integer -> IO a
sendFileMode :: String


-- | A cross-platform wrapper for sendfile -- this implements an available
--   operating-system call if supported, otherwise it falls back to a
--   portable haskell implementation.
--   
--   Two interfaces are provided for both the unsafe and safe sets of
--   functions. The first interface accepts an output socket/handle and the
--   path of the file you want to send; sendFile and unsafeSendFile
--   comprise this interface. The second interface accepts an output
--   socket/handle, a handle to the file you want to send, an offset, and
--   the number of bytes you want to send; sendFile' and unsafeSendFile'
--   comprise this interface.
--   
--   For consistent read/write behavior with either sendFile' or
--   unsafeSendFile', the input handle should be opened in Binary mode
--   rather than Text mode.
module Network.Socket.SendFile

-- | The length (in bytes) which should be sent
type ByteCount = Integer

-- | The file offset (in bytes) to start from
type Offset = Integer

-- | An iteratee for sendfile
--   
--   In general, a whole file is not sent by a single call to sendfile(),
--   but a series of calls which send successive pieces.
--   
--   The high-level API in this sendfile library has calls which will send
--   the entire file (or an entire requested offset+length), before
--   returning.
--   
--   However, there are instances where you want to be a bit more involved
--   in the sending loop. For example, if you want to tickle a timeout
--   after each chunk is sent or update a progress bar.
--   
--   The <a>Iter</a> type gives you that power with out requiring you to
--   manage all the low-level details of the sendfile loop. The interface
--   is simple and consistant across all platforms.
--   
--   A call to sendfile() can result in three different states:
--   
--   <ol>
--   <li>the requested number of bytes for that iteration was sent
--   successfully, there are more bytes left to send.</li>
--   <li>some (possibly 0) bytes were sent, but the file descriptor would
--   now block if more bytes were written. There are more bytes left to
--   send.</li>
--   <li>All the bytes were sent, and there is nothing left to send.</li>
--   </ol>
--   
--   We handle these three cases by using a type with three constructors:
--   
--   <pre>
--   data Iter
--       = Sent       Int64    (IO Iter)
--       | WouldBlock Int64 Fd (IO Iter)
--       | Done       Int64             
--   </pre>
--   
--   All three constructors provide an <a>Int64</a> which represents the
--   number of bytes sent for that particular iteration. (Not the total
--   byte count).
--   
--   The <a>Sent</a> and <a>WouldBlock</a> constructors provide <a>IO</a>
--   <a>Iter</a> as their final argument. Running this IO action will send
--   the next block of data.
--   
--   The <a>WouldBlock</a> constructor also provides the <a>Fd</a> for the
--   output socket. You should not send anymore data until the <a>Fd</a>
--   would not block. The easiest way to do that is to use
--   <a>threadWaitWrite</a> to suspend the thread until the <a>Fd</a> is
--   available.
--   
--   A very simple function to drive the Iter might look like:
--   
--   <pre>
--   runIter :: IO Iter -&gt; IO ()
--   runIter iter =
--      do r &lt;- iter
--         case r of
--           (Done _n)      -&gt; return ()
--           (Sent _n cont) -&gt; runIter cont
--           (WouldBlock _n fd cont) -&gt; 
--               do threadWaitWrite fd
--                  runIter cont
--   </pre>
--   
--   You would use it as the first argument to a *IterWith function, e.g.
--   
--   <pre>
--   sendFileIterWith runIter outputSocket "/path/to/file" 2^16 
--   </pre>
--   
--   The <a>runIter</a> function provided by this module is similar, but
--   also returns the total number of bytes sent.
--   
--   NOTE: You must not use the <a>Fd</a> or the <a>IO</a> <a>Iter</a>
--   after the call to *IterWith has returned. When the *IterWith functions
--   return, the file descriptors may be closed due to finalizers running.
data Iter

-- | number of bytes sent this pass and a continuation to send more
Sent :: Int64 -> IO Iter -> Iter

-- | number of bytes sent, Fd that blocked, continuation to send more.
--   NOTE: The Fd should not be used outside the running of the Iter as it
--   may be freed when the Iter is done
WouldBlock :: Int64 -> Fd -> IO Iter -> Iter

-- | number of bytes sent, no more to send
Done :: Int64 -> Iter

-- | A simple function to drive the *IterWith functions. It returns the
--   total number of bytes sent.
runIter :: IO Iter -> IO Int64

-- | The simplest interface. Simply give it an output <a>Socket</a> and the
--   <a>FilePath</a> to the input file.
sendFile :: Socket -> FilePath -> IO ()

-- | The simplest interface. Simply give it an output <a>Socket</a> and the
--   <a>FilePath</a> to the input file.
--   
--   This variant takes a function to drive the iteration loop. See
--   <a>Iter</a> for more information.
sendFileIterWith :: (IO Iter -> IO a) -> Socket -> FilePath -> ByteCount -> IO a

-- | A more powerful interface than sendFile which accepts a starting
--   offset, and the bytecount to send; the offset and the count must be a
--   positive integer. The initial position of the input file handle
--   matters not since the offset is absolute, and the final position may
--   be different depending on the platform -- no assumptions can be made.
sendFile' :: Socket -> FilePath -> Offset -> ByteCount -> IO ()

-- | A more powerful interface than sendFile which accepts a starting
--   offset, and the bytecount to send; the offset and the count must be a
--   positive integer. The initial position of the input file handle
--   matters not since the offset is absolute, and the final position may
--   be different depending on the platform -- no assumptions can be made.
--   
--   This variant takes a function to drive the iteration loop. See
--   <a>Iter</a> for more information.
sendFileIterWith' :: (IO Iter -> IO a) -> Socket -> FilePath -> ByteCount -> Offset -> ByteCount -> IO a

-- | The unsafe version of sendFile which accepts a <a>Handle</a> instead
--   of a <a>Socket</a> for the output. It will flush the output handle
--   before sending any file data.
unsafeSendFile :: Handle -> FilePath -> IO ()

-- | The unsafe version of sendFile which accepts a <a>Handle</a> instead
--   of a <a>Socket</a> for the output. It will flush the output handle
--   before sending any file data.
--   
--   This variant takes a function to drive the iteration loop. See
--   <a>Iter</a> for more information.
unsafeSendFileIterWith :: (IO Iter -> IO a) -> Handle -> FilePath -> ByteCount -> IO a

-- | The unsafe version of sendFile' which accepts a <a>Handle</a> instead
--   of a <a>Socket</a> for the output. It will flush the output handle
--   before sending any file data.
unsafeSendFile' :: Handle -> FilePath -> Offset -> ByteCount -> IO ()

-- | The unsafe version of sendFile' which accepts a <a>Handle</a> instead
--   of a <a>Socket</a> for the output. It will flush the output handle
--   before sending any file data.
--   
--   This variant takes a function to drive the iteration loop. See
--   <a>Iter</a> for more information.
unsafeSendFileIterWith' :: (IO Iter -> IO a) -> Handle -> FilePath -> ByteCount -> Offset -> ByteCount -> IO a

-- | Returns the mode that sendfile was compiled with. Mainly for debugging
--   use. Possible values are <tt>WIN32_SENDFILE</tt>,
--   <tt>LINUX_SENDFILE</tt>, <tt>FREEBSD_SENDFILE</tt>,
--   <tt>DARWIN_SENDFILE</tt>, and <tt>PORTABLE_SENDFILE</tt>.
sendFileMode :: String


-- | Handle-based versions of some of the functions exported by
--   Network.Socket.SendFile.
module Network.Socket.SendFile.Handle

-- | The length (in bytes) which should be sent
type ByteCount = Integer

-- | The file offset (in bytes) to start from
type Offset = Integer

-- | An iteratee for sendfile
--   
--   In general, a whole file is not sent by a single call to sendfile(),
--   but a series of calls which send successive pieces.
--   
--   The high-level API in this sendfile library has calls which will send
--   the entire file (or an entire requested offset+length), before
--   returning.
--   
--   However, there are instances where you want to be a bit more involved
--   in the sending loop. For example, if you want to tickle a timeout
--   after each chunk is sent or update a progress bar.
--   
--   The <a>Iter</a> type gives you that power with out requiring you to
--   manage all the low-level details of the sendfile loop. The interface
--   is simple and consistant across all platforms.
--   
--   A call to sendfile() can result in three different states:
--   
--   <ol>
--   <li>the requested number of bytes for that iteration was sent
--   successfully, there are more bytes left to send.</li>
--   <li>some (possibly 0) bytes were sent, but the file descriptor would
--   now block if more bytes were written. There are more bytes left to
--   send.</li>
--   <li>All the bytes were sent, and there is nothing left to send.</li>
--   </ol>
--   
--   We handle these three cases by using a type with three constructors:
--   
--   <pre>
--   data Iter
--       = Sent       Int64    (IO Iter)
--       | WouldBlock Int64 Fd (IO Iter)
--       | Done       Int64             
--   </pre>
--   
--   All three constructors provide an <a>Int64</a> which represents the
--   number of bytes sent for that particular iteration. (Not the total
--   byte count).
--   
--   The <a>Sent</a> and <a>WouldBlock</a> constructors provide <a>IO</a>
--   <a>Iter</a> as their final argument. Running this IO action will send
--   the next block of data.
--   
--   The <a>WouldBlock</a> constructor also provides the <a>Fd</a> for the
--   output socket. You should not send anymore data until the <a>Fd</a>
--   would not block. The easiest way to do that is to use
--   <a>threadWaitWrite</a> to suspend the thread until the <a>Fd</a> is
--   available.
--   
--   A very simple function to drive the Iter might look like:
--   
--   <pre>
--   runIter :: IO Iter -&gt; IO ()
--   runIter iter =
--      do r &lt;- iter
--         case r of
--           (Done _n)      -&gt; return ()
--           (Sent _n cont) -&gt; runIter cont
--           (WouldBlock _n fd cont) -&gt; 
--               do threadWaitWrite fd
--                  runIter cont
--   </pre>
--   
--   You would use it as the first argument to a *IterWith function, e.g.
--   
--   <pre>
--   sendFileIterWith runIter outputSocket "/path/to/file" 2^16 
--   </pre>
--   
--   The <a>runIter</a> function provided by this module is similar, but
--   also returns the total number of bytes sent.
--   
--   NOTE: You must not use the <a>Fd</a> or the <a>IO</a> <a>Iter</a>
--   after the call to *IterWith has returned. When the *IterWith functions
--   return, the file descriptors may be closed due to finalizers running.
data Iter

-- | number of bytes sent this pass and a continuation to send more
Sent :: Int64 -> IO Iter -> Iter

-- | number of bytes sent, Fd that blocked, continuation to send more.
--   NOTE: The Fd should not be used outside the running of the Iter as it
--   may be freed when the Iter is done
WouldBlock :: Int64 -> Fd -> IO Iter -> Iter

-- | number of bytes sent, no more to send
Done :: Int64 -> Iter

-- | A simple function to drive the *IterWith functions. It returns the
--   total number of bytes sent.
runIter :: IO Iter -> IO Int64

-- | Simple sendFile - give it a Socket and a Handle, and it sends the
--   entire file through the socket.
--   
--   WARNING: This function will raise <a>IOError</a>
--   <tt>IllegalOperation</tt> if the <a>Handle</a> is not for an
--   <tt>Fd</tt>.
sendFile :: Socket -> Handle -> IO ()

-- | 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 <a>IOError</a>
--   <tt>IllegalOperation</tt> if the <a>Handle</a> is not for an
--   <tt>Fd</tt>.
sendFileIterWith :: (IO Iter -> IO a) -> Socket -> Handle -> ByteCount -> IO a

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

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