{-# LANGUAGE CPP, RankNTypes #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- | /NOTE/ It is recommended to start using "Data.Conduit.Combinators" instead
-- of this module.
--
-- Functions for interacting with bytes.
--
-- For many purposes, it's recommended to use the conduit-combinators library,
-- which provides a more complete set of functions.
module Data.Conduit.Binary
    ( -- * Files and @Handle@s

      -- | Note that most of these functions live in the @MonadResource@ monad
      -- to ensure resource finalization even in the presence of exceptions. In
      -- order to run such code, you will need to use @runResourceT@.

      -- ** Sources
      CC.sourceFile
    , CC.sourceHandle
    , CC.sourceHandleUnsafe
    , CC.sourceIOHandle
    , sourceFileRange
    , sourceHandleRange
    , sourceHandleRangeWithBuffer
    , CC.withSourceFile
      -- ** Sinks
    , CC.sinkFile
    , CC.sinkFileCautious
    , CC.sinkTempFile
    , CC.sinkSystemTempFile
    , CC.sinkHandle
    , CC.sinkIOHandle
    , CC.sinkHandleBuilder
    , CC.sinkHandleFlush
    , CC.withSinkFile
    , CC.withSinkFileBuilder
    , CC.withSinkFileCautious
      -- ** Conduits
    , conduitFile
    , conduitHandle
      -- * Utilities
      -- ** Sources
    , sourceLbs
      -- ** Sinks
    , head
    , dropWhile
    , take
    , drop
    , sinkCacheLength
    , sinkLbs
    , mapM_
      -- *** Storable
    , sinkStorable
    , sinkStorableEx
      -- ** Conduits
    , isolate
    , takeWhile
    , Data.Conduit.Binary.lines
    ) where

import qualified Data.Conduit.Combinators as CC
import Prelude hiding (head, take, drop, takeWhile, dropWhile, mapM_)
import qualified Data.ByteString as S
import Data.ByteString.Unsafe (unsafeUseAsCString)
import qualified Data.ByteString.Lazy as L
import Data.Conduit
import Data.Conduit.List (sourceList, consume)
import Control.Exception (assert, finally)
import Control.Monad (unless)
import Control.Monad.IO.Class (liftIO, MonadIO)
import Control.Monad.Trans.Resource (allocate, release, MonadThrow (..))
import Control.Monad.Trans.Class (lift)
import qualified System.IO as IO
import Data.Word (Word8, Word64)
#if (__GLASGOW_HASKELL__ < 710)
import Control.Applicative ((<$>))
#endif
import System.Directory (getTemporaryDirectory, removeFile)
import Data.ByteString.Lazy.Internal (defaultChunkSize)
import Data.ByteString.Internal (ByteString (PS), accursedUnutterablePerformIO)
import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
import Foreign.ForeignPtr (touchForeignPtr)
import Foreign.Ptr (plusPtr, castPtr)
import Foreign.Storable (Storable, peek, sizeOf)
import Control.Monad.Trans.Resource (MonadResource)
import Control.Exception (Exception)
import Data.Typeable (Typeable)
import Foreign.Ptr (Ptr)
#ifndef ALLOW_UNALIGNED_ACCESS
import Foreign.Marshal (alloca, copyBytes)
#endif

-- | Stream the contents of a file as binary data, starting from a certain
-- offset and only consuming up to a certain number of bytes.
--
-- Since 0.3.0
sourceFileRange :: MonadResource m
                => FilePath
                -> Maybe Integer -- ^ Offset
                -> Maybe Integer -- ^ Maximum count
                -> ConduitT i S.ByteString m ()
sourceFileRange :: forall (m :: * -> *) i.
MonadResource m =>
FilePath
-> Maybe Integer -> Maybe Integer -> ConduitT i ByteString m ()
sourceFileRange FilePath
fp Maybe Integer
offset Maybe Integer
count = forall (m :: * -> *) a i o r.
MonadResource m =>
IO a -> (a -> IO ()) -> (a -> ConduitT i o m r) -> ConduitT i o m r
bracketP
    (FilePath -> IOMode -> IO Handle
IO.openBinaryFile FilePath
fp IOMode
IO.ReadMode)
    Handle -> IO ()
IO.hClose
    (\Handle
h -> forall (m :: * -> *) i.
MonadIO m =>
Handle
-> Maybe Integer -> Maybe Integer -> ConduitT i ByteString m ()
sourceHandleRange Handle
h Maybe Integer
offset Maybe Integer
count)

-- | Stream the contents of a handle as binary data, starting from a certain
-- offset and only consuming up to a certain number of bytes.
--
-- Since 1.0.8
sourceHandleRange :: MonadIO m
                  => IO.Handle
                  -> Maybe Integer -- ^ Offset
                  -> Maybe Integer -- ^ Maximum count
                  -> ConduitT i S.ByteString m ()
sourceHandleRange :: forall (m :: * -> *) i.
MonadIO m =>
Handle
-> Maybe Integer -> Maybe Integer -> ConduitT i ByteString m ()
sourceHandleRange Handle
handle Maybe Integer
offset Maybe Integer
count =
  forall (m :: * -> *) i.
MonadIO m =>
Handle
-> Maybe Integer
-> Maybe Integer
-> Int
-> ConduitT i ByteString m ()
sourceHandleRangeWithBuffer Handle
handle Maybe Integer
offset Maybe Integer
count Int
defaultChunkSize

-- | Stream the contents of a handle as binary data, starting from a certain
-- offset and only consuming up to a certain number of bytes. This function
-- consumes chunks as specified by the buffer size.
--
-- Since 1.1.8
sourceHandleRangeWithBuffer :: MonadIO m
                  => IO.Handle
                  -> Maybe Integer -- ^ Offset
                  -> Maybe Integer -- ^ Maximum count
                  -> Int -- ^ Buffer size
                  -> ConduitT i S.ByteString m ()
sourceHandleRangeWithBuffer :: forall (m :: * -> *) i.
MonadIO m =>
Handle
-> Maybe Integer
-> Maybe Integer
-> Int
-> ConduitT i ByteString m ()
sourceHandleRangeWithBuffer Handle
handle Maybe Integer
offset Maybe Integer
count Int
buffer = do
    case Maybe Integer
offset of
        Maybe Integer
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
        Just Integer
off -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Handle -> SeekMode -> Integer -> IO ()
IO.hSeek Handle
handle SeekMode
IO.AbsoluteSeek Integer
off
    case Maybe Integer
count of
        Maybe Integer
Nothing -> forall {i}. ConduitT i ByteString m ()
pullUnlimited
        Just Integer
c -> forall {m :: * -> *} {i}.
MonadIO m =>
Int -> ConduitT i ByteString m ()
pullLimited (forall a. Num a => Integer -> a
fromInteger Integer
c)
  where
    pullUnlimited :: ConduitT i ByteString m ()
pullUnlimited = do
        ByteString
bs <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Handle -> Int -> IO ByteString
S.hGetSome Handle
handle Int
buffer
        if ByteString -> Bool
S.null ByteString
bs
            then forall (m :: * -> *) a. Monad m => a -> m a
return ()
            else do
                forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ByteString
bs
                ConduitT i ByteString m ()
pullUnlimited

    pullLimited :: Int -> ConduitT i ByteString m ()
pullLimited Int
c = do
        ByteString
bs <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Handle -> Int -> IO ByteString
S.hGetSome Handle
handle (forall a. Ord a => a -> a -> a
min Int
c Int
buffer)
        let c' :: Int
c' = Int
c forall a. Num a => a -> a -> a
- ByteString -> Int
S.length ByteString
bs
        forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
c' forall a. Ord a => a -> a -> Bool
>= Int
0) forall a b. (a -> b) -> a -> b
$
            if ByteString -> Bool
