{-# 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
  , 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 :: Stream (ByteStream m) m r -> ByteStream m r
concat Stream (ByteStream m) m r
x = Stream (ByteStream m) m r
-> (ByteStream m (ByteStream m r) -> ByteStream m r)
-> (m (ByteStream m r) -> ByteStream m r)
-> (r -> ByteStream m r)
-> ByteStream m r
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 ByteStream m (ByteStream m r) -> ByteStream m r
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join m (ByteStream m r) -> ByteStream m r
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go r -> ByteStream m r
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 :: ByteStream (t m) a -> t (ByteStream m) a
distribute ByteStream (t m) a
ls = ByteStream (t m) a
-> (a -> t (ByteStream m) a)
-> (ByteString -> t (ByteStream m) a -> t (ByteStream m) a)
-> (t m (t (ByteStream m) a) -> t (ByteStream m) a)
-> t (ByteStream m) a
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
             a -> t (ByteStream m) a
forall (m :: * -> *) a. Monad m => a -> m a
return
             (\ByteString
bs t (ByteStream m) a
x -> t (ByteStream m) (t (ByteStream m) a) -> t (ByteStream m) a
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (t (ByteStream m) (t (ByteStream m) a) -> t (ByteStream m) a)
-> t (ByteStream m) (t (ByteStream m) a) -> t (ByteStream m) a
forall a b. (a -> b) -> a -> b
$ ByteStream m (t (ByteStream m) a)
-> t (ByteStream m) (t (ByteStream m) a)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ByteStream m (t (ByteStream m) a)
 -> t (ByteStream m) (t (ByteStream m) a))
-> ByteStream m (t (ByteStream m) a)
-> t (ByteStream m) (t (ByteStream m) a)
forall a b. (a -> b) -> a -> b
$ ByteString
-> ByteStream m (t (ByteStream m) a)
-> ByteStream m (t (ByteStream m) a)
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs (t (ByteStream m) a -> ByteStream m (t (ByteStream m) a)
forall (m :: * -> *) r. r -> ByteStream m r
Empty t (ByteStream m) a
x) )
             (t (ByteStream m) (t (ByteStream m) a) -> t (ByteStream m) a
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (t (ByteStream m) (t (ByteStream m) a) -> t (ByteStream m) a)
-> (t m (t (ByteStream m) a)
    -> t (ByteStream m) (t (ByteStream m) a))
-> t m (t (ByteStream m) a)
-> t (ByteStream m) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall a. m a -> ByteStream m a)
-> t m (t (ByteStream m) a)
-> t (ByteStream m) (t (ByteStream m) a)
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 (m (ByteStream m a) -> ByteStream m a
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (m (ByteStream m a) -> ByteStream m a)
-> (m a -> m (ByteStream m a)) -> m a -> ByteStream m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> ByteStream m a) -> m a -> m (ByteStream m a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> ByteStream m a
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 :: ByteStream m r -> m r
effects ByteStream m r
bs = case ByteStream m r
bs of
  Empty r
r      -> r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return r
r
  Go m (ByteStream m r)
m         -> m (ByteStream m r)
m m (ByteStream m r) -> (ByteStream m r -> m r) -> m r
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m r
forall (m :: * -> *) r. Monad m => ByteStream m r -> m r
effects
  Chunk ByteString
_ ByteStream m r
rest -> ByteStream m r -> m r
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 :: t m (ByteStream m r) -> t m r
drained t m (ByteStream m r)
t = t m (ByteStream m r)
t t m (ByteStream m r) -> (ByteStream m r -> t m r) -> t m r
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m r -> t m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m r -> t m r)
-> (ByteStream m r -> m r) -> ByteStream m r -> t m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStream m r -> m r
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 :: ByteStream m ()
empty = () -> ByteStream m ()
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 :: Word8 -> ByteStream m ()
singleton Word8
w = ByteString -> ByteStream m () -> ByteStream m ()
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Word8 -> ByteString
B.singleton Word8
w)  (() -> ByteStream m ()
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 :: Stream (Of Word8) m r -> ByteStream m r
pack = Stream (Of Word8) m r -> ByteStream m r
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 :: ByteStream m r -> Stream (Of Word8) m r
unpack = ByteStream m r -> Stream (Of Word8) m r
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 :: Stream (Of ByteString) m r -> ByteStream m r
fromChunks Stream (Of ByteString) m r
cs = Stream (Of ByteString) m r
-> (Of ByteString (ByteStream m r) -> ByteStream m r)
-> (m (ByteStream m r) -> ByteStream m r)
-> (r -> ByteStream m r)
-> ByteStream m r
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) -> ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs ByteStream m r
rest) m (ByteStream m r) -> ByteStream m r
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go r -> ByteStream m r
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 :: ByteStream m r -> Stream (Of ByteString) m r
toChunks ByteStream m r
bs = ByteStream m r
-> (r -> Stream (Of ByteString) m r)
-> (ByteString
    -> Stream (Of ByteString) m r -> Stream (Of ByteString) m r)
-> (m (Stream (Of ByteString) m r) -> Stream (Of ByteString) m r)
-> Stream (Of ByteString) m r
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 -> Stream (Of ByteString) m r
forall (m :: * -> *) a. Monad m => a -> m a
return (\ByteString
b Stream (Of ByteString) m r
mx -> Of ByteString (Stream (Of ByteString) m r)
-> Stream (Of ByteString) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteString
bByteString
-> Stream (Of ByteString) m r
-> Of ByteString (Stream (Of ByteString) m r)
forall a b. a -> b -> Of a b
:> Stream (Of ByteString) m r
mx)) m (Stream (Of ByteString) m r) -> Stream (Of ByteString) m r
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 :: ByteString -> ByteStream m ()
fromStrict ByteString
bs | ByteString -> Bool
B.null ByteString
bs = () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
              | Bool
otherwise = ByteString -> ByteStream m () -> ByteStream m ()
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs (() -> ByteStream m ()
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_ :: ByteStream m r -> m ByteString
toStrict_ = ([ByteString] -> ByteString) -> m [ByteString] -> m ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [ByteString] -> ByteString
B.concat (m [ByteString] -> m ByteString)
-> (ByteStream m r -> m [ByteString])
-> ByteStream m r
-> m ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stream (Of ByteString) m r -> m [ByteString]
forall (m :: * -> *) a r. Monad m => Stream (Of a) m r -> m [a]
SP.toList_ (Stream (Of ByteString) m r -> m [ByteString])
-> (ByteStream m r -> Stream (Of ByteString) m r)
-> ByteStream m r
-> m [ByteString]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStream m r -> Stream (Of ByteString) m r
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 :: ByteStream m r -> m (Of ByteString r)
toStrict ByteStream m r
bs = do
  ([ByteString]
bss :> r
r) <- Stream (Of ByteString) m r -> m (Of [ByteString] r)
forall (m :: * -> *) a r.
Monad m =>
Stream (Of a) m r -> m (Of [a] r)
SP.toList (ByteStream m r -> Stream (Of ByteString) m r
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of ByteString) m r
toChunks ByteStream m r
bs)
  Of ByteString r -> m (Of ByteString r)
