{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Mismi.S3.Internal.Binary (
slurpHandle
, slurpHandleWithBuffer
) where
import Control.Monad.IO.Class (MonadIO, liftIO)
import qualified Data.ByteString as BS
import Data.Conduit (ConduitT, yield)
import System.IO (Handle, hSeek, SeekMode (..))
slurpHandle :: MonadIO m
=> Handle
-> Integer
-> Maybe Integer
-> ConduitT () BS.ByteString m ()
slurpHandle handle offset count' =
slurpHandleWithBuffer handle offset count' (1024 * 1024)
slurpHandleWithBuffer :: MonadIO m
=> Handle
-> Integer
-> Maybe Integer
-> Int
-> ConduitT () BS.ByteString m ()
slurpHandleWithBuffer handle offset count' buffer = do
liftIO $ hSeek handle AbsoluteSeek offset
case count' of
Nothing -> pullUnlimited
Just c -> pullLimited (fromInteger c)
where
pullUnlimited = do
bs <- liftIO $ BS.hGetSome handle buffer
if BS.null bs
then return ()
else do
yield bs
pullUnlimited
pullLimited c = do
bs <- liftIO $ BS.hGetSome handle (min c $ buffer)
let c' = c - BS.length bs
if BS.null bs
then return ()
else do
yield bs
pullLimited c'