S.null ByteString
bs
                then forall (m :: * -> *) a. Monad m => a -> m a
return ()
                else do
                    forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ByteString
bs
                    Int -> ConduitT i ByteString m ()
pullLimited Int
c'

-- | Stream the contents of the input to a file, and also send it along the
-- pipeline. Similar in concept to the Unix command @tee@.
--
-- Since 0.3.0
conduitFile :: MonadResource m
            => FilePath
            -> ConduitT S.ByteString S.ByteString m ()
conduitFile :: forall (m :: * -> *).
MonadResource m =>
FilePath -> ConduitT ByteString ByteString m ()
conduitFile FilePath
fp = forall (m :: * -> *) a i o r.
MonadResource m =>
IO a -> (a -> IO ()) -> (a -> ConduitT i o m r) -> ConduitT i o m r
bracketP
    (FilePath -> IOMode -> IO Handle
IO.openBinaryFile FilePath
fp IOMode
IO.WriteMode)
    Handle -> IO ()
IO.hClose
    forall (m :: * -> *).
MonadIO m =>
Handle -> ConduitT ByteString ByteString m ()
conduitHandle

-- | Stream the contents of the input to a @Handle@, and also send it along the
-- pipeline. Similar in concept to the Unix command @tee@. Like @sourceHandle@,
-- does not close the handle on completion. Related to: @conduitFile@.
--
-- Since 1.0.9
conduitHandle :: MonadIO m => IO.Handle -> ConduitT S.ByteString S.ByteString m ()
conduitHandle :: forall (m :: * -> *).
MonadIO m =>
Handle -> ConduitT ByteString ByteString m ()
conduitHandle Handle
h = forall (m :: * -> *) i o r.
Monad m =>
(i -> ConduitT i o m r) -> ConduitT i o m ()
awaitForever forall a b. (a -> b) -> a -> b
$ \ByteString
bs -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> ByteString -> IO ()
S.hPut Handle
h ByteString
bs) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ByteString
bs

