{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP          #-}
{-# LANGUAGE GADTs        #-}
{-# LANGUAGE LambdaCase   #-}
{-# LANGUAGE RankNTypes   #-}
{-# LANGUAGE ViewPatterns #-}

-- |
-- Module      : Streaming.ByteString
-- Copyright   : (c) Don Stewart 2006
--               (c) Duncan Coutts 2006-2011
--               (c) Michael Thompson 2015
-- License     : BSD-style
--
-- Maintainer  : what_is_it_to_do_anything@yahoo.com
-- Stability   : experimental
-- Portability : portable
--
-- See the simple examples of use <https://gist.github.com/michaelt/6c6843e6dd8030e95d58 here>
-- and the @ghci@ examples especially in "Streaming.ByteString.Char8".
-- We begin with a slight modification of the documentation to "Data.ByteString.Lazy":
--
-- A time and space-efficient implementation of effectful byte streams using a
-- stream of packed 'Word8' arrays, suitable for high performance use, both in
-- terms of large data quantities, or high speed requirements. Streaming
-- ByteStrings are encoded as streams of strict chunks of bytes.
--
-- A key feature of streaming ByteStrings is the means to manipulate large or
-- unbounded streams of data without requiring the entire sequence to be
-- resident in memory. To take advantage of this you have to write your
-- functions in a streaming style, e.g. classic pipeline composition. The
-- default I\/O chunk size is 32k, which should be good in most circumstances.
--
-- Some operations, such as 'concat', 'append', and 'cons', have better
-- complexity than their "Data.ByteString" equivalents, due to optimisations
-- resulting from the list spine structure. For other operations streaming, like
-- lazy, ByteStrings are usually within a few percent of strict ones.
--
-- This module is intended to be imported @qualified@, to avoid name clashes
-- with "Prelude" functions. eg.
--
-- > import qualified Streaming.ByteString as Q
--
-- Original GHC implementation by Bryan O\'Sullivan. Rewritten to use
-- 'Data.Array.Unboxed.UArray' by Simon Marlow. Rewritten to support slices and
-- use 'Foreign.ForeignPtr.ForeignPtr' by David Roundy. Rewritten again and
-- extended by Don Stewart and Duncan Coutts. Lazy variant by Duncan Coutts and
-- Don Stewart. Streaming variant by Michael Thompson, following the ideas of
-- Gabriel Gonzales' pipes-bytestring.
module Streaming.ByteString
  ( -- * The @ByteStream@ type
    ByteStream
  , ByteString

    -- * Introducing and eliminating 'ByteStream's
  , empty
  , singleton
  , pack
  , unpack
  , fromLazy
  , toLazy
  , toLazy_
  , fromChunks
  , toChunks
  , fromStrict
  , toStrict
  , toStrict_
  , effects
  , copy
  , drained
  , mwrap

    -- * Transforming ByteStreams
  , map
  , for
  , intercalate
  , intersperse

    -- * Basic interface
  , cons
  , cons'
  , snoc
  , append
  , filter
  , uncons
  , nextByte

    -- * Substrings
    -- ** Breaking strings
  , break
  , drop
  , dropWhile
  , group
  , groupBy
  , span
  , splitAt
  , splitWith
  , take
  , takeWhile

    -- ** Breaking into many substrings
  , split

    -- ** Special folds
  , concat
  , denull

    -- * Builders
  , toStreamingByteString

  , toStreamingByteStringWith

  , toBuilder
  , concatBuilders

    -- * Building ByteStreams
    -- ** Infinite ByteStreams
  , repeat
  , iterate
  , cycle

    -- ** Unfolding ByteStreams
  , unfoldM
  , unfoldr
  , reread

    -- *  Folds, including support for `Control.Foldl`
  , foldr
  , fold
  , fold_
  , head
  , head_
  , last
  , last_
  , length
  , length_
  , null
  , null_
  , nulls
  , testNull
  , count
  , count_

    -- * I\/O with 'ByteStream's
    -- ** Standard input and output
  , getContents
  , stdin
  , stdout
  , interact

    -- ** Files
  , readFile
  , writeFile
  , appendFile

    -- ** I\/O with Handles
  , fromHandle
  , toHandle
  , hGet
  , hGetContents
  , hGetContentsN
  , hGetN
  , hGetNonBlocking
  , hGetNonBlockingN
  , hPut
  --    , hPutNonBlocking

    -- * Simple chunkwise operations
  , unconsChunk
  , nextChunk
  , chunk
  , foldrChunks
  , foldlChunks
  , chunkFold
  , chunkFoldM
  , chunkMap
  , chunkMapM
  , chunkMapM_

    -- * Etc.
  , dematerialize
  , materialize
  , distribute
  , zipWithStream
  ) where

import           Prelude hiding
    (all, any, appendFile, break, concat, concatMap, cycle, drop, dropWhile,
    elem, filter, foldl, foldl1, foldr, foldr1, getContents, getLine, head,
    init, interact, iterate, last, length, lines, map, maximum, minimum,
    notElem, null, putStr, putStrLn, readFile, repeat, replicate, reverse,
    scanl, scanl1, scanr, scanr1, span, splitAt, tail, take, takeWhile,
    unlines, unzip, writeFile, zip, zipWith)

import qualified Data.ByteString as P (ByteString)
import qualified Data.ByteString as B
import           Data.ByteString.Builder.Internal hiding
    (append, defaultChunkSize, empty, hPut)
import qualified Data.ByteString.Internal as B
import qualified Data.ByteString.Lazy.Internal as BI
import qualified Data.ByteString.Unsafe as B

import           Streaming hiding (concats, distribute, unfold)
import           Streaming.ByteString.Internal
import           Streaming.Internal (Stream(..))
import qualified Streaming.Prelude as SP

import           Control.Monad (forever)
import           Control.Monad.Trans.Resource
import           Data.Int (Int64)
import qualified Data.List as L
import           Data.Word (Word8)
import           Foreign.Ptr
import           Foreign.Storable
import           System.IO (Handle, IOMode(..), hClose, openBinaryFile)
import qualified System.IO as IO (stdin, stdout)
import           System.IO.Error (illegalOperationErrorType, mkIOError)

-- | /O(n)/ Concatenate a stream of byte streams.
concat :: Monad m => Stream (ByteStream m) m r -> ByteStream m r
concat :: forall (m :: * -> *) r.
Monad m =>
Stream (ByteStream m) m r -> ByteStream m r
concat Stream (ByteStream m) m r
x = forall (f :: * -> *) (m :: * -> *) r b.
(Functor f, Monad m) =>
Stream f m r -> (f b -> b) -> (m b -> b) -> (r -> b) -> b
destroy Stream (ByteStream m) m r
x forall (m :: * -> *) a. Monad m => m (m a) -> m a
join forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go forall (m :: * -> *) r. r -> ByteStream m r
Empty
{-# INLINE concat #-}

-- | Given a byte stream on a transformed monad, make it possible to \'run\'
-- transformer.
distribute
  :: (Monad m, MonadTrans t, MFunctor t, Monad (t m), Monad (t (ByteStream m)))
  => ByteStream (t m) a -> t (ByteStream m) a
distribute :: forall (m :: * -> *) (t :: (* -> *) -> * -> *) a.
(Monad m, MonadTrans t, MFunctor t, Monad (t m),
 Monad (t (ByteStream m))) =>
ByteStream (t m) a -> t (ByteStream m) a
distribute ByteStream (t m) a
ls = forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream (t m) a
ls
             forall (m :: * -> *) a. Monad m => a -> m a
return
             (\ByteString
bs t (ByteStream m) a
x -> forall (m :: * -> *) a. Monad m => m (m a) -> m a
join forall a b. (a -> b) -> a -> b
$ forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs (forall (m :: * -> *) r. r -> ByteStream m r
Empty t (ByteStream m) a
x) )
             (forall (m :: * -> *) a. Monad m => m (m a) -> m a
join forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (t :: (* -> *) -> k -> *) (m :: * -> *) (n :: * -> *)
       (b :: k).
(MFunctor t, Monad m) =>
(forall a. m a -> n a) -> t m b -> t n b
hoist (forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall (m :: * -> *) r. r -> ByteStream m r
Empty))
{-# INLINE distribute #-}

-- | Perform the effects contained in an effectful bytestring, ignoring the bytes.
effects :: Monad m => ByteStream m r -> m r
effects :: forall (m :: * -> *) r. Monad m => ByteStream m r -> m r
effects ByteStream m r
bs = case ByteStream m r
bs of
  Empty r
r      -> forall (m :: * -> *) a. Monad m => a -> m a
return r
r
  Go m (ByteStream m r)
m         -> m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r. Monad m => ByteStream m r -> m r
effects
  Chunk ByteString
_ ByteStream m r
rest -> forall (m :: * -> *) r. Monad m => ByteStream m r -> m r
effects ByteStream m r
rest
{-# INLINABLE effects #-}

-- | Perform the effects contained in the second in an effectful pair of
-- bytestrings, ignoring the bytes. It would typically be used at the type
--
-- > ByteStream m (ByteStream m r) -> ByteStream m r
drained :: (Monad m, MonadTrans t, Monad (t m)) => t m (ByteStream m r) -> t m r
drained :: forall (m :: * -> *) (t :: (* -> *) -> * -> *) r.
(Monad m, MonadTrans t, Monad (t m)) =>
t m (ByteStream m r) -> t m r
drained t m (ByteStream m r)
t = t m (ByteStream m r)
t forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= 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 :: * -> *) r. Monad m => ByteStream m r -> m r
effects

-- -----------------------------------------------------------------------------
-- Introducing and eliminating 'ByteStream's

-- | /O(1)/ The empty 'ByteStream' -- i.e. @return ()@ Note that @ByteStream m w@ is
-- generally a monoid for monoidal values of @w@, like @()@.
empty :: ByteStream m ()
empty :: forall (m :: * -> *). ByteStream m ()
empty = forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
{-# INLINE empty #-}

-- | /O(1)/ Yield a 'Word8' as a minimal 'ByteStream'.
singleton :: Monad m => Word8 -> ByteStream m ()
singleton :: forall (m :: * -> *). Monad m => Word8 -> ByteStream m ()
singleton Word8
w = forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Word8 -> ByteString
B.singleton Word8
w)  (forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
{-# INLINE singleton #-}

-- | /O(n)/ Convert a monadic stream of individual 'Word8's into a packed byte stream.
pack :: Monad m => Stream (Of Word8) m r -> ByteStream m r
pack :: forall (m :: * -> *) r.
Monad m =>
Stream (Of Word8) m r -> ByteStream m r
pack = forall (m :: * -> *) r.
Monad m =>
Stream (Of Word8) m r -> ByteStream m r
packBytes
{-# INLINE pack #-}

-- | /O(n)/ Converts a packed byte stream into a stream of individual bytes.
unpack ::  Monad m => ByteStream m r -> Stream (Of Word8) m r
unpack :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of Word8) m r
unpack = forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of Word8) m r
unpackBytes

-- | /O(c)/ Convert a monadic stream of individual strict 'ByteString' chunks
-- into a byte stream.
fromChunks :: Monad m => Stream (Of P.ByteString) m r -> ByteStream m r
fromChunks :: forall (m :: * -> *) r.
Monad m =>
Stream (Of ByteString) m r -> ByteStream m r
fromChunks Stream (Of ByteString) m r
cs = forall (f :: * -> *) (m :: * -> *) r b.
(Functor f, Monad m) =>
Stream f m r -> (f b -> b) -> (m b -> b) -> (r -> b) -> b
destroy Stream (Of ByteString) m r
cs (\(ByteString
bs :> ByteStream m r
rest) -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs ByteStream m r
rest) forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go forall (m :: * -> *) a. Monad m => a -> m a
return
{-# INLINE fromChunks #-}

-- | /O(c)/ Convert a byte stream into a stream of individual strict
-- bytestrings. This of course exposes the internal chunk structure.
toChunks :: Monad m => ByteStream m r -> Stream (Of P.ByteString) m r
toChunks :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of ByteString) m r
toChunks ByteStream m r
bs = forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
bs forall (m :: * -> *) a. Monad m => a -> m a
return (\ByteString
b Stream (Of ByteString) m r
mx -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteString
bforall a b. a -> b -> Of a b
:> Stream (Of ByteString) m r
mx)) forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect
{-# INLINE toChunks #-}

-- | /O(1)/ Yield a strict 'ByteString' chunk.
fromStrict :: P.ByteString -> ByteStream m ()
fromStrict :: forall (m :: * -> *). ByteString -> ByteStream m ()
fromStrict ByteString
bs | ByteString -> Bool
B.null ByteString
bs = forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
              | Bool
otherwise = forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs (forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
{-# INLINE fromStrict #-}

-- | /O(n)/ Convert a byte stream into a single strict 'ByteString'.
--
-- Note that this is an /expensive/ operation that forces the whole monadic
-- ByteString into memory and then copies all the data. If possible, try to
-- avoid converting back and forth between streaming and strict bytestrings.
toStrict_ :: Monad m => ByteStream m r -> m B.ByteString
#if MIN_VERSION_streaming (0,2,2)
toStrict_ :: forall (m :: * -> *) r. Monad m => ByteStream m r -> m ByteString
toStrict_ = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [ByteString] -> ByteString
B.concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a r. Monad m => Stream (Of a) m r -> m [a]
SP.toList_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of ByteString) m r
toChunks
#else
toStrict_ = fmap B.concat . SP.toList_ . void . toChunks
#endif
{-# INLINE toStrict_ #-}

-- | /O(n)/ Convert a monadic byte stream into a single strict 'ByteString',
-- retaining the return value of the original pair. This operation is for use
-- with 'mapped'.
--
-- > mapped R.toStrict :: Monad m => Stream (ByteStream m) m r -> Stream (Of ByteString) m r
--
-- It is subject to all the objections one makes to Data.ByteString.Lazy
-- 'toStrict'; all of these are devastating.
toStrict :: Monad m => ByteStream m r -> m (Of B.ByteString r)
toStrict :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of ByteString r)
toStrict ByteStream m r
bs = do
  ([ByteString]
bss :> r
r) <- forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Of [a] r)
SP.toList (forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of ByteString) m r
toChunks ByteStream m r
bs)
  forall (m :: * -> *) a. Monad m => a -> m a
return ([ByteString] -> ByteString
B.concat [ByteString]
bss forall a b. a -> b -> Of a b
:> r
r)
{-# INLINE toStrict #-}

-- |/O(c)/ Transmute a pseudo-pure lazy bytestring to its representation as a
-- monadic stream of chunks.
--
-- >>> Q.putStrLn $ Q.fromLazy "hi"
-- hi
-- >>>  Q.fromLazy "hi"
-- Chunk "hi" (Empty (()))  -- note: a 'show' instance works in the identity monad
-- >>>  Q.fromLazy $ BL.fromChunks ["here", "are", "some", "chunks"]
-- Chunk "here" (Chunk "are" (Chunk "some" (Chunk "chunks" (Empty (())))))
fromLazy :: Monad m => BI.ByteString -> ByteStream m ()
fromLazy :: forall (m :: * -> *). Monad m => ByteString -> ByteStream m ()
fromLazy = forall a. (ByteString -> a -> a) -> a -> ByteString -> a
BI.foldrChunks forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
{-# INLINE fromLazy #-}

-- | /O(n)/ Convert an effectful byte stream into a single lazy 'ByteStream'
-- with the same internal chunk structure. See `toLazy` which preserve
-- connectedness by keeping the return value of the effectful bytestring.
toLazy_ :: Monad m => ByteStream m r -> m BI.ByteString
toLazy_ :: forall (m :: * -> *) r. Monad m => ByteStream m r -> m ByteString
toLazy_ ByteStream m r
bs = forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
bs (\r
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
BI.Empty) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString -> ByteString
BI.Chunk) forall (m :: * -> *) a. Monad m => m (m a) -> m a
join
{-# INLINE toLazy_ #-}

-- | /O(n)/ Convert an effectful byte stream into a single lazy 'ByteString'
-- with the same internal chunk structure, retaining the original return value.
--
-- This is the canonical way of breaking streaming (`toStrict` and the like are
-- far more demonic). Essentially one is dividing the interleaved layers of
-- effects and bytes into one immense layer of effects, followed by the memory
-- of the succession of bytes.
--
-- Because one preserves the return value, `toLazy` is a suitable argument for
-- 'Streaming.mapped':
--
-- > S.mapped Q.toLazy :: Stream (ByteStream m) m r -> Stream (Of L.ByteString) m r
--
-- >>> Q.toLazy "hello"
-- "hello" :> ()
-- >>> S.toListM $ traverses Q.toLazy $ Q.lines "one\ntwo\nthree\nfour\nfive\n"
-- ["one","two","three","four","five",""]  -- [L.ByteString]
toLazy :: Monad m => ByteStream m r -> m (Of BI.ByteString r)
toLazy :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of ByteString r)
toLazy ByteStream m r
bs0 = forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
bs0
                (\r
r -> forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString
BI.Empty forall a b. a -> b -> Of a b
:> r
r))
                (\ByteString
b m (Of ByteString r)
mx -> do
                      (ByteString
bs :> r
x) <- m (Of ByteString r)
mx
                      forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> ByteString
BI.Chunk ByteString
b ByteString
bs forall a b. a -> b -> Of a b
:> r
x
                      )
                forall (m :: * -> *) a. Monad m => m (m a) -> m a
join
{-# INLINE toLazy #-}

-- ---------------------------------------------------------------------
-- Basic interface
--

-- | Test whether a `ByteStream` is empty, collecting its return value; to reach
-- the return value, this operation must check the whole length of the string.
--
-- >>> Q.null "one\ntwo\three\nfour\nfive\n"
-- False :> ()
-- >>> Q.null ""
-- True :> ()
-- >>> S.print $ mapped R.null $ Q.lines "yours,\nMeredith"
-- False
-- False
--
-- Suitable for use with `SP.mapped`:
--
-- @
-- S.mapped Q.null :: Streaming (ByteStream m) m r -> Stream (Of Bool) m r
-- @
null :: Monad m => ByteStream m r -> m (Of Bool r)
null :: forall (m :: * -> *) r. Monad m => ByteStream m r -> m (Of Bool r)
null (Empty r
r)  = forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True forall a b. a -> b -> Of a b
:> r
r)
null (Go m (ByteStream m r)
m)     = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r. Monad m => ByteStream m r -> m (Of Bool r)
null
null (Chunk ByteString
bs ByteStream m r
rest) = if ByteString -> Bool
B.null ByteString
bs
   then forall (m :: * -> *) r. Monad m => ByteStream m r -> m (Of Bool r)
null ByteStream m r
rest
   else do
     r
r <- forall (m :: * -> *) a r. Monad m => Stream (Of a) m r -> m r
SP.effects (forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of ByteString) m r
toChunks ByteStream m r
rest)
     forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False forall a b. a -> b -> Of a b
:> r
r)
{-# INLINABLE null #-}

-- | /O(1)/ Test whether a `ByteStream` is empty. The value is of course in the
-- monad of the effects.
--
-- >>>  Q.null "one\ntwo\three\nfour\nfive\n"
-- False
-- >>> Q.null $ Q.take 0 Q.stdin
-- True
-- >>> :t Q.null $ Q.take 0 Q.stdin
-- Q.null $ Q.take 0 Q.stdin :: MonadIO m => m Bool
null_ :: Monad m => ByteStream m r -> m Bool
null_ :: forall (m :: * -> *) r. Monad m => ByteStream m r -> m Bool
null_ (Empty r
_)      = forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
null_ (Go m (ByteStream m r)
m)         = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r. Monad m => ByteStream m r -> m Bool
null_
null_ (Chunk ByteString
bs ByteStream m r
rest) = if ByteString -> Bool
B.null ByteString
bs
  then forall (m :: * -> *) r. Monad m => ByteStream m r -> m Bool
null_ ByteStream m r
rest
  else forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
{-# INLINABLE null_ #-}

-- | Similar to `null`, but yields the remainder of the `ByteStream` stream when
-- an answer has been determined.
testNull :: Monad m => ByteStream m r -> m (Of Bool (ByteStream m r))
testNull :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of Bool (ByteStream m r))
testNull (Empty r
r)  = forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True forall a b. a -> b -> Of a b
:> forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r)
testNull (Go m (ByteStream m r)
m)     = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of Bool (ByteStream m r))
testNull
testNull p :: ByteStream m r
p@(Chunk ByteString
bs ByteStream m r
rest) = if ByteString -> Bool
B.null ByteString
bs
   then forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of Bool (ByteStream m r))
testNull ByteStream m r
rest
   else forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False forall a b. a -> b -> Of a b
:> ByteStream m r
p)
{-# INLINABLE testNull #-}

-- | Remove empty ByteStrings from a stream of bytestrings.
denull :: Monad m => Stream (ByteStream m) m r -> Stream (ByteStream m) m r
{-# INLINABLE denull #-}
denull :: forall (m :: * -> *) r.
Monad m =>
Stream (ByteStream m) m r -> Stream (ByteStream m) m r
denull = forall {r}.
Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right
  where
    -- Scan each substream, dropping empty chunks along the way.  As soon as a
    -- non-empty chunk is found, just apply the loop to the next substream in
    -- the terminal value via fmap.  If Empty comes up before that happens,
    -- continue the current stream instead with its denulled tail.
    --
    -- This implementation is tail recursive:
    -- * Recursion via 'loop . Left' continues scanning an inner ByteStream.
    -- * Recursion via 'loop . Right' moves to the next substream.
    --
    -- The old version below was shorter, but noticeably slower, especially
    -- when empty substreams are frequent:
    --
    --    denull = hoist (run . maps effects) . separate . mapped nulls
    --
    loop :: Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop = \ case
      Left ByteStream m (Stream (ByteStream m) m r)
mbs -> case ByteStream m (Stream (ByteStream m) m r)
mbs of
          Chunk ByteString
c ByteStream m (Stream (ByteStream m) m r)
cs | ByteString -> Int
B.length ByteString
c forall a. Ord a => a -> a -> Bool
> Int
0 -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right) ByteStream m (Stream (ByteStream m) m r)
cs
                     | Bool
otherwise      -> Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left ByteStream m (Stream (ByteStream m) m r)
cs
          Go m (ByteStream m (Stream (ByteStream m) m r))
m                        -> forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b. (a -> b) -> a -> b
$ Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ByteStream m (Stream (ByteStream m) m r))
m
          Empty Stream (ByteStream m) m r
r                     -> Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right Stream (ByteStream m) m r
r
      Right Stream (ByteStream m) m r
strm -> case Stream (ByteStream m) m r
strm of
        Step ByteStream m (Stream (ByteStream m) m r)
mbs -> case ByteStream m (Stream (ByteStream m) m r)
mbs of
          Chunk ByteString
c ByteStream m (Stream (ByteStream m) m r)
cs | ByteString -> Int
B.length ByteString
c forall a. Ord a => a -> a -> Bool
> Int
0 -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right) ByteStream m (Stream (ByteStream m) m r)
cs
                     | Bool
otherwise      -> Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop forall a b. (a -> b) -> a -> b
$ forall a b. a -> Either a b
Left ByteStream m (Stream (ByteStream m) m r)
cs
          Go m (ByteStream m (Stream (ByteStream m) m r))
m                        -> forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b. (a -> b) -> a -> b
$ Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ByteStream m (Stream (ByteStream m) m r))
m
          Empty Stream (ByteStream m) m r