forall (m :: * -> *) a. Monad m => a -> m a
return ([ByteString] -> ByteString
B.concat [ByteString]
bss ByteString -> r -> Of ByteString r
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 :: ByteString -> ByteStream m ()
fromLazy = (ByteString -> ByteStream m () -> ByteStream m ())
-> ByteStream m () -> ByteString -> ByteStream m ()
forall a. (ByteString -> a -> a) -> a -> ByteString -> a
BI.foldrChunks ByteString -> ByteStream m () -> ByteStream m ()
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (() -> ByteStream m ()
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_ :: ByteStream m r -> m ByteString
toLazy_ ByteStream m r
bs = ByteStream m r
-> (r -> m ByteString)
-> (ByteString -> m ByteString -> m ByteString)
-> (m (m ByteString) -> m ByteString)
-> m ByteString
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
_ -> ByteString -> m ByteString
forall (m :: * -> *) a. Monad m => a -> m a
return ByteString
BI.Empty) ((ByteString -> ByteString) -> m ByteString -> m ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((ByteString -> ByteString) -> m ByteString -> m ByteString)
-> (ByteString -> ByteString -> ByteString)
-> ByteString
-> m ByteString
-> m ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString -> ByteString
BI.Chunk) m (m ByteString) -> m ByteString
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 :: ByteStream m r -> m (Of ByteString r)
toLazy ByteStream m r
bs0 = ByteStream m r
-> (r -> m (Of ByteString r))
-> (ByteString -> m (Of ByteString r) -> m (Of ByteString r))
-> (m (m (Of ByteString r)) -> m (Of ByteString r))
-> m (Of ByteString r)
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 -> Of ByteString r -> m (Of ByteString r)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString
BI.Empty ByteString -> r -> Of ByteString r
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
                      Of ByteString r -> m (Of ByteString r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Of ByteString r -> m (Of ByteString r))
-> Of ByteString r -> m (Of ByteString r)
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString -> ByteString
BI.Chunk ByteString
b ByteString
bs ByteString -> r -> Of ByteString r
forall a b. a -> b -> Of a b
:> r
x
                      )
                m (m (Of ByteString r)) -> m (Of ByteString r)
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 :: ByteStream m r -> m (Of Bool r)
null (Empty r
r)  = Of Bool r -> m (Of Bool r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True Bool -> r -> Of Bool r
forall a b. a -> b -> Of a b
:> r
r)
null (Go m (ByteStream m r)
m)     = m (ByteStream m r)
m m (ByteStream m r)
-> (ByteStream m r -> m (Of Bool r)) -> m (Of Bool r)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m (Of Bool r)
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 ByteStream m r -> m (Of Bool r)
forall (m :: * -> *) r. Monad m => ByteStream m r -> m (Of Bool r)
null ByteStream m r
rest
   else do
     r
