{-# LANGUAGE CPP, RankNTypes #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Data.Conduit.Binary
(
CC.sourceFile
, CC.sourceHandle
, CC.sourceHandleUnsafe
, CC.sourceIOHandle
, sourceFileRange
, sourceHandleRange
, sourceHandleRangeWithBuffer
, CC.withSourceFile
, CC.sinkFile
, CC.sinkFileCautious
, CC.sinkTempFile
, CC.sinkSystemTempFile
, CC.sinkHandle
, CC.sinkIOHandle
, CC.sinkHandleBuilder
, CC.sinkHandleFlush
, CC.withSinkFile
, CC.withSinkFileBuilder
, CC.withSinkFileCautious
, conduitFile
, conduitHandle
, sourceLbs
, head
, dropWhile
, take
, drop
, sinkCacheLength
, sinkLbs
, mapM_
, sinkStorable
, sinkStorableEx
, 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
sourceFileRange :: MonadResource m
=> FilePath
-> Maybe Integer
-> Maybe Integer
-> 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)
sourceHandleRange :: MonadIO m
=> IO.Handle
-> Maybe Integer
-> Maybe Integer
-> 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
sourceHandleRangeWithBuffer :: MonadIO m
=> IO.Handle
-> Maybe Integer
-> Maybe Integer
-> Int
-> 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'
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
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
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'
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)
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
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 :: 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 :: 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 ()
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
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
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)
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 #-}
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_ #-}
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)
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)
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
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
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