# LANGUAGE Haskell98 #
# LINE 1 " Data / ByteString / Lazy / Char8.hs " #























































# LANGUAGE CPP , BangPatterns #
{-# OPTIONS_HADDOCK prune #-}
# LANGUAGE Trustworthy #

-- |
-- Module      : Data.ByteString.Lazy.Char8
  Copyright    : ( c )   2006 - 2008
                ( c )   2006 - 2011
-- License     : BSD-style
--
-- Maintainer  : , 
-- Stability   : stable
-- Portability : portable
--
  Manipulate /lazy/ ' ByteString 's using '  ' operations . All  will
  be truncated to 8 bits . It can be expected that these functions will
-- run at identical speeds to their 'Data.Word.Word8' equivalents in
  " Data . ByteString . Lazy " .
--
-- This module is intended to be imported @qualified@, to avoid name
  clashes with " Prelude " functions .   eg .
--
  > import qualified Data . ByteString . Lazy . Char8 as C
--
  The Char8 interface to bytestrings provides an instance of IsString
  for the ByteString type , enabling you to use string literals , and
  have them implicitly packed to ByteStrings .
  Use @{-\ # LANGUAGE OverloadedStrings \#-}@ to enable this .
--

module Data.ByteString.Lazy.Char8 (

        -- * The @ByteString@ type
  instances :  , Ord , Show , Read , Data , 

  * Introducing and eliminating ' ByteString 's
        empty,                  -- :: ByteString
  : :     ByteString
        pack,                   -- :: String -> ByteString
        unpack,                 -- :: ByteString -> String
        fromChunks,             -- :: [Strict.ByteString] -> ByteString
        toChunks,               -- :: ByteString -> [Strict.ByteString]
        fromStrict,             -- :: Strict.ByteString -> ByteString
        toStrict,               -- :: ByteString -> Strict.ByteString

        -- * Basic interface
  : :       ByteString
  : :       ByteString
        snoc,                   -- :: ByteString -> Char -> ByteString
        append,                 -- :: ByteString -> ByteString -> ByteString
  : : ByteString - > 
  : : ByteString - > Maybe (  , ByteString )
  : : ByteString - > 
        tail,                   -- :: ByteString -> ByteString
  : : ByteString - > Maybe ( ByteString ,  )
        init,                   -- :: ByteString -> ByteString
        null,                   -- :: ByteString -> Bool
  : : ByteString - > Int64

        -- * Transforming ByteStrings
  : : (     ) - > ByteString - > ByteString
        reverse,                -- :: ByteString -> ByteString
  : :       ByteString
        intercalate,            -- :: ByteString -> [ByteString] -> ByteString
        transpose,              -- :: [ByteString] -> [ByteString]

        -- * Reducing 'ByteString's (folds)
        foldl,                  -- :: (a -> Char -> a) -> a -> ByteString -> a
        foldl',                 -- :: (a -> Char -> a) -> a -> ByteString -> a
  : : (    Char - >  ) - > ByteString - > 
  : : (    Char - >  ) - > ByteString - > 
        foldr,                  -- :: (Char -> a -> a) -> a -> ByteString -> a
  : : (    Char - >  ) - > ByteString - > 

        -- ** Special folds
        concat,                 -- :: [ByteString] -> ByteString
        concatMap,              -- :: (Char -> ByteString) -> ByteString -> ByteString
  : : (    Bool ) - > ByteString - > Bool
  : : (    Bool ) - > ByteString - > Bool
  : : ByteString - > 
  : : ByteString - > 

        -- * Building ByteStrings
        -- ** Scans
  : : (    Char - >  ) - > Char - > ByteString - > ByteString
       scanl1 ,                  -- : : (    Char - >  ) - > ByteString - > ByteString
       scanr ,                   -- : : (    Char - >  ) - > Char - > ByteString - > ByteString
       scanr1 ,                  -- : : (    Char - >  ) - > ByteString - > ByteString

        -- ** Accumulating maps
  : : ( acc - > Char - > ( acc ,  ) ) - > acc - > ByteString - > ( acc , ByteString )
  : : ( acc - > Char - > ( acc ,  ) ) - > acc - > ByteString - > ( acc , ByteString )

        -- ** Infinite ByteStrings
  : :    
        replicate,              -- :: Int64 -> Char -> ByteString
        cycle,                  -- :: ByteString -> ByteString
  : : (     ) - > Char - > ByteString

  * * Unfolding ByteStrings
  : : ( a - > Maybe (  , a ) ) - > a - > ByteString

  * Substrings

        -- ** Breaking strings
        take,                   -- :: Int64 -> ByteString -> ByteString
        drop,                   -- :: Int64 -> ByteString -> ByteString
  : : Int64 - > ByteString - > ( ByteString , ByteString )
  : : (    Bool ) - > ByteString - > ByteString
  : : (    Bool ) - > ByteString - > ByteString
  : : (    Bool ) - > ByteString - > ( ByteString , ByteString )
  : : (    Bool ) - > ByteString - > ( ByteString , ByteString )
        group,                  -- :: ByteString -> [ByteString]
  : : (    Char - > Bool ) - > ByteString - > [ ByteString ]
        inits,                  -- :: ByteString -> [ByteString]
        tails,                  -- :: ByteString -> [ByteString]
  : : ByteString - > ByteString - > Maybe ByteString
  : : ByteString - > ByteString - > Maybe ByteString

        -- ** Breaking into many substrings
  : :       [ ByteString ]
  : : (    Bool ) - > ByteString - > [ ByteString ]

        -- ** Breaking into lines and words
        lines,                  -- :: ByteString -> [ByteString]
        words,                  -- :: ByteString -> [ByteString]
        unlines,                -- :: [ByteString] -> ByteString
        unwords,                -- :: ByteString -> [ByteString]

        -- * Predicates
        isPrefixOf,             -- :: ByteString -> ByteString -> Bool
        isSuffixOf,             -- :: ByteString -> ByteString -> Bool

  * Searching ByteStrings

        -- ** Searching by equality
  : :       Bool
  : :       Bool

        -- ** Searching with a predicate
  : : (    Bool ) - > ByteString - > Maybe 
  : : (    Bool ) - > ByteString - > ByteString
       partition                -- : : (    Bool ) - > ByteString - > ( ByteString , ByteString )

  * Indexing ByteStrings
  : : ByteString - > Int64 - > 
  : :     - > Maybe Int64
  : :       [ Int64 ]
  : : (    Bool ) - > ByteString - > Maybe Int64
  : : (    Bool ) - > ByteString - > [ Int64 ]
  : :     - > Int64

  * Zipping and unzipping ByteStrings
  : : ByteString - > ByteString - > [ (  ,  ) ]
  : : (    Char - > c ) - > ByteString - > ByteString - > [ c ]
       unzip ,                   -- : : [ (  ,  ) ] - > ( ByteString , ByteString )

  * Ordered ByteStrings
--        sort,                   -- :: ByteString -> ByteString

        -- * Low level conversions
  * * Copying ByteStrings
        copy,                   -- :: ByteString -> ByteString

  * Reading from ByteStrings
        readInt,
        readInteger,

  * I\/O with ' ByteString 's
        -- | ByteString I/O uses binary mode, without any character decoding
        -- or newline conversion. The fact that it does not respect the Handle
        -- newline mode is considered a flaw and may be changed in a future version.

        -- ** Standard input and output
  : : IO ByteString
        putStr,                 -- :: ByteString -> IO ()
        putStrLn,               -- :: ByteString -> IO ()
        interact,               -- :: (ByteString -> ByteString) -> IO ()

        -- ** Files
        readFile,               -- :: FilePath -> IO ByteString
        writeFile,              -- :: FilePath -> ByteString -> IO ()
        appendFile,             -- :: FilePath -> ByteString -> IO ()

        -- ** I\/O with Handles
        hGetContents,           -- :: Handle -> IO ByteString
        hGet,                   -- :: Handle -> Int64 -> IO ByteString
        hGetNonBlocking,        -- :: Handle -> Int64 -> IO ByteString
        hPut,                   -- :: Handle -> ByteString -> IO ()
  : : Handle - > ByteString - > IO ByteString
        hPutStr,                -- :: Handle -> ByteString -> IO ()
        hPutStrLn,              -- :: Handle -> ByteString -> IO ()

  ) where

-- Functions transparently exported
import Data.ByteString.Lazy 
        (fromChunks, toChunks, fromStrict, toStrict
        ,empty,null,length,tail,init,append,reverse,transpose,cycle
        ,concat,take,drop,splitAt,intercalate
        ,isPrefixOf,isSuffixOf,group,inits,tails,copy
        ,stripPrefix,stripSuffix
        ,hGetContents, hGet, hPut, getContents
        ,hGetNonBlocking, hPutNonBlocking
        ,putStr, hPutStr, interact)

-- Functions we need to wrap.
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString as S (ByteString) -- typename only
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as B
import Data.ByteString.Lazy.Internal

import Data.ByteString.Internal (w2c, c2w, isSpaceWord8)

import Data.Int (Int64)
import qualified Data.List as List

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

import System.IO            (Handle,stdout,hClose,openBinaryFile,IOMode(..))
import Control.Exception    (bracket)

------------------------------------------------------------------------

  | /O(1)/ Convert a '  ' into a ' ByteString '
singleton :: Char -> ByteString
singleton = L.singleton . c2w
# INLINE singleton #

-- | /O(n)/ Convert a 'String' into a 'ByteString'. 
pack :: [Char] -> ByteString
pack = packChars

-- | /O(n)/ Converts a 'ByteString' to a 'String'.
unpack :: ByteString -> [Char]
unpack = unpackChars

infixr 5 `cons`, `cons'` --same as list (:)
infixl 5 `snoc`

-- | /O(1)/ 'cons' is analogous to '(:)' for lists.
cons :: Char -> ByteString -> ByteString
cons = L.cons . c2w
# INLINE cons #

  | /O(1)/ Unlike ' 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 lazy ByteStrings .
--
cons' :: Char -> ByteString -> ByteString
cons' = L.cons' . c2w
{-# INLINE cons' #-}

  | /O(n)/ Append a  to the end of a ' ByteString ' . Similar to
-- 'cons', this function performs a memcpy.
snoc :: ByteString -> Char -> ByteString
snoc p = L.snoc p . c2w
# INLINE snoc #

  | /O(1)/ Extract the first element of a ByteString , which must be non - empty .
head :: ByteString -> Char
head = w2c . L.head
# INLINE head #

  | /O(1)/ Extract the head and tail of a ByteString , returning Nothing
-- if it is empty.
uncons :: ByteString -> Maybe (Char, ByteString)
uncons bs = case L.uncons bs of
                  Nothing -> Nothing
                  Just (w, bs') -> Just (w2c w, bs')
# INLINE uncons #

  | /O(n\/c)/ Extract the ' init ' and ' last ' of a ByteString , returning Nothing
-- if it is empty.
unsnoc :: ByteString -> Maybe (ByteString, Char)
unsnoc bs = case L.unsnoc bs of
                  Nothing -> Nothing
                  Just (bs', w) -> Just (bs', w2c w)
# INLINE unsnoc #

-- | /O(1)/ Extract the last element of a packed string, which must be non-empty.
last :: ByteString -> Char
last = w2c . L.last
# INLINE last #

  | /O(n)/ ' map '   is the ByteString obtained by applying @f@ to each element of @xs@
map :: (Char -> Char) -> ByteString -> ByteString
map f = L.map (c2w . f . w2c)
# INLINE map #

  | /O(n)/ The ' intersperse ' function takes a  and a ' ByteString '
  and  ' that  between the elements of the
  ' ByteString ' .   It is analogous to the intersperse function on Lists .
intersperse :: Char -> ByteString -> ByteString
intersperse = L.intersperse . c2w
# INLINE intersperse #

-- | 'foldl', applied to a binary operator, a starting value (typically
  the left - identity of the operator ) , and a ByteString , reduces the
  ByteString using the binary operator , from left to right .
foldl :: (a -> Char -> a) -> a -> ByteString -> a
foldl f = L.foldl (\a c -> f a (w2c c))
{-# INLINE foldl #-}

-- | 'foldl\'' is like foldl, but strict in the accumulator.
foldl' :: (a -> Char -> a) -> a -> ByteString -> a
foldl' f = L.foldl' (\a c -> f a (w2c c))
{-# INLINE foldl' #-}

-- | 'foldr', applied to a binary operator, a starting value
-- (typically the right-identity of the operator), and a packed string,
-- reduces the packed string using the binary operator, from right to left.
foldr :: (Char -> a -> a) -> a -> ByteString -> a
foldr f = L.foldr (\c a -> f (w2c c) a)
# INLINE foldr #

  | ' foldl1 ' is a variant of ' foldl ' that has no starting value
  argument , and thus must be applied to non - empty ' ByteStrings ' .
foldl1 :: (Char -> Char -> Char) -> ByteString -> Char
foldl1 f ps = w2c (L.foldl1 (\x y -> c2w (f (w2c x) (w2c y))) ps)
# INLINE foldl1 #

  | ' foldl1\ '' is like ' foldl1 ' , but strict in the accumulator .
foldl1' :: (Char -> Char -> Char) -> ByteString -> Char
foldl1' f ps = w2c (L.foldl1' (\x y -> c2w (f (w2c x) (w2c y))) ps)

  | '  ' is a variant of ' foldr ' that has no starting value argument ,
  and thus must be applied to non - empty ' ByteString 's
foldr1 :: (Char -> Char -> Char) -> ByteString -> Char
foldr1 f ps = w2c (L.foldr1 (\x y -> c2w (f (w2c x) (w2c y))) ps)
# INLINE foldr1 #

-- | Map a function over a 'ByteString' and concatenate the results
concatMap :: (Char -> ByteString) -> ByteString -> ByteString
concatMap f = L.concatMap (f . w2c)
# INLINE concatMap #

  | Applied to a predicate and a ByteString , ' any ' determines if
-- any element of the 'ByteString' satisfies the predicate.
any :: (Char -> Bool) -> ByteString -> Bool
any f = L.any (f . w2c)
# INLINE any #

-- | Applied to a predicate and a 'ByteString', 'all' determines if
-- all elements of the 'ByteString' satisfy the predicate.
all :: (Char -> Bool) -> ByteString -> Bool
all f = L.all (f . w2c)
# INLINE all #

  | ' maximum ' returns the maximum value from a ' ByteString '
maximum :: ByteString -> Char
maximum = w2c . L.maximum
# INLINE maximum #

  | ' minimum ' returns the minimum value from a ' ByteString '
minimum :: ByteString -> Char
minimum = w2c . L.minimum
# INLINE minimum #

-- ---------------------------------------------------------------------
  Building ByteStrings

  | '  ' is similar to ' foldl ' , but returns a list of successive
-- reduced values from the left. This function will fuse.
--
  >  f z [ x1 , x2 , ... ] = = [ z , z ` f ` x1 , ( z ` f ` x1 ) ` f ` x2 , ... ]
--
-- Note that
--
  > last (  f z xs ) = = foldl f z xs .
scanl :: (Char -> Char -> Char) -> Char -> ByteString -> ByteString
scanl f z = L.scanl (\a b -> c2w (f (w2c a) (w2c b))) (c2w z)

-- | The 'mapAccumL' function behaves like a combination of 'map' and
  ' foldl ' ; it applies a function to each element of a ByteString ,
-- passing an accumulating parameter from left to right, and returning a
  final value of this accumulator together with the new ByteString .
mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)
mapAccumL f = L.mapAccumL (\a w -> case f a (w2c w) of (a',c) -> (a', c2w c))

-- | The 'mapAccumR' function behaves like a combination of 'map' and
  ' foldr ' ; it applies a function to each element of a ByteString ,
-- passing an accumulating parameter from right to left, and returning a
  final value of this accumulator together with the new ByteString .
mapAccumR :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)
mapAccumR f = L.mapAccumR (\acc w -> case f acc (w2c w) of (acc', c) -> (acc', c2w c))

------------------------------------------------------------------------
  Generating and unfolding ByteStrings

  | @'iterate ' f  returns an infinite ByteString of repeated applications
  of  to @x@ :
--
-- > iterate f x == [x, f x, f (f x), ...]
--
iterate :: (Char -> Char) -> Char -> ByteString
iterate f = L.iterate (c2w . f . w2c) . c2w

  | @'repeat '  is an infinite ByteString , with @x@ the value of every
-- element.
--
repeat :: Char -> ByteString
repeat = L.repeat . c2w

  | /O(n)/ @'replicate ' n  is a ByteString of length @n@ with @x@
-- the value of every element.
--
replicate :: Int64 -> Char -> ByteString
replicate w c = L.replicate w (c2w c)

-- | /O(n)/ The 'unfoldr' function is analogous to the List \'unfoldr\'.
  ' unfoldr ' builds a ByteString from a seed value .   The function takes
-- the element and returns 'Nothing' if it is done producing the
  ByteString or returns ' Just ' @(a , b)@ , in which case , @a@ is a
  prepending to the ByteString and  is used as the next element in a
-- recursive call.
unfoldr :: (a -> Maybe (Char, a)) -> a -> ByteString
unfoldr f = L.unfoldr $ \a -> case f a of
                                    Nothing      -> Nothing
                                    Just (c, a') -> Just (c2w c, a')

------------------------------------------------------------------------

  | ' takeWhile ' , applied to a predicate @p@ and a ByteString @xs@ ,
-- returns the longest prefix (possibly empty) of @xs@ of elements that
  satisfy @p@.
takeWhile :: (Char -> Bool) -> ByteString -> ByteString
takeWhile f = L.takeWhile (f . w2c)
# INLINE takeWhile #

  | ' dropWhile ' @p xs@ returns the suffix remaining after ' takeWhile ' @p xs@.
dropWhile :: (Char -> Bool) -> ByteString -> ByteString
dropWhile f = L.dropWhile (f . w2c)
# INLINE dropWhile #

  | ' break ' @p@ is equivalent to @'span ' ( ' not ' . p)@.
break :: (Char -> Bool) -> ByteString -> (ByteString, ByteString)
break f = L.break (f . w2c)
# INLINE break #

  | ' span ' @p xs@ breaks the ByteString into two segments . It is
  equivalent to @('takeWhile ' p xs , ' dropWhile ' p xs)@
span :: (Char -> Bool) -> ByteString -> (ByteString, ByteString)
span f = L.span (f . w2c)
# INLINE span #


 -- | ' breakChar ' breaks its ByteString argument at the first occurence 
 -- of the specified  . It is more efficient than ' break ' as it is 
 -- implemented with @memchr(3)@. I.e. 
 -- 
 -- > break (= = ' c ' ) " abcd " = = breakChar ' c ' " abcd " 
 -- 
 breakChar : :       ( ByteString , ByteString ) 
 breakChar = L.breakByte . c2w 
 { - # INLINE breakChar #
-- | 'breakChar' breaks its ByteString argument at the first occurence
-- of the specified Char. It is more efficient than 'break' as it is
-- implemented with @memchr(3)@. I.e.
-- 
-- > break (=='c') "abcd" == breakChar 'c' "abcd"
--
breakChar :: Char -> ByteString -> (ByteString, ByteString)
breakChar = L.breakByte . c2w
{-# INLINE breakChar #-}

  | ' spanChar ' breaks its ByteString argument at the first
  occurence of a  other than its argument . It is more efficient
-- than 'span (==)'
--
-- > span  (=='c') "abcd" == spanByte 'c' "abcd"
--
spanChar :: Char -> ByteString -> (ByteString, ByteString)
spanChar = L.spanByte . c2w
# INLINE spanChar #
-}

--
  TODO , more rules for breakChar *
--

-- | /O(n)/ Break a 'ByteString' 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 ' ByteStrings ' that
-- are slices of the original.
--
split :: Char -> ByteString -> [ByteString]
split = L.split . c2w
# INLINE split #

-- | /O(n)/ Splits a 'ByteString' 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 :: (Char -> Bool) -> ByteString -> [ByteString]
splitWith f = L.splitWith (f . w2c)
# INLINE splitWith #

-- | The 'groupBy' function is the non-overloaded version of 'group'.
groupBy :: (Char -> Char -> Bool) -> ByteString -> [ByteString]
groupBy k = L.groupBy (\a b -> k (w2c a) (w2c b))

  | /O(1)/ ' ByteString ' index ( subscript ) operator , starting from 0 .
index :: ByteString -> Int64 -> Char
index = (w2c .) . L.index
# INLINE index #

  | /O(n)/ The ' elemIndex ' function returns the index of the first
  element in the given ' ByteString ' which is equal ( by memchr ) to the
-- query element, or 'Nothing' if there is no such element.
elemIndex :: Char -> ByteString -> Maybe Int64
elemIndex = L.elemIndex . c2w
{-# INLINE elemIndex #-}

-- | /O(n)/ The 'elemIndices' function extends 'elemIndex', by returning
-- the indices of all elements equal to the query element, in ascending order.
elemIndices :: Char -> ByteString -> [Int64]
elemIndices = L.elemIndices . c2w
# INLINE elemIndices #

-- | The 'findIndex' function takes a predicate and a 'ByteString' and
  returns the index of the first element in the ByteString satisfying the predicate .
findIndex :: (Char -> Bool) -> ByteString -> Maybe Int64
findIndex f = L.findIndex (f . w2c)
# INLINE findIndex #

-- | The 'findIndices' function extends 'findIndex', by returning the
-- indices of all elements satisfying the predicate, in ascending order.
findIndices :: (Char -> Bool) -> ByteString -> [Int64]
findIndices f = L.findIndices (f . w2c)

  | count returns the number of times its argument appears in the ByteString
--
-- > count      == length . elemIndices
-- > count '\n' == length . lines
--
-- But more efficiently than using length on the intermediate list.
count :: Char -> ByteString -> Int64
count c = L.count (c2w c)

  | /O(n)/ ' elem ' is the ' ByteString ' membership predicate . This
  implementation uses @memchr(3)@.
elem :: Char -> ByteString -> Bool
elem c = L.elem (c2w c)
# INLINE elem #

-- | /O(n)/ 'notElem' is the inverse of 'elem'
notElem :: Char -> ByteString -> Bool
notElem c = L.notElem (c2w c)
# INLINE notElem #

  | /O(n)/ ' filter ' , applied to a predicate and a ByteString ,
  returns a ByteString containing those characters that satisfy the
-- predicate.
filter :: (Char -> Bool) -> ByteString -> ByteString
filter f = L.filter (f . w2c)
# INLINE filter #


 -- | /O(n)/ and /O(n\/c ) space/ A first order equivalent of /filter . 
 -- (= =) / , for the common case of filtering a single  . It is more 
 -- efficient to use /filterChar/ in this case . 
 -- 
 -- > filterChar = = filter . (= =) 
 -- 
 -- filterChar is around 10x faster , and uses much less space , than its 
 -- filter equivalent 
 -- 
 filterChar : :       ByteString 
 filterChar c ps = replicate ( count c ps ) c 
 { - # INLINE filterChar #
-- | /O(n)/ and /O(n\/c) space/ A first order equivalent of /filter .
-- (==)/, for the common case of filtering a single Char. It is more
-- efficient to use /filterChar/ in this case.
--
-- > filterChar == filter . (==)
--
-- filterChar is around 10x faster, and uses much less space, than its
-- filter equivalent
--
filterChar :: Char -> ByteString -> ByteString
filterChar c ps = replicate (count c ps) c
{-# INLINE filterChar #-}

# RULES 
   " ByteString specialise filter (= = x ) " forall x. 
       filter ( (=   ) =   
   #
  "ByteString specialise filter (== x)" forall x.
      filter ((==) x) = filterChar x
  #-}

# RULES 
   " ByteString specialise filter (= = x ) " forall x. 
      filter (= = x ) =   
   #
  "ByteString specialise filter (== x)" forall x.
     filter (== x) = filterChar x
  #-}
-}

  | /O(n)/ The ' find ' function takes a predicate and a ByteString ,
  and returns the first element in matching the predicate , or ' Nothing '
-- if there is no such element.
find :: (Char -> Bool) -> ByteString -> Maybe Char
find f ps = w2c `fmap` L.find (f . w2c) ps
{-# INLINE find #-}


 -- | /O(n)/ A first order equivalent of /filter . (= =) / , for the common 
 -- case of filtering a single  . It is more efficient to use 
 -- filterChar in this case . 
 -- 
 -- > filterChar = = filter . (= =) 
 -- 
 -- filterChar is around 10x faster , and uses much less space , than its 
 -- filter equivalent 
 -- 
 filterChar : :       ByteString 
 filterChar c = L.filterByte ( c2w c ) 
 { - # INLINE filterChar #
-- | /O(n)/ A first order equivalent of /filter . (==)/, for the common
-- case of filtering a single Char. It is more efficient to use
-- filterChar in this case.
--
-- > filterChar == filter . (==)
--
-- filterChar is around 10x faster, and uses much less space, than its
-- filter equivalent
--
filterChar :: Char -> ByteString -> ByteString
filterChar c = L.filterByte (c2w c)
{-# INLINE filterChar #-}

  | /O(n)/ A first order equivalent of /filter . ( \/=)/ , for the common
  case of filtering a single  out of a list . It is more efficient
-- to use /filterNotChar/ in this case.
--
-- > filterNotChar == filter . (/=)
--
-- filterNotChar is around 3x faster, and uses much less space, than its
-- filter equivalent
--
filterNotChar :: Char -> ByteString -> ByteString
filterNotChar c = L.filterNotByte (c2w c)
# INLINE filterNotChar #
-}

  | /O(n)/ ' zip ' takes two ByteStrings and returns a list of
  corresponding pairs of  . If one input ByteString is short ,
  excess elements of the longer ByteString are discarded . This is
-- equivalent to a pair of 'unpack' operations, and so space
  usage may be large for multi - megabyte ByteStrings
zip :: ByteString -> ByteString -> [(Char,Char)]
zip ps qs
    | L.null ps || L.null qs = []
    | otherwise = (head ps, head qs) : zip (L.tail ps) (L.tail qs)

-- | 'zipWith' generalises 'zip' by zipping with the function given as
  the first argument , instead of a tupling function .   For example ,
  @'zipWith ' ( + ) @ is applied to two ByteStrings to produce the list
-- of corresponding sums.
zipWith :: (Char -> Char -> a) -> ByteString -> ByteString -> [a]
zipWith f = L.zipWith ((. w2c) . f . w2c)

  | ' lines ' breaks a ByteString up into a list of ByteStrings at
-- newline Chars. The resulting strings do not contain newlines.
--
  As of bytestring 0.9.0.3 , this function is stricter than its
-- list cousin.
--
lines :: ByteString -> [ByteString]
lines Empty          = []
lines (Chunk c0 cs0) = loop0 c0 cs0
    where
    -- this is a really performance sensitive function but the
    -- chunked representation makes the general case a bit expensive
    -- however assuming a large chunk size and normalish line lengths
    -- we will find line endings much more frequently than chunk
    -- endings so it makes sense to optimise for that common case.
  So we partition into two special cases depending on whether we
    -- are keeping back a list of chunks that will eventually be output
    -- once we get to the end of the current line.

    -- the common special case where we have no existing chunks of
    -- the current line
    loop0 :: S.ByteString -> ByteString -> [ByteString]
    loop0 c cs =
        case B.elemIndex (c2w '\n') c of
            Nothing -> case cs of
                           Empty  | B.null c  ->                 []
                                  | otherwise -> Chunk c Empty : []
                           (Chunk c' cs')
                               | B.null c  -> loop0 c'     cs'
                               | otherwise -> loop  c' [c] cs'

            Just n | n /= 0    -> Chunk (B.unsafeTake n c) Empty
                                : loop0 (B.unsafeDrop (n+1) c) cs
                   | otherwise -> Empty
                                : loop0 (B.unsafeTail c) cs

    -- the general case when we are building a list of chunks that are
    -- part of the same line
    loop :: S.ByteString -> [S.ByteString] -> ByteString -> [ByteString]
    loop c line cs =
        case B.elemIndex (c2w '\n') c of
            Nothing ->
                case cs of
                    Empty -> let c' = revChunks (c : line)
                              in c' `seq` (c' : [])

                    (Chunk c' cs') -> loop c' (c : line) cs'

            Just n ->
                let c' = revChunks (B.unsafeTake n c : line)
                 in c' `seq` (c' : loop0 (B.unsafeDrop (n+1) c) cs)



 This function is too strict !   Consider , 

 > prop_lazy = 
     ( L.unpack . head . lazylines $ L.append ( L.pack " a\nb\n " ) ( error " failed " ) ) 
   = = 
     " a " 

 fails .   Here 's a properly lazy version of ' lines ' for lazy bytestrings 

     lazylines            : : L.ByteString - > [ L.ByteString ] 
     lazylines s 
         | L.null s   = [ ] 
         | otherwise = 
             let ( l , s ' ) = L.break ( (= =) ' \n ' ) s 
             in l : if L.null s ' then [ ] 
                                 else lazylines ( L.tail s ' ) 

 we need a similarly lazy , but efficient version . 



This function is too strict!  Consider,

> prop_lazy =
    (L.unpack . head . lazylines $ L.append (L.pack "a\nb\n") (error "failed"))
  ==
    "a"

fails.  Here's a properly lazy version of 'lines' for lazy bytestrings

    lazylines           :: L.ByteString -> [L.ByteString]
    lazylines s
        | L.null s  = []
        | otherwise =
            let (l,s') = L.break ((==) '\n') s
            in l : if L.null s' then []
                                else lazylines (L.tail s')

we need a similarly lazy, but efficient version.

-}


-- | 'unlines' is an inverse operation to 'lines'.  It joins lines,
-- after appending a terminating newline to each.
unlines :: [ByteString] -> ByteString
unlines [] = empty
unlines ss = (concat $ List.intersperse nl ss) `append` nl -- half as much space
    where nl = singleton '\n'

  | ' words ' breaks a ByteString up into a list of words , which
  were delimited by  representing white space . And
--
-- > tokens isSpace = words
--
words :: ByteString -> [ByteString]
words = List.filter (not . L.null) . L.splitWith isSpaceWord8
# INLINE words #

-- | The 'unwords' function is analogous to the 'unlines' function, on words.
unwords :: [ByteString] -> ByteString
unwords = intercalate (singleton ' ')
# INLINE unwords #

  | readInt reads an Int from the beginning of the ByteString .   If
-- there is no integer at the beginning of the string, it returns
-- Nothing, otherwise it just returns the int read, and the rest of the
-- string.

readInt :: ByteString -> Maybe (Int, ByteString)
# INLINE readInt #
readInt Empty        = Nothing
readInt (Chunk x xs) = case w2c (B.unsafeHead x) of
    '-' -> loop True  0 0 (B.unsafeTail x) xs
    '+' -> loop False 0 0 (B.unsafeTail x) xs
    _   -> loop False 0 0 x xs

    where loop :: Bool -> Int -> Int
                -> S.ByteString -> ByteString -> Maybe (Int, ByteString)
          loop neg !i !n !c cs
              | B.null c = case cs of
                             Empty          -> end  neg i n c  cs
                             (Chunk c' cs') -> loop neg i n c' cs'
              | otherwise =
                  case B.unsafeHead c of
                    w | w >= 0x30
                     && w <= 0x39 -> loop neg (i+1)
                                          (n * 10 + (fromIntegral w - 0x30))
                                          (B.unsafeTail c) cs
                      | otherwise -> end neg i n c cs

# INLINE end #
          end _   0 _ _  _ = Nothing
          end neg _ n c cs = e `seq` e
                where n' = if neg then negate n else n
                      c' = chunk c cs
                      e  = n' `seq` c' `seq` Just $! (n',c')
         --                  in n' `seq` c' `seq` JustS n' c'


  | readInteger reads an Integer from the beginning of the ByteString .   If
-- there is no integer at the beginning of the string, it returns Nothing,
-- otherwise it just returns the int read, and the rest of the string.
readInteger :: ByteString -> Maybe (Integer, ByteString)
readInteger Empty = Nothing
readInteger (Chunk c0 cs0) =
        case w2c (B.unsafeHead c0) of
            '-' -> first (B.unsafeTail c0) cs0 >>= \(n, cs') -> return (-n, cs')
            '+' -> first (B.unsafeTail c0) cs0
            _   -> first c0 cs0

    where first c cs
              | B.null c = case cs of
                  Empty          -> Nothing
                  (Chunk c' cs') -> first' c' cs'
              | otherwise = first' c cs

          first' c cs = case B.unsafeHead c of
              w | w >= 0x30 && w <= 0x39 -> Just $
                  loop 1 (fromIntegral w - 0x30) [] (B.unsafeTail c) cs
                | otherwise              -> Nothing

          loop :: Int -> Int -> [Integer]
               -> S.ByteString -> ByteString -> (Integer, ByteString)
          loop !d !acc ns !c cs
              | B.null c = case cs of
                             Empty          -> combine d acc ns c cs
                             (Chunk c' cs') -> loop d acc ns c' cs'
              | otherwise =
                  case B.unsafeHead c of
                   w | w >= 0x30 && w <= 0x39 ->
                       if d < 9 then loop (d+1)
                                          (10*acc + (fromIntegral w - 0x30))
                                          ns (B.unsafeTail c) cs
                                else loop 1 (fromIntegral w - 0x30)
                                          (fromIntegral acc : ns)
                                          (B.unsafeTail c) cs
                     | otherwise -> combine d acc ns c cs

          combine _ acc [] c cs = end (fromIntegral acc) c cs
          combine d acc ns c cs =
              end (10^d * combine1 1000000000 ns + fromIntegral acc) c cs

          combine1 _ [n] = n
          combine1 b ns  = combine1 (b*b) $ combine2 b ns

          combine2 b (n:m:ns) = let t = n+m*b in t `seq` (t : combine2 b ns)
          combine2 _ ns       = ns

          end n c cs = let c' = chunk c cs
                        in c' `seq` (n, c')

-- | Read an entire file /lazily/ into a 'ByteString'.
readFile :: FilePath -> IO ByteString
readFile f = openBinaryFile f ReadMode >>= hGetContents

-- | Write a 'ByteString' to a file.
writeFile :: FilePath -> ByteString -> IO ()
writeFile f txt = bracket (openBinaryFile f WriteMode) hClose
    (\hdl -> hPut hdl txt)

-- | Append a 'ByteString' to a file.
appendFile :: FilePath -> ByteString -> IO ()
appendFile f txt = bracket (openBinaryFile f AppendMode) hClose
    (\hdl -> hPut hdl txt)


  | Write a ByteString to a handle , appending a newline byte
--
hPutStrLn :: Handle -> ByteString -> IO ()
hPutStrLn h ps = hPut h ps >> hPut h (L.singleton 0x0a)

  | Write a ByteString to stdout , appending a newline byte
putStrLn :: ByteString -> IO ()
putStrLn = hPutStrLn stdout


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

  reverse a list of possibly - empty chunks into a lazy ByteString
revChunks :: [S.ByteString] -> ByteString
revChunks cs = List.foldl' (flip chunk) Empty cs

# OPTIONS_HADDOCK prune #
 |
 Module      : Data.ByteString.Lazy.Char8
 License     : BSD-style

 Maintainer  : , 
 Stability   : stable
 Portability : portable

 run at identical speeds to their 'Data.Word.Word8' equivalents in

 This module is intended to be imported @qualified@, to avoid name


\ # LANGUAGE OverloadedStrings \#

 * The @ByteString@ type
 :: ByteString
 :: String -> ByteString
 :: ByteString -> String
 :: [Strict.ByteString] -> ByteString
 :: ByteString -> [Strict.ByteString]
 :: Strict.ByteString -> ByteString
 :: ByteString -> Strict.ByteString
 * Basic interface
 :: ByteString -> Char -> ByteString
 :: ByteString -> ByteString -> ByteString
 :: ByteString -> ByteString
 :: ByteString -> ByteString
 :: ByteString -> Bool
 * Transforming ByteStrings
 :: ByteString -> ByteString
 :: ByteString -> [ByteString] -> ByteString
 :: [ByteString] -> [ByteString]
 * Reducing 'ByteString's (folds)
 :: (a -> Char -> a) -> a -> ByteString -> a
 :: (a -> Char -> a) -> a -> ByteString -> a
 :: (Char -> a -> a) -> a -> ByteString -> a
 ** Special folds
 :: [ByteString] -> ByteString
 :: (Char -> ByteString) -> ByteString -> ByteString
 * Building ByteStrings
 ** Scans
 : : (    Char - >  ) - > ByteString - > ByteString
 : : (    Char - >  ) - > Char - > ByteString - > ByteString
 : : (    Char - >  ) - > ByteString - > ByteString
 ** Accumulating maps
 ** Infinite ByteStrings
 :: Int64 -> Char -> ByteString
 :: ByteString -> ByteString
 ** Breaking strings
 :: Int64 -> ByteString -> ByteString
 :: Int64 -> ByteString -> ByteString
 :: ByteString -> [ByteString]
 :: ByteString -> [ByteString]
 :: ByteString -> [ByteString]
 ** Breaking into many substrings
 ** Breaking into lines and words
 :: ByteString -> [ByteString]
 :: ByteString -> [ByteString]
 :: [ByteString] -> ByteString
 :: ByteString -> [ByteString]
 * Predicates
 :: ByteString -> ByteString -> Bool
 :: ByteString -> ByteString -> Bool
 ** Searching by equality
 ** Searching with a predicate
 : : (    Bool ) - > ByteString - > ( ByteString , ByteString )
 : : [ (  ,  ) ] - > ( ByteString , ByteString )
        sort,                   -- :: ByteString -> ByteString
 * Low level conversions
 :: ByteString -> ByteString
 | ByteString I/O uses binary mode, without any character decoding
 or newline conversion. The fact that it does not respect the Handle
 newline mode is considered a flaw and may be changed in a future version.
 ** Standard input and output
 :: ByteString -> IO ()
 :: ByteString -> IO ()
 :: (ByteString -> ByteString) -> IO ()
 ** Files
 :: FilePath -> IO ByteString
 :: FilePath -> ByteString -> IO ()
 :: FilePath -> ByteString -> IO ()
 ** I\/O with Handles
 :: Handle -> IO ByteString
 :: Handle -> Int64 -> IO ByteString
 :: Handle -> Int64 -> IO ByteString
 :: Handle -> ByteString -> IO ()
 :: Handle -> ByteString -> IO ()
 :: Handle -> ByteString -> IO ()
 Functions transparently exported
 Functions we need to wrap.
 typename only
----------------------------------------------------------------------
 | /O(n)/ Convert a 'String' into a 'ByteString'. 
 | /O(n)/ Converts a 'ByteString' to a 'String'.
same as list (:)
 | /O(1)/ 'cons' is analogous to '(:)' for lists.
 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

# INLINE cons' #
 'cons', this function performs a memcpy.
 if it is empty.
 if it is empty.
 | /O(1)/ Extract the last element of a packed string, which must be non-empty.
 | 'foldl', applied to a binary operator, a starting value (typically
# INLINE foldl #
 | 'foldl\'' is like foldl, but strict in the accumulator.
# INLINE foldl' #
 | 'foldr', applied to a binary operator, a starting value
 (typically the right-identity of the operator), and a packed string,
 reduces the packed string using the binary operator, from right to left.
 | Map a function over a 'ByteString' and concatenate the results
 any element of the 'ByteString' satisfies the predicate.
 | Applied to a predicate and a 'ByteString', 'all' determines if
 all elements of the 'ByteString' satisfy the predicate.
 ---------------------------------------------------------------------
 reduced values from the left. This function will fuse.


 Note that

 | The 'mapAccumL' function behaves like a combination of 'map' and
 passing an accumulating parameter from left to right, and returning a
 | The 'mapAccumR' function behaves like a combination of 'map' and
 passing an accumulating parameter from right to left, and returning a
----------------------------------------------------------------------

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

 element.

 the value of every element.

 | /O(n)/ The 'unfoldr' function is analogous to the List \'unfoldr\'.
 the element and returns 'Nothing' if it is done producing the
 recursive call.
----------------------------------------------------------------------
 returns the longest prefix (possibly empty) of @xs@ of elements that
 | ' breakChar ' breaks its ByteString argument at the first occurence 
 of the specified  . It is more efficient than ' break ' as it is 
 implemented with @memchr(3)@. I.e. 
 
 > break (= = ' c ' ) " abcd " = = breakChar ' c ' " abcd " 
 
 | 'breakChar' breaks its ByteString argument at the first occurence
 of the specified Char. It is more efficient than 'break' as it is
 implemented with @memchr(3)@. I.e.
 
 > break (=='c') "abcd" == breakChar 'c' "abcd"

# INLINE breakChar #
 than 'span (==)'

 > span  (=='c') "abcd" == spanByte 'c' "abcd"



 | /O(n)/ Break a 'ByteString' into pieces separated by the byte
 argument, consuming the delimiter. I.e.

 > split '\n' "a\nb\nd\ne" == ["a","b","d","e"]
 > split 'x'  "x"          == ["",""]
 
 and

 > intercalate [c] . split c == id
 > split == splitWith . (==)
 
 As for all splitting functions in this library, this function does
 are slices of the original.

 | /O(n)/ Splits a 'ByteString' into components delimited by
 separators, where the predicate returns True for a separator element.
 separators result in an empty component in the output.  eg.

 > splitWith (=='a') "aabbaca" == ["","","bb","c",""]

 | The 'groupBy' function is the non-overloaded version of 'group'.
 query element, or 'Nothing' if there is no such element.
# INLINE elemIndex #
 | /O(n)/ The 'elemIndices' function extends 'elemIndex', by returning
 the indices of all elements equal to the query element, in ascending order.
 | The 'findIndex' function takes a predicate and a 'ByteString' and
 | The 'findIndices' function extends 'findIndex', by returning the
 indices of all elements satisfying the predicate, in ascending order.

 > count      == length . elemIndices
 > count '\n' == length . lines

 But more efficiently than using length on the intermediate list.
 | /O(n)/ 'notElem' is the inverse of 'elem'
 predicate.
 | /O(n)/ and /O(n\/c ) space/ A first order equivalent of /filter . 
 (= =) / , for the common case of filtering a single  . It is more 
 efficient to use /filterChar/ in this case . 
 
 > filterChar = = filter . (= =) 
 
 filterChar is around 10x faster , and uses much less space , than its 
 filter equivalent 
 
 | /O(n)/ and /O(n\/c) space/ A first order equivalent of /filter .
 (==)/, for the common case of filtering a single Char. It is more
 efficient to use /filterChar/ in this case.

 > filterChar == filter . (==)

 filterChar is around 10x faster, and uses much less space, than its
 filter equivalent

# INLINE filterChar #
 if there is no such element.
# INLINE find #
 | /O(n)/ A first order equivalent of /filter . (= =) / , for the common 
 case of filtering a single  . It is more efficient to use 
 filterChar in this case . 
 
 > filterChar = = filter . (= =) 
 
 filterChar is around 10x faster , and uses much less space , than its 
 filter equivalent 
 
 | /O(n)/ A first order equivalent of /filter . (==)/, for the common
 case of filtering a single Char. It is more efficient to use
 filterChar in this case.

 > filterChar == filter . (==)

 filterChar is around 10x faster, and uses much less space, than its
 filter equivalent

# INLINE filterChar #
 to use /filterNotChar/ in this case.

 > filterNotChar == filter . (/=)

 filterNotChar is around 3x faster, and uses much less space, than its
 filter equivalent

 equivalent to a pair of 'unpack' operations, and so space
 | 'zipWith' generalises 'zip' by zipping with the function given as
 of corresponding sums.
 newline Chars. The resulting strings do not contain newlines.

 list cousin.

 this is a really performance sensitive function but the
 chunked representation makes the general case a bit expensive
 however assuming a large chunk size and normalish line lengths
 we will find line endings much more frequently than chunk
 endings so it makes sense to optimise for that common case.
 are keeping back a list of chunks that will eventually be output
 once we get to the end of the current line.
 the common special case where we have no existing chunks of
 the current line
 the general case when we are building a list of chunks that are
 part of the same line
 | 'unlines' is an inverse operation to 'lines'.  It joins lines,
 after appending a terminating newline to each.
 half as much space

 > tokens isSpace = words

 | The 'unwords' function is analogous to the 'unlines' function, on words.
 there is no integer at the beginning of the string, it returns
 Nothing, otherwise it just returns the int read, and the rest of the
 string.
                  in n' `seq` c' `seq` JustS n' c'
 there is no integer at the beginning of the string, it returns Nothing,
 otherwise it just returns the int read, and the rest of the string.
 | Read an entire file /lazily/ into a 'ByteString'.
 | Write a 'ByteString' to a file.
 | Append a 'ByteString' to a file.

 ---------------------------------------------------------------------
# LANGUAGE Haskell98 #
# LINE 1 " Data / ByteString / Lazy / Char8.hs " #























































# LANGUAGE CPP , BangPatterns #
# LANGUAGE Trustworthy #

  Copyright    : ( c )   2006 - 2008
                ( c )   2006 - 2011
  Manipulate /lazy/ ' ByteString 's using '  ' operations . All  will
  be truncated to 8 bits . It can be expected that these functions will
  " Data . ByteString . Lazy " .
  clashes with " Prelude " functions .   eg .
  > import qualified Data . ByteString . Lazy . Char8 as C
  The Char8 interface to bytestrings provides an instance of IsString
  for the ByteString type , enabling you to use string literals , and
  have them implicitly packed to ByteStrings .

module Data.ByteString.Lazy.Char8 (

  instances :  , Ord , Show , Read , Data , 

  * Introducing and eliminating ' ByteString 's
  : :     ByteString

  : :       ByteString
  : :       ByteString
  : : ByteString - > 
  : : ByteString - > Maybe (  , ByteString )
  : : ByteString - > 
  : : ByteString - > Maybe ( ByteString ,  )
  : : ByteString - > Int64

  : : (     ) - > ByteString - > ByteString
  : :       ByteString

  : : (    Char - >  ) - > ByteString - > 
  : : (    Char - >  ) - > ByteString - > 
  : : (    Char - >  ) - > ByteString - > 

  : : (    Bool ) - > ByteString - > Bool
  : : (    Bool ) - > ByteString - > Bool
  : : ByteString - > 
  : : ByteString - > 

  : : (    Char - >  ) - > Char - > ByteString - > ByteString

  : : ( acc - > Char - > ( acc ,  ) ) - > acc - > ByteString - > ( acc , ByteString )
  : : ( acc - > Char - > ( acc ,  ) ) - > acc - > ByteString - > ( acc , ByteString )

  : :    
  : : (     ) - > Char - > ByteString

  * * Unfolding ByteStrings
  : : ( a - > Maybe (  , a ) ) - > a - > ByteString

  * Substrings

  : : Int64 - > ByteString - > ( ByteString , ByteString )
  : : (    Bool ) - > ByteString - > ByteString
  : : (    Bool ) - > ByteString - > ByteString
  : : (    Bool ) - > ByteString - > ( ByteString , ByteString )
  : : (    Bool ) - > ByteString - > ( ByteString , ByteString )
  : : (    Char - > Bool ) - > ByteString - > [ ByteString ]
  : : ByteString - > ByteString - > Maybe ByteString
  : : ByteString - > ByteString - > Maybe ByteString

  : :       [ ByteString ]
  : : (    Bool ) - > ByteString - > [ ByteString ]



  * Searching ByteStrings

  : :       Bool
  : :       Bool

  : : (    Bool ) - > ByteString - > Maybe 
  : : (    Bool ) - > ByteString - > ByteString

  * Indexing ByteStrings
  : : ByteString - > Int64 - > 
  : :     - > Maybe Int64
  : :       [ Int64 ]
  : : (    Bool ) - > ByteString - > Maybe Int64
  : : (    Bool ) - > ByteString - > [ Int64 ]
  : :     - > Int64

  * Zipping and unzipping ByteStrings
  : : ByteString - > ByteString - > [ (  ,  ) ]
  : : (    Char - > c ) - > ByteString - > ByteString - > [ c ]

  * Ordered ByteStrings

  * * Copying ByteStrings

  * Reading from ByteStrings
        readInt,
        readInteger,

  * I\/O with ' ByteString 's

  : : IO ByteString


  : : Handle - > ByteString - > IO ByteString

  ) where

import Data.ByteString.Lazy 
        (fromChunks, toChunks, fromStrict, toStrict
        ,empty,null,length,tail,init,append,reverse,transpose,cycle
        ,concat,take,drop,splitAt,intercalate
        ,isPrefixOf,isSuffixOf,group,inits,tails,copy
        ,stripPrefix,stripSuffix
        ,hGetContents, hGet, hPut, getContents
        ,hGetNonBlocking, hPutNonBlocking
        ,putStr, hPutStr, interact)

import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as B
import Data.ByteString.Lazy.Internal

import Data.ByteString.Internal (w2c, c2w, isSpaceWord8)

import Data.Int (Int64)
import qualified Data.List as List

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

import System.IO            (Handle,stdout,hClose,openBinaryFile,IOMode(..))
import Control.Exception    (bracket)


  | /O(1)/ Convert a '  ' into a ' ByteString '
singleton :: Char -> ByteString
singleton = L.singleton . c2w
# INLINE singleton #

pack :: [Char] -> ByteString
pack = packChars

unpack :: ByteString -> [Char]
unpack = unpackChars

infixl 5 `snoc`

cons :: Char -> ByteString -> ByteString
cons = L.cons . c2w
# INLINE cons #

  | /O(1)/ Unlike ' 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
  infinite lazy ByteStrings .
cons' :: Char -> ByteString -> ByteString
cons' = L.cons' . c2w

  | /O(n)/ Append a  to the end of a ' ByteString ' . Similar to
snoc :: ByteString -> Char -> ByteString
snoc p = L.snoc p . c2w
# INLINE snoc #

  | /O(1)/ Extract the first element of a ByteString , which must be non - empty .
head :: ByteString -> Char
head = w2c . L.head
# INLINE head #

  | /O(1)/ Extract the head and tail of a ByteString , returning Nothing
uncons :: ByteString -> Maybe (Char, ByteString)
uncons bs = case L.uncons bs of
                  Nothing -> Nothing
                  Just (w, bs') -> Just (w2c w, bs')
# INLINE uncons #

  | /O(n\/c)/ Extract the ' init ' and ' last ' of a ByteString , returning Nothing
unsnoc :: ByteString -> Maybe (ByteString, Char)
unsnoc bs = case L.unsnoc bs of
                  Nothing -> Nothing
                  Just (bs', w) -> Just (bs', w2c w)
# INLINE unsnoc #

last :: ByteString -> Char
last = w2c . L.last
# INLINE last #

  | /O(n)/ ' map '   is the ByteString obtained by applying @f@ to each element of @xs@
map :: (Char -> Char) -> ByteString -> ByteString
map f = L.map (c2w . f . w2c)
# INLINE map #

  | /O(n)/ The ' intersperse ' function takes a  and a ' ByteString '
  and  ' that  between the elements of the
  ' ByteString ' .   It is analogous to the intersperse function on Lists .
intersperse :: Char -> ByteString -> ByteString
intersperse = L.intersperse . c2w
# INLINE intersperse #

  the left - identity of the operator ) , and a ByteString , reduces the
  ByteString using the binary operator , from left to right .
foldl :: (a -> Char -> a) -> a -> ByteString -> a
foldl f = L.foldl (\a c -> f a (w2c c))

foldl' :: (a -> Char -> a) -> a -> ByteString -> a
foldl' f = L.foldl' (\a c -> f a (w2c c))

foldr :: (Char -> a -> a) -> a -> ByteString -> a
foldr f = L.foldr (\c a -> f (w2c c) a)
# INLINE foldr #

  | ' foldl1 ' is a variant of ' foldl ' that has no starting value
  argument , and thus must be applied to non - empty ' ByteStrings ' .
foldl1 :: (Char -> Char -> Char) -> ByteString -> Char
foldl1 f ps = w2c (L.foldl1 (\x y -> c2w (f (w2c x) (w2c y))) ps)
# INLINE foldl1 #

  | ' foldl1\ '' is like ' foldl1 ' , but strict in the accumulator .
foldl1' :: (Char -> Char -> Char) -> ByteString -> Char
foldl1' f ps = w2c (L.foldl1' (\x y -> c2w (f (w2c x) (w2c y))) ps)

  | '  ' is a variant of ' foldr ' that has no starting value argument ,
  and thus must be applied to non - empty ' ByteString 's
foldr1 :: (Char -> Char -> Char) -> ByteString -> Char
foldr1 f ps = w2c (L.foldr1 (\x y -> c2w (f (w2c x) (w2c y))) ps)
# INLINE foldr1 #

concatMap :: (Char -> ByteString) -> ByteString -> ByteString
concatMap f = L.concatMap (f . w2c)
# INLINE concatMap #

  | Applied to a predicate and a ByteString , ' any ' determines if
any :: (Char -> Bool) -> ByteString -> Bool
any f = L.any (f . w2c)
# INLINE any #

all :: (Char -> Bool) -> ByteString -> Bool
all f = L.all (f . w2c)
# INLINE all #

  | ' maximum ' returns the maximum value from a ' ByteString '
maximum :: ByteString -> Char
maximum = w2c . L.maximum
# INLINE maximum #

  | ' minimum ' returns the minimum value from a ' ByteString '
minimum :: ByteString -> Char
minimum = w2c . L.minimum
# INLINE minimum #

  Building ByteStrings

  | '  ' is similar to ' foldl ' , but returns a list of successive
  >  f z [ x1 , x2 , ... ] = = [ z , z ` f ` x1 , ( z ` f ` x1 ) ` f ` x2 , ... ]
  > last (  f z xs ) = = foldl f z xs .
scanl :: (Char -> Char -> Char) -> Char -> ByteString -> ByteString
scanl f z = L.scanl (\a b -> c2w (f (w2c a) (w2c b))) (c2w z)

  ' foldl ' ; it applies a function to each element of a ByteString ,
  final value of this accumulator together with the new ByteString .
mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)
mapAccumL f = L.mapAccumL (\a w -> case f a (w2c w) of (a',c) -> (a', c2w c))

  ' foldr ' ; it applies a function to each element of a ByteString ,
  final value of this accumulator together with the new ByteString .
mapAccumR :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString)
mapAccumR f = L.mapAccumR (\acc w -> case f acc (w2c w) of (acc', c) -> (acc', c2w c))

  Generating and unfolding ByteStrings

  | @'iterate ' f  returns an infinite ByteString of repeated applications
  of  to @x@ :
iterate :: (Char -> Char) -> Char -> ByteString
iterate f = L.iterate (c2w . f . w2c) . c2w

  | @'repeat '  is an infinite ByteString , with @x@ the value of every
repeat :: Char -> ByteString
repeat = L.repeat . c2w

  | /O(n)/ @'replicate ' n  is a ByteString of length @n@ with @x@
replicate :: Int64 -> Char -> ByteString
replicate w c = L.replicate w (c2w c)

  ' unfoldr ' builds a ByteString from a seed value .   The function takes
  ByteString or returns ' Just ' @(a , b)@ , in which case , @a@ is a
  prepending to the ByteString and  is used as the next element in a
unfoldr :: (a -> Maybe (Char, a)) -> a -> ByteString
unfoldr f = L.unfoldr $ \a -> case f a of
                                    Nothing      -> Nothing
                                    Just (c, a') -> Just (c2w c, a')


  | ' takeWhile ' , applied to a predicate @p@ and a ByteString @xs@ ,
  satisfy @p@.
takeWhile :: (Char -> Bool) -> ByteString -> ByteString
takeWhile f = L.takeWhile (f . w2c)
# INLINE takeWhile #

  | ' dropWhile ' @p xs@ returns the suffix remaining after ' takeWhile ' @p xs@.
dropWhile :: (Char -> Bool) -> ByteString -> ByteString
dropWhile f = L.dropWhile (f . w2c)
# INLINE dropWhile #

  | ' break ' @p@ is equivalent to @'span ' ( ' not ' . p)@.
break :: (Char -> Bool) -> ByteString -> (ByteString, ByteString)
break f = L.break (f . w2c)
# INLINE break #

  | ' span ' @p xs@ breaks the ByteString into two segments . It is
  equivalent to @('takeWhile ' p xs , ' dropWhile ' p xs)@
span :: (Char -> Bool) -> ByteString -> (ByteString, ByteString)
span f = L.span (f . w2c)
# INLINE span #


 breakChar : :       ( ByteString , ByteString ) 
 breakChar = L.breakByte . c2w 
 { - # INLINE breakChar #
breakChar :: Char -> ByteString -> (ByteString, ByteString)
breakChar = L.breakByte . c2w

  | ' spanChar ' breaks its ByteString argument at the first
  occurence of a  other than its argument . It is more efficient
spanChar :: Char -> ByteString -> (ByteString, ByteString)
spanChar = L.spanByte . c2w
# INLINE spanChar #
-}

  TODO , more rules for breakChar *

  > split ' a '   " aXaXaXa "     = = [ " " , " X","X","X " ]
  not copy the substrings , it just constructs new ' ByteStrings ' that
split :: Char -> ByteString -> [ByteString]
split = L.split . c2w
# INLINE split #

  The resulting components do not contain the separators .   Two adjacent
splitWith :: (Char -> Bool) -> ByteString -> [ByteString]
splitWith f = L.splitWith (f . w2c)
# INLINE splitWith #

groupBy :: (Char -> Char -> Bool) -> ByteString -> [ByteString]
groupBy k = L.groupBy (\a b -> k (w2c a) (w2c b))

  | /O(1)/ ' ByteString ' index ( subscript ) operator , starting from 0 .
index :: ByteString -> Int64 -> Char
index = (w2c .) . L.index
# INLINE index #

  | /O(n)/ The ' elemIndex ' function returns the index of the first
  element in the given ' ByteString ' which is equal ( by memchr ) to the
elemIndex :: Char -> ByteString -> Maybe Int64
elemIndex = L.elemIndex . c2w

elemIndices :: Char -> ByteString -> [Int64]
elemIndices = L.elemIndices . c2w
# INLINE elemIndices #

  returns the index of the first element in the ByteString satisfying the predicate .
findIndex :: (Char -> Bool) -> ByteString -> Maybe Int64
findIndex f = L.findIndex (f . w2c)
# INLINE findIndex #

findIndices :: (Char -> Bool) -> ByteString -> [Int64]
findIndices f = L.findIndices (f . w2c)

  | count returns the number of times its argument appears in the ByteString
count :: Char -> ByteString -> Int64
count c = L.count (c2w c)

  | /O(n)/ ' elem ' is the ' ByteString ' membership predicate . This
  implementation uses @memchr(3)@.
elem :: Char -> ByteString -> Bool
elem c = L.elem (c2w c)
# INLINE elem #

notElem :: Char -> ByteString -> Bool
notElem c = L.notElem (c2w c)
# INLINE notElem #

  | /O(n)/ ' filter ' , applied to a predicate and a ByteString ,
  returns a ByteString containing those characters that satisfy the
filter :: (Char -> Bool) -> ByteString -> ByteString
filter f = L.filter (f . w2c)
# INLINE filter #


 filterChar : :       ByteString 
 filterChar c ps = replicate ( count c ps ) c 
 { - # INLINE filterChar #
filterChar :: Char -> ByteString -> ByteString
filterChar c ps = replicate (count c ps) c

# RULES 
   " ByteString specialise filter (= = x ) " forall x. 
       filter ( (=   ) =   
   #
  "ByteString specialise filter (== x)" forall x.
      filter ((==) x) = filterChar x
  #-}

# RULES 
   " ByteString specialise filter (= = x ) " forall x. 
      filter (= = x ) =   
   #
  "ByteString specialise filter (== x)" forall x.
     filter (== x) = filterChar x
  #-}
-}

  | /O(n)/ The ' find ' function takes a predicate and a ByteString ,
  and returns the first element in matching the predicate , or ' Nothing '
find :: (Char -> Bool) -> ByteString -> Maybe Char
find f ps = w2c `fmap` L.find (f . w2c) ps


 filterChar : :       ByteString 
 filterChar c = L.filterByte ( c2w c ) 
 { - # INLINE filterChar #
filterChar :: Char -> ByteString -> ByteString
filterChar c = L.filterByte (c2w c)

  | /O(n)/ A first order equivalent of /filter . ( \/=)/ , for the common
  case of filtering a single  out of a list . It is more efficient
filterNotChar :: Char -> ByteString -> ByteString
filterNotChar c = L.filterNotByte (c2w c)
# INLINE filterNotChar #
-}

  | /O(n)/ ' zip ' takes two ByteStrings and returns a list of
  corresponding pairs of  . If one input ByteString is short ,
  excess elements of the longer ByteString are discarded . This is
  usage may be large for multi - megabyte ByteStrings
zip :: ByteString -> ByteString -> [(Char,Char)]
zip ps qs
    | L.null ps || L.null qs = []
    | otherwise = (head ps, head qs) : zip (L.tail ps) (L.tail qs)

  the first argument , instead of a tupling function .   For example ,
  @'zipWith ' ( + ) @ is applied to two ByteStrings to produce the list
zipWith :: (Char -> Char -> a) -> ByteString -> ByteString -> [a]
zipWith f = L.zipWith ((. w2c) . f . w2c)

  | ' lines ' breaks a ByteString up into a list of ByteStrings at
  As of bytestring 0.9.0.3 , this function is stricter than its
lines :: ByteString -> [ByteString]
lines Empty          = []
lines (Chunk c0 cs0) = loop0 c0 cs0
    where
  So we partition into two special cases depending on whether we

    loop0 :: S.ByteString -> ByteString -> [ByteString]
    loop0 c cs =
        case B.elemIndex (c2w '\n') c of
            Nothing -> case cs of
                           Empty  | B.null c  ->                 []
                                  | otherwise -> Chunk c Empty : []
                           (Chunk c' cs')
                               | B.null c  -> loop0 c'     cs'
                               | otherwise -> loop  c' [c] cs'

            Just n | n /= 0    -> Chunk (B.unsafeTake n c) Empty
                                : loop0 (B.unsafeDrop (n+1) c) cs
                   | otherwise -> Empty
                                : loop0 (B.unsafeTail c) cs

    loop :: S.ByteString -> [S.ByteString] -> ByteString -> [ByteString]
    loop c line cs =
        case B.elemIndex (c2w '\n') c of
            Nothing ->
                case cs of
                    Empty -> let c' = revChunks (c : line)
                              in c' `seq` (c' : [])

                    (Chunk c' cs') -> loop c' (c : line) cs'

            Just n ->
                let c' = revChunks (B.unsafeTake n c : line)
                 in c' `seq` (c' : loop0 (B.unsafeDrop (n+1) c) cs)



 This function is too strict !   Consider , 

 > prop_lazy = 
     ( L.unpack . head . lazylines $ L.append ( L.pack " a\nb\n " ) ( error " failed " ) ) 
   = = 
     " a " 

 fails .   Here 's a properly lazy version of ' lines ' for lazy bytestrings 

     lazylines            : : L.ByteString - > [ L.ByteString ] 
     lazylines s 
         | L.null s   = [ ] 
         | otherwise = 
             let ( l , s ' ) = L.break ( (= =) ' \n ' ) s 
             in l : if L.null s ' then [ ] 
                                 else lazylines ( L.tail s ' ) 

 we need a similarly lazy , but efficient version . 



This function is too strict!  Consider,

> prop_lazy =
    (L.unpack . head . lazylines $ L.append (L.pack "a\nb\n") (error "failed"))
  ==
    "a"

fails.  Here's a properly lazy version of 'lines' for lazy bytestrings

    lazylines           :: L.ByteString -> [L.ByteString]
    lazylines s
        | L.null s  = []
        | otherwise =
            let (l,s') = L.break ((==) '\n') s
            in l : if L.null s' then []
                                else lazylines (L.tail s')

we need a similarly lazy, but efficient version.

-}


unlines :: [ByteString] -> ByteString
unlines [] = empty
    where nl = singleton '\n'

  | ' words ' breaks a ByteString up into a list of words , which
  were delimited by  representing white space . And
words :: ByteString -> [ByteString]
words = List.filter (not . L.null) . L.splitWith isSpaceWord8
# INLINE words #

unwords :: [ByteString] -> ByteString
unwords = intercalate (singleton ' ')
# INLINE unwords #

  | readInt reads an Int from the beginning of the ByteString .   If

readInt :: ByteString -> Maybe (Int, ByteString)
# INLINE readInt #
readInt Empty        = Nothing
readInt (Chunk x xs) = case w2c (B.unsafeHead x) of
    '-' -> loop True  0 0 (B.unsafeTail x) xs
    '+' -> loop False 0 0 (B.unsafeTail x) xs
    _   -> loop False 0 0 x xs

    where loop :: Bool -> Int -> Int
                -> S.ByteString -> ByteString -> Maybe (Int, ByteString)
          loop neg !i !n !c cs
              | B.null c = case cs of
                             Empty          -> end  neg i n c  cs
                             (Chunk c' cs') -> loop neg i n c' cs'
              | otherwise =
                  case B.unsafeHead c of
                    w | w >= 0x30
                     && w <= 0x39 -> loop neg (i+1)
                                          (n * 10 + (fromIntegral w - 0x30))
                                          (B.unsafeTail c) cs
                      | otherwise -> end neg i n c cs

# INLINE end #
          end _   0 _ _  _ = Nothing
          end neg _ n c cs = e `seq` e
                where n' = if neg then negate n else n
                      c' = chunk c cs
                      e  = n' `seq` c' `seq` Just $! (n',c')


  | readInteger reads an Integer from the beginning of the ByteString .   If
readInteger :: ByteString -> Maybe (Integer, ByteString)
readInteger Empty = Nothing
readInteger (Chunk c0 cs0) =
        case w2c (B.unsafeHead c0) of
            '-' -> first (B.unsafeTail c0) cs0 >>= \(n, cs') -> return (-n, cs')
            '+' -> first (B.unsafeTail c0) cs0
            _   -> first c0 cs0

    where first c cs
              | B.null c = case cs of
                  Empty          -> Nothing
                  (Chunk c' cs') -> first' c' cs'
              | otherwise = first' c cs

          first' c cs = case B.unsafeHead c of
              w | w >= 0x30 && w <= 0x39 -> Just $
                  loop 1 (fromIntegral w - 0x30) [] (B.unsafeTail c) cs
                | otherwise              -> Nothing

          loop :: Int -> Int -> [Integer]
               -> S.ByteString -> ByteString -> (Integer, ByteString)
          loop !d !acc ns !c cs
              | B.null c = case cs of
                             Empty          -> combine d acc ns c cs
                             (Chunk c' cs') -> loop d acc ns c' cs'
              | otherwise =
                  case B.unsafeHead c of
                   w | w >= 0x30 && w <= 0x39 ->
                       if d < 9 then loop (d+1)
                                          (10*acc + (fromIntegral w - 0x30))
                                          ns (B.unsafeTail c) cs
                                else loop 1 (fromIntegral w - 0x30)
                                          (fromIntegral acc : ns)
                                          (B.unsafeTail c) cs
                     | otherwise -> combine d acc ns c cs

          combine _ acc [] c cs = end (fromIntegral acc) c cs
          combine d acc ns c cs =
              end (10^d * combine1 1000000000 ns + fromIntegral acc) c cs

          combine1 _ [n] = n
          combine1 b ns  = combine1 (b*b) $ combine2 b ns

          combine2 b (n:m:ns) = let t = n+m*b in t `seq` (t : combine2 b ns)
          combine2 _ ns       = ns

          end n c cs = let c' = chunk c cs
                        in c' `seq` (n, c')

readFile :: FilePath -> IO ByteString
readFile f = openBinaryFile f ReadMode >>= hGetContents

writeFile :: FilePath -> ByteString -> IO ()
writeFile f txt = bracket (openBinaryFile f WriteMode) hClose
    (\hdl -> hPut hdl txt)

appendFile :: FilePath -> ByteString -> IO ()
appendFile f txt = bracket (openBinaryFile f AppendMode) hClose
    (\hdl -> hPut hdl txt)


  | Write a ByteString to a handle , appending a newline byte
hPutStrLn :: Handle -> ByteString -> IO ()
hPutStrLn h ps = hPut h ps >> hPut h (L.singleton 0x0a)

  | Write a ByteString to stdout , appending a newline byte
putStrLn :: ByteString -> IO ()
putStrLn = hPutStrLn stdout


  Internal utilities

  reverse a list of possibly - empty chunks into a lazy ByteString
revChunks :: [S.ByteString] -> ByteString
revChunks cs = List.foldl' (flip chunk) Empty cs