r                     -> Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right Stream (ByteStream m) m r
r
        Effect m (Stream (ByteStream m) m r)
m                      -> forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right) m (Stream (ByteStream m) m r)
m
        r :: Stream (ByteStream m) m r
r@(Return r
_)                  -> Stream (ByteStream m) m r
r

{-| /O1/ Distinguish empty from non-empty lines, while maintaining streaming;
    the empty ByteStrings are on the right

>>> nulls  ::  ByteStream m r -> m (Sum (ByteStream m) (ByteStream m) r)

    There are many (generally slower) ways to remove null bytestrings from a
    @Stream (ByteStream m) m r@ (besides using @denull@). If we pass next to

>>> mapped nulls bs :: Stream (Sum (ByteStream m) (ByteStream m)) m r

    then can then apply @Streaming.separate@ to get

>>> separate (mapped nulls bs) :: Stream (ByteStream m) (Stream (ByteStream m) m) r

    The inner monad is now made of the empty bytestrings; we act on this
    with @hoist@ , considering that

>>> :t Q.effects . Q.concat
Q.effects . Q.concat
  :: Monad m => Stream (Q.ByteStream m) m r -> m r

    we have

>>> hoist (Q.effects . Q.concat) . separate . mapped Q.nulls
  :: Monad n =>  Stream (Q.ByteStream n) n b -> Stream (Q.ByteStream n) n b
-}
nulls :: Monad m => ByteStream m r -> m (Sum (ByteStream m) (ByteStream m) r)
nulls :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Sum (ByteStream m) (ByteStream m) r)
nulls (Empty r
r)  = forall (m :: * -> *) a. Monad m => a -> m a
return (forall {k} (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR (forall (m :: * -> *) a. Monad m => a -> m a
return r
r))
nulls (Go m (ByteStream m r)
m)     = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Sum (ByteStream m) (ByteStream m) r)
nulls
nulls (Chunk ByteString
bs ByteStream m r
rest) = if ByteString -> Bool
B.null ByteString
bs
   then forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Sum (ByteStream m) (ByteStream m) r)
