    {-# LANGUAGE CPP #-}
    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE Trustworthy #-}

    {- |
    Module      :  Lens.Micro.GHC.Internal
    Copyright   :  (C) 2013-2016 Edward Kmett, 2015-2016 Artyom Kazak, 2018 Monadfix
    License     :  BSD-style (see the file LICENSE)
    -}
    module Lens.Micro.GHC.Internal
    (
      IsByteString(..),
      -- * Unpacking bytestrings
      unpackStrict,
      unpackStrict8,
      unpackLazy,
      unpackLazy8,
      -- * Converting bytestrings between strict and lazy
      fromStrict,
      toStrict,
      -- * Traversing bytestrings
      traversedStrictTree,
      traversedStrictTree8,
      traversedLazy,
      traversedLazy8,
    )
    where

    import Lens.Micro
    import Lens.Micro.Internal

    import qualified Data.ByteString            as B
    import qualified Data.ByteString.Lazy       as BL
    import qualified Data.ByteString.Char8      as B8
    import qualified Data.ByteString.Lazy.Char8 as BL8
    import qualified Data.ByteString.Internal   as BI
    import qualified Data.ByteString.Unsafe     as BU

    import Data.Int
    import Data.Word
    import Data.Char
    import Data.Monoid
    import Foreign.Storable
    import Foreign.Ptr
    import Data.Bits
    #if MIN_VERSION_base(4,8,0)
    import Foreign.ForeignPtr
    #else
    import Foreign.ForeignPtr.Safe
    #endif
    import GHC.ForeignPtr (mallocPlainForeignPtrBytes)
    #if !MIN_VERSION_bytestring(0,10,4)
    import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
    #endif
    import GHC.IO (unsafeDupablePerformIO)
    import GHC.Base (unsafeChr)

    #if !MIN_VERSION_base(4,8,0)
    import Control.Applicative
    #endif

    class IsByteString t where
      {- |
    Treat a list of bytes as a strict or lazy @ByteString@.
      -}
      packedBytes :: Lens' [Word8] t
      {- |
    Treat a strict or lazy @ByteString@ as a list of bytes.
      -}
      unpackedBytes :: Lens' t [Word8]
      {- |
    Treat a 'String' as a strict or lazy @ByteString@. (Note that it will garble characters above 0xFF, same as 'B8.pack' does.)
      -}
      packedChars :: Lens' String t
      {- |
    Treat a strict or lazy @ByteString@ as a 'String'. (Just as 'packedChars', it will garble characters above 0xFF.)
      -}
      unpackedChars :: Lens' t String
      {- |
    Traverse characters in a strict or lazy @ByteString@ (to traverse bytes instead of characters, use 'each').
      -}
      chars :: Traversal' t Char

    -- When writing back to the 'ByteString' it is assumed that every 'Char'
    -- lies between @'\x00'@ and @'\xff'@.

    instance IsByteString B.ByteString where
      packedBytes :: Lens' [Word8] ByteString
    packedBytes ByteString -> f ByteString
    f [Word8]
    s = ByteString -> [Word8]
    unpackStrict (ByteString -> [Word8]) -> f ByteString -> f [Word8]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ByteString -> f ByteString
    f ([Word8] -> ByteString
    B.pack [Word8]
    s)
      {-# INLINE packedBytes #-}
      unpackedBytes :: Lens' ByteString [Word8]
    unpackedBytes [Word8] -> f [Word8]
    f ByteString
    s = [Word8] -> ByteString
    B.pack ([Word8] -> ByteString) -> f [Word8] -> f ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Word8] -> f [Word8]
    f (ByteString -> [Word8]
    unpackStrict ByteString
    s)
      {-# INLINE unpackedBytes #-}
      packedChars :: Lens' String ByteString
    packedChars ByteString -> f ByteString
    f String
    s = ByteString -> String
    unpackStrict8 (ByteString -> String) -> f ByteString -> f String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ByteString -> f ByteString
    f (String -> ByteString
    B8.pack String
    s)
      {-# INLINE packedChars #-}
      unpackedChars :: Lens' ByteString String
    unpackedChars String -> f String
    f ByteString
    s = String -> ByteString
    B8.pack (String -> ByteString) -> f String -> f ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> String -> f String
    f (ByteString -> String
    unpackStrict8 ByteString
    s)
      {-# INLINE unpackedChars #-}
      chars :: Traversal' ByteString Char
    chars = (Char -> f Char) -> ByteString -> f ByteString
    Traversal' ByteString Char
    traversedStrictTree8
      {-# INLINE chars #-}

    instance IsByteString BL.ByteString where
      packedBytes :: Lens' [Word8] ByteString
    packedBytes ByteString -> f ByteString
    f [Word8]
    s = ByteString -> [Word8]
    unpackLazy (ByteString -> [Word8]) -> f ByteString -> f [Word8]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ByteString -> f ByteString
    f ([Word8] -> ByteString
    BL.pack [Word8]
    s)
      {-# INLINE packedBytes #-}
      unpackedBytes :: Lens' ByteString [Word8]
    unpackedBytes [Word8] -> f [Word8]
    f ByteString
    s = [Word8] -> ByteString
    BL.pack ([Word8] -> ByteString) -> f [Word8] -> f ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [Word8] -> f [Word8]
    f (ByteString -> [Word8]
    unpackLazy ByteString
    s)
      {-# INLINE unpackedBytes #-}
      packedChars :: Lens' String ByteString
    packedChars ByteString -> f ByteString
    f String
    s = ByteString -> String
    unpackLazy8 (ByteString -> String) -> f ByteString -> f String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ByteString -> f ByteString
    f (String -> ByteString
    BL8.pack String
    s)
      {-# INLINE packedChars #-}
      unpackedChars :: Lens' ByteString String
    unpackedChars String -> f String
    f ByteString
    s = String -> ByteString
    BL8.pack (String -> ByteString) -> f String -> f ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> String -> f String
    f (ByteString -> String
    unpackLazy8 ByteString
    s)
      {-# INLINE unpackedChars #-}
      chars :: Traversal' ByteString Char
    chars = (Char -> f Char) -> ByteString -> f ByteString
    Traversal' ByteString Char
    traversedLazy8
      {-# INLINE chars #-}

    -- unpacking

    unpackStrict :: B.ByteString -> [Word8]
    #if MIN_VERSION_bytestring(0,10,4)
    unpackStrict :: ByteString -> [Word8]
    unpackStrict = ByteString -> [Word8]
    B.unpack
    #else
    unpackStrict (BI.PS fp off len) =
          let p = unsafeForeignPtrToPtr fp
           in go (p `plusPtr` off) (p `plusPtr` (off+len))
        where
          go !p !q | p == q    = []
                   | otherwise = let !x = BI.inlinePerformIO $ do
                                            x' <- peek p
                                            touchForeignPtr fp
                                            return x'
                                 in x : go (p `plusPtr` 1) q
    #endif
    {-# INLINE unpackStrict #-}

    unpackStrict8 :: B.ByteString -> String
    #if MIN_VERSION_bytestring(0,10,4)
    unpackStrict8 :: ByteString -> String
    unpackStrict8 = ByteString -> String
    B8.unpack
    #else
    unpackStrict8 (BI.PS fp off len) =
          let p = unsafeForeignPtrToPtr fp
           in go (p `plusPtr` off) (p `plusPtr` (off+len))
        where
          go !p !q | p == q    = []
                   | otherwise = let !x = BI.inlinePerformIO $ do
                                            x' <- peek p
                                            touchForeignPtr fp
                                            return x'
                                 in w2c x : go (p `plusPtr` 1) q
    #endif
    {-# INLINE unpackStrict8 #-}

    unpackLazy :: BL.ByteString -> [Word8]
    unpackLazy :: ByteString -> [Word8]
    unpackLazy = ByteString -> [Word8]
    BL.unpack
    {-# INLINE unpackLazy #-}

    unpackLazy8 :: BL.ByteString -> String
    unpackLazy8 :: ByteString -> String
    unpackLazy8 = ByteString -> String
    BL8.unpack
    {-# INLINE unpackLazy8 #-}

    -- converting between strict and lazy

    fromStrict :: B.ByteString -> BL.ByteString
    #if MIN_VERSION_bytestring(0,10,0)
    fromStrict :: ByteString -> ByteString
    fromStrict = ByteString -> ByteString
    BL.fromStrict
    #else
    fromStrict = \x -> BL.fromChunks [x]
    #endif
    {-# INLINE fromStrict #-}

    toStrict :: BL.ByteString -> B.ByteString
    #if MIN_VERSION_bytestring(0,10,0)
    toStrict :: ByteString -> ByteString
    toStrict = ByteString -> ByteString
    BL.toStrict
    #else
    toStrict = B.concat . BL.toChunks
    #endif
    {-# INLINE toStrict #-}

    -- traversing

    grain :: Int
    grain :: Int
    grain = Int
    32
    {-# INLINE grain #-}

    traversedStrictTree :: Traversal' B.ByteString Word8
    traversedStrictTree :: Traversal' ByteString Word8
    traversedStrictTree Word8 -> f Word8
    afb ByteString
    bs = Int -> (Ptr Word8 -> IO ()) -> ByteString
    unsafeCreate Int
    len ((Ptr Word8 -> IO ()) -> ByteString)
    -> f (Ptr Word8 -> IO ()) -> f ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> Int -> f (Ptr Word8 -> IO ())
    forall {b}. Int -> Int -> f (Ptr b -> IO ())
    go Int
    0 Int
    len
     where
       len :: Int
    len = ByteString -> Int
    B.length ByteString
    bs
       go :: Int -> Int -> f (Ptr b -> IO ())
    go !Int
    i !Int
    j
         | Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    grain Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    j, Int
    k <- Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int -> Int -> Int
    forall a. Bits a => a -> Int -> a
    shiftR (Int
    j Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    i) Int
    1 = (\Ptr b -> IO ()
    l Ptr b -> IO ()
    r Ptr b
    q -> Ptr b -> IO ()
    l Ptr b
    q IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Ptr b -> IO ()
    r Ptr b
    q) ((Ptr b -> IO ()) -> (Ptr b -> IO ()) -> Ptr b -> IO ())
    -> f (Ptr b -> IO ()) -> f ((Ptr b -> IO ()) -> Ptr b -> IO ())
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> Int -> f (Ptr b -> IO ())
    go Int
    i Int
    k f ((Ptr b -> IO ()) -> Ptr b -> IO ())
    -> f (Ptr b -> IO ()) -> f (Ptr b -> IO ())
    forall a b. f (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Int -> Int -> f (Ptr b -> IO ())
    go Int
    k Int
    j
         | Bool
    otherwise = Int -> Int -> f (Ptr b -> IO ())
    forall {b}. Int -> Int -> f (Ptr b -> IO ())
    run Int
    i Int
    j
       run :: Int -> Int -> f (Ptr b -> IO ())
    run !Int
    i !Int
    j
         | Int
    i Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    j    = (Ptr b -> IO ()) -> f (Ptr b -> IO ())
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (\Ptr b
    _ -> () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())
         | Bool
    otherwise = let !x :: Word8
    x = ByteString -> Int -> Word8
    BU.unsafeIndex ByteString
    bs Int
    i
                       in (\Word8
    y Ptr b -> IO ()
    ys Ptr b
    q -> Ptr b -> Int -> Word8 -> IO ()
    forall b. Ptr b -> Int -> Word8 -> IO ()
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
    pokeByteOff Ptr b
    q Int
    i Word8
    y IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Ptr b -> IO ()
    ys Ptr b
    q) (Word8 -> (Ptr b -> IO ()) -> Ptr b -> IO ())
    -> f Word8 -> f ((Ptr b -> IO ()) -> Ptr b -> IO ())
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Word8 -> f Word8
    afb Word8
    x f ((Ptr b -> IO ()) -> Ptr b -> IO ())
    -> f (Ptr b -> IO ()) -> f (Ptr b -> IO ())
    forall a b. f (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Int -> Int -> f (Ptr b -> IO ())
    run (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) Int
    j
    {-# INLINE [0] traversedStrictTree #-}

    {-# RULES
    "bytes -> map"
      traversedStrictTree = sets B.map :: ASetter' B.ByteString Word8;
    "bytes -> foldr"
      traversedStrictTree = foldring B.foldr :: Getting (Endo r) B.ByteString Word8;
      #-}

    traversedStrictTree8 :: Traversal' B.ByteString Char
    traversedStrictTree8 :: Traversal' ByteString Char
    traversedStrictTree8 Char -> f Char
    pafb ByteString
    bs = Int -> (Ptr Word8 -> IO ()) -> ByteString
    unsafeCreate Int
    len ((Ptr Word8 -> IO ()) -> ByteString)
    -> f (Ptr Word8 -> IO ()) -> f ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> Int -> f (Ptr Word8 -> IO ())
    forall {b}. Int -> Int -> f (Ptr b -> IO ())
    go Int
    0 Int
    len
     where
       len :: Int
    len = ByteString -> Int
    B.length ByteString
    bs
       go :: Int -> Int -> f (Ptr b -> IO ())
    go !Int
    i !Int
    j
         | Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    grain Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    j    = let k :: Int
    k = Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int -> Int -> Int
    forall a. Bits a => a -> Int -> a
    shiftR (Int
    j Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    i) Int
    1
                              in (\Ptr b -> IO ()
    l Ptr b -> IO ()
    r Ptr b
    q -> Ptr b -> IO ()
    l Ptr b
    q IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Ptr b -> IO ()
    r Ptr b
    q) ((Ptr b -> IO ()) -> (Ptr b -> IO ()) -> Ptr b -> IO ())
    -> f (Ptr b -> IO ()) -> f ((Ptr b -> IO ()) -> Ptr b -> IO ())
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> Int -> f (Ptr b -> IO ())
    go Int
    i Int
    k f ((Ptr b -> IO ()) -> Ptr b -> IO ())
    -> f (Ptr b -> IO ()) -> f (Ptr b -> IO ())
    forall a b. f (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Int -> Int -> f (Ptr b -> IO ())
    go Int
    k Int
    j
         | Bool
    otherwise        = Int -> Int -> f (Ptr b -> IO ())
    forall {b}. Int -> Int -> f (Ptr b -> IO ())
    run Int
    i Int
    j
       run :: Int -> Int -> f (Ptr b -> IO ())
    run !Int
    i !Int
    j
         | Int
    i Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    j           = (Ptr b -> IO ()) -> f (Ptr b -> IO ())
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (\Ptr b
    _ -> () -> IO ()
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())
         | Bool
    otherwise        = let !x :: Word8
    x = ByteString -> Int -> Word8
    BU.unsafeIndex ByteString
    bs Int
    i
                              in (\Char
    y Ptr b -> IO ()
    ys Ptr b
    q -> Ptr b -> Int -> Word8 -> IO ()
    forall b. Ptr b -> Int -> Word8 -> IO ()
    forall a b. Storable a => Ptr b -> Int -> a -> IO ()
    pokeByteOff Ptr b
    q Int
    i (Char -> Word8
    c2w Char
    y) IO () -> IO () -> IO ()
    forall a b. IO a -> IO b -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Ptr b -> IO ()
    ys Ptr b
    q)
                             (Char -> (Ptr b -> IO ()) -> Ptr b -> IO ())
    -> f Char -> f ((Ptr b -> IO ()) -> Ptr b -> IO ())
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Char -> f Char
    pafb (Word8 -> Char
    w2c Word8
    x)
                             f ((Ptr b -> IO ()) -> Ptr b -> IO ())
    -> f (Ptr b -> IO ()) -> f (Ptr b -> IO ())
    forall a b. f (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Int -> Int -> f (Ptr b -> IO ())
    run (Int
    i Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    1) Int
    j
    {-# INLINE [0] traversedStrictTree8 #-}

    {-# RULES
    "chars -> map"
      traversedStrictTree8 = sets B8.map :: ASetter' B.ByteString Char;
    "chars -> foldr"
      traversedStrictTree8 = foldring B8.foldr :: Getting (Endo r) B.ByteString Char;
      #-}

    traversedLazy :: Traversal' BL.ByteString Word8
    traversedLazy :: Traversal' ByteString Word8
    traversedLazy Word8 -> f Word8
    pafb = \ByteString
    lbs -> (ByteString -> (Int64 -> f ByteString) -> Int64 -> f ByteString)
    -> (Int64 -> f ByteString) -> ByteString -> Int64 -> f ByteString
    forall r. (ByteString -> r -> r) -> r -> ByteString -> r
    foldrChunks ByteString -> (Int64 -> f ByteString) -> Int64 -> f ByteString
    go (\Int64
    _ -> ByteString -> f ByteString
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ByteString
    BL.empty) ByteString
    lbs Int64
    0
      where
      go :: ByteString -> (Int64 -> f ByteString) -> Int64 -> f ByteString
    go ByteString
    c Int64 -> f ByteString
    fcs Int64
    acc = ByteString -> ByteString -> ByteString
    BL.append (ByteString -> ByteString -> ByteString)
    -> (ByteString -> ByteString)
    -> ByteString
    -> ByteString
    -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> ByteString
    fromStrict
                 (ByteString -> ByteString -> ByteString)
    -> f ByteString -> f (ByteString -> ByteString)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Word8 -> f Word8) -> ByteString -> f ByteString
    Traversal' ByteString Word8
    traversedStrictTree Word8 -> f Word8
    pafb ByteString
    c
                 f (ByteString -> ByteString) -> f ByteString -> f ByteString
    forall a b. f (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Int64 -> f ByteString
    fcs Int64
    acc'
        where
        acc' :: Int64
        !acc' :: Int64
    acc' = Int64
    acc Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    + Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (ByteString -> Int
    B.length ByteString
    c)
    {-# INLINE [1] traversedLazy #-}

    {-# RULES
    "sets lazy bytestring"
      traversedLazy = sets BL.map :: ASetter' BL.ByteString Word8;
    "gets lazy bytestring"
      traversedLazy = foldring BL.foldr :: Getting (Endo r) BL.ByteString Word8;
      #-}

    traversedLazy8 :: Traversal' BL.ByteString Char
    traversedLazy8 :: Traversal' ByteString Char
    traversedLazy8 Char -> f Char
    pafb = \ByteString
    lbs -> (ByteString -> (Int64 -> f ByteString) -> Int64 -> f ByteString)
    -> (Int64 -> f ByteString) -> ByteString -> Int64 -> f ByteString
    forall r. (ByteString -> r -> r) -> r -> ByteString -> r
    foldrChunks ByteString -> (Int64 -> f ByteString) -> Int64 -> f ByteString
    go (\Int64
    _ -> ByteString -> f ByteString
    forall a. a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ByteString
    BL.empty) ByteString
    lbs Int64
    0
      where
      go :: ByteString -> (Int64 -> f ByteString) -> Int64 -> f ByteString
    go ByteString
    c Int64 -> f ByteString
    fcs Int64
    acc = ByteString -> ByteString -> ByteString
    BL.append (ByteString -> ByteString -> ByteString)
    -> (ByteString -> ByteString)
    -> ByteString
    -> ByteString
    -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> ByteString
    fromStrict
                 (ByteString -> ByteString -> ByteString)
    -> f ByteString -> f (ByteString -> ByteString)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Char -> f Char) -> ByteString -> f ByteString
    Traversal' ByteString Char
    traversedStrictTree8 Char -> f Char
    pafb ByteString
    c
                 f (ByteString -> ByteString) -> f ByteString -> f ByteString
    forall a b. f (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Int64 -> f ByteString
    fcs Int64
    acc'
        where
        acc' :: Int64
        !acc' :: Int64
    acc' = Int64
    acc Int64 -> Int64 -> Int64
    forall a. Num a => a -> a -> a
    + Int -> Int64
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (ByteString -> Int
    B.length ByteString
    c)
    {-# INLINE [1] traversedLazy8 #-}

    {-# RULES
    "sets lazy bytestring"
      traversedLazy8 = sets BL8.map :: ASetter' BL8.ByteString Char;
    "gets lazy bytestring"
      traversedLazy8 = foldring BL8.foldr :: Getting (Endo r) BL8.ByteString Char;
      #-}

    -- A way of creating ByteStrings outside the IO monad. The @Int@
    -- argument gives the final size of the ByteString. Unlike
    -- 'createAndTrim' the ByteString is not reallocated if the final size
    -- is less than the estimated size.
    unsafeCreate :: Int -> (Ptr Word8 -> IO ()) -> B.ByteString
    unsafeCreate :: Int -> (Ptr Word8 -> IO ()) -> ByteString
    unsafeCreate Int
    l Ptr Word8 -> IO ()
    f = IO ByteString -> ByteString
    forall a. IO a -> a
    unsafeDupablePerformIO (Int -> (Ptr Word8 -> IO ()) -> IO ByteString
    create Int
    l Ptr Word8 -> IO ()
    f)
    {-# INLINE unsafeCreate #-}

    -- Create ByteString of size @l@ and use action @f@ to fill its contents.
    create :: Int -> (Ptr Word8 -> IO ()) -> IO B.ByteString
    create :: Int -> (Ptr Word8 -> IO ()) -> IO ByteString
    create Int
    l Ptr Word8 -> IO ()
    f = do
        fp <- Int -> IO (ForeignPtr Word8)
    forall a. Int -> IO (ForeignPtr a)
    mallocPlainForeignPtrBytes Int
    l
        withForeignPtr fp $ \Ptr Word8
    p -> Ptr Word8 -> IO ()
    f Ptr Word8
    p
        return $! BI.PS fp 0 l
    {-# INLINE create #-}

    foldrChunks :: (B.ByteString -> r -> r) -> r -> BL.ByteString -> r
    #if MIN_VERSION_bytestring(0,10,0)
    foldrChunks :: forall r. (ByteString -> r -> r) -> r -> ByteString -> r
    foldrChunks = (ByteString -> r -> r) -> r -> ByteString -> r
    forall r. (ByteString -> r -> r) -> r -> ByteString -> r
    BL.foldrChunks
    #else
    foldrChunks f z b = foldr f z (BL.toChunks b)
    #endif
    {-# INLINE foldrChunks #-}

    w2c :: Word8 -> Char
    w2c :: Word8 -> Char
    w2c = Int -> Char
    unsafeChr (Int -> Char) -> (Word8 -> Int) -> Word8 -> Char
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Word8 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral
    {-# INLINE w2c #-}

    c2w :: Char -> Word8
    c2w :: Char -> Word8
    c2w = Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Word8) -> (Char -> Int) -> Char -> Word8
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Char -> Int
    ord
    {-# INLINE c2w #-}