-- | Ensure that only up to the given number of bytes are consumed by the inner
-- sink. Note that this does /not/ ensure that all of those bytes are in fact
-- consumed.
--
-- Since 0.3.0
isolate :: Monad m
        => Int
        -> ConduitT S.ByteString S.ByteString m ()
isolate :: forall (m :: * -> *).
Monad m =>
Int -> ConduitT ByteString ByteString m ()
isolate =
    forall (m :: * -> *).
Monad m =>
Int -> ConduitT ByteString ByteString m ()
loop
  where
    loop :: Int -> ConduitT ByteString ByteString m ()
loop Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return ()
    loop Int
count = do
        Maybe ByteString
mbs <- forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await
        case Maybe ByteString
mbs of
            Maybe ByteString
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
            Just ByteString
bs -> do
                let (ByteString
a, ByteString
b) = Int -> ByteString -> (ByteString, ByteString)
S.splitAt Int
count ByteString
bs
                case Int
count forall a. Num a => a -> a -> a
- ByteString -> Int
S.length ByteString
a of
                    Int
0 -> do
                        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (ByteString -> Bool
S.null ByteString
b) forall a b. (a -> b) -> a -> b
$ forall i o (m :: * -> *). i -> ConduitT i o m ()
leftover ByteString
b
                        forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ByteString
a
                    Int
count' -> forall a. (?callStack::CallStack) => Bool -> a -> a
assert (ByteString -> Bool
S.null ByteString
b) forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ByteString
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> ConduitT ByteString ByteString m ()
loop Int
count'

-- | Return the next byte from the stream, if available.
--
-- Since 0.3.0
head :: Monad m => ConduitT S.ByteString o m (Maybe Word8)
head :: forall (m :: * -> *) o.
Monad m =>
ConduitT ByteString o m (Maybe Word8)
head = do
    Maybe ByteString
mbs <- forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await
    case Maybe ByteString
mbs of
        Maybe ByteString
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
        Just ByteString
bs ->
            case ByteString -> Maybe (Word8, ByteString)
S.uncons ByteString
bs of
                Maybe (Word8, ByteString)
Nothing -> forall (m :: * -> *) o.
Monad m =>
ConduitT ByteString o m (Maybe Word8)
head
                Just (Word8
w, ByteString
bs') -> forall i o (m :: * -> *). i -> ConduitT i o m ()
leftover ByteString
bs' forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just Word8
w)