r <- Stream (Of ByteString) m r -> m r
forall (m :: * -> *) a r. Monad m => Stream (Of a) m r -> m r
SP.effects (ByteStream m r -> Stream (Of ByteString) m r
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of ByteString) m r
toChunks ByteStream m r
rest)
     Of Bool r -> m (Of Bool r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False Bool -> r -> Of Bool r
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_ :: ByteStream m r -> m Bool
null_ (Empty r
_)      = Bool -> m Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
null_ (Go m (ByteStream m r)
m)         = m (ByteStream m r)
m m (ByteStream m r) -> (ByteStream m r -> m Bool) -> m Bool
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m Bool
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 ByteStream m r -> m Bool
forall (m :: * -> *) r. Monad m => ByteStream m r -> m Bool
null_ ByteStream m r
rest
  else Bool -> m Bool
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 :: ByteStream m r -> m (Of Bool (ByteStream m r))
testNull (Empty r
r)  = Of Bool (ByteStream m r) -> m (Of Bool (ByteStream m r))
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True Bool -> ByteStream m r -> Of Bool (ByteStream m r)
forall a b. a -> b -> Of a b
:> r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r)
testNull (Go m (ByteStream m r)
m)     = m (ByteStream m r)
m m (ByteStream m r)
-> (ByteStream m r -> m (Of Bool (ByteStream m r)))
-> m (Of Bool (ByteStream m r))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m (Of Bool (ByteStream m r))
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 ByteStream m r -> m (Of Bool (ByteStream m r))
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of Bool (ByteStream m r))
testNull ByteStream m r
rest
   else Of Bool (ByteStream m r) -> m (Of Bool (ByteStream m r))
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False Bool -> ByteStream m r -> Of Bool (ByteStream m r)
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 :: Stream (ByteStream m) m r -> Stream (ByteStream m) m r
denull = Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall r.
Either
  (ByteStream m (Stream (ByteStream m) m r))
  (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
loop (Either
   (ByteStream m (Stream (ByteStream m) m r))
   (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> (Stream (ByteStream m) m r
    -> Either
         (ByteStream m (Stream (ByteStream m) m r))
         (Stream (ByteStream m) m r))
-> Stream (ByteStream m) m r
-> Stream (ByteStream m) m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stream (ByteStream m) m r
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 -> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ ByteString
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (ByteStream m (Stream (ByteStream m) m r)
 -> ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall a b. (a -> b) -> a -> b
$ (Stream (ByteStream m) m r -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
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 (Either
   (ByteStream m (Stream (ByteStream m) m r))
   (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> (Stream (ByteStream m) m r
    -> Either
         (ByteStream m (Stream (ByteStream m) m r))
         (Stream (ByteStream m) m r))
-> Stream (ByteStream m) m r
-> Stream (ByteStream m) m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stream (ByteStream m) m r
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
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 (Either
   (ByteStream m (Stream (ByteStream m) m r))
   (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ ByteStream m (Stream (ByteStream m) m r)
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
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                        -> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r)
-> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
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 (Either
   (ByteStream m (Stream (ByteStream m) m r))
   (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> (ByteStream m (Stream (ByteStream m) m r)
    -> Either
         (ByteStream m (Stream (ByteStream m) m r))
         (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStream m (Stream (ByteStream m) m r)
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
forall a b. a -> Either a b
Left (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> m (ByteStream m (Stream (ByteStream m) m r))
-> m (Stream (ByteStream m) m r)
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 (Either
   (ByteStream m (Stream (ByteStream m) m r))
   (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ Stream (ByteStream m) m r
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 -> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ ByteString
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (ByteStream m (Stream (ByteStream m) m r)
 -> ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall a b. (a -> b) -> a -> b
$ (Stream (ByteStream m) m r -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
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 (Either
   (ByteStream m (Stream (ByteStream m) m r))
   (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> (Stream (ByteStream m) m r
    -> Either
         (ByteStream m (Stream (ByteStream m) m r))
         (Stream (ByteStream m) m r))
-> Stream (ByteStream m) m r
-> Stream (ByteStream m) m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stream (ByteStream m) m r
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
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 (Either
   (ByteStream m (Stream (ByteStream m) m r))
   (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ ByteStream m (Stream (ByteStream m) m r)
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
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                        -> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r)
-> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
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 (Either
   (ByteStream m (Stream (ByteStream m) m r))
   (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> (ByteStream m (Stream (ByteStream m) m r)
    -> Either
         (ByteStream m (Stream (ByteStream m) m r))
         (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStream m (Stream (ByteStream m) m r)
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
forall a b. a -> Either a b
Left (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> m (ByteStream m (Stream (ByteStream m) m r))
-> m (Stream (ByteStream m) m r)
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 (Either
   (ByteStream m (Stream (ByteStream m) m r))
   (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ Stream (ByteStream m) m r
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
forall a b. b -> Either a b
Right Stream (ByteStream m) m r
r
        Effect m (Stream (ByteStream m) m r)
m                      -> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r)
-> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ (Stream (ByteStream m) m r -> Stream (ByteStream m) m r)
-> m (Stream (ByteStream m) m r) -> m (Stream (ByteStream m) m r)
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 (Either
   (ByteStream m (Stream (ByteStream m) m r))
   (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> (Stream (ByteStream m) m r
    -> Either
         (ByteStream m (Stream (ByteStream m) m r))
         (Stream (ByteStream m) m r))
-> Stream (ByteStream m) m r
-> Stream (ByteStream m) m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Stream (ByteStream m) m r
-> Either
     (ByteStream m (Stream (ByteStream m) m r))
     (Stream (ByteStream m) m r)
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 :: ByteStream m r -> m (Sum (ByteStream m) (ByteStream m) r)
nulls (Empty r
r)  = Sum (ByteStream m) (ByteStream m) r
-> m (Sum (ByteStream m) (ByteStream m) r)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteStream m r -> Sum (ByteStream m) (ByteStream m) r
forall k (f :: k -> *) (g :: k -> *) (a :: k). g a -> Sum f g a
InR (r -> ByteStream m r
forall (m :: * -> *) a. Monad m => a -> m a
return r
r))
nulls (Go m (ByteStream m r)
m)     = m (ByteStream m r)
m m (ByteStream m r)
-> (ByteStream m r -> m (Sum (ByteStream m) (ByteStream m) r))
-> m (Sum (ByteStream m) (ByteStream m) r)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m (Sum (ByteStream m) (ByteStream m) r)
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 ByteStream m r -> m (Sum (ByteStream m) (ByteStream m) r)
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Sum (ByteStream m) (ByteStream m) r)
nulls ByteStream m r
rest
   else Sum (ByteStream m) (ByteStream m) r
-> m (Sum (ByteStream m) (ByteStream m) r)
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteStream m r -> Sum (ByteStream m) (ByteStream m) r
forall k (f :: k -> *) (g :: k -> *) (a :: k). f a -> Sum f g a
InL (ByteString -> ByteStream m r -> ByteStream m r
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_ :: ByteStream m r -> m Int
length_ = (Of Int r -> Int) -> m (Of Int r) -> m Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Int
n:> r
_) -> Int
n) (m (Of Int r) -> m Int)
-> (ByteStream m r -> m (Of Int r)) -> ByteStream m r -> m Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> ByteString -> Int) -> Int -> ByteStream m r -> m (Of Int r)
forall (m :: * -> *) a r.
Monad m =>
(a -> ByteString -> a) -> a -> ByteStream m r -> m (Of a r)
foldlChunks (\Int
n ByteString
c -> Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
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 :: ByteStream m r -> m (Of Int r)
length = (Int -> ByteString -> Int) -> Int -> ByteStream m r -> m (Of Int r)
forall (m :: * -> *) a r.
Monad m =>
(a -> ByteString -> a) -> a -> ByteStream m r -> m (Of a r)
foldlChunks (\Int
n ByteString
c -> Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
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 :: Word8 -> ByteStream m r -> ByteStream m r
cons Word8
c ByteStream m r
cs = ByteString -> ByteStream m r -> ByteStream m r
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' :: Word8 -> ByteStream m r -> ByteStream m r
cons' Word8
w (Chunk ByteString
c ByteStream m r
cs) | ByteString -> Int
B.length ByteString
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
16 = ByteString -> ByteStream m r -> ByteStream m r
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           = ByteString -> ByteStream m r -> ByteStream m r
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 :: ByteStream m r -> Word8 -> ByteStream m r
snoc ByteStream m r
cs Word8
w = do    -- cs <* singleton w
  r
r <- ByteStream m r
cs
  Word8 -> ByteStream m ()
forall (m :: * -> *). Monad m => Word8 -> ByteStream m ()
singleton Word8
w
  r -> ByteStream m r
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_ :: ByteStream m r -> m Word8
head_ (Empty r
_)   = [Char] -> m Word8
forall a. HasCallStack => [Char] -> a
error [Char]
"head"
head_ (Chunk ByteString
c ByteStream m r
bs) = if ByteString -> Bool
B.null ByteString
c
                        then ByteStream m r -> m Word8
forall (m :: * -> *) r. Monad m => ByteStream m r -> m Word8
head_ ByteStream m r
bs
                        else Word8 -> m Word8
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8 -> m Word8) -> Word8 -> m Word8
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 m (ByteStream m r) -> (ByteStream m r -> m Word8) -> m Word8
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m Word8
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 :: ByteStream m r -> m (Of (Maybe Word8) r)
head (Empty r
r)  = Of (Maybe Word8) r -> m (Of (Maybe Word8) r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Word8
forall a. Maybe a
Nothing Maybe Word8 -> r -> Of (Maybe Word8) r
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 -> ByteStream m r -> m (Of (Maybe Word8) r)
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 <- Stream (Of ByteString) m r -> m r
forall (m :: * -> *) a r. Monad m => Stream (Of a) m r -> m r
SP.effects (Stream (Of ByteString) m r -> m r)
-> Stream (Of ByteString) m r -> m r
forall a b. (a -> b) -> a -> b
$ ByteStream m r -> Stream (Of ByteString) m r
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of ByteString) m r
toChunks ByteStream m r
rest
    Of (Maybe Word8) r -> m (Of (Maybe Word8) r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Of (Maybe Word8) r -> m (Of (Maybe Word8) r))
-> Of (Maybe Word8) r -> m (Of (Maybe Word8) r)
forall a b. (a -> b) -> a -> b
$! Word8 -> Maybe Word8
forall a. a -> Maybe a
Just Word8
w Maybe Word8 -> r -> Of (Maybe Word8) r
forall a b. a -> b -> Of a b
:> r
r
head (Go m (ByteStream m r)
m)      = m (ByteStream m r)
m m (ByteStream m r)
-> (ByteStream m r -> m (Of (Maybe Word8) r))
-> m (Of (Maybe Word8) r)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m (Of (Maybe Word8) r)
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 :: 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 Int -> Int -> Bool
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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 then ByteString -> ByteStream m r -> ByteStream m r
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 Either r (Word8, ByteStream m r)
-> m (Either r (Word8, ByteStream m r))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either r (Word8, ByteStream m r)
 -> m (Either r (Word8, ByteStream m r)))
-> Either r (Word8, ByteStream m r)
-> m (Either r (Word8, ByteStream m r))
forall a b. (a -> b) -> a -> b
$ (Word8, ByteStream m r) -> Either r (Word8, ByteStream m r)
forall a b. b -> Either a b
Right (Word8
h, ByteStream m r
t)
    | Bool
otherwise  = ByteStream m r -> m (Either r (Word8, ByteStream m r))
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 m (ByteStream m r)
-> (ByteStream m r -> m (Either r (Word8, ByteStream m r)))
-> m (Either r (Word8, ByteStream m r))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m (Either r (Word8, ByteStream m r))
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (Word8, ByteStream m r))
uncons
uncons (Empty r
r) = Either r (Word8, ByteStream m r)
-> m (Either r (Word8, ByteStream m r))
forall (m :: * -> *) a. Monad m => a -> m a
return (r -> Either r (Word8, ByteStream m r)
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 :: ByteStream m r -> m (Either r (Word8, ByteStream m r))
nextByte = ByteStream m r -> m (Either r (Word8, ByteStream m r))
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 :: ByteStream m r -> m (Either r (ByteString, ByteStream m r))
unconsChunk (Chunk ByteString
c ByteStream m r
cs)
  | ByteString -> Bool
B.null ByteString
c = ByteStream m r -> m (Either r (ByteString, ByteStream m r))
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (ByteString, ByteStream m r))
unconsChunk ByteStream m r
cs
  | Bool
otherwise = Either r (ByteString, ByteStream m r)
-> m (Either r (ByteString, ByteStream m r))
forall (m :: * -> *) a. Monad m => a -> m a
return ((ByteString, ByteStream m r)
-> Either r (ByteString, ByteStream m r)
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 m (ByteStream m r)
-> (ByteStream m r -> m (Either r (ByteString, ByteStream m r)))
-> m (Either r (ByteString, ByteStream m r))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m (Either r (ByteString, ByteStream m r))
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Either r (ByteString, ByteStream m r))
unconsChunk
unconsChunk (Empty r
r) = Either r (ByteString, ByteStream m r)
-> m (Either r (ByteString, ByteStream m r))
forall (m :: * -> *) a. Monad m => a -> m a
return (r -> Either r (ByteString, ByteStream m r)
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 :: ByteStream m r -> m (Either r (ByteString, ByteStream m r))
nextChunk = ByteStream m r -> m (Either r (ByteString, ByteStream m r))
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_ :: ByteStream m r -> m Word8
last_ (Empty r
_)      = [Char] -> m Word8
forall a. HasCallStack => [Char] -> a
error [Char]
"Streaming.ByteString.last: empty string"
last_ (Go m (ByteStream m r)
m)         = m (ByteStream m r)
m m (ByteStream m r) -> (ByteStream m r -> m Word8) -> m Word8
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m Word8
forall (m :: * -> *) r. Monad m => ByteStream m r -> m Word8
last_
last_ (Chunk ByteString
c0 ByteStream m r
cs0) = ByteString -> ByteStream m r -> m Word8
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 [Char] -> m Word8
forall a. HasCallStack => [Char] -> a
error [Char]
"Streaming.ByteString.last: empty string"
       else Word8 -> m Word8
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8 -> m Word8) -> Word8 -> m Word8
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 m (ByteStream m r) -> (ByteStream m r -> m Word8) -> m Word8
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 :: ByteStream m r -> m (Of (Maybe Word8) r)
last (Empty r
r)      = Of (Maybe Word8) r -> m (Of (Maybe Word8) r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Word8
forall a. Maybe a
Nothing Maybe Word8 -> r -> Of (Maybe Word8) r
forall a b. a -> b -> Of a b
:> r
r)
last (Go m (ByteStream m r)
m)         = m (ByteStream m r)
m m (ByteStream m r)
-> (ByteStream m r -> m (Of (Maybe Word8) r))
-> m (Of (Maybe Word8) r)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= ByteStream m r -> m (Of (Maybe Word8) r)
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> m (Of (Maybe Word8) r)
last
last (Chunk ByteString
c0 ByteStream m r
cs0) = ByteString -> ByteStream m r -> m (Of (Maybe Word8) r)
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)    = Of (Maybe Word8) b -> m (Of (Maybe Word8) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Word8 -> Maybe Word8
forall a. a -> Maybe a
Just (ByteString -> Word8
unsafeLast ByteString
c) Maybe Word8 -> b -> Of (Maybe Word8) b
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 m (ByteStream m b)
-> (ByteStream m b -> m (Of (Maybe Word8) b))
-> m (Of (Maybe Word8) b)
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 :: ByteStream m r -> ByteStream m s -> ByteStream m s
append ByteStream m r
xs ByteStream m s
ys = ByteStream m r
-> (r -> ByteStream m s)
-> (ByteString -> ByteStream m s -> ByteStream m s)
-> (m (ByteStream m s) -> ByteStream m s)
-> ByteStream m s
forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
xs (ByteStream m s -> r -> ByteStream m s
forall a b. a -> b -> a
const ByteStream m s
ys) ByteString -> ByteStream m s -> ByteStream m s
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk m (ByteStream m s) -> ByteStream m s
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 :: (Word8 -> Word8) -> ByteStream m r -> ByteStream m r
map Word8 -> Word8
f ByteStream m r
z = ByteStream m r
-> (r -> ByteStream m r)
-> (ByteString -> ByteStream m r -> ByteStream m r)
-> (m (ByteStream m r) -> ByteStream m r)
-> ByteStream m r
forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
z r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (ByteString -> ByteStream m r -> ByteStream m r)
-> (ByteString -> ByteString)
-> ByteString
-> ByteStream m r
-> ByteStream m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Word8 -> Word8) -> ByteString -> ByteString
B.map Word8 -> Word8
f) m (ByteStream m r) -> ByteStream m r
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go
{-# INLINE map #-}

-- -- | /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 :: Word8 -> ByteStream m r -> ByteStream m r
intersperse Word8
_ (Empty r
r)    = r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
intersperse Word8
w (Go m (ByteStream m r)
m)       = m (ByteStream m r) -> ByteStream m r
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go ((ByteStream m r -> ByteStream m r)
-> m (ByteStream m r) -> m (ByteStream m r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Word8 -> ByteStream m r -> ByteStream m r
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 = Word8 -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
Monad m =>
Word8 -> ByteStream m r -> ByteStream m r
intersperse Word8
w ByteStream m r
cs
                           | Bool
otherwise =
                               ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Word8 -> ByteString -> ByteString
B.intersperse Word8
w ByteString
c)
                                 (ByteStream m r
-> (r -> ByteStream m r)
-> (ByteString -> ByteStream m r -> ByteStream m r)
-> (m (ByteStream m r) -> ByteStream m r)
-> ByteStream m r
forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
cs r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (ByteString -> ByteStream m r -> ByteStream m r)
-> (ByteString -> ByteString)
-> ByteString
-> ByteStream m r
-> ByteStream m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
intersperse') m (ByteStream m r) -> ByteStream m r
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 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Int -> (Ptr Word8 -> IO ()) -> ByteString
B.unsafeCreate (Int
2Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
l) ((Ptr Word8 -> IO ()) -> ByteString)
-> (Ptr Word8 -> IO ()) -> ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p' -> ForeignPtr Word8 -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr Word8
fp ((Ptr Word8 -> IO ()) -> IO ()) -> (Ptr Word8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> do
              Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr Word8
p' Word8
w
              Ptr Word8 -> Ptr Word8 -> CULong -> Word8 -> IO ()
B.c_intersperse (Ptr Word8
p' Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
1) (Ptr Word8
p Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
o) (Int -> CULong
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 :: (Word8 -> a -> a) -> a -> ByteStream m () -> m a
foldr Word8 -> a -> a
k = (ByteString -> a -> a) -> a -> ByteStream m () -> m a
forall (m :: * -> *) a r.
Monad m =>
(ByteString -> a -> a) -> a -> ByteStream m r -> m a
foldrChunks ((a -> ByteString -> a) -> ByteString -> a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Word8 -> a -> a) -> a -> ByteString -> a
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_ :: (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 (x -> m b) -> x -> m b
forall a b. (a -> b) -> a -> b
$! (x -> Word8 -> x) -> x -> ByteString -> x
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 m (ByteStream m ()) -> (ByteStream m () -> m b) -> m b
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 ()
_      -> b -> m b
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 :: (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 (x -> m (Of b r)) -> x -> m (Of b r)
forall a b. (a -> b) -> a -> b
$! (x -> Word8 -> x) -> x -> ByteString -> x
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 m (ByteStream m r) -> (ByteStream m r -> m (Of b r)) -> m (Of b r)
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      -> Of b r -> m (Of b r)
forall (m :: * -> *) a. Monad m => a -> m a
return (x -> b
finish x
x b -> r -> Of b r
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 :: (Word8 -> Word8) -> Word8 -> ByteStream m r
iterate Word8 -> Word8
f = (Word8 -> Either r (Word8, Word8)) -> Word8 -> ByteStream m r
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' -> (Word8, Word8) -> Either r (Word8, Word8)
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 :: Word8 -> ByteStream m r
repeat Word8
w = ByteStream m r
cs where cs :: ByteStream m r
cs = ByteString -> ByteStream m r -> ByteStream m r
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 :: ByteStream m r -> ByteStream m s
cycle = ByteStream m r -> ByteStream m s
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 :: (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 Int -> (a -> Maybe (Word8, a)) -> a -> (ByteString, Maybe a)
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  -> () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
              | Bool
otherwise -> ByteString -> ByteStream m () -> ByteStream m ()
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (() -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
            (ByteString
c, Just a
s')  -> ByteString -> ByteStream m () -> ByteStream m ()
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (Int -> a -> ByteStream m ()
unfoldChunk (Int
nInt -> Int -> Int
forall 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 :: (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 Int -> (a -> Either r (Word8, a)) -> a -> (ByteString, Either r a)
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  -> r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
              | Bool
otherwise -> ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r)
            (ByteString
c, Right a
s') -> ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (Int -> a -> ByteStream m r
unfoldChunk (Int
nInt -> Int -> Int
forall 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 :: Int64 -> ByteStream m r -> ByteStream m ()
take Int64
i ByteStream m r
_ | Int64
i Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
0 = () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
take Int64
i ByteStream m r
cs0         = Int64 -> ByteStream m r -> ByteStream m ()
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
_            = () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
        take' t
_ (Empty r
_)    = () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
        take' t
n (Chunk ByteString
c ByteStream m r
cs) =
          if t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< Int -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)
            then ByteString -> ByteStream m () -> ByteStream m ()
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.take (t -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral t
n) ByteString
c) (() -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
            else ByteString -> ByteStream m () -> ByteStream m ()
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (t -> ByteStream m r -> ByteStream m ()
take' (t
n t -> t -> t
forall a. Num a => a -> a -> a
- Int -> t
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) = m (ByteStream m ()) -> ByteStream m ()
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go ((ByteStream m r -> ByteStream m ())
-> m (ByteStream m r) -> m (ByteStream m ())
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 :: Int64 -> ByteStream m r -> ByteStream m r
drop Int64
i ByteStream m r
p | Int64
i Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
0 = ByteStream m r
p
drop Int64
i ByteStream m r
cs0 = Int64 -> ByteStream m r -> ByteStream m r
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)    = r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
        drop' t
n (Chunk ByteString
c ByteStream m r
cs) =
          if t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< Int -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)
            then ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.drop (t -> Int
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 t -> t -> t
forall a. Num a => a -> a -> a
- Int -> t
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) = m (ByteStream m r) -> ByteStream m r
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go ((ByteStream m r -> ByteStream m r)
-> m (ByteStream m r) -> m (ByteStream m r)
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 :: Int64 -> ByteStream m r -> ByteStream m (ByteStream m r)
splitAt Int64
i ByteStream m r
cs0 | Int64
i Int64 -> Int64 -> Bool
forall a. Ord a => a -> a -> Bool
<= Int64
0 = ByteStream m r -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty ByteStream m r
cs0
splitAt Int64
i ByteStream m r
cs0 = Int64 -> ByteStream m r -> ByteStream m (ByteStream m r)
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           = ByteStream m r -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty ByteStream m r
cs
        splitAt' t
_ (Empty r
r  )   = ByteStream m r -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r)
        splitAt' t
n (Chunk ByteString
c ByteStream m r
cs) =
          if t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< Int -> t
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Int
B.length ByteString
c)
            then ByteString
-> ByteStream m (ByteStream m r) -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.take (t -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral t
n) ByteString
c) (ByteStream m (ByteStream m r) -> ByteStream m (ByteStream m r))
-> ByteStream m (ByteStream m r) -> ByteStream m (ByteStream m r)
forall a b. (a -> b) -> a -> b
$
                     ByteStream m r -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.drop (t -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral t
n) ByteString
c) ByteStream m r
cs)
            else ByteString
-> ByteStream m (ByteStream m r) -> ByteStream m (ByteStream m r)
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 t -> t -> t
forall a. Num a => a -> a -> a
- Int -> t
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) = m (ByteStream m (ByteStream m r)) -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go  ((ByteStream m r -> ByteStream m (ByteStream m r))
-> m (ByteStream m r) -> m (ByteStream m (ByteStream m r))
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 :: (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
_)    = () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
    takeWhile' (Go m (ByteStream m r)
m)       = m (ByteStream m ()) -> ByteStream m ()
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (m (ByteStream m ()) -> ByteStream m ())
-> m (ByteStream m ()) -> ByteStream m ()
forall a b. (a -> b) -> a -> b
$ (ByteStream m r -> ByteStream m ())
-> m (ByteStream m r) -> m (ByteStream m ())
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 (Bool -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Bool
f) ByteString
c of
        Int
0                  -> () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
        Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
B.length ByteString
c -> ByteString -> ByteStream m () -> ByteStream m ()
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.take Int
n ByteString
c) (() -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
          | Bool
otherwise      -> ByteString -> ByteStream m () -> ByteStream m ()
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 :: (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    -> r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
    Go m (ByteStream m r)
m       -> m (ByteStream m r) -> ByteStream m r
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go ((ByteStream m r -> ByteStream m r)
-> m (ByteStream m r) -> m (ByteStream m r)
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 (Bool -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Bool
p) ByteString
c of
        Int
0                  -> ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c ByteStream m r
cs
        Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
B.length ByteString
c -> ByteString -> ByteStream m r -> ByteStream m r
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 :: (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)        = ByteStream m r -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (r -> ByteStream m r
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                  -> ByteStream m r -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c ByteStream m r
cs)
            Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< ByteString -> Int
B.length ByteString
c -> ByteString
-> ByteStream m (ByteStream m r) -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (Int -> ByteString -> ByteString
B.take Int
n ByteString
c) (ByteStream m (ByteStream m r) -> ByteStream m (ByteStream m r))
-> ByteStream m (ByteStream m r) -> ByteStream m (ByteStream m r)
forall a b. (a -> b) -> a -> b
$
                                      ByteStream m r -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteString -> ByteStream m r -> ByteStream m r
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      -> ByteString
-> ByteStream m (ByteStream m r) -> ByteStream m (ByteStream m r)
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) = m (ByteStream m (ByteStream m r)) -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go ((ByteStream m r -> ByteStream m (ByteStream m r))
-> m (ByteStream m r) -> m (ByteStream m (ByteStream m r))
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 :: (Word8 -> Bool) -> ByteStream m r -> ByteStream m (ByteStream m r)
span Word8 -> Bool
p = (Word8 -> Bool) -> ByteStream m r -> ByteStream m (ByteStream m r)
forall (m :: * -> *) r.
Monad m =>
(Word8 -> Bool) -> ByteStream m r -> ByteStream m (ByteStream m r)
break (Bool -> Bool
not (Bool -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
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 :: (Word8 -> Bool) -> ByteStream m r -> Stream (ByteStream m) m r
splitWith Word8 -> Bool
_ (Empty r
r)      = r -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r
splitWith Word8 -> Bool
p (Go m (ByteStream m r)
m)         = m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r)
-> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ (ByteStream m r -> Stream (ByteStream m) m r)
-> m (ByteStream m r) -> m (Stream (ByteStream m) m r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Word8 -> Bool) -> ByteStream m r -> Stream (ByteStream m) m r
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)    = ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ (ByteStream m (Stream (ByteStream m) m r)
 -> ByteString -> ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
-> [ByteString]
-> ByteStream m (Stream (ByteStream m) m r)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' ((ByteString
 -> ByteStream m (Stream (ByteStream m) m r)
 -> ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteString
-> ByteStream m (Stream (ByteStream m) m r)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk)
                                                 (Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (r -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r))
                                                 (ByteString
sByteString -> [ByteString] -> [ByteString]
forall 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
sByteString -> [ByteString] -> [ByteString]
forall 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)       = m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect ((ByteStream m r -> Stream (ByteStream m) m r)
-> m (ByteStream m r) -> m (Stream (ByteStream m) m r)
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           = ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ (ByteStream m (Stream (ByteStream m) m r)
 -> ByteString -> ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
-> [ByteString]
-> ByteStream m (Stream (ByteStream m) m r)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' ((ByteString
 -> ByteStream m (Stream (ByteStream m) m r)
 -> ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteString
-> ByteStream m (Stream (ByteStream m) m r)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk)
                                                 (Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
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
sByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
acc)
  comb [ByteString]
acc []  (Empty r
r)    = ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ (ByteStream m (Stream (ByteStream m) m r)
 -> ByteString -> ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
-> [ByteString]
-> ByteStream m (Stream (ByteStream m) m r)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' ((ByteString
 -> ByteStream m (Stream (ByteStream m) m r)
 -> ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteString
-> ByteStream m (Stream (ByteStream m) m r)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk)
                                                 (Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (r -> Stream (ByteStream m) m r
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 :: 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      -> r -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r
    Go m (ByteStream m r)
m         -> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r)
-> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ (ByteStream m r -> Stream (ByteStream m) m r)
-> m (ByteStream m r) -> m (Stream (ByteStream m) m r)
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)    = ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
Monad m =>
[ByteString] -> r -> ByteStream m r
revChunks [ByteString]
acc (r -> Stream (ByteStream m) m r
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)   = ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
Monad m =>
[ByteString] -> r -> ByteStream m r
revChunks (ByteString
sByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
:[ByteString]
acc) (r -> Stream (ByteStream m) m r
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
sByteString -> [ByteString] -> [ByteString]
forall 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)         = m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect ((ByteStream m r -> Stream (ByteStream m) m r)
-> m (ByteStream m r) -> m (Stream (ByteStream m) m r)
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        = ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
Monad m =>
[ByteString] -> r -> ByteStream m r
revChunks (ByteString
sByteString -> [ByteString] -> [ByteString]
forall 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 :: ByteStream m r -> Stream (ByteStream m) m r
group = ByteStream m r -> Stream (ByteStream m) m r
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)        = r -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r
    go (Go m (ByteStream m r)
m)           = m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r)
-> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ (ByteStream m r -> Stream (ByteStream m) m r)
-> m (ByteStream m r) -> m (Stream (ByteStream m) m r)
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 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
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       = ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
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) (ByteString -> ByteStream m r -> ByteStream m r
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) = [ByteString]
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks [ByteString]
acc (Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (r -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r))
    to [ByteString]
acc !Word8
w (Go m (ByteStream m r)
m) = m (ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (m (ByteStream m (Stream (ByteStream m) m r))
 -> ByteStream m (Stream (ByteStream m) m r))
-> m (ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to [ByteString]
acc Word8
w (ByteStream m r -> ByteStream m (Stream (ByteStream m) m r))
-> m (ByteStream m r)
-> m (ByteStream m (Stream (ByteStream m) m r))
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 (Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Word8
w) ByteString
c of
      Int
0 -> [ByteString]
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks [ByteString]
acc (Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteStream m r -> Stream (ByteStream m) m r
go (ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c ByteStream m r
cs)))
      Int
n | Int
n Int -> Int -> Bool
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 ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
acc) Word8
w ByteStream m r
cs
        | Bool
otherwise       -> [ByteString]
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks (Int -> ByteString -> ByteString
B.unsafeTake Int
n ByteString
c ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
acc) (Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteStream m r -> Stream (ByteStream m) m r
go (ByteString -> ByteStream m r -> ByteStream m r
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 :: (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)        = r -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r
    go (Go m (ByteStream m r)
m)           = m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r)
-> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ (ByteStream m r -> Stream (ByteStream m) m r)
-> m (ByteStream m r) -> m (Stream (ByteStream m) m r)
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 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
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       = ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
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) (ByteString -> ByteStream m r -> ByteStream m r
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) = [ByteString]
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks [ByteString]
acc (Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (r -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r))
    to [ByteString]
acc !Word8
w (Go m (ByteStream m r)
m) = m (ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (m (ByteStream m (Stream (ByteStream m) m r))
 -> ByteStream m (Stream (ByteStream m) m r))
-> m (ByteStream m (Stream (ByteStream m) m r))
-> ByteStream m (Stream (ByteStream m) m r)
forall a b. (a -> b) -> a -> b
$ [ByteString]
-> Word8
-> ByteStream m r
-> ByteStream m (Stream (ByteStream m) m r)
to [ByteString]
acc Word8
w (ByteStream m r -> ByteStream m (Stream (ByteStream m) m r))
-> m (ByteStream m r)
-> m (ByteStream m (Stream (ByteStream m) m r))
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 (Bool -> Bool) -> (Word8 -> Bool) -> Word8 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Word8 -> Bool
rel Word8
w) ByteString
c of
      Int
0 -> [ByteString]
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks [ByteString]
acc (Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteStream m r -> Stream (ByteStream m) m r
go (ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c ByteStream m r
cs)))
      Int
n | Int
n Int -> Int -> Bool
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 ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
acc) Word8
w ByteStream m r
cs
        | Bool
otherwise       -> [ByteString]
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r.
[ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks (Int -> ByteString -> ByteString
B.unsafeTake Int
n ByteString
c ByteString -> [ByteString] -> [ByteString]
forall a. a -> [a] -> [a]
: [ByteString]
acc) (Stream (ByteStream m) m r
-> ByteStream m (Stream (ByteStream m) m r)
forall (m :: * -> *) r. r -> ByteStream m r
Empty (ByteStream m r -> Stream (ByteStream m) m r
go (ByteString -> ByteStream m r -> ByteStream m r
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 :: 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) = r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
    loop (Effect m (Stream (ByteStream m) m r)
m) = m (ByteStream m r) -> ByteStream m r
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (m (ByteStream m r) -> ByteStream m r)
-> m (ByteStream m r) -> ByteStream m r
forall a b. (a -> b) -> a -> b
$ (Stream (ByteStream m) m r -> ByteStream m r)
-> m (Stream (ByteStream m) m r) -> m (ByteStream m r)
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 ByteStream m (Stream (ByteStream m) m r)
-> (Stream (ByteStream m) m r -> ByteStream m r) -> ByteStream m r
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Return r
r -> r -> ByteStream m 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 ByteStream m () -> ByteStream m r -> ByteStream m r
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_ :: Word8 -> ByteStream m r -> m Int
count_ Word8
w  = (Of Int r -> Int) -> m (Of Int r) -> m Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\(Int
n :> r
_) -> Int
n) (m (Of Int r) -> m Int)
-> (ByteStream m r -> m (Of Int r)) -> ByteStream m r -> m Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> ByteString -> Int) -> Int -> ByteStream m r -> m (Of Int r)
forall (m :: * -> *) a r.
Monad m =>
(a -> ByteString -> a) -> a -> ByteStream m r -> m (Of a r)
foldlChunks (\Int
n ByteString
c -> Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
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 :: Word8 -> ByteStream m r -> m (Of Int r)
count Word8
w ByteStream m r
cs = (Int -> ByteString -> Int) -> Int -> ByteStream m r -> m (Of Int r)
forall (m :: * -> *) a r.
Monad m =>
(a -> ByteString -> a) -> a -> ByteStream m r -> m (Of a r)
foldlChunks (\Int
n ByteString
c -> Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int -> Int
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 :: (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 )   = r -> ByteStream m r
forall (m :: * -> *) r. r -> ByteStream m r
Empty r
r
        go (Chunk ByteString
x ByteStream m r
xs) = ByteString -> ByteStream m r -> ByteStream m r
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)       = m (ByteStream m r) -> ByteStream m r
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go ((ByteStream m r -> ByteStream m r)
-> m (ByteStream m r) -> m (ByteStream m r)
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 :: Int -> Handle -> ByteStream m ()
hGetContentsN Int
k Handle
h = ByteStream m ()
loop -- TODO close on exceptions
  where
    loop :: ByteStream m ()
loop = do
        ByteString
c <- IO ByteString -> ByteStream m ByteString
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 () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
          else ByteString -> ByteStream m () -> ByteStream m ()
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 :: Int -> Handle -> Int -> ByteStream m ()
hGetN Int
k Handle
h Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Int -> ByteStream m ()
readChunks Int
n
  where
    readChunks :: Int -> ByteStream m ()
readChunks !Int
i = m (ByteStream m ()) -> ByteStream m ()
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (m (ByteStream m ()) -> ByteStream m ())
-> m (ByteStream m ()) -> ByteStream m ()
forall a b. (a -> b) -> a -> b
$ do
        ByteString
c <- IO ByteString -> m ByteString
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> m ByteString) -> IO ByteString -> m ByteString
forall a b. (a -> b) -> a -> b
$ Handle -> Int -> IO ByteString
B.hGet Handle
h (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
k Int
i)
        case ByteString -> Int
B.length ByteString
c of
            Int
0 -> ByteStream m () -> m (ByteStream m ())
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteStream m () -> m (ByteStream m ()))
-> ByteStream m () -> m (ByteStream m ())
forall a b. (a -> b) -> a -> b
$ () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
            Int
m -> ByteStream m () -> m (ByteStream m ())
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteStream m () -> m (ByteStream m ()))
-> ByteStream m () -> m (ByteStream m ())
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteStream m () -> ByteStream m ()
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (Int -> ByteStream m ()
readChunks (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
m))
hGetN Int
_ Handle
_ Int
0 = () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
hGetN Int
_ Handle
h Int
n = IO () -> ByteStream m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ByteStream m ()) -> IO () -> ByteStream m ()
forall a b. (a -> b) -> a -> b
$ Handle -> [Char] -> Int -> IO ()
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 :: Int -> Handle -> Int -> ByteStream m ()
hGetNonBlockingN Int
k Handle
h Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 = Int -> ByteStream m ()
readChunks Int
n
  where
    readChunks :: Int -> ByteStream m ()
readChunks !Int
i = m (ByteStream m ()) -> ByteStream m ()
forall (m :: * -> *) r. m (ByteStream m r) -> ByteStream m r
Go (m (ByteStream m ()) -> ByteStream m ())
-> m (ByteStream m ()) -> ByteStream m ()
forall a b. (a -> b) -> a -> b
$ do
        ByteString
c <- IO ByteString -> m ByteString
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString -> m ByteString) -> IO ByteString -> m ByteString
forall a b. (a -> b) -> a -> b
$ Handle -> Int -> IO ByteString
B.hGetNonBlocking Handle
h (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
k Int
i)
        case ByteString -> Int
B.length ByteString
c of
            Int
0 -> ByteStream m () -> m (ByteStream m ())
forall (m :: * -> *) a. Monad m => a -> m a
return (() -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ())
            Int
m -> ByteStream m () -> m (ByteStream m ())
forall (m :: * -> *) a. Monad m => a -> m a
return (ByteString -> ByteStream m () -> ByteStream m ()
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
c (Int -> ByteStream m ()
readChunks (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
m)))
hGetNonBlockingN Int
_ Handle
_ Int
0 = () -> ByteStream m ()
forall (m :: * -> *) r. r -> ByteStream m r
Empty ()
hGetNonBlockingN Int
_ Handle
h Int
n = IO () -> ByteStream m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ByteStream m ()) -> IO () -> ByteStream m ()
forall a b. (a -> b) -> a -> b
$ Handle -> [Char] -> Int -> IO ()
forall a. Handle -> [Char] -> Int -> IO a
illegalBufferSize Handle
h [Char]
"hGetNonBlocking" Int
n
{-# INLINABLE hGetNonBlockingN #-}

illegalBufferSize :: Handle -> String -> Int -> IO a
illegalBufferSize :: Handle -> [Char] -> Int -> IO a
illegalBufferSize Handle
handle [Char]
fn Int
sz =
    IOError -> IO a
forall a. IOError -> IO a
ioError (IOErrorType -> [Char] -> Maybe Handle -> Maybe [Char] -> IOError
mkIOError IOErrorType
illegalOperationErrorType [Char]
msg (Handle -> Maybe Handle
forall a. a -> Maybe a
Just Handle
handle) Maybe [Char]
forall a. Maybe a
Nothing)
    --TODO: System.IO uses InvalidArgument here, but it's not exported :-(
    where
      msg :: [Char]
msg = [Char]
fn [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
": illegal ByteStream size " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> Int -> [Char] -> [Char]
forall a. Show a => Int -> a -> [Char] -> [Char]
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 :: Handle -> ByteStream m ()
hGetContents = Int -> Handle -> ByteStream m ()
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 :: Handle -> ByteStream m ()
fromHandle = Handle -> ByteStream m ()
forall (m :: * -> *). MonadIO m => Handle -> ByteStream m ()
hGetContents
{-# INLINE fromHandle #-}

-- | Pipes-style nomenclature for 'getContents'.
stdin :: MonadIO m => ByteStream m ()
stdin :: ByteStream m ()
stdin = Handle -> ByteStream m ()
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 :: Handle -> Int -> ByteStream m ()
hGet = Int -> Handle -> Int -> ByteStream m ()
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 :: Handle -> Int -> ByteStream m ()
hGetNonBlocking = Int -> Handle -> Int -> ByteStream m ()
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 :: [Char] -> ByteStream m r -> m r
writeFile [Char]
f ByteStream m r
str = do
  (ReleaseKey
key, Handle
handle) <- IO Handle -> (Handle -> IO ()) -> m (ReleaseKey, 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 <- Handle -> ByteStream m r -> m r
forall (m :: * -> *) r.
MonadIO m =>
Handle -> ByteStream m r -> m r
hPut Handle
handle ByteStream m r
str
  ReleaseKey -> m ()
forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
release ReleaseKey
key
  r -> m r
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 :: [Char] -> ByteStream m ()
readFile [Char]
f = IO Handle
-> (Handle -> IO ())
-> (Handle -> ByteStream m ())
-> ByteStream m ()
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 Handle -> ByteStream m ()
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 :: [Char] -> ByteStream m r -> m r
appendFile [Char]
f ByteStream m r
str = do
  (ReleaseKey
key, Handle
handle) <- IO Handle -> (Handle -> IO ()) -> m (ReleaseKey, 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 <- Handle -> ByteStream m r -> m r
forall (m :: * -> *) r.
MonadIO m =>
Handle -> ByteStream m r -> m r
hPut Handle
handle ByteStream m r
str
  ReleaseKey -> m ()
forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
release ReleaseKey
key
  r -> m r
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 :: ByteStream m ()
getContents = Handle -> ByteStream m ()
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 :: Handle -> ByteStream m r -> m r
hPut Handle
h ByteStream m r
cs = ByteStream m r
-> (r -> m r)
-> (ByteString -> m r -> m r)
-> (m (m r) -> m r)
-> m r
forall (m :: * -> *) r.
Monad m =>
ByteStream m r
-> forall x. (r -> x) -> (ByteString -> x -> x) -> (m x -> x) -> x
dematerialize ByteStream m r
cs r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return (\ByteString
x m r
y -> IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> ByteString -> IO ()
B.hPut Handle
h ByteString
x) m () -> m r -> m r
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m r
y) (m (m r) -> (m r -> m r) -> m r
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= m r -> m r
forall a. a -> a
id)
{-# INLINE hPut #-}

-- | Pipes nomenclature for 'hPut'.
toHandle :: MonadIO m => Handle -> ByteStream m r -> m r
toHandle :: Handle -> ByteStream m r -> m r
toHandle = Handle -> ByteStream m r -> m r
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 :: ByteStream m r -> m r
stdout = Handle -> ByteStream m r -> m r
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 :: (ByteStream IO () -> ByteStream IO r) -> IO r
interact ByteStream IO () -> ByteStream IO r
f = ByteStream IO r -> IO r
forall (m :: * -> *) r. MonadIO m => ByteStream m r -> m r
stdout (ByteStream IO () -> ByteStream IO r
f ByteStream IO ()
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 :: [ByteString] -> ByteStream m r -> ByteStream m r
revNonEmptyChunks = ((ByteStream m r -> ByteStream m r)
 -> ByteString -> ByteStream m r -> ByteStream m r)
-> (ByteStream m r -> ByteStream m r)
-> [ByteString]
-> ByteStream m r
-> ByteStream m r
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' (\ByteStream m r -> ByteStream m r
f ByteString
bs -> ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs (ByteStream m r -> ByteStream m r)
-> (ByteStream m r -> ByteStream m r)
-> ByteStream m r
-> ByteStream m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStream m r -> ByteStream m r
f) ByteStream m r -> ByteStream m r
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 :: [ByteString] -> r -> ByteStream m r
revChunks [ByteString]
cs r
r = (ByteStream m r -> ByteString -> ByteStream m r)
-> ByteStream m r -> [ByteString] -> ByteStream m r
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
L.foldl' ((ByteString -> ByteStream m r -> ByteStream m r)
-> ByteStream m r -> ByteString -> ByteStream m r
forall a b c. (a -> b -> c) -> b -> a -> c
flip ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk) (r -> ByteStream m r
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 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   -> r -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r. r -> Stream f m r
Return r
r
      Step ByteStream m (Stream (ByteStream m) m r)
fls   -> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
f (Stream f m r) -> Stream f m r
Step (ByteStream m (Stream (ByteStream m) m r)
 -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ (Stream (ByteStream m) m r -> Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
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) (a
-> ByteStream m (Stream (ByteStream m) m r)
-> ByteStream m (Stream (ByteStream m) m r)
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 -> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall (f :: * -> *) (m :: * -> *) r.
m (Stream f m r) -> Stream f m r
Effect (m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r)
-> m (Stream (ByteStream m) m r) -> Stream (ByteStream m) m r
forall a b. (a -> b) -> a -> b
$ (Stream (ByteStream m) m r -> Stream (ByteStream m) m r)
-> m (Stream (ByteStream m) m r) -> m (Stream (ByteStream m) m r)
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 :: Builder -> ByteStream m ()
toStreamingByteString = AllocationStrategy -> Builder -> ByteStream m ()
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 :: AllocationStrategy -> Builder -> ByteStream m ()
toStreamingByteStringWith AllocationStrategy
strategy Builder
builder0 = do
       ChunkIOStream ()
cios <- IO (ChunkIOStream ()) -> ByteStream m (ChunkIOStream ())
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (AllocationStrategy -> BuildStep () -> IO (ChunkIOStream ())
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   -> ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk ByteString
bs (ByteStream m r -> ByteStream m r)
-> ByteStream m r -> ByteStream m r
forall a b. (a -> b) -> a -> b
$ do
                    ChunkIOStream r
cios1 <- IO (ChunkIOStream r) -> ByteStream m (ChunkIOStream r)
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 -> Buffer -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r. Buffer -> ByteStream m r -> ByteStream m r
trimmedChunkFromBuffer Buffer
buf (r -> ByteStream m r
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 Int -> Int -> Int
forall a. Num a => a -> a -> a
* ByteString -> Int
B.length ByteString
bs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Buffer -> Int
bufferSize Buffer
buffer = ByteString -> ByteStream m r -> ByteStream m r
forall (m :: * -> *) r.
ByteString -> ByteStream m r -> ByteStream m r
Chunk (ByteString -> ByteString
B.copy ByteString
bs) ByteStream m r
k
              | Bool
otherwise                            = ByteString -> ByteStream m r -> ByteStream m r
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
       ChunkIOStream () -> ByteStream m ()
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 r. BuildStep r -> BuildStep r) -> Builder)
-> (forall r. BuildStep r -> BuildStep r) -> Builder
forall a b. (a -> b) -> a -> b
$ \BuildStep r
bstep BufferRange
r -> do
  case Stream (Of Builder) IO ()
p of
    Return ()
_          -> Builder -> BuildStep r -> BuildStep r
forall a. Builder -> BuildStep a -> BuildStep a
runBuilderWith Builder
forall a. Monoid a => a
mempty BuildStep r
bstep BufferRange
r
    Step (Builder
b :> Stream (Of Builder) IO ()
rest)  -> Builder -> BuildStep r -> BuildStep r
forall a. Builder -> BuildStep a -> BuildStep a
runBuilderWith (Builder
b Builder -> Builder -> Builder
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 IO (Stream (Of Builder) IO ())
-> (Stream (Of Builder) IO () -> IO (BuildSignal r))
-> IO (BuildSignal r)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Stream (Of Builder) IO ()
p' -> Builder -> BuildStep r -> BuildStep r
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 (Stream (Of Builder) IO () -> Builder)
-> (ByteStream IO () -> Stream (Of Builder) IO ())
-> ByteStream IO ()
-> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ByteString -> Builder)
-> Stream (Of ByteString) IO () -> Stream (Of Builder) IO ()
forall (m :: * -> *) a b r.
Monad m =>
(a -> b) -> Stream (Of a) m r -> Stream (Of b) m r
SP.map ByteString -> Builder
byteString (Stream (Of ByteString) IO () -> Stream (Of Builder) IO ())
-> (ByteStream IO () -> Stream (Of ByteString) IO ())
-> ByteStream IO ()
-> Stream (Of Builder) IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteStream IO () -> Stream (Of ByteString) IO ()
forall (m :: * -> *) r.
Monad m =>
ByteStream m r -> Stream (Of ByteString) m r
toChunks
{-# INLINABLE toBuilder #-}