nulls ByteStream m r
rest
   else forall (m :: * -> *) a. Monad m => a -> m a
return (forall {k} (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs ByteStream m r
rest))
{-# INLINABLE nulls #-}

-- | Like `length`, report the length in bytes of the `ByteStream` by running
-- through its contents. Since the return value is in the effect @m@, this is
-- one way to "get out" of the stream.
length_ :: Monad m => ByteStream m r -> m Int
length_ :: forall (m :: * -> *) r. Monad m => ByteStream m r -> m Int
length_ = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Int
n:> r
_) -> Int
n) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a r.
Monad m =>
(a -> ByteString -> a) -> a -> ByteStream m r -> m (Of a r)
foldlChunks (\Int
n ByteString
c -> Int
n forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)) Int
0
{-# INLINE length_ #-}

-- | /O(n\/c)/ 'length' returns the length of a byte stream as an 'Int' together
-- with the return value. This makes various maps possible.
--
-- >>> Q.length "one\ntwo\three\nfour\nfive\n"
-- 23 :> ()
-- >>> S.print $ S.take 3 $ mapped Q.length $ Q.lines "one\ntwo\three\nfour\nfive\n"
-- 3
-- 8
-- 4
length :: Monad m => ByteStream m r -> m (Of Int r)
length :: forall (m :: * -> *) r. Monad m => ByteStream m r -> m (Of Int r)
length = forall (m :: * -> *) a r.
Monad m =>
(a -> ByteString -> a) -> a -> ByteStream m r -> m (Of a r)
foldlChunks (\Int
n ByteString
c -> Int
n forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)) Int
0
{-# INLINE length #-}

-- | /O(1)/ 'cons' is analogous to @(:)@ for lists.
cons :: Monad m => Word8 -> ByteStream m r -> ByteStream m r
cons :: forall (m :: * -> *) r.
Monad m =>
Word8 -> ByteStream m r -> ByteStream m r
cons Word8
c ByteStream m r
cs = forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Word8 -> ByteString
B.singleton Word8
c) ByteStream m r
cs
{-# INLINE cons #-}

-- | /O(1)/ Unlike 'cons', 'cons\'' is strict in the ByteString that we are
-- consing onto. More precisely, it forces the head and the first chunk. It does
-- this because, for space efficiency, it may coalesce the new byte onto the
-- first \'chunk\' rather than starting a new \'chunk\'.
--
-- So that means you can't use a lazy recursive contruction like this:
--
-- > let xs = cons\' c xs in xs
--
-- You can however use 'cons', as well as 'repeat' and 'cycle', to build
-- infinite byte streams.
cons' :: Word8 -> ByteStream m r -> ByteStream m r
cons' :: forall (m :: * -> *) r. Word8 -> ByteStream m r -> ByteStream m r
cons' Word8
w (Chunk ByteString
c ByteStream m r
cs) | ByteString -> Int
B.length ByteString
c forall a. Ord a => a -> a -> Bool
< Int
16 = forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Word8 -> ByteString -> ByteString
B.cons Word8
w ByteString
c) ByteStream m r
cs
cons' Word8
w ByteStream m r
cs           = forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Word8 -> ByteString
B.singleton Word8
w) ByteStream m r
cs
{-# INLINE cons' #-}

-- | /O(n\/c)/ Append a byte to the end of a 'ByteStream'.
snoc :: Monad m => ByteStream m r -> Word8 -> ByteStream m r
snoc :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Word8 -> ByteStream m r
snoc ByteStream m r
cs Word8
w = do    -- cs <* singleton w
  r
r <- ByteStream m r
cs
  forall (m :: * -> *). Monad m => Word8 -> ByteStream m ()
singleton Word8
w
  forall (m :: * -> *) a. Monad m => a -> m a
return r
r
{-# INLINE snoc #-}

-- | /O(1)/ Extract the first element of a 'ByteStream', which must be non-empty.
head_ :: Monad m => ByteStream m r -> m Word8
head_ :: forall (m :: * -> *) r. Monad m => ByteStream m r -> m Word8
head_ (Empty r
_)   = forall a. HasCallStack => [Char] -> a
error [Char]
"head"
head_ (Chunk ByteString
c ByteStream m r
bs) = if ByteString -> Bool
B.null ByteString
c
                        then forall (m :: * -> *) r. Monad m => ByteStream m r -> m Word8
head_ ByteStream m r
bs
                        else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ByteString -> Word8
B.unsafeHead ByteString
c
head_ (Go m (ByteStream m r)
m)      = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r. Monad m => ByteStream m r -> m Word8
head_
{-# INLINABLE head_ #-}

-- | /O(c)/ Extract the first element of a 'ByteStream', if there is one.
-- Suitable for use with `SP.mapped`:
--
-- @
-- S.mapped Q.head :: Stream (Q.ByteStream m) m r -> Stream (Of (Maybe Word8)) m r
-- @
head :: Monad m => ByteStream m r -> m (Of (Maybe Word8) r)
head :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of (Maybe Word8) r)
head (Empty r
r)  = forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Maybe a
Nothing forall a b. a -> b -> Of a b
:> r
r)
head (Chunk ByteString
c ByteStream m r
rest) = case ByteString -> Maybe (Word8, ByteString)
B.uncons ByteString
c of
  Maybe (Word8, ByteString)
Nothing -> forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of (Maybe Word8) r)
head ByteStream m r
rest
  Just (Word8
w,ByteString
_) -> do
    r
r <- forall (m :: * -> *) a r. Monad m => Stream (Of a) m r -> m r
SP.effects forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of ByteString) m r
toChunks ByteStream m r
rest
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! forall a. a -> Maybe a
Just Word8
w forall a b. a -> b -> Of a b
:> r
r
head (Go m (ByteStream m r)
m)      = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of (Maybe Word8) r)
head
{-# INLINABLE head #-}

-- | /O(1)/ Extract the head and tail of a 'ByteStream', or its return value if
-- it is empty. This is the \'natural\' uncons for an effectful byte stream.
uncons :: Monad m => ByteStream m r -> m (Either r (Word8, ByteStream m r))
uncons :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (Word8, ByteStream m r))
uncons (Chunk c :: ByteString
c@(ByteString -> Int
B.length -> Int
len) ByteStream m r
cs)
    | Int
len forall a. Ord a => a -> a -> Bool
> Int
0    = let !h :: Word8
h = ByteString -> Word8
B.unsafeHead ByteString
c
                       !t :: ByteStream m r
t = if Int
len forall a. Ord a => a -> a -> Bool
> Int
1 then forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (ByteString -> ByteString
B.unsafeTail ByteString
c) ByteStream m r
cs else ByteStream m r
cs
                    in forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a b. b -> Either a b
Right (Word8
h, ByteStream m r
t)
    | Bool
otherwise  = forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (Word8, ByteStream m r))
uncons ByteStream m r
cs
uncons (Go m (ByteStream m r)
m)    = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (Word8, ByteStream m r))
uncons
uncons (Empty r
r) = forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. a -> Either a b
Left r
r)
{-# INLINABLE uncons #-}

-- | The same as `uncons`, will be removed in the next version.
nextByte :: Monad m => ByteStream m r -> m (Either r (Word8, ByteStream m r))
nextByte :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (Word8, ByteStream m r))
nextByte = forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (Word8, ByteStream m r))
uncons
{-# INLINABLE nextByte #-}
{-# DEPRECATED nextByte "Use uncons instead." #-}

-- | Like `uncons`, but yields the entire first `B.ByteString` chunk that the
-- stream is holding onto. If there wasn't one, it tries to fetch it.  Yields
-- the final @r@ return value when the 'ByteStream' is empty.
unconsChunk :: Monad m => ByteStream m r -> m (Either r (B.ByteString, ByteStream m r))
unconsChunk :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (ByteString, ByteStream m r))
unconsChunk (Chunk ByteString
c ByteStream m r
cs)
  | ByteString -> Bool
B.null ByteString
c = forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (ByteString, ByteStream m r))
unconsChunk ByteStream m r
cs
  | Bool
otherwise = forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. b -> Either a b
Right (ByteString
c,ByteStream m r
cs))
unconsChunk (Go m (ByteStream m r)
m) = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (ByteString, ByteStream m r))
unconsChunk
unconsChunk (Empty r
r) = forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. a -> Either a b
Left r
r)
{-# INLINABLE unconsChunk #-}

-- | The same as `unconsChunk`, will be removed in the next version.
nextChunk :: Monad m => ByteStream m r -> m (Either r (B.ByteString, ByteStream m r))
nextChunk :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (ByteString, ByteStream m r))
nextChunk = forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (ByteString, ByteStream m r))
unconsChunk
{-# INLINABLE nextChunk #-}
{-# DEPRECATED nextChunk "Use unconsChunk instead." #-}

-- | /O(n\/c)/ Extract the last element of a 'ByteStream', which must be finite
-- and non-empty.
last_ :: Monad m => ByteStream m r -> m Word8
last_ :: forall (m :: * -> *) r. Monad m => ByteStream m r -> m Word8
last_ (Empty r
_)      = forall a. HasCallStack => [Char] -> a
error [Char]
"Streaming.ByteString.last: empty string"
last_ (Go m (ByteStream m r)
m)         = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r. Monad m => ByteStream m r -> m Word8
last_
last_ (Chunk ByteString
c0 ByteStream m r
cs0) = forall {m :: * -> *} {r}.
Monad m =>
ByteString -> ByteStream m r -> m Word8
go ByteString
c0 ByteStream m r
cs0
 where
   go :: ByteString -> ByteStream m r -> m Word8
go ByteString
c (Empty r
_)    = if ByteString -> Bool
B.null ByteString
c
       then forall a. HasCallStack => [Char] -> a
error [Char]
"Streaming.ByteString.last: empty string"
       else forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ByteString -> Word8
unsafeLast ByteString
c
   go ByteString
_ (Chunk ByteString
c ByteStream m r
cs) = ByteString -> ByteStream m r -> m Word8
go ByteString
c ByteStream m r
cs
   go ByteString
x (Go m (ByteStream m r)
m)       = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> ByteStream m r -> m Word8
go ByteString
x
{-# INLINABLE last_ #-}

-- | Extract the last element of a `ByteStream`, if possible. Suitable for use
-- with `SP.mapped`:
--
-- @
-- S.mapped Q.last :: Streaming (ByteStream m) m r -> Stream (Of (Maybe Word8)) m r
-- @
last :: Monad m => ByteStream m r -> m (Of (Maybe Word8) r)
last :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of (Maybe Word8) r)
last (Empty r
r)      = forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Maybe a
Nothing forall a b. a -> b -> Of a b
:> r
r)
last (Go m (ByteStream m r)
m)         = m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of (Maybe Word8) r)
last
last (Chunk ByteString
c0 ByteStream m r
cs0) = forall {m :: * -> *} {b}.
Monad m =>
ByteString -> ByteStream m b -> m (Of (Maybe Word8) b)
go ByteString
c0 ByteStream m r
cs0
  where
    go :: ByteString -> ByteStream m b -> m (Of (Maybe Word8) b)
go ByteString
c (Empty b
r)    = forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just (ByteString -> Word8
unsafeLast ByteString
c) forall a b. a -> b -> Of a b
:> b
r)
    go ByteString
_ (Chunk ByteString
c ByteStream m b
cs) = ByteString -> ByteStream m b -> m (Of (Maybe Word8) b)
go ByteString
c ByteStream m b
cs
    go ByteString