-- | Return all bytes while the predicate returns @True@.
--
-- Since 0.3.0
takeWhile :: Monad m => (Word8 -> Bool) -> ConduitT S.ByteString S.ByteString m ()
takeWhile :: forall (m :: * -> *).
Monad m =>
(Word8 -> Bool) -> ConduitT ByteString ByteString m ()
takeWhile Word8 -> Bool
p =
    ConduitT ByteString ByteString m ()
loop
  where
    loop :: ConduitT ByteString ByteString m ()
loop = forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. Monad m => a -> m a
return ()) ByteString -> ConduitT ByteString ByteString m ()
go

    go :: ByteString -> ConduitT ByteString ByteString m ()
go ByteString
bs
        | ByteString -> Bool
S.null ByteString
x = ConduitT ByteString ByteString m ()
next
        | Bool
otherwise = forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ByteString
x forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ConduitT ByteString ByteString m ()
next
      where
        next :: ConduitT ByteString ByteString m ()
next = if ByteString -> Bool
S.null ByteString
y then ConduitT ByteString ByteString m ()
loop else forall i o (m :: * -> *). i -> ConduitT i o m ()
leftover ByteString
y
        (ByteString
x, ByteString
y) = (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
S.span Word8 -> Bool
p ByteString
bs

-- | Ignore all bytes while the predicate returns @True@.
--
-- Since 0.3.0
dropWhile :: Monad m => (Word8 -> Bool) -> ConduitT S.ByteString o m ()
dropWhile :: forall (m :: * -> *) o.
Monad m =>
(Word8 -> Bool) -> ConduitT ByteString o m ()
dropWhile Word8 -> Bool
p =
    forall {o}. ConduitT ByteString o m ()
loop
  where
    loop :: ConduitT ByteString o m ()
loop = do
        Maybe ByteString
mbs <- forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await
        case (Word8 -> Bool) -> ByteString -> ByteString
S.dropWhile Word8 -> Bool
p forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe ByteString
mbs of
            Maybe ByteString
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
            Just ByteString
bs
                | ByteString -> Bool
S.null ByteString
bs -> ConduitT ByteString o m ()
loop
                | Bool
otherwise -> forall i o (m :: * -> *). i -> ConduitT i o m ()
leftover ByteString
bs

-- | Take the given number of bytes, if available.
--
-- Since 0.3.0
take :: Monad m => Int -> ConduitT S.ByteString o m L.ByteString
take :: forall (m :: * -> *) o.
Monad m =>
Int -> ConduitT ByteString o m ByteString
take  Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
L.empty
take Int
n0 = forall {m :: * -> *} {o}.
Monad m =>
Int
-> ([ByteString] -> [ByteString])
-> ConduitT ByteString o m ByteString
go Int
n0 forall a. a -> a
id
  where
    go :: Int
-> ([ByteString] -> [ByteString])
-> ConduitT ByteString o m ByteString
go Int
n [ByteString] -> [ByteString]
front =
        forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
L.fromChunks forall a b. (a -> b) -> a -> b
$ [ByteString] -> [ByteString]
front []) ByteString -> ConduitT ByteString o m ByteString
go'
      where
        go' :: ByteString -> ConduitT ByteString o m ByteString
go' ByteString
bs =
            case ByteString -> Int
S.length ByteString
bs forall a. Ord a => a -> a -> Ordering
`compare` Int
n of
                Ordering
LT -> Int
-> ([ByteString] -> [ByteString])
-> ConduitT ByteString o m ByteString
go (Int
n forall a. Num a => a -> a -> a
- ByteString -> Int
S.length ByteString
bs) ([ByteString] -> [ByteString]
front forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString
bsforall a. a -> [a] -> [a]
:))
                Ordering
EQ -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [ByteString] -> ByteString
L.fromChunks forall a b. (a -> b) -> a -> b
$ [ByteString] -> [ByteString]
front [ByteString
bs]
                Ordering
GT ->
                    let (ByteString
x, ByteString
y) = Int -> ByteString -> (ByteString, ByteString)
S.splitAt Int
n ByteString
bs
                     in forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ ByteString -> Bool
S.null ByteString
y) forall a b. (a -> b) -> a -> b
$ forall i o (m :: * -> *). i -> ConduitT i o m ()
leftover ByteString
y forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return ([ByteString] -> ByteString
L.fromChunks forall a b. (a -> b) -> a -> b
$ [ByteString] -> [ByteString]
front [ByteString
x])

-- | Drop up to the given number of bytes.
--
-- Since 0.5.0
drop :: Monad m => Int -> ConduitT S.ByteString o m ()
drop :: forall (m :: * -> *) o.
Monad m =>
Int -> ConduitT ByteString o m ()
drop  Int
0 = forall (m :: * -> *) a. Monad m => a -> m a
return ()
drop Int
n0 = forall (m :: * -> *) o.
Monad m =>
Int -> ConduitT ByteString o m ()
go Int
n0
  where
    go :: Int -> ConduitT ByteString o m ()
go Int
n =
        forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. Monad m => a -> m a
return ()) ByteString -> ConduitT ByteString o m ()
go'
      where
        go' :: ByteString -> ConduitT ByteString o m ()
go' ByteString
bs =
            case ByteString -> Int
S.length ByteString
bs forall a. Ord a => a -> a -> Ordering
`compare` Int
n of
                Ordering
LT -> Int -> ConduitT ByteString o m ()
go (Int
n forall a. Num a => a -> a -> a
- ByteString -> Int
S.length ByteString
bs)
                Ordering
EQ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
                Ordering
GT ->
                    let y :: ByteString
y = Int -> ByteString -> ByteString
S.drop Int
n ByteString
bs
                     in forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ ByteString -> Bool
S.null ByteString
y) forall a b. (a -> b) -> a -> b
$ forall i o (m :: * -> *). i -> ConduitT i o m ()
leftover ByteString
y forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return ()

-- | Split the input bytes into lines. In other words, split on the LF byte
-- (10), and strip it from the output.
--
-- Since 0.3.0
lines :: Monad m => ConduitT S.ByteString S.ByteString m ()
lines :: forall (m :: * -> *).
Monad m =>
ConduitT ByteString ByteString m ()
lines =
    forall {m :: * -> *}.
Monad m =>
[ByteString] -> ConduitT ByteString ByteString m ()
loop []
  where
    loop :: [ByteString] -> ConduitT ByteString ByteString m ()
loop [ByteString]
acc = forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall {m :: * -> *} {i}.
Monad m =>
[ByteString] -> ConduitT i ByteString m ()
finish [ByteString]
acc) ([ByteString] -> ByteString -> ConduitT ByteString ByteString m ()
go [ByteString]
acc)

    finish :: [ByteString] -> ConduitT i ByteString m ()
finish [ByteString]
acc =
        let final :: ByteString
final = [ByteString] -> ByteString
S.concat forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse [ByteString]
acc
         in forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (ByteString -> Bool
S.null ByteString
final) (forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ByteString
final)

    go :: [ByteString] -> ByteString -> ConduitT ByteString ByteString m ()
go [ByteString]
acc ByteString
more =
        case ByteString -> Maybe (Word8, ByteString)