x (Go m (ByteStream m b)
m)       = m (ByteStream m b)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteString -> ByteStream m b -> m (Of (Maybe Word8) b)
go ByteString
x
{-# INLINABLE last #-}

-- | /O(n\/c)/ Append two `ByteString`s together.
append :: Monad m => ByteStream m r -> ByteStream m s -> ByteStream m s
append :: forall (m :: * -> *) r s.
Monad m =>
ByteStream m r -> ByteStream m s -> ByteStream m s
append ByteStream m r
xs ByteStream m s
ys = forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
xs (forall a b. a -> b -> a
const ByteStream m s
ys) forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go
{-# INLINE append #-}

-- ---------------------------------------------------------------------
-- Transformations

-- | /O(n)/ 'map' @f xs@ is the ByteStream obtained by applying @f@ to each
-- element of @xs@.
map :: Monad m => (Word8 -> Word8) -> ByteStream m r -> ByteStream m r
map :: forall (m :: * -> *) r.
Monad m =>
(Word8 -> Word8) -> ByteStream m r -> ByteStream m r
map Word8 -> Word8
f ByteStream m r
z = forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
z forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> Word8) -> ByteString -> ByteString
B.map Word8 -> Word8
f) forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go
{-# INLINE map #-}

-- | @'for' xs f@ applies @f@ to each chunk in the stream, and
-- concatenates the resulting streams.
--
-- Generalised in 0.2.4 to match @streaming@: the callback's (ignored)
-- return value can be of any type.
--
-- @since 0.2.3
for :: Monad m => ByteStream m r -> (P.ByteString -> ByteStream m x) -> ByteStream m r
for :: forall (m :: * -> *) r x.
Monad m =>
ByteStream m r -> (ByteString -> ByteStream m x) -> ByteStream m r
for ByteStream m r
stream ByteString -> ByteStream m x
f = case ByteStream m r
stream of
  Empty r
r -> forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
  Chunk ByteString
bs ByteStream m r
bss -> ByteString -> ByteStream m x
f ByteString
bs forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall (m :: * -> *) r x.
Monad m =>
ByteStream m r -> (ByteString -> ByteStream m x) -> ByteStream m r
for ByteStream m r
bss ByteString -> ByteStream m x
f
  Go m (ByteStream m r)
m -> forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go ((forall (m :: * -> *) r x.
Monad m =>
ByteStream m r -> (ByteString -> ByteStream m x) -> ByteStream m r
`for` ByteString -> ByteStream m x
f) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ByteStream m r)
m)
{-# INLINE for #-}

-- -- | /O(n)/ 'reverse' @xs@ returns the elements of @xs@ in reverse order.
-- reverse :: ByteString -> ByteString
-- reverse cs0 = rev Empty cs0
--   where rev a Empty        = a
--         rev a (Chunk c cs) = rev (Chunk (B.reverse c) a) cs
-- {-# INLINE reverse #-}

-- | The 'intersperse' function takes a 'Word8' and a 'ByteStream' and
-- \`intersperses\' that byte between the elements of the 'ByteStream'. It is
-- analogous to the intersperse function on Streams.
intersperse :: Monad m => Word8 -> ByteStream m r -> ByteStream m r
intersperse :: forall (m :: * -> *) r.
Monad m =>
Word8 -> ByteStream m r -> ByteStream m r
intersperse Word8
_ (Empty r
r)    = forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
intersperse Word8
w (Go m (ByteStream m r)
m)       = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (m :: * -> *) r.
Monad m =>
Word8 -> ByteStream m r -> ByteStream m r
intersperse Word8
w) m (ByteStream m r)
m)
intersperse Word8
w (Chunk ByteString
c ByteStream m r
cs) | ByteString -> Bool
B.null ByteString
c = forall (m :: * -> *) r.
Monad m =>
Word8 -> ByteStream m r -> ByteStream m r
intersperse Word8
w ByteStream m r
cs
                           | Bool
otherwise =
                               forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Word8 -> ByteString -> ByteString
B.intersperse Word8
w ByteString
c)
                                 (forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
cs forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
intersperse') forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go)
  where intersperse' :: P.ByteString -> P.ByteString
        intersperse' :: ByteString -> ByteString
intersperse' (B.PS ForeignPtr Word8
fp Int
o Int
l)
          | Int
l forall a. Ord a => a -> a -> Bool
> Int
0 = Int -> (Ptr Word8 -> IO ()) -> ByteString
B.unsafeCreate (Int
2forall a. Num a => a -> a -> a
*Int
l) forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p' -> forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr Word8
fp forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> do
              forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr Word8
p' Word8
w
              Ptr Word8 -> Ptr Word8 -> CSize -> Word8 -> IO ()
B.c_intersperse (Ptr Word8
p' forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
1) (Ptr Word8
p forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
o) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
l) Word8
w
          | Bool
otherwise = ByteString
B.empty
{-# INLINABLE intersperse #-}

-- | 'foldr', applied to a binary operator, a starting value (typically the
-- right-identity of the operator), and a ByteStream, reduces the ByteStream
-- using the binary operator, from right to left.
--
foldr :: Monad m => (Word8 -> a -> a) -> a -> ByteStream m () -> m a
foldr :: forall (m :: * -> *) a.
Monad m =>
(Word8 -> a -> a) -> a -> ByteStream m () -> m a
foldr Word8 -> a -> a
k = forall (m :: * -> *) a r.
Monad m =>
(ByteString -> a -> a) -> a -> ByteStream m r -> m a
foldrChunks (forall a b c. (a -> b -> c) -> b -> a -> c
flip (forall a. (Word8 -> a -> a) -> a -> ByteString -> a
B.foldr Word8 -> a -> a
k))
{-# INLINE foldr #-}

-- | 'fold_', applied to a binary operator, a starting value (typically the
-- left-identity of the operator), and a ByteStream, reduces the ByteStream
-- using the binary operator, from left to right. We use the style of the foldl
-- library for left folds
fold_ :: Monad m => (x -> Word8 -> x) -> x -> (x -> b) -> ByteStream m () -> m b
fold_ :: forall (m :: * -> *) x b.
Monad m =>
(x -> Word8 -> x) -> x -> (x -> b) -> ByteStream m () -> m b
fold_ x -> Word8 -> x
step0 x
begin x -> b
finish ByteStream m ()
p0 = ByteStream m () -> x -> m b
loop ByteStream m ()
p0 x
begin
  where
    loop :: ByteStream m () -> x -> m b
loop ByteStream m ()
p !x
x = case ByteStream m ()
p of
        Chunk ByteString
bs ByteStream m ()
bss -> ByteStream m () -> x -> m b
loop ByteStream m ()
bss forall a b. (a -> b) -> a -> b
$! forall a. (a -> Word8 -> a) -> a -> ByteString -> a
B.foldl' x -> Word8 -> x
step0 x
x ByteString
bs
        Go    m (ByteStream m ())
m      -> m (ByteStream m ())
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ByteStream m ()
p' -> ByteStream m () -> x -> m b
loop ByteStream m ()
p' x
x
        Empty ()
_      -> forall (m :: * -> *) a. Monad m => a -> m a
return (x -> b
finish x
x)
{-# INLINABLE fold_ #-}

-- | 'fold' keeps the return value of the left-folded bytestring. Useful for
-- simultaneous folds over a segmented bytestream.
fold :: Monad m => (x -> Word8 -> x) -> x -> (x -> b) -> ByteStream m r -> m (Of b r)
fold :: forall (m :: * -> *) x b r.
Monad m =>
(x -> Word8 -> x) -> x -> (x -> b) -> ByteStream m r -> m (Of b r)
fold x -> Word8 -> x
step0 x
begin x -> b
finish ByteStream m r
p0 = ByteStream m r -> x -> m (Of b r)
loop ByteStream m r
p0 x
begin
  where
    loop :: ByteStream m r -> x -> m (Of b r)
loop ByteStream m r
p !x
x = case ByteStream m r
p of
        Chunk ByteString
bs ByteStream m r
bss -> ByteStream m r -> x -> m (Of b r)
loop ByteStream m r
bss forall a b. (a -> b) -> a -> b
$! forall a. (a -> Word8 -> a) -> a -> ByteString -> a
B.foldl' x -> Word8 -> x
step0 x
x ByteString
bs
        Go    m (ByteStream m r)
m      -> m (ByteStream m r)
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ByteStream m r
p' -> ByteStream m r -> x -> m (Of b r)
loop ByteStream m r
p' x
x
        Empty r
r      -> forall (m :: * -> *) a. Monad m => a -> m a
return (x -> b
finish x
x forall a b. a -> b -> Of a b
:> r
r)
{-# INLINABLE fold #-}

-- ---------------------------------------------------------------------
-- Special folds

-- /O(n)/ Concatenate a list of ByteStreams.
-- concat :: (Monad m) => [ByteStream m ()] -> ByteStream m ()
-- concat css0 = to css0
--   where
--     go css (Empty m')   = to css
--     go css (Chunk c cs) = Chunk c (go css cs)
--     go css (Go m)       = Go (fmap (go css) m)
--     to []               = Empty ()
--     to (cs:css)         = go css cs

-- ---------------------------------------------------------------------
-- Unfolds and replicates

{-| @'iterate' f x@ returns an infinite ByteStream of repeated applications
-- of @f@ to @x@:

> iterate f x == [x, f x, f (f x), ...]

>>> R.stdout $ R.take 50 $ R.iterate succ 39
()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXY
>>> Q.putStrLn $ Q.take 50 $ Q.iterate succ '\''
()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXY
-}
iterate :: (Word8 -> Word8) -> Word8 -> ByteStream m r
iterate :: forall (m :: * -> *) r. (Word8 -> Word8) -> Word8 -> ByteStream m r
iterate Word8 -> Word8
f = forall a r (m :: * -> *).
(a -> Either r (Word8, a)) -> a -> ByteStream m r
unfoldr (\Word8
x -> case Word8 -> Word8
f Word8
x of !Word8
x' -> forall a b. b -> Either a b
Right (Word8
x', Word8
x'))
{-# INLINABLE iterate #-}

{- | @'repeat' x@ is an infinite ByteStream, with @x@ the value of every
     element.

>>> R.stdout $ R.take 50 $ R.repeat 60
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>>> Q.putStrLn $ Q.take 50 $ Q.repeat 'z'
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
-}
repeat :: Word8 -> ByteStream m r
repeat :: forall (m :: * -> *) r. Word8 -> ByteStream m r
repeat Word8
w = ByteStream m r
cs where cs :: ByteStream m r
cs = forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> Word8 -> ByteString
B.replicate Int
BI.smallChunkSize Word8
w) ByteStream m r
cs
{-# INLINABLE repeat #-}

{- | 'cycle' ties a finite ByteStream into a circular one, or equivalently,
     the infinite repetition of the original ByteStream. For an empty bytestring
     (like @return 17@) it of course makes an unproductive loop

>>> Q.putStrLn $ Q.take 7 $ Q.cycle  "y\n"
y
y
y
y
-}
cycle :: Monad m => ByteStream m r -> ByteStream m s
cycle :: forall (m :: * -> *) r s.
Monad m =>
ByteStream m r -> ByteStream m s
cycle = forall (f :: * -> *) a b. Applicative f => f a -> f b
forever
{-# INLINE cycle #-}

-- | /O(n)/ The 'unfoldM' function is analogous to the Stream @unfoldr@.
-- 'unfoldM' builds a ByteStream from a seed value. The function takes the
-- element and returns 'Nothing' if it is done producing the ByteStream or
-- returns @'Just' (a,b)@, in which case, @a@ is a prepending to the ByteStream
-- and @b@ is used as the next element in a recursive call.
unfoldM :: Monad m => (a -> Maybe (Word8, a)) -> a -> ByteStream m ()
unfoldM :: forall (m :: * -> *) a.
Monad m =>
(a -> Maybe (Word8, a)) -> a -> ByteStream m ()
unfoldM a -> Maybe (Word8, a)
f a
s0 = Int -> a -> ByteStream m ()
unfoldChunk Int
32 a
s0
  where unfoldChunk :: Int -> a -> ByteStream m ()
unfoldChunk Int
n a
s =
          case forall a.
Int -> (a -> Maybe (Word8, a)) -> a -> (ByteString, Maybe a)
B.unfoldrN Int
n a -> Maybe (Word8, a)
f a
s of
            (ByteString
c, Maybe a
Nothing)
              | ByteString -> Bool
B.null ByteString
c  -> forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
              | Bool
otherwise -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
            (ByteString
c, Just a
s')  -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (Int -> a -> ByteStream m ()
unfoldChunk (Int
nforall a. Num a => a -> a -> a
*Int
2) a
s')
{-# INLINABLE unfoldM #-}

-- | Like `unfoldM`, but yields a final @r@ when the `Word8` generation is
-- complete.
unfoldr :: (a -> Either r (Word8, a)) -> a -> ByteStream m r
unfoldr :: forall a r (m :: * -> *).
(a -> Either r (Word8, a)) -> a -> ByteStream m r
unfoldr a -> Either r (Word8, a)
f a
s0 = Int -> a -> ByteStream m r
unfoldChunk Int
32 a
s0
  where unfoldChunk :: Int -> a -> ByteStream m r
unfoldChunk Int
n a
s =
          case forall a r.
Int -> (a -> Either r (Word8, a)) -> a -> (ByteString, Either r a)
unfoldrNE Int
n a -> Either r (Word8, a)
f a
s of
            (ByteString
c, Left r
r)
              | ByteString -> Bool
B.null ByteString
c  -> forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
              | Bool
otherwise -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r)
            (ByteString
c, Right a
s') -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (Int -> a -> ByteStream m r
unfoldChunk (Int
nforall a. Num a => a -> a -> a
*Int
2) a
s')
{-# INLINABLE unfoldr #-}

-- ---------------------------------------------------------------------
-- Substrings

{-| /O(n\/c)/ 'take' @n@, applied to a ByteStream @xs@, returns the prefix
    of @xs@ of length @n@, or @xs@ itself if @n > 'length' xs@.

    Note that in the streaming context this drops the final return value;
    'splitAt' preserves this information, and is sometimes to be preferred.

>>> Q.putStrLn $ Q.take 8 $ "Is there a God?" >> return True
Is there
>>> Q.putStrLn $ "Is there a God?" >> return True
Is there a God?
True
>>> rest <- Q.putStrLn $ Q.splitAt 8 $ "Is there a God?" >> return True
Is there
>>> Q.effects  rest
True
-}
take :: Monad m => Int64 -> ByteStream m r -> ByteStream m ()
take :: forall (m :: * -> *) r.
Monad m =>
Int64 -> ByteStream m r -> ByteStream m ()
take Int64
i ByteStream m r
_ | Int64
i forall a. Ord a => a -> a -> Bool
<= Int64
0 = forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
take Int64
i ByteStream m r
cs0         = forall {t} {m :: * -> *} {r}.
(Integral t, Functor m) =>
t -> ByteStream m r -> ByteStream m ()
take' Int64
i ByteStream m r
cs0
  where take' :: t -> ByteStream m r -> ByteStream m ()
take' t
0 ByteStream m r
_            = forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
        take' t
_ (Empty r
_)    = forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
        take' t
n (Chunk ByteString
c ByteStream m r
cs) =
          if t
n forall a. Ord a => a -> a -> Bool
< forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)
            then forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.take (forall a b. (Integral a, Num b) => a -> b
fromIntegral t
n) ByteString
c) (forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
            else forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (t -> ByteStream m r -> ByteStream m ()
take' (t
n forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)) ByteStream m r
cs)
        take' t
n (Go m (ByteStream m r)
m) = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t -> ByteStream m r -> ByteStream m ()
take' t
n) m (ByteStream m r)
m)
{-# INLINABLE take #-}

{-| /O(n\/c)/ 'drop' @n xs@ returns the suffix of @xs@ after the first @n@
    elements, or @[]@ if @n > 'length' xs@.

>>> Q.putStrLn $ Q.drop 6 "Wisconsin"
sin
>>> Q.putStrLn $ Q.drop 16 "Wisconsin"
<BLANKLINE>
-}
drop :: Monad m => Int64 -> ByteStream m r -> ByteStream m r
drop :: forall (m :: * -> *) r.
Monad m =>
Int64 -> ByteStream m r -> ByteStream m r
drop Int64
i ByteStream m r
p | Int64
i forall a. Ord a => a -> a -> Bool
<= Int64
0 = ByteStream m r
p
drop Int64
i ByteStream m r
cs0 = forall {t} {m :: * -> *} {r}.
(Integral t, Functor m) =>
t -> ByteStream m r -> ByteStream m r
drop' Int64
i ByteStream m r
cs0
  where drop' :: t -> ByteStream m r -> ByteStream m r
drop' t
0 ByteStream m r
cs           = ByteStream m r
cs
        drop' t
_ (Empty r
r)    = forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
        drop' t
n (Chunk ByteString
c ByteStream m r
cs) =
          if t
n forall a. Ord a => a -> a -> Bool
< forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)
            then forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.drop (forall a b. (Integral a, Num b) => a -> b
fromIntegral t
n) ByteString
c) ByteStream m r
cs
            else t -> ByteStream m r -> ByteStream m r
drop' (t
n forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)) ByteStream m r
cs
        drop' t
n (Go m (ByteStream m r)
m) = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t -> ByteStream m r -> ByteStream m r
drop' t
n) m (ByteStream m r)
m)
{-# INLINABLE drop #-}

{-| /O(n\/c)/ 'splitAt' @n xs@ is equivalent to @('take' n xs, 'drop' n xs)@.

>>> rest <- Q.putStrLn $ Q.splitAt 3 "therapist is a danger to good hyphenation, as Knuth notes"
the
>>> Q.putStrLn $ Q.splitAt 19 rest
rapist is a danger
-}
splitAt :: Monad m => Int64 -> ByteStream m r -> ByteStream m (ByteStream m r)
splitAt :: forall (m :: * -> *) r.
Monad m =>
Int64 -> ByteStream m r -> ByteStream m (ByteStream m r)
splitAt Int64
i ByteStream m r
cs0 | Int64
i forall a. Ord a => a -> a -> Bool
<= Int64
0 = forall (m :: * -> *) r. r -> ByteStream m r
Empty ByteStream m r
cs0
splitAt Int64
i ByteStream m r
cs0 = forall {t} {m :: * -> *} {r}.
(Integral t, Functor m) =>
t -> ByteStream m r -> ByteStream m (ByteStream m r)
splitAt' Int64
i ByteStream m r
cs0
  where splitAt' :: t -> ByteStream m r -> ByteStream m (ByteStream m r)
splitAt' t
0 ByteStream m r
cs           = forall (m :: * -> *) r. r -> ByteStream m r
Empty ByteStream m r
cs
        splitAt' t
_ (Empty r
r  )   = forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r)
        splitAt' t
n (Chunk ByteString
c ByteStream m r
cs) =
          if t
n forall a. Ord a => a -> a -> Bool
< forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)
            then forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.take (forall a b. (Integral a, Num b) => a -> b
fromIntegral t
n) ByteString
c) forall a b. (a -> b) -> a -> b
$
                     forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.drop (forall a b. (Integral a, Num b) => a -> b
fromIntegral t
n) ByteString
c) ByteStream m r
cs)
            else forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (t -> ByteStream m r -> ByteStream m (ByteStream m r)
splitAt' (t
n forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)) ByteStream m r
cs)
        splitAt' t
n (Go m (ByteStream m r)
m) = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go  (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t -> ByteStream m r -> ByteStream m (ByteStream m r)
splitAt' t
n) m (ByteStream m r)
m)
{-# INLINABLE splitAt #-}

-- | 'takeWhile', applied to a predicate @p@ and a ByteStream @xs@, returns the
-- longest prefix (possibly empty) of @xs@ of elements that satisfy @p@.
takeWhile :: Monad m => (Word8 -> Bool) -> ByteStream m r -> ByteStream m ()
takeWhile :: forall (m :: * -> *) r.
Monad m =>
(Word8 -> Bool) -> ByteStream m r -> ByteStream m ()
takeWhile Word8 -> Bool
f ByteStream m r
cs0 = ByteStream m r -> ByteStream m ()
takeWhile' ByteStream m r
cs0
  where
    takeWhile' :: ByteStream m r -> ByteStream m ()
takeWhile' (Empty r
_)    = forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
    takeWhile' (Go m (ByteStream m r)
m)       = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteStream m r -> ByteStream m ()
takeWhile' m (ByteStream m r)
m
    takeWhile' (Chunk ByteString
c ByteStream m r
cs) =
      case (Word8 -> Bool) -> ByteString -> Int
findIndexOrEnd (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Bool
f) ByteString
c of
        Int
0                  -> forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
        Int
n | Int
n forall a. Ord a => a -> a -> Bool
< ByteString -> Int
B.length ByteString
c -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.take Int
n ByteString
c) (forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
          | Bool
otherwise      -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (ByteStream m r -> ByteStream m ()
takeWhile' ByteStream m r
cs)
{-# INLINABLE takeWhile #-}

-- | 'dropWhile' @p xs@ returns the suffix remaining after 'takeWhile' @p xs@.
dropWhile :: Monad m => (Word8 -> Bool) -> ByteStream m r -> ByteStream m r
dropWhile :: forall (m :: * -> *) r.
Monad m =>
(Word8 -> Bool) -> ByteStream m r -> ByteStream m r
dropWhile Word8 -> Bool
p = ByteStream m r -> ByteStream m r
drop' where
  drop' :: ByteStream m r -> ByteStream m r
drop' ByteStream m r
bs = case ByteStream m r
bs of
    Empty r
r    -> forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
    Go m (ByteStream m r)
m       -> forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteStream m r -> ByteStream m r
drop' m (ByteStream m r)
m)
    Chunk ByteString
c ByteStream m r
cs -> case (Word8 -> Bool) -> ByteString -> Int
findIndexOrEnd (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Bool
p) ByteString
c of
        Int
0                  -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c ByteStream m r
cs
        Int
n | Int
n forall a. Ord a => a -> a -> Bool
< ByteString -> Int
B.length ByteString
c -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.drop Int
n ByteString
c) ByteStream m r
cs
          | Bool
otherwise      -> ByteStream m r -> ByteStream m r
drop' ByteStream m r
cs
{-# INLINABLE dropWhile #-}

-- | 'break' @p@ is equivalent to @'span' ('not' . p)@.
break :: Monad m => (Word8 -> Bool) -> ByteStream m r -> ByteStream m (ByteStream m r)
break :: forall (m :: * -> *) r.
Monad m =>
(Word8 -> Bool) -> ByteStream m r -> ByteStream m (ByteStream m r)
break Word8 -> Bool
f ByteStream m r
cs0 = ByteStream m r -> ByteStream m (ByteStream m r)
break' ByteStream m r
cs0
  where break' :: ByteStream m r -> ByteStream m (ByteStream m r)
break' (Empty r
r)        = forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r)
        break' (Chunk ByteString
c ByteStream m r
cs) =
          case (Word8 -> Bool) -> ByteString -> Int
findIndexOrEnd Word8 -> Bool
f ByteString
c of
            Int
0                  -> forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c ByteStream m r
cs)
            Int
n | Int
n forall a. Ord a => a -> a -> Bool
< ByteString -> Int
B.length ByteString
c -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.take Int
n ByteString
c) forall a b. (a -> b) -> a -> b
$
                                      forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.drop Int
n ByteString
c) ByteStream m r
cs)
              | Bool
otherwise      -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (ByteStream m r -> ByteStream m (ByteStream m r)
break' ByteStream m r
cs)
        break' (Go m (ByteStream m r)
m) = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteStream m r -> ByteStream m (ByteStream m r)
break' m (ByteStream m r)
m)
{-# INLINABLE break #-}

-- | 'span' @p xs@ breaks the ByteStream into two segments. It is equivalent to
-- @('takeWhile' p xs, 'dropWhile' p xs)@.
span :: Monad m => (Word8 -> Bool) -> ByteStream m r -> ByteStream m (ByteStream m r)
span :: forall (m :: * -> *) r.
Monad m =>
(Word8 -> Bool) -> ByteStream m r -> ByteStream m (ByteStream m r)
span Word8 -> Bool
p = forall (m :: * -> *) r.
Monad m =>
(Word8 -> Bool) -> ByteStream m r -> ByteStream m (ByteStream m r)
break (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Bool
p)
{-# INLINE span #-}

-- | /O(n)/ Splits a 'ByteStream' into components delimited by separators, where
-- the predicate returns True for a separator element. The resulting components
-- do not contain the separators. Two adjacent separators result in an empty
-- component in the output. eg.
--
-- > splitWith (=='a') "aabbaca" == ["","","bb","c",""]
-- > splitWith (=='a') []        == []
splitWith :: Monad m => (Word8 -> Bool) -> ByteStream m r -> Stream (ByteStream m) m r
splitWith :: forall (m :: * -> *) r.
Monad m =>
(Word8 -> Bool) -> ByteStream m r -> Stream (ByteStream m) m r
splitWith Word8 -> Bool
_ (Empty r
r)      = forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r
splitWith Word8 -> Bool
p (Go m (ByteStream m r)
m)         = forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (m :: * -> *) r.
Monad m =>
(Word8 -> Bool) -> ByteStream m r -> Stream (ByteStream m) m r
splitWith Word8 -> Bool
p) m (ByteStream m r)
m
splitWith Word8 -> Bool
p (Chunk ByteString
c0 ByteStream m r
cs0) = [ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb [] ((Word8 -> Bool) -> ByteString -> [ByteString]
B.splitWith Word8 -> Bool
p ByteString
c0) ByteStream m r
cs0
  where
-- comb :: [P.ByteString] -> [P.ByteString] -> ByteString -> [ByteString]
--  comb acc (s:[]) (Empty r)    = Step (revChunks (s:acc) (Return r))
  comb :: [ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb [ByteString]
acc [ByteString
s]    (Empty r
r)    = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk)
                                                 (forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r))
                                                 (ByteString
sforall a. a -> [a] -> [a]
:[ByteString]
acc)
  comb [ByteString]
acc [ByteString
s]    (Chunk ByteString
c ByteStream m r
cs) = [ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb (ByteString
sforall a. a -> [a] -> [a]
:[ByteString]
acc) ((Word8 -> Bool) -> ByteString -> [ByteString]
B.splitWith Word8 -> Bool
p ByteString
c) ByteStream m r
cs
  comb [ByteString]
acc [ByteString]
b      (Go m (ByteStream m r)
m)       = forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb [ByteString]
acc [ByteString]
b) m (ByteStream m r)
m)
  comb [ByteString]
acc (ByteString
s:[ByteString]
ss) ByteStream m r
cs           = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk)
                                                 (forall (m :: * -> *) r. r -> ByteStream m r
Empty ([ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb [] [ByteString]
ss ByteStream m r
cs))
                                                 (ByteString
sforall a. a -> [a] -> [a]
:[ByteString]
acc)
  comb [ByteString]
acc []  (Empty r
r)    = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk)
                                                 (forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r))
                                                 [ByteString]
acc
  comb [ByteString]
acc []  (Chunk ByteString
c ByteStream m r
cs) = [ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb [ByteString]
acc ((Word8 -> Bool) -> ByteString -> [ByteString]
B.splitWith Word8 -> Bool
p ByteString
c) ByteStream m r
cs
 --  comb acc (s:ss) cs           = Step (revChunks (s:acc) (comb [] ss cs))

{-# INLINABLE splitWith #-}

-- | /O(n)/ Break a 'ByteStream' into pieces separated by the byte
-- argument, consuming the delimiter. I.e.
--
-- > split '\n' "a\nb\nd\ne" == ["a","b","d","e"]
-- > split 'a'  "aXaXaXa"    == ["","X","X","X",""]
-- > split 'x'  "x"          == ["",""]
--
-- and
--
-- > intercalate [c] . split c == id
-- > split == splitWith . (==)
--
-- As for all splitting functions in this library, this function does not copy
-- the substrings, it just constructs new 'ByteStream's that are slices of the
-- original.
split :: Monad m => Word8 -> ByteStream m r -> Stream (ByteStream m) m r
split :: forall (m :: * -> *) r.
Monad m =>
Word8 -> ByteStream m r -> Stream (ByteStream m) m r
split Word8
w = ByteStream m r -> Stream (ByteStream m) m r
loop
  where
  loop :: ByteStream m r -> Stream (ByteStream m) m r
loop !ByteStream m r
x = case ByteStream m r
x of
    Empty r
r      -> forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r
    Go m (ByteStream m r)
m         -> forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteStream m r -> Stream (ByteStream m) m r
loop m (ByteStream m r)
m
    Chunk ByteString
c0 ByteStream m r
cs0 -> [ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb [] (Word8 -> ByteString -> [ByteString]
B.split Word8
w ByteString
c0) ByteStream m r
cs0
  comb :: [ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb ![ByteString]
acc [] (Empty r
r)    = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r.
Monad m =>
[ByteString] -> r -> ByteStream m r
revChunks [ByteString]
acc (forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r)
  comb [ByteString]
acc [] (Chunk ByteString
c ByteStream m r
cs)  = [ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb [ByteString]
acc (Word8 -> ByteString -> [ByteString]
B.split Word8
w ByteString
c) ByteStream m r
cs
  comb ![ByteString]
acc [ByteString
s] (Empty r
r)   = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r.
Monad m =>
[ByteString] -> r -> ByteStream m r
revChunks (ByteString
sforall a. a -> [a] -> [a]
:[ByteString]
acc) (forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r)
  comb [ByteString]
acc [ByteString
s] (Chunk ByteString
c ByteStream m r
cs) = [ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb (ByteString
sforall a. a -> [a] -> [a]
:[ByteString]
acc) (Word8 -> ByteString -> [ByteString]
B.split Word8
w ByteString
c) ByteStream m r
cs
  comb [ByteString]
acc [ByteString]
b (Go m (ByteStream m r)
m)         = forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb [ByteString]
acc [ByteString]
b) m (ByteStream m r)
m)
  comb [ByteString]
acc (ByteString
s:[ByteString]
ss) ByteStream m r
cs        = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r.
Monad m =>
[ByteString] -> r -> ByteStream m r
revChunks (ByteString
sforall a. a -> [a] -> [a]
:[ByteString]
acc) ([ByteString]
-> [ByteString] -> ByteStream m r -> Stream (ByteStream m) m r
comb [] [ByteString]
ss ByteStream m r
cs)
{-# INLINABLE split #-}

-- | The 'group' function takes a ByteStream and returns a list of ByteStreams
-- such that the concatenation of the result is equal to the argument. Moreover,
-- each sublist in the result contains only equal elements. For example,
--
-- > group "Mississippi" = ["M","i","ss","i","ss","i","pp","i"]
--
-- It is a special case of 'groupBy', which allows the programmer to supply
-- their own equality test.
group :: Monad m => ByteStream m r -> Stream (ByteStream m) m r
group :: forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (ByteStream m) m r
group = forall {m :: * -> *} {r}.
Functor m =>
ByteStream m r -> Stream (ByteStream m) m r
go
  where
    go :: ByteStream m r -> Stream (ByteStream m) m r
go (Empty r
r)        = forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r
    go (Go m (ByteStream m r)
m)           = forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteStream m r -> Stream (ByteStream m) m r
go m (ByteStream m r)
m
    go (Chunk ByteString
c ByteStream m r
cs)
      | ByteString -> Int
B.length ByteString
c forall a. Eq a => a -> a -> Bool
== Int
1 = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to [ByteString
c] (ByteString -> Word8
B.unsafeHead ByteString
c) ByteStream m r
cs
      | Bool
otherwise       = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to [Int -> ByteString -> ByteString
B.unsafeTake Int
1 ByteString
c] (ByteString -> Word8
B.unsafeHead ByteString
c) (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (ByteString -> ByteString
B.unsafeTail ByteString
c) ByteStream m r
cs)

    to :: [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to [ByteString]
acc !Word8
_ (Empty r
r) = forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks [ByteString]
acc (forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r))
    to [ByteString]
acc !Word8
w (Go m (ByteStream m r)
m) = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to [ByteString]
acc Word8
w forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ByteStream m r)
m
    to [ByteString]
acc !Word8
w (Chunk ByteString
c ByteStream m r
cs) = case (Word8 -> Bool) -> ByteString -> Int
findIndexOrEnd (forall a. Eq a => a -> a -> Bool
/= Word8
w) ByteString
c of
      Int
0 -> forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks [ByteString]
acc (forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteStream m r -> Stream (ByteStream m) m r
go (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c ByteStream m r
cs)))
      Int
n | Int
n forall a. Eq a => a -> a -> Bool
== ByteString -> Int
B.length ByteString
c -> [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to (Int -> ByteString -> ByteString
B.unsafeTake Int
n ByteString
c forall a. a -> [a] -> [a]
: [ByteString]
acc) Word8
w ByteStream m r
cs
        | Bool
otherwise       -> forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks (Int -> ByteString -> ByteString
B.unsafeTake Int
n ByteString
c forall a. a -> [a] -> [a]
: [ByteString]
acc) (forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteStream m r -> Stream (ByteStream m) m r
go (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.unsafeDrop Int
n ByteString
c) ByteStream m r
cs)))
{-# INLINABLE group #-}

-- | The 'groupBy' function is a generalized version of 'group'.
groupBy :: Monad m => (Word8 -> Word8 -> Bool) -> ByteStream m r -> Stream (ByteStream m) m r
groupBy :: forall (m :: * -> *) r.
Monad m =>
(Word8 -> Word8 -> Bool)
-> ByteStream m r -> Stream (ByteStream m) m r
groupBy Word8 -> Word8 -> Bool
rel = ByteStream m r -> Stream (ByteStream m) m r
go
  where
    -- go :: ByteStream m r -> Stream (ByteStream m) m r
    go :: ByteStream m r -> Stream (ByteStream m) m r
go (Empty r
r)        = forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r
    go (Go m (ByteStream m r)
m)           = forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteStream m r -> Stream (ByteStream m) m r
go m (ByteStream m r)
m
    go (Chunk ByteString
c ByteStream m r
cs)
      | ByteString -> Int
B.length ByteString
c forall a. Eq a => a -> a -> Bool
== Int
1 = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to [ByteString
c] (ByteString -> Word8
B.unsafeHead ByteString
c) ByteStream m r
cs
      | Bool
otherwise       = forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to [Int -> ByteString -> ByteString
B.unsafeTake Int
1 ByteString
c] (ByteString -> Word8
B.unsafeHead ByteString
c) (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (ByteString -> ByteString
B.unsafeTail ByteString
c) ByteStream m r
cs)

    -- to :: [B.ByteString] -> Word8 -> ByteStream m r -> ByteStream m (Stream (ByteStream m) m r)
    to :: [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to [ByteString]
acc !Word8
_ (Empty r
r) = forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks [ByteString]
acc (forall (m :: * -> *) r. r -> ByteStream m r
Empty (forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r))
    to [ByteString]
acc !Word8
w (Go m (ByteStream m r)
m) = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to [ByteString]
acc Word8
w forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m (ByteStream m r)
m
    to [ByteString]
acc !Word8
w (Chunk ByteString
c ByteStream m r
cs) = case (Word8 -> Bool) -> ByteString -> Int
findIndexOrEnd (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word8 -> Bool
rel Word8
w) ByteString
c of
      Int
0 -> forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks [ByteString]
acc (forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteStream m r -> Stream (ByteStream m) m r
go (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c ByteStream m r
cs)))
      Int
n | Int
n forall a. Eq a => a -> a -> Bool
== ByteString -> Int
B.length ByteString
c -> [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to (Int -> ByteString -> ByteString
B.unsafeTake Int
n ByteString
c forall a. a -> [a] -> [a]
: [ByteString]
acc) Word8
w ByteStream m r
cs
        | Bool
otherwise       -> forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks (Int -> ByteString -> ByteString
B.unsafeTake Int
n ByteString
c forall a. a -> [a] -> [a]
: [ByteString]
acc) (forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteStream m r -> Stream (ByteStream m) m r
go (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.unsafeDrop Int
n ByteString
c) ByteStream m r
cs)))
{-# INLINABLE groupBy #-}

-- | /O(n)/ The 'intercalate' function takes a 'ByteStream' and a list of
-- 'ByteStream's and concatenates the list after interspersing the first
-- argument between each element of the list.
intercalate :: Monad m => ByteStream m () -> Stream (ByteStream m) m r -> ByteStream m r
intercalate :: forall (m :: * -> *) r.
Monad m =>
ByteStream m () -> Stream (ByteStream m) m r -> ByteStream m r
intercalate ByteStream m ()
s = Stream (ByteStream m) m r -> ByteStream m r
loop
  where
    loop :: Stream (ByteStream m) m r -> ByteStream m r
loop (Return r
r) = forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
    loop (Effect m (Stream (ByteStream m) m r)
m) = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Stream (ByteStream m) m r -> ByteStream m r
loop m (Stream (ByteStream m) m r)
m
    loop (Step ByteStream m (Stream (ByteStream m) m r)
bs) = ByteStream m (Stream (ByteStream m) m r)
bs forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Return r
r -> forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r  -- not between final substream and stream end
        Stream (ByteStream m) m r
x        -> ByteStream m ()
s forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Stream (ByteStream m) m r -> ByteStream m r
loop Stream (ByteStream m) m r
x
{-# INLINABLE intercalate #-}

-- | Returns the number of times its argument appears in the `ByteStream`.
--
-- > count = length . elemIndices
count_ :: Monad m => Word8 -> ByteStream m r -> m Int
count_ :: forall (m :: * -> *) r. Monad m => Word8 -> ByteStream m r -> m Int
count_ Word8
w  = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Int
n :> r
_) -> Int
n) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a r.
Monad m =>
(a -> ByteString -> a) -> a -> ByteStream m r -> m (Of a r)
foldlChunks (\Int
n ByteString
c -> Int
n forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> ByteString -> Int
B.count Word8
w ByteString
c)) Int
0
{-# INLINE count_ #-}

-- | Returns the number of times its argument appears in the `ByteStream`.
-- Suitable for use with `SP.mapped`:
--
-- @
-- S.mapped (Q.count 37) :: Stream (Q.ByteStream m) m r -> Stream (Of Int) m r
-- @
count :: Monad m => Word8 -> ByteStream m r -> m (Of Int r)
count :: forall (m :: * -> *) r.
Monad m =>
Word8 -> ByteStream m r -> m (Of Int r)
count Word8
w ByteStream m r
cs = forall (m :: * -> *) a r.
Monad m =>
(a -> ByteString -> a) -> a -> ByteStream m r -> m (Of a r)
foldlChunks (\Int
n ByteString
c -> Int
n forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> ByteString -> Int
B.count Word8
w ByteString
c)) Int
0 ByteStream m r
cs
{-# INLINE count #-}

-- ---------------------------------------------------------------------
-- Searching ByteStreams

-- | /O(n)/ 'filter', applied to a predicate and a ByteStream, returns a
-- ByteStream containing those characters that satisfy the predicate.
filter :: Monad m => (Word8 -> Bool) -> ByteStream m r -> ByteStream m r
filter :: forall (m :: * -> *) r.
Monad m =>
(Word8 -> Bool) -> ByteStream m r -> ByteStream m r
filter Word8 -> Bool
p ByteStream m r
s = ByteStream m r -> ByteStream m r
go ByteStream m r
s
    where
        go :: ByteStream m r -> ByteStream m r
go (Empty r
r )   = forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
        go (Chunk ByteString
x ByteStream m r
xs) = forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
consChunk ((Word8 -> Bool) -> ByteString -> ByteString
B.filter Word8 -> Bool
p ByteString
x) (ByteStream m r -> ByteStream m r
go ByteStream m r
xs)
        go (Go m (ByteStream m r)
m)       = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteStream m r -> ByteStream m r
go m (ByteStream m r)
m)
                            -- should inspect for null
{-# INLINABLE filter #-}

-- ---------------------------------------------------------------------
-- ByteStream IO
--
-- Rule for when to close: is it expected to read the whole file?
-- If so, close when done.
--

-- | Read entire handle contents /lazily/ into a 'ByteStream'. Chunks are read
-- on demand, in at most @k@-sized chunks. It does not block waiting for a whole
-- @k@-sized chunk, so if less than @k@ bytes are available then they will be
-- returned immediately as a smaller chunk.
--
-- Note: the 'Handle' should be placed in binary mode with
-- 'System.IO.hSetBinaryMode' for 'hGetContentsN' to work correctly.
hGetContentsN :: MonadIO m => Int -> Handle -> ByteStream m ()
hGetContentsN :: forall (m :: * -> *). MonadIO m => Int -> Handle -> ByteStream m ()
hGetContentsN Int
k Handle
h = ByteStream m ()
loop -- TODO close on exceptions
  where
    loop :: ByteStream m ()
loop = do
        ByteString
c <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> Int -> IO ByteString
B.hGetSome Handle
h Int
k)
        -- only blocks if there is no data available
        if ByteString -> Bool
B.null ByteString
c
          then forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
          else forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c ByteStream m ()
loop
{-# INLINABLE hGetContentsN #-} -- very effective inline pragma

-- | Read @n@ bytes into a 'ByteStream', directly from the specified 'Handle',
-- in chunks of size @k@.
hGetN :: MonadIO m => Int -> Handle -> Int -> ByteStream m ()
hGetN :: forall (m :: * -> *).
MonadIO m =>
Int -> Handle -> Int -> ByteStream m ()
hGetN Int
k Handle
h Int
n | Int
n forall a. Ord a => a -> a -> Bool
> Int
0 = Int -> ByteStream m ()
readChunks Int
n
  where
    readChunks :: Int -> ByteStream m ()
readChunks !Int
i = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go forall a b. (a -> b) -> a -> b
$ do
        ByteString
c <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Handle -> Int -> IO ByteString
B.hGet Handle
h (forall a. Ord a => a -> a -> a
min Int
k Int
i)
        case ByteString -> Int
B.length ByteString
c of
            Int
0 -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
            Int
m -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (Int -> ByteStream m ()
readChunks (Int
i forall a. Num a => a -> a -> a
- Int
m))
hGetN Int
_ Handle
_ Int
0 = forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
hGetN Int
_ Handle
h Int
n = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Handle -> [Char] -> Int -> IO a
illegalBufferSize Handle
h [Char]
"hGet" Int
n  -- <--- REPAIR !!!
{-# INLINABLE hGetN #-}

-- | hGetNonBlockingN is similar to 'hGetContentsN', except that it will never
-- block waiting for data to become available, instead it returns only whatever
-- data is available. Chunks are read on demand, in @k@-sized chunks.
hGetNonBlockingN :: MonadIO m => Int -> Handle -> Int ->  ByteStream m ()
hGetNonBlockingN :: forall (m :: * -> *).
MonadIO m =>
Int -> Handle -> Int -> ByteStream m ()
hGetNonBlockingN Int
k Handle
h Int
n | Int
n forall a. Ord a => a -> a -> Bool
> Int
0 = Int -> ByteStream m ()
readChunks Int
n
  where
    readChunks :: Int -> ByteStream m ()
readChunks !Int
i = forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go forall a b. (a -> b) -> a -> b
$ do
        ByteString
c <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Handle -> Int -> IO ByteString
B.hGetNonBlocking Handle
h (forall a. Ord a => a -> a -> a
min Int
k Int
i)
        case ByteString -> Int
B.length ByteString
c of
            Int
0 -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
            Int
m -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (Int -> ByteStream m ()
readChunks (Int
i forall a. Num a => a -> a -> a
- Int
m)))
hGetNonBlockingN Int
_ Handle
_ Int
0 = forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
hGetNonBlockingN Int
_ Handle
h Int
n = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Handle -> [Char] -> Int -> IO a
illegalBufferSize Handle
h [Char]
"hGetNonBlocking" Int
n
{-# INLINABLE hGetNonBlockingN #-}

illegalBufferSize :: Handle -> String -> Int -> IO a
illegalBufferSize :: forall a. Handle -> [Char] -> Int -> IO a
illegalBufferSize Handle
handle [Char]
fn Int
sz =
    forall a. IOError -> IO a
ioError (IOErrorType -> [Char] -> Maybe Handle -> Maybe [Char] -> IOError
mkIOError IOErrorType
illegalOperationErrorType [Char]
msg (forall a. a -> Maybe a
Just Handle
handle) forall a. Maybe a
Nothing)
    --TODO: System.IO uses InvalidArgument here, but it's not exported :-(
    where
      msg :: [Char]
msg = [Char]
fn forall a. [a] -> [a] -> [a]
++ [Char]
": illegal ByteStream size " forall a. [a] -> [a] -> [a]
++ forall a. Show a => Int -> a -> ShowS
showsPrec Int
9 Int
sz []
{-# INLINABLE illegalBufferSize #-}

-- | Read entire handle contents /lazily/ into a 'ByteStream'. Chunks are read
-- on demand, using the default chunk size.
--
-- Note: the 'Handle' should be placed in binary mode with
-- 'System.IO.hSetBinaryMode' for 'hGetContents' to work correctly.
hGetContents :: MonadIO m => Handle -> ByteStream m ()
hGetContents :: forall (m :: * -> *). MonadIO m => Handle -> ByteStream m ()
hGetContents = forall (m :: * -> *). MonadIO m => Int -> Handle -> ByteStream m ()
hGetContentsN Int
defaultChunkSize
{-# INLINE hGetContents #-}

-- | Pipes-style nomenclature for 'hGetContents'.
fromHandle :: MonadIO m => Handle -> ByteStream m ()
fromHandle :: forall (m :: * -> *). MonadIO m => Handle -> ByteStream m ()
fromHandle = forall (m :: * -> *). MonadIO m => Handle -> ByteStream m ()
hGetContents
{-# INLINE fromHandle #-}

-- | Pipes-style nomenclature for 'getContents'.
stdin :: MonadIO m => ByteStream m ()
stdin :: forall (m :: * -> *). MonadIO m => ByteStream m ()
stdin = forall (m :: * -> *). MonadIO m => Handle -> ByteStream m ()
hGetContents Handle
IO.stdin
{-# INLINE stdin #-}

-- | Read @n@ bytes into a 'ByteStream', directly from the specified 'Handle'.
hGet :: MonadIO m => Handle -> Int -> ByteStream m ()
hGet :: forall (m :: * -> *). MonadIO m => Handle -> Int -> ByteStream m ()
hGet = forall (m :: * -> *).
MonadIO m =>
Int -> Handle -> Int -> ByteStream m ()
hGetN Int
defaultChunkSize
{-# INLINE hGet #-}

-- | hGetNonBlocking is similar to 'hGet', except that it will never block
-- waiting for data to become available, instead it returns only whatever data
-- is available. If there is no data available to be read, 'hGetNonBlocking'
-- returns 'empty'.
--
-- Note: on Windows and with Haskell implementation other than GHC, this
-- function does not work correctly; it behaves identically to 'hGet'.
hGetNonBlocking :: MonadIO m => Handle -> Int -> ByteStream m ()
hGetNonBlocking :: forall (m :: * -> *). MonadIO m => Handle -> Int -> ByteStream m ()
hGetNonBlocking = forall (m :: * -> *).
MonadIO m =>
Int -> Handle -> Int -> ByteStream m ()
hGetNonBlockingN Int
defaultChunkSize
{-# INLINE hGetNonBlocking #-}

-- | Write a 'ByteStream' to a file. Use
-- 'Control.Monad.Trans.ResourceT.runResourceT' to ensure that the handle is
-- closed.
--
-- >>> :set -XOverloadedStrings
-- >>> runResourceT $ Q.writeFile "hello.txt" "Hello world.\nGoodbye world.\n"
-- >>> :! cat "hello.txt"
-- Hello world.
-- Goodbye world.
-- >>> runResourceT $ Q.writeFile "hello2.txt" $ Q.readFile "hello.txt"
-- >>> :! cat hello2.txt
-- Hello world.
-- Goodbye world.
writeFile :: MonadResource m => FilePath -> ByteStream m r -> m r
writeFile :: forall (m :: * -> *) r.
MonadResource m =>
[Char] -> ByteStream m r -> m r
writeFile [Char]
f ByteStream m r
str = do
  (ReleaseKey
key, Handle
handle) <- forall (m :: * -> *) a.
MonadResource m =>
IO a -> (a -> IO ()) -> m (ReleaseKey, a)
allocate ([Char] -> IOMode -> IO Handle
openBinaryFile [Char]
f IOMode
WriteMode) Handle -> IO ()
hClose
  r
r <- forall (m :: * -> *) r.
MonadIO m =>
Handle -> ByteStream m r -> m r
hPut Handle
handle ByteStream m r
str
  forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
release ReleaseKey
key
  forall (m :: * -> *) a. Monad m => a -> m a
return r
r
{-# INLINE writeFile #-}

-- | Read an entire file into a chunked @'ByteStream' IO ()@. The handle will be
-- held open until EOF is encountered. The block governed by
-- 'Control.Monad.Trans.Resource.runResourceT' will end with the closing of any
-- handles opened.
--
-- >>> :! cat hello.txt
-- Hello world.
-- Goodbye world.
-- >>> runResourceT $ Q.stdout $ Q.readFile "hello.txt"
-- Hello world.
-- Goodbye world.
readFile :: MonadResource m => FilePath -> ByteStream m ()
readFile :: forall (m :: * -> *). MonadResource m => [Char] -> ByteStream m ()
readFile [Char]
f = forall (m :: * -> *) a b.
MonadResource m =>
IO a -> (a -> IO ()) -> (a -> ByteStream m b) -> ByteStream m b
bracketByteString ([Char] -> IOMode -> IO Handle
openBinaryFile [Char]
f IOMode
ReadMode) Handle -> IO ()
hClose forall (m :: * -> *). MonadIO m => Handle -> ByteStream m ()
hGetContents
{-# INLINE readFile #-}

-- | Append a 'ByteStream' to a file. Use
-- 'Control.Monad.Trans.ResourceT.runResourceT' to ensure that the handle is
-- closed.
--
-- >>> runResourceT $ Q.writeFile "hello.txt" "Hello world.\nGoodbye world.\n"
-- >>> runResourceT $ Q.stdout $ Q.readFile "hello.txt"
-- Hello world.
-- Goodbye world.
-- >>> runResourceT $ Q.appendFile "hello.txt" "sincerely yours,\nArthur\n"
-- >>> runResourceT $ Q.stdout $  Q.readFile "hello.txt"
-- Hello world.
-- Goodbye world.
-- sincerely yours,
-- Arthur
appendFile :: MonadResource m => FilePath -> ByteStream m r -> m r
appendFile :: forall (m :: * -> *) r.
MonadResource m =>
[Char] -> ByteStream m r -> m r
appendFile [Char]
f ByteStream m r
str = do
  (ReleaseKey
key, Handle
handle) <- forall (m :: * -> *) a.
MonadResource m =>
IO a -> (a -> IO ()) -> m (ReleaseKey, a)
allocate ([Char] -> IOMode -> IO Handle
openBinaryFile [Char]
f IOMode
AppendMode) Handle -> IO ()
hClose
  r
r <- forall (m :: * -> *) r.
MonadIO m =>
Handle -> ByteStream m r -> m r
hPut Handle
handle ByteStream m r
str
  forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
release ReleaseKey
key
  forall (m :: * -> *) a. Monad m => a -> m a
return r
r
{-# INLINE appendFile #-}

-- | Equivalent to @hGetContents stdin@. Will read /lazily/.
getContents :: MonadIO m => ByteStream m ()
getContents :: forall (m :: * -> *). MonadIO m => ByteStream m ()
getContents = forall (m :: * -> *). MonadIO m => Handle -> ByteStream m ()
hGetContents Handle
IO.stdin
{-# INLINE getContents #-}

-- | Outputs a 'ByteStream' to the specified 'Handle'.
hPut ::  MonadIO m => Handle -> ByteStream m r -> m r
hPut :: forall (m :: * -> *) r.
MonadIO m =>
Handle -> ByteStream m r -> m r
hPut Handle
h ByteStream m r
cs = forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
cs forall (m :: * -> *) a. Monad m => a -> m a
return (\ByteString
x m r
y -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> ByteString -> IO ()
B.hPut Handle
h ByteString
x) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m r
y) (forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall a. a -> a
id)
{-# INLINE hPut #-}

-- | Pipes nomenclature for 'hPut'.
toHandle :: MonadIO m => Handle -> ByteStream m r -> m r
toHandle :: forall (m :: * -> *) r.
MonadIO m =>
Handle -> ByteStream m r -> m r
toHandle = forall (m :: * -> *) r.
MonadIO m =>
Handle -> ByteStream m r -> m r
hPut
{-# INLINE toHandle #-}

-- | Pipes-style nomenclature for @putStr@.
stdout ::  MonadIO m => ByteStream m r -> m r
stdout :: forall (m :: * -> *) r. MonadIO m => ByteStream m r -> m r
stdout = forall (m :: * -> *) r.
MonadIO m =>
Handle -> ByteStream m r -> m r
hPut Handle
IO.stdout
{-# INLINE stdout #-}

-- -- | Similar to 'hPut' except that it will never block. Instead it returns
-- any tail that did not get written. This tail may be 'empty' in the case that
-- the whole string was written, or the whole original string if nothing was
-- written. Partial writes are also possible.
--
-- Note: on Windows and with Haskell implementation other than GHC, this
-- function does not work correctly; it behaves identically to 'hPut'.
--
-- hPutNonBlocking ::  MonadIO m => Handle -> ByteStream m r -> ByteStream m r
-- hPutNonBlocking _ (Empty r)         = Empty r
-- hPutNonBlocking h (Go m) = Go $ fmap (hPutNonBlocking h) m
-- hPutNonBlocking h bs@(Chunk c cs) = do
--   c' <- lift $ B.hPutNonBlocking h c
--   case B.length c' of
--     l' | l' == B.length c -> hPutNonBlocking h cs
--     0                     -> bs
--     _                     -> Chunk c' cs
-- {-# INLINABLE hPutNonBlocking #-}

-- | A synonym for @hPut@, for compatibility
--
-- hPutStr :: Handle -> ByteStream IO r -> IO r
-- hPutStr = hPut
--
-- -- | Write a ByteStream to stdout
-- putStr :: ByteStream IO r -> IO r
-- putStr = hPut IO.stdout

-- | The interact function takes a function of type @ByteStream -> ByteStream@
-- as its argument. The entire input from the standard input device is passed to
-- this function as its argument, and the resulting string is output on the
-- standard output device.
--
-- > interact morph = stdout (morph stdin)
interact :: (ByteStream IO () -> ByteStream IO r) -> IO r
interact :: forall r. (ByteStream IO () -> ByteStream IO r) -> IO r
interact ByteStream IO () -> ByteStream IO r
f = forall (m :: * -> *) r. MonadIO m => ByteStream m r -> m r
stdout (ByteStream IO () -> ByteStream IO r
f forall (m :: * -> *). MonadIO m => ByteStream m ()
stdin)
{-# INLINE interact #-}

-- -- ---------------------------------------------------------------------
-- -- Internal utilities

-- | Used in `group` and `groupBy`.
revNonEmptyChunks :: [P.ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks :: forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' (\ByteStream m r -> ByteStream m r
f ByteString
bs -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStream m r -> ByteStream m r
f) forall a. a -> a
id
{-# INLINE revNonEmptyChunks #-}

-- | Reverse a list of possibly-empty chunks into a lazy ByteString.
revChunks :: Monad m => [P.ByteString] -> r -> ByteStream m r
revChunks :: forall (m :: * -> *) r.
Monad m =>
[ByteString] -> r -> ByteStream m r
revChunks [ByteString]
cs r
r = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk) (forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r) [ByteString]
cs
{-# INLINE revChunks #-}

-- | Zip a list and a stream-of-byte-streams together.
zipWithStream
  :: Monad m
  => (forall x . a -> ByteStream m x -> ByteStream m x)
  -> [a]
  -> Stream (ByteStream m) m r
  -> Stream (ByteStream m) m r
zipWithStream :: forall (m :: * -> *) a r.
Monad m =>
(forall x. a -> ByteStream m x -> ByteStream m x)
-> [a] -> Stream (ByteStream m) m r -> Stream (ByteStream m) m r
zipWithStream forall x. a -> ByteStream m x -> ByteStream m x
op [a]
zs = [a] -> Stream (ByteStream m) m r -> Stream (ByteStream m) m r
loop [a]
zs
  where
    loop :: [a] -> Stream (ByteStream m) m r -> Stream (ByteStream m) m r
loop [] !Stream (ByteStream m) m r
ls      = [a] -> Stream (ByteStream m) m r -> Stream (ByteStream m) m r
loop [a]
zs Stream (ByteStream m) m r
ls
    loop a :: [a]
a@(a
x:[a]
xs)  Stream (ByteStream m) m r
ls = case Stream (ByteStream m) m r
ls of
      Return r
r   -> forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r
      Step ByteStream m (Stream (ByteStream m) m r)
fls   -> forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([a] -> Stream (ByteStream m) m r -> Stream (ByteStream m) m r
loop [a]
xs) (forall x. a -> ByteStream m x -> ByteStream m x
op a
x ByteStream m (Stream (ByteStream m) m r)
fls)
      Effect m (Stream (ByteStream m) m r)
mls -> forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([a] -> Stream (ByteStream m) m r -> Stream (ByteStream m) m r
loop [a]
a) m (Stream (ByteStream m) m r)
mls
{-# INLINABLE zipWithStream #-}

-- | Take a builder constructed otherwise and convert it to a genuine streaming
-- bytestring.
--
-- >>>  Q.putStrLn $ Q.toStreamingByteString $ stringUtf8 "哈斯克尔" <> stringUtf8 " " <> integerDec 98
-- 哈斯克尔 98
--
-- <https://gist.github.com/michaelt/6ea89ca95a77b0ef91f3 This benchmark> shows
-- its performance is indistinguishable from @toLazyByteString@
toStreamingByteString :: MonadIO m => Builder -> ByteStream m ()
toStreamingByteString :: forall (m :: * -> *). MonadIO m => Builder -> ByteStream m ()
toStreamingByteString = forall (m :: * -> *).
MonadIO m =>
AllocationStrategy -> Builder -> ByteStream m ()
toStreamingByteStringWith
 (Int -> Int -> AllocationStrategy
safeStrategy Int
BI.smallChunkSize Int
BI.defaultChunkSize)
{-# INLINE toStreamingByteString #-}

-- | Take a builder and convert it to a genuine streaming bytestring, using a
-- specific allocation strategy.
toStreamingByteStringWith :: MonadIO m => AllocationStrategy -> Builder -> ByteStream m ()
toStreamingByteStringWith :: forall (m :: * -> *).
MonadIO m =>
AllocationStrategy -> Builder -> ByteStream m ()
toStreamingByteStringWith AllocationStrategy
strategy Builder
builder0 = do
       ChunkIOStream ()
cios <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (forall a. AllocationStrategy -> BuildStep a -> IO (ChunkIOStream a)
buildStepToCIOS AllocationStrategy
strategy (Builder -> BuildStep ()
runBuilder Builder
builder0))
       let loop :: ChunkIOStream r -> ByteStream m r
loop ChunkIOStream r
cios0 = case ChunkIOStream r
cios0 of
              Yield1 ByteString
bs IO (ChunkIOStream r)
io   -> forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs forall a b. (a -> b) -> a -> b
$ do
                    ChunkIOStream r
cios1 <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (ChunkIOStream r)
io
                    ChunkIOStream r -> ByteStream m r
loop ChunkIOStream r
cios1
              Finished Buffer
buf r
r -> forall {m :: * -> *} {r}.
Buffer -> ByteStream m r -> ByteStream m r
trimmedChunkFromBuffer Buffer
buf (forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r)
           trimmedChunkFromBuffer :: Buffer -> ByteStream m r -> ByteStream m r
trimmedChunkFromBuffer Buffer
buffer ByteStream m r
k
              | ByteString -> Bool
B.null ByteString
bs                            = ByteStream m r
k
              |  Int
2 forall a. Num a => a -> a -> a
* ByteString -> Int
B.length ByteString
bs forall a. Ord a => a -> a -> Bool
< Buffer -> Int
bufferSize Buffer
buffer = forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (ByteString -> ByteString
B.copy ByteString
bs) ByteStream m r
k
              | Bool
otherwise                            = forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs          ByteStream m r
k
              where
                bs :: ByteString
bs = Buffer -> ByteString
byteStringFromBuffer Buffer
buffer
       forall {m :: * -> *} {r}.
MonadIO m =>
ChunkIOStream r -> ByteStream m r
loop ChunkIOStream ()
cios
{-# INLINABLE toStreamingByteStringWith #-}
{-# SPECIALIZE toStreamingByteStringWith ::  AllocationStrategy -> Builder -> ByteStream IO () #-}

-- | Concatenate a stream of builders (not a streaming bytestring!) into a
-- single builder.
--
-- >>> let aa = yield (integerDec 10000) >> yield (string8 " is a number.") >> yield (char8 '\n')
-- >>> hPutBuilder IO.stdout $ concatBuilders aa
-- 10000 is a number.
concatBuilders :: Stream (Of Builder) IO () -> Builder
concatBuilders :: Stream (Of Builder) IO () -> Builder
concatBuilders Stream (Of Builder) IO ()
p = (forall r. BuildStep r -> BuildStep r) -> Builder
builder forall a b. (a -> b) -> a -> b
$ \BuildStep r
bstep BufferRange
r -> do
  case Stream (Of Builder) IO ()
p of
    Return ()
_          -> forall a. Builder -> BuildStep a -> BuildStep a
runBuilderWith forall a. Monoid a => a
mempty BuildStep r
bstep BufferRange
r
    Step (Builder
b :> Stream (Of Builder) IO ()
rest)  -> forall a. Builder -> BuildStep a -> BuildStep a
runBuilderWith (Builder
b forall a. Monoid a => a -> a -> a
`mappend` Stream (Of Builder) IO () -> Builder
concatBuilders Stream (Of Builder) IO ()
rest) BuildStep r
bstep BufferRange
r
    Effect IO (Stream (Of Builder) IO ())
m          -> IO (Stream (Of Builder) IO ())
m forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Stream (Of Builder) IO ()
p' -> forall a. Builder -> BuildStep a -> BuildStep a
runBuilderWith (Stream (Of Builder) IO () -> Builder
concatBuilders Stream (Of Builder) IO ()
p') BuildStep r
bstep BufferRange
r
{-# INLINABLE concatBuilders #-}

-- | A simple construction of a builder from a 'ByteString'.
--
-- >>> let aaa = "10000 is a number\n" :: Q.ByteString IO ()
-- >>>  hPutBuilder  IO.stdout $ toBuilder  aaa
-- 10000 is a number
toBuilder :: ByteStream IO () -> Builder
toBuilder :: ByteStream IO () -> Builder
toBuilder  =  Stream (Of Builder) IO () -> Builder
concatBuilders forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
SP.map ByteString -> Builder
byteString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of ByteString) m r
toChunks
{-# INLINABLE toBuilder #-}