S.uncons ByteString
second of
            Just (Word8
_, ByteString
second') -> forall (m :: * -> *) o i. Monad m => o -> ConduitT i o m ()
yield ([ByteString] -> ByteString
S.concat forall a b. (a -> b) -> a -> b
$ forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ ByteString
firstforall a. a -> [a] -> [a]
:[ByteString]
acc) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [ByteString] -> ByteString -> ConduitT ByteString ByteString m ()
go [] ByteString
second'
            Maybe (Word8, ByteString)
Nothing -> [ByteString] -> ConduitT ByteString ByteString m ()
loop forall a b. (a -> b) -> a -> b
$ ByteString
moreforall a. a -> [a] -> [a]
:[ByteString]
acc
      where
        (ByteString
first, ByteString
second) = (Word8 -> Bool) -> ByteString -> (ByteString, ByteString)
S.break (forall a. Eq a => a -> a -> Bool
== Word8
10) ByteString
more

-- | Stream the chunks from a lazy bytestring.
--
-- Since 0.5.0
sourceLbs :: Monad m => L.ByteString -> ConduitT i S.ByteString m ()
sourceLbs :: forall (m :: * -> *) i.
Monad m =>
ByteString -> ConduitT i ByteString m ()
sourceLbs = forall (m :: * -> *) a i. Monad m => [a] -> ConduitT i a m ()
sourceList forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
L.toChunks

-- | Stream the input data into a temp file and count the number of bytes
-- present. When complete, return a new @Source@ reading from the temp file
-- together with the length of the input in bytes.
--
-- All resources will be cleaned up automatically.
--
-- Since 1.0.5
sinkCacheLength :: (MonadResource m1, MonadResource m2)
                => ConduitT S.ByteString o m1 (Word64, ConduitT i S.ByteString m2 ())
sinkCacheLength :: forall (m1 :: * -> *) (m2 :: * -> *) o i.
(MonadResource m1, MonadResource m2) =>
ConduitT ByteString o m1 (Word64, ConduitT i ByteString m2 ())
sinkCacheLength = do
    FilePath
tmpdir <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO FilePath
getTemporaryDirectory
    (ReleaseKey
releaseKey, (FilePath
fp, Handle
h)) <- forall (m :: * -> *) a.
MonadResource m =>
IO a -> (a -> IO ()) -> m (ReleaseKey, a)
allocate
        (FilePath -> FilePath -> IO (FilePath, Handle)
IO.openBinaryTempFile FilePath
tmpdir FilePath
"conduit.cache")
        (\(FilePath
fp, Handle
h) -> Handle -> IO ()
IO.hClose Handle
h forall a b. IO a -> IO b -> IO a
`finally` FilePath -> IO ()
removeFile FilePath
fp)
    Word64
len <- forall (m :: * -> *) o.
MonadResource m =>
Handle -> ConduitT ByteString o m Word64
sinkHandleLen Handle
h
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Handle -> IO ()
IO.hClose Handle
h
    forall (m :: * -> *) a. Monad m => a -> m a
return (Word64
len, forall (m :: * -> *) i.
MonadResource m =>
FilePath -> ConduitT i ByteString m ()
CC.sourceFile FilePath
fp forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
release ReleaseKey
releaseKey)
  where
    sinkHandleLen :: MonadResource m => IO.Handle -> ConduitT S.ByteString o m Word64
    sinkHandleLen :: forall (m :: * -> *) o.
MonadResource m =>
Handle -> ConduitT ByteString o m Word64
sinkHandleLen Handle
h =
        forall {m :: * -> *} {b} {o}.
(MonadIO m, Num b) =>
b -> ConduitT ByteString o m b
loop Word64
0
      where
        loop :: b -> ConduitT ByteString o m b
loop b
x =
            forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. Monad m => a -> m a
return b
x) ByteString -> ConduitT ByteString o m b
go
          where
            go :: ByteString -> ConduitT ByteString o m b
go ByteString
bs = do
                forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Handle -> ByteString -> IO ()
S.hPut Handle
h ByteString
bs
                b -> ConduitT ByteString o m b
loop forall a b. (a -> b) -> a -> b
$ b
x forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
S.length ByteString
bs)

-- | Consume a stream of input into a lazy bytestring. Note that no lazy I\/O
-- is performed, but rather all content is read into memory strictly.
--
-- Since 1.0.5
sinkLbs :: Monad m => ConduitT S.ByteString o m L.ByteString
sinkLbs :: forall (m :: * -> *) o.
Monad m =>
ConduitT ByteString o m ByteString
sinkLbs = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [ByteString] -> ByteString
L.fromChunks forall (m :: * -> *) a o. Monad m => ConduitT a o m [a]
consume

mapM_BS :: Monad m => (Word8 -> m ()) -> S.ByteString -> m ()
mapM_BS :: forall (m :: * -> *).
Monad m =>
(Word8 -> m ()) -> ByteString -> m ()
mapM_BS Word8 -> m ()
f (PS ForeignPtr Word8
fptr Int
offset Int
len) = do
    let start :: Ptr b
start = forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr Word8
fptr forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
offset
        end :: Ptr b
end = forall {b}. Ptr b
start forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
len
        loop :: Ptr Word8 -> m ()
loop Ptr Word8
ptr
            | Ptr Word8
ptr forall a. Ord a => a -> a -> Bool
>= forall {b}. Ptr b
end = forall a. IO a -> a
accursedUnutterablePerformIO (forall a. ForeignPtr a -> IO ()
touchForeignPtr ForeignPtr Word8
fptr) seq :: forall a b. a -> b -> b
`seq` forall (m :: * -> *) a. Monad m => a -> m a
return ()
            | Bool
otherwise = do
                Word8 -> m ()
f (forall a. IO a -> a
accursedUnutterablePerformIO (forall a. Storable a => Ptr a -> IO a
peek Ptr Word8
ptr))
                Ptr Word8 -> m ()
loop (Ptr Word8
ptr forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
1)
    Ptr Word8 -> m ()
loop forall {b}. Ptr b
start
{-# INLINE mapM_BS #-}

-- | Perform a computation on each @Word8@ in a stream.
--
-- Since 1.0.10
mapM_ :: Monad m => (Word8 -> m ()) -> ConduitT S.ByteString o m ()
mapM_ :: forall (m :: * -> *) o.
Monad m =>
(Word8 -> m ()) -> ConduitT ByteString o m ()
mapM_ Word8 -> m ()
f = forall (m :: * -> *) i o r.
Monad m =>
(i -> ConduitT i o m r) -> ConduitT i o m ()
awaitForever (forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *).
Monad m =>
(Word8 -> m ()) -> ByteString -> m ()
mapM_BS Word8 -> m ()
f)
{-# INLINE mapM_ #-}

-- | Consume some instance of @Storable@ from the incoming byte stream. In the
-- event of insufficient bytes in the stream, returns a @Nothing@ and returns
-- all unused input as leftovers.
--
-- @since 1.1.13
sinkStorable :: (Monad m, Storable a) => ConduitT S.ByteString o m (Maybe a)
sinkStorable :: forall (m :: * -> *) a o.
(Monad m, Storable a) =>
ConduitT ByteString o m (Maybe a)
sinkStorable = forall (m :: * -> *) a b o.
(Monad m, Storable a) =>
(a -> b) -> ConduitT ByteString o m b -> ConduitT ByteString o m b
sinkStorableHelper forall a. a -> Maybe a
Just (forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing)

-- | Same as 'sinkStorable', but throws a 'SinkStorableInsufficientBytes'
-- exception (via 'throwM') in the event of insufficient bytes. This can be
-- more efficient to use than 'sinkStorable' as it avoids the need to
-- construct/deconstruct a @Maybe@ wrapper in the success case.
--
-- @since 1.1.13
sinkStorableEx :: (MonadThrow m, Storable a) => ConduitT S.ByteString o m a
sinkStorableEx :: forall (m :: * -> *) a o.
(MonadThrow m, Storable a) =>
ConduitT ByteString o m a
sinkStorableEx = forall (m :: * -> *) a b o.
(Monad m, Storable a) =>
(a -> b) -> ConduitT ByteString o m b -> ConduitT ByteString o m b
sinkStorableHelper forall a. a -> a
id (forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM SinkStorableException
SinkStorableInsufficientBytes)

sinkStorableHelper :: forall m a b o. (Monad m, Storable a)
                   => (a -> b)
                   -> (ConduitT S.ByteString o m b)
                   -> ConduitT S.ByteString o m b
sinkStorableHelper :: forall (m :: * -> *) a b o.
(Monad m, Storable a) =>
(a -> b) -> ConduitT ByteString o m b -> ConduitT ByteString o m b
sinkStorableHelper a -> b
wrap ConduitT ByteString o m b
failure = do
    ConduitT ByteString o m b
start
  where
    size :: Int
size = forall a. Storable a => a -> Int
sizeOf (forall a. (?callStack::CallStack) => a
undefined :: a)

    -- try the optimal case: next chunk has all the data we need
    start :: ConduitT ByteString o m b
start = do
        Maybe ByteString
mbs <- forall (m :: * -> *) i o. Monad m => ConduitT i o m (Maybe i)
await
        case Maybe ByteString
mbs of
            Maybe ByteString
Nothing -> ConduitT ByteString o m b
failure
            Just ByteString
bs
                | ByteString -> Bool
S.null ByteString
bs -> ConduitT ByteString o m b
start
                | Bool
otherwise ->
                    case forall a. Ord a => a -> a -> Ordering
compare (ByteString -> Int
S.length ByteString
bs) Int
size of
                        Ordering
LT -> do
                            -- looks like we're stuck concating
                            forall i o (m :: * -> *). i -> ConduitT i o m ()
leftover ByteString
bs
                            ByteString
lbs <- forall (m :: * -> *) o.
Monad m =>
Int -> ConduitT ByteString o m ByteString
take Int
size
                            let bs' :: ByteString
bs' = [ByteString] -> ByteString
S.concat forall a b. (a -> b) -> a -> b
$ ByteString -> [ByteString]
L.toChunks ByteString
lbs
                            case forall a. Ord a => a -> a -> Ordering
compare (ByteString -> Int
S.length ByteString
bs') Int
size of
                                Ordering
LT -> do
                                    forall i o (m :: * -> *). i -> ConduitT i o m ()
leftover ByteString
bs'
                                    ConduitT ByteString o m b
failure
                                Ordering
EQ -> forall {m :: * -> *}. Monad m => ByteString -> m b
process ByteString
bs'
                                Ordering
GT -> forall a. (?callStack::CallStack) => Bool -> a -> a
assert Bool
False (forall {m :: * -> *}. Monad m => ByteString -> m b
process ByteString
bs')
                        Ordering
EQ -> forall {m :: * -> *}. Monad m => ByteString -> m b
process ByteString
bs
                        Ordering
GT -> do
                            let (ByteString
x, ByteString
y) = Int -> ByteString -> (ByteString, ByteString)
S.splitAt Int
size ByteString
bs
                            forall i o (m :: * -> *). i -> ConduitT i o m ()
leftover ByteString
y
                            forall {m :: * -> *}. Monad m => ByteString -> m b
process ByteString
x

    -- Given a bytestring of exactly the correct size, grab the value
    process :: ByteString -> m b
process ByteString
bs = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! a -> b
wrap forall a b. (a -> b) -> a -> b
$! forall a. IO a -> a
accursedUnutterablePerformIO forall a b. (a -> b) -> a -> b
$!
        forall a. ByteString -> (CString -> IO a) -> IO a
unsafeUseAsCString ByteString
bs (a -> Ptr a -> IO a
safePeek forall a. (?callStack::CallStack) => a
undefined forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Ptr a -> Ptr b
castPtr)

    safePeek :: a -> Ptr a -> IO a
#ifdef ALLOW_UNALIGNED_ACCESS
    safePeek _ = peek
#else
    safePeek :: a -> Ptr a -> IO a
safePeek a
val Ptr a
ptr = forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca (\Ptr a
t -> forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr a
t Ptr a
ptr (forall a. Storable a => a -> Int
sizeOf a
val) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Storable a => Ptr a -> IO a
peek Ptr a
t)
#endif
{-# INLINE sinkStorableHelper #-}

data SinkStorableException = SinkStorableInsufficientBytes
    deriving (Int -> SinkStorableException -> ShowS
[SinkStorableException] -> ShowS
SinkStorableException -> FilePath
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [SinkStorableException] -> ShowS
$cshowList :: [SinkStorableException] -> ShowS
show :: SinkStorableException -> FilePath
$cshow :: SinkStorableException -> FilePath
showsPrec :: Int -> SinkStorableException -> ShowS
$cshowsPrec :: Int -> SinkStorableException -> ShowS
Show, Typeable)
instance Exception SinkStorableException