    -- |
    -- Module      : Basement.String
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : portable
    --
    -- A String type backed by a UTF8 encoded byte array and all the necessary
    -- functions to manipulate the string.
    --
    -- You can think of String as a specialization of a byte array that
    -- have element of type Char.
    --
    -- The String data must contain UTF8 valid data.
    --
    {-# LANGUAGE BangPatterns               #-}
    {-# LANGUAGE MagicHash                  #-}
    {-# LANGUAGE NoImplicitPrelude          #-}
    {-# LANGUAGE TypeFamilies               #-}
    {-# LANGUAGE UnboxedTuples              #-}
    {-# LANGUAGE FlexibleContexts           #-}
    {-# LANGUAGE CPP                        #-}
    module Basement.String
        ( String(..)
        , MutableString(..)
        , create
        , replicate
        , length
        -- * Binary conversion
        , Encoding(..)
        , fromBytes
        , fromChunkBytes
        , fromBytesUnsafe
        , fromBytesLenient
        , toBytes
        , mutableValidate
        , copy
        , ValidationFailure(..)
        , index
        , null
        , drop
        , take
        , splitAt
        , revDrop
        , revTake
        , revSplitAt
        , splitOn
        , sub
        , elem
        , indices
        , intersperse
        , span
        , spanEnd
        , break
        , breakEnd
        , breakElem
        , breakLine
        , dropWhile
        , singleton
        , charMap
        , snoc
        , cons
        , unsnoc
        , uncons
        , find
        , findIndex
        , sortBy
        , filter
        , reverse
        , replace
        , builderAppend
        , builderBuild
        , builderBuild_
        , readInteger
        , readIntegral
        , readNatural
        , readDouble
        , readRational
        , readFloatingExact
        , upper
        , lower
        , caseFold
        , isPrefixOf
        , isSuffixOf
        , isInfixOf
        , stripPrefix
        , stripSuffix
        , all
        , any
        -- * Legacy utility
        , lines
        , words
        , toBase64
        , toBase64URL
        , toBase64OpenBSD
        ) where

    import           Basement.UArray           (UArray)
    import qualified Basement.UArray           as Vec
    import qualified Basement.UArray           as C
    import qualified Basement.UArray.Mutable   as MVec
    import           Basement.Block.Mutable (Block(..), MutableBlock(..))
    import qualified Basement.Block.Mutable    as MBLK
    import           Basement.Compat.Bifunctor
    import           Basement.Compat.Base
    import           Basement.Compat.Natural
    import           Basement.Compat.MonadTrans
    import           Basement.Compat.Primitive
    import           Basement.Types.OffsetSize
    import           Basement.Numerical.Additive
    import           Basement.Numerical.Subtractive
    import           Basement.Numerical.Multiplicative
    import           Basement.Numerical.Number
    import           Basement.Cast
    import           Basement.Monad
    import           Basement.PrimType
    import           Basement.FinalPtr
    import           Basement.IntegralConv
    import           Basement.Floating
    import           Basement.MutableBuilder
    import           Basement.String.CaseMapping (upperMapping, lowerMapping, foldMapping)
    import           Basement.UTF8.Table
    import           Basement.UTF8.Helper
    import           Basement.UTF8.Base
    import           Basement.UTF8.Types
    import           Basement.UArray.Base as C (onBackendPrim, onBackend, onBackendPure, offset, ValidRange(..), offsetsValidRange, MUArray(..), MUArrayBackend(..))
    import           Basement.Alg.Class (Indexable)
    import qualified Basement.Alg.UTF8 as UTF8
    import qualified Basement.Alg.String as Alg
    import           Basement.Types.Char7 (Char7(..), c7Upper, c7Lower)
    import qualified Basement.Types.Char7 as Char7
    import           GHC.Prim
    import           GHC.ST
    import           GHC.Types
    import           GHC.Word
    #if MIN_VERSION_base(4,9,0)
    import           GHC.Char
    #endif

     -- temporary
    import qualified Data.List
    import           Data.Ratio
    import           Data.Char (toUpper, toLower)
    import qualified Prelude

    import qualified Basement.String.Encoding.Encoding   as Encoder
    import qualified Basement.String.Encoding.ASCII7     as Encoder
    import qualified Basement.String.Encoding.UTF16      as Encoder
    import qualified Basement.String.Encoding.UTF32      as Encoder
    import qualified Basement.String.Encoding.ISO_8859_1 as Encoder

    -- | UTF8 Encoder
    data EncoderUTF8 = EncoderUTF8

    instance Encoder.Encoding EncoderUTF8 where
        type Unit EncoderUTF8 = Word8
        type Error EncoderUTF8 = ValidationFailure
        encodingNext :: EncoderUTF8
    -> (Offset (Unit EncoderUTF8) -> Unit EncoderUTF8)
    -> Offset (Unit EncoderUTF8)
    -> Either (Error EncoderUTF8) (Char, Offset (Unit EncoderUTF8))
    encodingNext  EncoderUTF8
    _ = \Offset (Unit EncoderUTF8) -> Unit EncoderUTF8
    ofs -> (Char, Offset Word8)
    -> Either ValidationFailure (Char, Offset Word8)
    forall a b. b -> Either a b
    Right ((Char, Offset Word8)
     -> Either ValidationFailure (Char, Offset Word8))
    -> (Offset Word8 -> (Char, Offset Word8))
    -> Offset Word8
    -> Either ValidationFailure (Char, Offset Word8)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (Offset Word8 -> Word8) -> Offset Word8 -> (Char, Offset Word8)
    nextWithIndexer Offset Word8 -> Word8
    Offset (Unit EncoderUTF8) -> Unit EncoderUTF8
    ofs
        encodingWrite :: forall (st :: * -> *) err.
    (PrimMonad st, Monad st) =>
    EncoderUTF8
    -> Char
    -> Builder
         (UArray (Unit EncoderUTF8))
         (MUArray (Unit EncoderUTF8))
         (Unit EncoderUTF8)
         st
         err
         ()
    encodingWrite EncoderUTF8
    _ = Char -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    Char
    -> Builder
         (UArray (Unit EncoderUTF8))
         (MUArray (Unit EncoderUTF8))
         (Unit EncoderUTF8)
         st
         err
         ()
    forall (st :: * -> *) err.
    (PrimMonad st, Monad st) =>
    Char -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    writeWithBuilder

    -- | Validate a bytearray for UTF8'ness
    --
    -- On success Nothing is returned
    -- On Failure the position along with the failure reason
    validate :: UArray Word8
             -> Offset8
             -> CountOf Word8
             -> (Offset8, Maybe ValidationFailure)
    validate :: UArray Word8
    -> Offset Word8
    -> CountOf Word8
    -> (Offset Word8, Maybe ValidationFailure)
    validate UArray Word8
    array Offset Word8
    ofsStart CountOf Word8
    sz = (Block Word8
     -> Offset Word8 -> (Offset Word8, Maybe ValidationFailure))
    -> (Ptr Word8
        -> Offset Word8 -> ST Any (Offset Word8, Maybe ValidationFailure))
    -> UArray Word8
    -> (Offset Word8, Maybe ValidationFailure)
    forall ty a s.
    (Block ty -> Offset ty -> a)
    -> (Ptr ty -> Offset ty -> ST s a) -> UArray ty -> a
    C.unsafeDewrap Block Word8
    -> Offset Word8 -> (Offset Word8, Maybe ValidationFailure)
    goBa Ptr Word8
    -> Offset Word8 -> ST Any (Offset Word8, Maybe ValidationFailure)
    goAddr UArray Word8
    array
      where
        unTranslateOffset :: Offset a -> p (Offset a) c -> p (Offset a) c
    unTranslateOffset Offset a
    start = (Offset a -> Offset a) -> p (Offset a) c -> p (Offset a) c
    forall a b c. (a -> b) -> p a c -> p b c
    forall (p :: * -> * -> *) a b c.
    Bifunctor p =>
    (a -> b) -> p a c -> p b c
    first (\Offset a
    e -> Offset a
    e Offset a -> Offset a -> Offset a
    forall a. Offset a -> Offset a -> Offset a
    `offsetSub` Offset a
    start)
        goBa :: Block Word8
    -> Offset Word8 -> (Offset Word8, Maybe ValidationFailure)
    goBa Block Word8
    ba Offset Word8
    start =
            Offset Word8
    -> (Offset Word8, Maybe ValidationFailure)
    -> (Offset Word8, Maybe ValidationFailure)
    forall {p :: * -> * -> *} {a} {c}.
    Bifunctor p =>
    Offset a -> p (Offset a) c -> p (Offset a) c
    unTranslateOffset Offset Word8
    start ((Offset Word8, Maybe ValidationFailure)
     -> (Offset Word8, Maybe ValidationFailure))
    -> (Offset Word8, Maybe ValidationFailure)
    -> (Offset Word8, Maybe ValidationFailure)
    forall a b. (a -> b) -> a -> b
    $ Offset Word8
    -> Block Word8
    -> Offset Word8
    -> (Offset Word8, Maybe ValidationFailure)
    forall container.
    Indexable container Word8 =>
    Offset Word8
    -> container
    -> Offset Word8
    -> (Offset Word8, Maybe ValidationFailure)
    Alg.validate (Offset Word8
    startOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    end) Block Word8
    ba (Offset Word8
    start Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    ofsStart)
        goAddr :: Ptr Word8
    -> Offset Word8 -> ST Any (Offset Word8, Maybe ValidationFailure)
    goAddr ptr :: Ptr Word8
    ptr@(Ptr !Addr#
    _) Offset Word8
    start =
            (Offset Word8, Maybe ValidationFailure)
    -> ST Any (Offset Word8, Maybe ValidationFailure)
    forall a. a -> ST Any a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ((Offset Word8, Maybe ValidationFailure)
     -> ST Any (Offset Word8, Maybe ValidationFailure))
    -> (Offset Word8, Maybe ValidationFailure)
    -> ST Any (Offset Word8, Maybe ValidationFailure)
    forall a b. (a -> b) -> a -> b
    $ Offset Word8
    -> (Offset Word8, Maybe ValidationFailure)
    -> (Offset Word8, Maybe ValidationFailure)
    forall {p :: * -> * -> *} {a} {c}.
    Bifunctor p =>
    Offset a -> p (Offset a) c -> p (Offset a) c
    unTranslateOffset Offset Word8
    start ((Offset Word8, Maybe ValidationFailure)
     -> (Offset Word8, Maybe ValidationFailure))
    -> (Offset Word8, Maybe ValidationFailure)
    -> (Offset Word8, Maybe ValidationFailure)
    forall a b. (a -> b) -> a -> b
    $ Offset Word8
    -> Ptr Word8
    -> Offset Word8
    -> (Offset Word8, Maybe ValidationFailure)
    forall container.
    Indexable container Word8 =>
    Offset Word8
    -> container
    -> Offset Word8
    -> (Offset Word8, Maybe ValidationFailure)
    Alg.validate (Offset Word8
    startOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    end) Ptr Word8
    ptr (Offset Word8
    ofsStart Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    start)
        end :: Offset Word8
    end = Offset Word8
    ofsStart Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz

    -- | Similar to 'validate' but works on a 'MutableByteArray'
    mutableValidate :: PrimMonad prim
                    => MVec.MUArray Word8 (PrimState prim)
                    -> Offset Word8
                    -> CountOf Word8
                    -> prim (Offset Word8, Maybe ValidationFailure)
    mutableValidate :: forall (prim :: * -> *).
    PrimMonad prim =>
    MUArray Word8 (PrimState prim)
    -> Offset Word8
    -> CountOf Word8
    -> prim (Offset Word8, Maybe ValidationFailure)
    mutableValidate MUArray Word8 (PrimState prim)
    mba Offset Word8
    ofsStart CountOf Word8
    sz = do
        Offset Word8 -> prim (Offset Word8, Maybe ValidationFailure)
    loop Offset Word8
    ofsStart
      where
        end :: Offset Word8
    end = Offset Word8
    ofsStart Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz

        loop :: Offset Word8 -> prim (Offset Word8, Maybe ValidationFailure)
    loop Offset Word8
    ofs
            | Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    end  = [Char] -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "mutableValidate: internal error: went pass offset"
            | Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end = (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    end, Maybe ValidationFailure
    forall a. Maybe a
    Nothing)
            | Bool
    otherwise  = do
                (Offset Word8, Maybe ValidationFailure)
    r <- Offset Word8 -> prim (Offset Word8, Maybe ValidationFailure)
    one Offset Word8
    ofs
                case (Offset Word8, Maybe ValidationFailure)
    r of
                    (Offset Word8
    nextOfs, Maybe ValidationFailure
    Nothing)  -> Offset Word8 -> prim (Offset Word8, Maybe ValidationFailure)
    loop Offset Word8
    nextOfs
                    (Offset Word8
    pos, Just ValidationFailure
    failure) -> (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    pos, ValidationFailure -> Maybe ValidationFailure
    forall a. a -> Maybe a
    Just ValidationFailure
    failure)

        one :: Offset Word8 -> prim (Offset Word8, Maybe ValidationFailure)
    one Offset Word8
    pos = do
            StepASCII
    h <- Word8 -> StepASCII
    StepASCII (Word8 -> StepASCII) -> prim Word8 -> prim StepASCII
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> MUArray Word8 (PrimState prim) -> Offset Word8 -> prim Word8
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> prim ty
    Vec.unsafeRead MUArray Word8 (PrimState prim)
    mba Offset Word8
    pos
            let nbConts :: Int
    nbConts = StepASCII -> Int
    getNbBytes StepASCII
    h
            if Int
    nbConts Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0xff
                then (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    pos, ValidationFailure -> Maybe ValidationFailure
    forall a. a -> Maybe a
    Just ValidationFailure
    InvalidHeader)
                else if Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1 Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    nbConts Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    end
                    then (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    pos, ValidationFailure -> Maybe ValidationFailure
    forall a. a -> Maybe a
    Just ValidationFailure
    MissingByte)
                    else do
                        case Int
    nbConts of
                            Int
    0 -> (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1, Maybe ValidationFailure
    forall a. Maybe a
    Nothing)
                            Int
    1 -> do
                                Word8
    c1 <- MUArray Word8 (PrimState prim) -> Offset Word8 -> prim Word8
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> prim ty
    Vec.unsafeRead MUArray Word8 (PrimState prim)
    mba (Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1)
                                if Word8 -> Bool
    isContinuation Word8
    c1
                                    then (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    2, Maybe ValidationFailure
    forall a. Maybe a
    Nothing)
                                    else (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    pos, ValidationFailure -> Maybe ValidationFailure
    forall a. a -> Maybe a
    Just ValidationFailure
    InvalidContinuation)
                            Int
    2 -> do
                                Word8
    c1 <- MUArray Word8 (PrimState prim) -> Offset Word8 -> prim Word8
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> prim ty
    Vec.unsafeRead MUArray Word8 (PrimState prim)
    mba (Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1)
                                Word8
    c2 <- MUArray Word8 (PrimState prim) -> Offset Word8 -> prim Word8
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> prim ty
    Vec.unsafeRead MUArray Word8 (PrimState prim)
    mba (Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    2)
                                if Word8 -> Bool
    isContinuation Word8
    c1 Bool -> Bool -> Bool
    && Word8 -> Bool
    isContinuation Word8
    c2
                                    then (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    3, Maybe ValidationFailure
    forall a. Maybe a
    Nothing)
                                    else (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    pos, ValidationFailure -> Maybe ValidationFailure
    forall a. a -> Maybe a
    Just ValidationFailure
    InvalidContinuation)
                            Int
    3 -> do
                                Word8
    c1 <- MUArray Word8 (PrimState prim) -> Offset Word8 -> prim Word8
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> prim ty
    Vec.unsafeRead MUArray Word8 (PrimState prim)
    mba (Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1)
                                Word8
    c2 <- MUArray Word8 (PrimState prim) -> Offset Word8 -> prim Word8
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> prim ty
    Vec.unsafeRead MUArray Word8 (PrimState prim)
    mba (Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    2)
                                Word8
    c3 <- MUArray Word8 (PrimState prim) -> Offset Word8 -> prim Word8
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> prim ty
    Vec.unsafeRead MUArray Word8 (PrimState prim)
    mba (Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    3)
                                if Word8 -> Bool
    isContinuation Word8
    c1 Bool -> Bool -> Bool
    && Word8 -> Bool
    isContinuation Word8
    c2 Bool -> Bool -> Bool
    && Word8 -> Bool
    isContinuation Word8
    c3
                                    then (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    pos Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    4, Maybe ValidationFailure
    forall a. Maybe a
    Nothing)
                                    else (Offset Word8, Maybe ValidationFailure)
    -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    pos, ValidationFailure -> Maybe ValidationFailure
    forall a. a -> Maybe a
    Just ValidationFailure
    InvalidContinuation)
                            Int
    _ -> [Char] -> prim (Offset Word8, Maybe ValidationFailure)
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "internal error"

    nextWithIndexer :: (Offset Word8 -> Word8)
                    -> Offset Word8
                    -> (Char, Offset Word8)
    nextWithIndexer :: (Offset Word8 -> Word8) -> Offset Word8 -> (Char, Offset Word8)
    nextWithIndexer Offset Word8 -> Word8
    getter Offset Word8
    off =
        case Word8# -> Int#
    getNbBytes# Word8#
    b# of
            Int#
    0# -> (Word# -> Char
    toChar Word#
    h, Offset Word8
    off Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1)
            Int#
    1# -> (Word# -> Char
    toChar (Word8 -> Word#
    decode2 (Offset Word8 -> Word8
    getter (Offset Word8 -> Word8) -> Offset Word8 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Offset Word8
    off Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1)), Offset Word8
    off Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    2)
            Int#
    2# -> (Word# -> Char
    toChar (Word8 -> Word8 -> Word#
    decode3 (Offset Word8 -> Word8
    getter (Offset Word8 -> Word8) -> Offset Word8 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Offset Word8
    off Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1) (Offset Word8 -> Word8
    getter (Offset Word8 -> Word8) -> Offset Word8 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Offset Word8
    off Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    2)), Offset Word8
    off Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    3)
            Int#
    3# -> (Word# -> Char
    toChar (Word8 -> Word8 -> Word8 -> Word#
    decode4 (Offset Word8 -> Word8
    getter (Offset Word8 -> Word8) -> Offset Word8 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Offset Word8
    off Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1) (Offset Word8 -> Word8
    getter (Offset Word8 -> Word8) -> Offset Word8 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Offset Word8
    off Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    2) (Offset Word8 -> Word8
    getter (Offset Word8 -> Word8) -> Offset Word8 -> Word8
    forall a b. (a -> b) -> a -> b
    $ Offset Word8
    off Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    3))
                  , Offset Word8
    off Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    4)
            Int#
    r -> [Char] -> (Char, Offset Word8)
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "next: internal error: invalid input: " [Char] -> [Char] -> [Char]
    forall a. Semigroup a => a -> a -> a
    <> Int -> [Char]
    forall a. Show a => a -> [Char]
    show (Int# -> Int
    I# Int#
    r) [Char] -> [Char] -> [Char]
    forall a. Semigroup a => a -> a -> a
    <> [Char]
    " " [Char] -> [Char] -> [Char]
    forall a. Semigroup a => a -> a -> a
    <> Word -> [Char]
    forall a. Show a => a -> [Char]
    show (Word# -> Word
    W# Word#
    h))
      where
        b :: Word8
    b@(W8# Word8#
    b#) = Offset Word8 -> Word8
    getter Offset Word8
    off
        !(W# Word#
    h) = Word8 -> Word
    forall a b. IntegralUpsize a b => a -> b
    integralUpsize Word8
    b

        toChar :: Word# -> Char
        toChar :: Word# -> Char
    toChar Word#
    w = Char# -> Char
    C# (Int# -> Char#
    chr# (Word# -> Int#
    word2Int# Word#
    w))

        decode2 :: Word8 -> Word#
        decode2 :: Word8 -> Word#
    decode2 (W8# Word8#
    b1) =
            Word# -> Word# -> Word#
    or# (Word# -> Int# -> Word#
    uncheckedShiftL# (Word# -> Word# -> Word#
    and# Word#
    h Word#
    0x1f##) Int#
    6#)
                (Word# -> Word# -> Word#
    and# Word#
    c1 Word#
    0x3f##)
          where
            c1 :: Word#
    c1 = Word8# -> Word#
    word8ToWord# Word8#
    b1

        decode3 :: Word8 -> Word8 -> Word#
        decode3 :: Word8 -> Word8 -> Word#
    decode3 (W8# Word8#
    b1) (W8# Word8#
    b2) =
            Word# -> Word# -> Word#
    or# (Word# -> Int# -> Word#
    uncheckedShiftL# (Word# -> Word# -> Word#
    and# Word#
    h Word#
    0xf##) Int#
    12#)
                (Word# -> Word# -> Word#
    or# (Word# -> Int# -> Word#
    uncheckedShiftL# (Word# -> Word# -> Word#
    and# Word#
    c1 Word#
    0x3f##) Int#
    6#)
                     (Word# -> Word# -> Word#
    and# Word#
    c2 Word#
    0x3f##))
          where
            c1 :: Word#
    c1 = Word8# -> Word#
    word8ToWord# Word8#
    b1
            c2 :: Word#
    c2 = Word8# -> Word#
    word8ToWord# Word8#
    b2

        decode4 :: Word8 -> Word8 -> Word8 -> Word#
        decode4 :: Word8 -> Word8 -> Word8 -> Word#
    decode4 (W8# Word8#
    b1) (W8# Word8#
    b2) (W8# Word8#
    b3) =
            Word# -> Word# -> Word#
    or# (Word# -> Int# -> Word#
    uncheckedShiftL# (Word# -> Word# -> Word#
    and# Word#
    h Word#
    0x7##) Int#
    18#)
                (Word# -> Word# -> Word#
    or# (Word# -> Int# -> Word#
    uncheckedShiftL# (Word# -> Word# -> Word#
    and# Word#
    c1 Word#
    0x3f##) Int#
    12#)
                    (Word# -> Word# -> Word#
    or# (Word# -> Int# -> Word#
    uncheckedShiftL# (Word# -> Word# -> Word#
    and# Word#
    c2 Word#
    0x3f##) Int#
    6#)
                        (Word# -> Word# -> Word#
    and# Word#
    c3 Word#
    0x3f##))
                )
          where
            c1 :: Word#
    c1 = Word8# -> Word#
    word8ToWord# Word8#
    b1
            c2 :: Word#
    c2 = Word8# -> Word#
    word8ToWord# Word8#
    b2
            c3 :: Word#
    c3 = Word8# -> Word#
    word8ToWord# Word8#
    b3

    writeWithBuilder :: (PrimMonad st, Monad st)
                     => Char
                     -> Builder (UArray Word8) (MVec.MUArray Word8) Word8 st err ()
    writeWithBuilder :: forall (st :: * -> *) err.
    (PrimMonad st, Monad st) =>
    Char -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    writeWithBuilder Char
    c
        | Int# -> Bool
    bool# (Word# -> Word# -> Int#
    ltWord# Word#
    x Word#
    0x80##   ) = Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    encode1
        | Int# -> Bool
    bool# (Word# -> Word# -> Int#
    ltWord# Word#
    x Word#
    0x800##  ) = Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    encode2
        | Int# -> Bool
    bool# (Word# -> Word# -> Int#
    ltWord# Word#
    x Word#
    0x10000##) = Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    encode3
        | Bool
    otherwise = Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    encode4
      where
        !(I# Int#
    xi) = Char -> Int
    forall a. Enum a => a -> Int
    fromEnum Char
    c
        !x :: Word#
    x       = Int# -> Word#
    int2Word# Int#
    xi

        encode1 :: Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    encode1 = Word8 -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    Vec.builderAppend (Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    x))

        encode2 :: Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    encode2 = do
            let x1 :: Word#
    x1  = Word# -> Word# -> Word#
    or# (Word# -> Int# -> Word#
    uncheckedShiftRL# Word#
    x Int#
    6#) Word#
    0xc0##
                x2 :: Word#
    x2  = Word# -> Word#
    toContinuation Word#
    x
            Word8 -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    Vec.builderAppend (Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    x1)) Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall a b.
    Builder (UArray Word8) (MUArray Word8) Word8 st err a
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Word8 -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    Vec.builderAppend (Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    x2))

        encode3 :: Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    encode3 = do
            let x1 :: Word#
    x1  = Word# -> Word# -> Word#
    or# (Word# -> Int# -> Word#
    uncheckedShiftRL# Word#
    x Int#
    12#) Word#
    0xe0##
                x2 :: Word#
    x2  = Word# -> Word#
    toContinuation (Word# -> Int# -> Word#
    uncheckedShiftRL# Word#
    x Int#
    6#)
                x3 :: Word#
    x3  = Word# -> Word#
    toContinuation Word#
    x
            Word8 -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    Vec.builderAppend (Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    x1)) Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall a b.
    Builder (UArray Word8) (MUArray Word8) Word8 st err a
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Word8 -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    Vec.builderAppend (Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    x2)) Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall a b.
    Builder (UArray Word8) (MUArray Word8) Word8 st err a
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Word8 -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    Vec.builderAppend (Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    x3))

        encode4 :: Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    encode4 = do
            let x1 :: Word#
    x1  = Word# -> Word# -> Word#
    or# (Word# -> Int# -> Word#
    uncheckedShiftRL# Word#
    x Int#
    18#) Word#
    0xf0##
                x2 :: Word#
    x2  = Word# -> Word#
    toContinuation (Word# -> Int# -> Word#
    uncheckedShiftRL# Word#
    x Int#
    12#)
                x3 :: Word#
    x3  = Word# -> Word#
    toContinuation (Word# -> Int# -> Word#
    uncheckedShiftRL# Word#
    x Int#
    6#)
                x4 :: Word#
    x4  = Word# -> Word#
    toContinuation Word#
    x
            Word8 -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    Vec.builderAppend (Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    x1)) Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall a b.
    Builder (UArray Word8) (MUArray Word8) Word8 st err a
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Word8 -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    Vec.builderAppend (Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    x2)) Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall a b.
    Builder (UArray Word8) (MUArray Word8) Word8 st err a
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Word8 -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    Vec.builderAppend (Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    x3)) Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall a b.
    Builder (UArray Word8) (MUArray Word8) Word8 st err a
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    -> Builder (UArray Word8) (MUArray Word8) Word8 st err b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    >> Word8 -> Builder (UArray Word8) (MUArray Word8) Word8 st err ()
    forall ty (state :: * -> *) err.
    (PrimType ty, PrimMonad state) =>
    ty -> Builder (UArray ty) (MUArray ty) ty state err ()
    Vec.builderAppend (Word8# -> Word8
    W8# (Word# -> Word8#
    wordToWord8# Word#
    x4))

        toContinuation :: Word# -> Word#
        toContinuation :: Word# -> Word#
    toContinuation Word#
    w = Word# -> Word# -> Word#
    or# (Word# -> Word# -> Word#
    and# Word#
    w Word#
    0x3f##) Word#
    0x80##

    writeUTF8Char :: PrimMonad prim => MutableString (PrimState prim) -> Offset8 -> UTF8Char -> prim ()
    writeUTF8Char :: forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> UTF8Char -> prim ()
    writeUTF8Char (MutableString MUArray Word8 (PrimState prim)
    mba) Offset Word8
    i (UTF8_1 Word8
    x1) =
        MUArray Word8 (PrimState prim) -> Offset Word8 -> Word8 -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    Vec.unsafeWrite MUArray Word8 (PrimState prim)
    mba Offset Word8
    i     Word8
    x1
    writeUTF8Char (MutableString MUArray Word8 (PrimState prim)
    mba) Offset Word8
    i (UTF8_2 Word8
    x1 Word8
    x2) = do
        MUArray Word8 (PrimState prim) -> Offset Word8 -> Word8 -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    Vec.unsafeWrite MUArray Word8 (PrimState prim)
    mba Offset Word8
    i     Word8
    x1
        MUArray Word8 (PrimState prim) -> Offset Word8 -> Word8 -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    Vec.unsafeWrite MUArray Word8 (PrimState prim)
    mba (Offset Word8
    iOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    1) Word8
    x2
    writeUTF8Char (MutableString MUArray Word8 (PrimState prim)
    mba) Offset Word8
    i (UTF8_3 Word8
    x1 Word8
    x2 Word8
    x3) = do
        MUArray Word8 (PrimState prim) -> Offset Word8 -> Word8 -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    Vec.unsafeWrite MUArray Word8 (PrimState prim)
    mba Offset Word8
    i     Word8
    x1
        MUArray Word8 (PrimState prim) -> Offset Word8 -> Word8 -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    Vec.unsafeWrite MUArray Word8 (PrimState prim)
    mba (Offset Word8
    iOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    1) Word8
    x2
        MUArray Word8 (PrimState prim) -> Offset Word8 -> Word8 -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    Vec.unsafeWrite MUArray Word8 (PrimState prim)
    mba (Offset Word8
    iOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    2) Word8
    x3
    writeUTF8Char (MutableString MUArray Word8 (PrimState prim)
    mba) Offset Word8
    i (UTF8_4 Word8
    x1 Word8
    x2 Word8
    x3 Word8
    x4) = do
        MUArray Word8 (PrimState prim) -> Offset Word8 -> Word8 -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    Vec.unsafeWrite MUArray Word8 (PrimState prim)
    mba Offset Word8
    i     Word8
    x1
        MUArray Word8 (PrimState prim) -> Offset Word8 -> Word8 -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    Vec.unsafeWrite MUArray Word8 (PrimState prim)
    mba (Offset Word8
    iOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    1) Word8
    x2
        MUArray Word8 (PrimState prim) -> Offset Word8 -> Word8 -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    Vec.unsafeWrite MUArray Word8 (PrimState prim)
    mba (Offset Word8
    iOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    2) Word8
    x3
        MUArray Word8 (PrimState prim) -> Offset Word8 -> Word8 -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
    Vec.unsafeWrite MUArray Word8 (PrimState prim)
    mba (Offset Word8
    iOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    3) Word8
    x4
    {-# INLINE writeUTF8Char #-}

    unsafeFreezeShrink :: PrimMonad prim => MutableString (PrimState prim) -> CountOf Word8 -> prim String
    unsafeFreezeShrink :: forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> CountOf Word8 -> prim String
    unsafeFreezeShrink (MutableString MUArray Word8 (PrimState prim)
    mba) CountOf Word8
    s = UArray Word8 -> String
    String (UArray Word8 -> String) -> prim (UArray Word8) -> prim String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> MUArray Word8 (PrimState prim)
    -> CountOf Word8 -> prim (UArray Word8)
    forall ty (prim :: * -> *).
    (PrimType ty, PrimMonad prim) =>
    MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
    Vec.unsafeFreezeShrink MUArray Word8 (PrimState prim)
    mba CountOf Word8
    s
    {-# INLINE unsafeFreezeShrink #-}

    ------------------------------------------------------------------------
    -- real functions

    -- | Check if a String is null
    null :: String -> Bool
    null :: String -> Bool
    null (String UArray Word8
    ba) = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    ba CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf Word8
    0

    -- we don't know in constant time the count of character in string,
    -- however if we estimate bounds of what N characters would
    -- take in space (between N and N*4). If the count is thus bigger than
    -- the number of bytes, then we know for sure that it's going to
    -- be out of bounds
    countCharMoreThanBytes :: CountOf Char -> UArray Word8 -> Bool
    countCharMoreThanBytes :: CountOf Char -> UArray Word8 -> Bool
    countCharMoreThanBytes (CountOf Int
    chars) UArray Word8
    ba = Int
    chars Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    bytes
      where (CountOf Int
    bytes) = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    ba

    -- | Create a string composed of a number @n of Chars (Unicode code points).
    --
    -- if the input @s contains less characters than required, then the input string is returned.
    take :: CountOf Char -> String -> String
    take :: CountOf Char -> String -> String
    take CountOf Char
    n s :: String
    s@(String UArray Word8
    ba)
        | CountOf Char
    n CountOf Char -> CountOf Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= CountOf Char
    0                      = String
    forall a. Monoid a => a
    mempty
        | CountOf Char -> UArray Word8 -> Bool
    countCharMoreThanBytes CountOf Char
    n UArray Word8
    ba = String
    s
        | Bool
    otherwise                   = UArray Word8 -> String
    String (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ CountOf Word8 -> UArray Word8 -> UArray Word8
    forall ty. CountOf ty -> UArray ty -> UArray ty
    Vec.unsafeTake (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize (Offset Word8 -> CountOf Word8) -> Offset Word8 -> CountOf Word8
    forall a b. (a -> b) -> a -> b
    $ CountOf Char -> String -> Offset Word8
    indexN CountOf Char
    n String
    s) UArray Word8
    ba

    -- | Create a string with the remaining Chars after dropping @n Chars from the beginning
    drop :: CountOf Char -> String -> String
    drop :: CountOf Char -> String -> String
    drop CountOf Char
    n s :: String
    s@(String UArray Word8
    ba)
        | CountOf Char
    n CountOf Char -> CountOf Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= CountOf Char
    0                      = String
    s
        | CountOf Char -> UArray Word8 -> Bool
    countCharMoreThanBytes CountOf Char
    n UArray Word8
    ba = String
    forall a. Monoid a => a
    mempty
        | Bool
    otherwise                   = UArray Word8 -> String
    String (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ CountOf Word8 -> UArray Word8 -> UArray Word8
    forall ty. CountOf ty -> UArray ty -> UArray ty
    Vec.drop (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize (Offset Word8 -> CountOf Word8) -> Offset Word8 -> CountOf Word8
    forall a b. (a -> b) -> a -> b
    $ CountOf Char -> String -> Offset Word8
    indexN CountOf Char
    n String
    s) UArray Word8
    ba

    -- | Split a string at the Offset specified (in Char) returning both
    -- the leading part and the remaining part.
    splitAt :: CountOf Char -> String -> (String, String)
    splitAt :: CountOf Char -> String -> (String, String)
    splitAt CountOf Char
    n s :: String
    s@(String UArray Word8
    ba)
        | CountOf Char
    n CountOf Char -> CountOf Char -> Bool
    forall a. Ord a => a -> a -> Bool
    <= CountOf Char
    0                      = (String
    forall a. Monoid a => a
    mempty, String
    s)
        | CountOf Char -> UArray Word8 -> Bool
    countCharMoreThanBytes CountOf Char
    n UArray Word8
    ba = (String
    s, String
    forall a. Monoid a => a
    mempty)
        | Bool
    otherwise                   =
            let (UArray Word8
    v1,UArray Word8
    v2) = CountOf Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
    forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
    C.splitAt (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize (Offset Word8 -> CountOf Word8) -> Offset Word8 -> CountOf Word8
    forall a b. (a -> b) -> a -> b
    $ CountOf Char -> String -> Offset Word8
    indexN CountOf Char
    n String
    s) UArray Word8
    ba
             in (UArray Word8 -> String
    String UArray Word8
    v1, UArray Word8 -> String
    String UArray Word8
    v2)

    -- | Return the offset (in bytes) of the N'th sequence in an UTF8 String
    indexN :: CountOf Char -> String -> Offset Word8
    indexN :: CountOf Char -> String -> Offset Word8
    indexN !CountOf Char
    n (String UArray Word8
    ba) = (Block Word8 -> Offset Word8 -> Offset Word8)
    -> (Ptr Word8 -> Offset Word8 -> ST Any (Offset Word8))
    -> UArray Word8
    -> Offset Word8
    forall ty a s.
    (Block ty -> Offset ty -> a)
    -> (Ptr ty -> Offset ty -> ST s a) -> UArray ty -> a
    Vec.unsafeDewrap Block Word8 -> Offset Word8 -> Offset Word8
    goVec Ptr Word8 -> Offset Word8 -> ST Any (Offset Word8)
    forall s. Ptr Word8 -> Offset Word8 -> ST s (Offset Word8)
    goAddr UArray Word8
    ba
      where
        goVec :: Block Word8 -> Offset Word8 -> Offset Word8
        goVec :: Block Word8 -> Offset Word8 -> Offset Word8
    goVec (Block !ByteArray#
    ma) !Offset Word8
    start = Offset Word8 -> Offset Char -> Offset Word8
    loop Offset Word8
    start Offset Char
    0
          where
            !len :: Offset Word8
    len = Offset Word8
    start Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    Vec.length UArray Word8
    ba
            loop :: Offset Word8 -> Offset Char -> Offset Word8
            loop :: Offset Word8 -> Offset Char -> Offset Word8
    loop !Offset Word8
    idx !Offset Char
    i
                | Offset Word8
    idx Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Offset Word8
    len Bool -> Bool -> Bool
    || Offset Char
    i Offset Char -> CountOf Char -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf Char
    n = CountOf Word8 -> Offset Word8
    forall a. CountOf a -> Offset a
    sizeAsOffset (Offset Word8
    idx Offset Word8 -> Offset Word8 -> Difference (Offset Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - Offset Word8
    start)
                | Bool
    otherwise              = Offset Word8 -> Offset Char -> Offset Word8
    loop (Offset Word8
    idx Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    d) (Offset Char
    i Offset Char -> Offset Char -> Offset Char
    forall a. Additive a => a -> a -> a
    + Int -> Offset Char
    forall ty. Int -> Offset ty
    Offset Int
    1)
              where d :: CountOf Word8
    d = Word8 -> CountOf Word8
    skipNextHeaderValue (ByteArray# -> Offset Word8 -> Word8
    forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
    primBaIndex ByteArray#
    ma Offset Word8
    idx)
        {-# INLINE goVec #-}

        goAddr :: Ptr Word8 -> Offset Word8 -> ST s (Offset Word8)
        goAddr :: forall s. Ptr Word8 -> Offset Word8 -> ST s (Offset Word8)
    goAddr (Ptr Addr#
    ptr) !Offset Word8
    start = Offset Word8 -> ST s (Offset Word8)
    forall a. a -> ST s a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8 -> ST s (Offset Word8))
    -> Offset Word8 -> ST s (Offset Word8)
    forall a b. (a -> b) -> a -> b
    $ Offset Word8 -> Offset Char -> Offset Word8
    loop Offset Word8
    start (Int -> Offset Char
    forall ty. Int -> Offset ty
    Offset Int
    0)
          where
            !len :: Offset Word8
    len = Offset Word8
    start Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    Vec.length UArray Word8
    ba
            loop :: Offset Word8 -> Offset Char -> Offset Word8
            loop :: Offset Word8 -> Offset Char -> Offset Word8
    loop !Offset Word8
    idx !Offset Char
    i
                | Offset Word8
    idx Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Offset Word8
    len Bool -> Bool -> Bool
    || Offset Char
    i Offset Char -> CountOf Char -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf Char
    n = CountOf Word8 -> Offset Word8
    forall a. CountOf a -> Offset a
    sizeAsOffset (Offset Word8
    idx Offset Word8 -> Offset Word8 -> Difference (Offset Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - Offset Word8
    start)
                | Bool
    otherwise              = Offset Word8 -> Offset Char -> Offset Word8
    loop (Offset Word8
    idx Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    d) (Offset Char
    i Offset Char -> Offset Char -> Offset Char
    forall a. Additive a => a -> a -> a
    + Int -> Offset Char
    forall ty. Int -> Offset ty
    Offset Int
    1)
              where d :: CountOf Word8
    d = Word8 -> CountOf Word8
    skipNextHeaderValue (Addr# -> Offset Word8 -> Word8
    forall ty. PrimType ty => Addr# -> Offset ty -> ty
    primAddrIndex Addr#
    ptr Offset Word8
    idx)
        {-# INLINE goAddr #-}
    {-# INLINE indexN #-}

    -- inverse a CountOf that is specified from the end (e.g. take n Chars from the end)
    --
    -- rev{Take,Drop,SplitAt} TODO optimise:
    -- we can process the string from the end using a skipPrev instead of getting the length
    countFromStart :: String -> CountOf Char -> CountOf Char
    countFromStart :: String -> CountOf Char -> CountOf Char
    countFromStart String
    s sz :: CountOf Char
    sz@(CountOf Int
    sz')
        | CountOf Char
    sz CountOf Char -> CountOf Char -> Bool
    forall a. Ord a => a -> a -> Bool
    >= CountOf Char
    len = Int -> CountOf Char
    forall ty. Int -> CountOf ty
    CountOf Int
    0
        | Bool
    otherwise = Int -> CountOf Char
    forall ty. Int -> CountOf ty
    CountOf (Int
    len' Int -> Int -> Difference Int
    forall a. Subtractive a => a -> a -> Difference a
    - Int
    sz')
      where len :: CountOf Char
    len@(CountOf Int
    len') = String -> CountOf Char
    length String
    s

    -- | Similar to 'take' but from the end
    revTake :: CountOf Char -> String -> String
    revTake :: CountOf Char -> String -> String
    revTake CountOf Char
    n String
    v = CountOf Char -> String -> String
    drop (String -> CountOf Char -> CountOf Char
    countFromStart String
    v CountOf Char
    n) String
    v

    -- | Similar to 'drop' but from the end
    revDrop :: CountOf Char -> String -> String
    revDrop :: CountOf Char -> String -> String
    revDrop CountOf Char
    n String
    v = CountOf Char -> String -> String
    take (String -> CountOf Char -> CountOf Char
    countFromStart String
    v CountOf Char
    n) String
    v

    -- | Similar to 'splitAt' but from the end
    revSplitAt :: CountOf Char -> String -> (String, String)
    revSplitAt :: CountOf Char -> String -> (String, String)
    revSplitAt CountOf Char
    n String
    v = (CountOf Char -> String -> String
    drop CountOf Char
    idx String
    v, CountOf Char -> String -> String
    take CountOf Char
    idx String
    v) where idx :: CountOf Char
    idx = String -> CountOf Char -> CountOf Char
    countFromStart String
    v CountOf Char
    n

    -- | Split on the input string using the predicate as separator
    --
    -- e.g.
    --
    -- > splitOn (== ',') ","          == ["",""]
    -- > splitOn (== ',') ",abc,"      == ["","abc",""]
    -- > splitOn (== ':') "abc"        == ["abc"]
    -- > splitOn (== ':') "abc::def"   == ["abc","","def"]
    -- > splitOn (== ':') "::abc::def" == ["","","abc","","def"]
    --
    splitOn :: (Char -> Bool) -> String -> [String]
    splitOn :: (Char -> Bool) -> String -> [String]
    splitOn Char -> Bool
    predicate String
    s
        | CountOf Word8
    sz CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int -> CountOf Word8
    forall ty. Int -> CountOf ty
    CountOf Int
    0 = [String
    forall a. Monoid a => a
    mempty]
        | Bool
    otherwise    = Offset Word8 -> Offset Word8 -> [String]
    loop Offset Word8
    forall a. Additive a => a
    azero Offset Word8
    forall a. Additive a => a
    azero
      where
        !sz :: CountOf Word8
    sz = String -> CountOf Word8
    size String
    s
        end :: Offset Word8
    end = Offset Word8
    forall a. Additive a => a
    azero Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz
        loop :: Offset Word8 -> Offset Word8 -> [String]
    loop Offset Word8
    prevIdx Offset Word8
    idx
            | Offset Word8
    idx Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end = [String -> Offset Word8 -> Offset Word8 -> String
    sub String
    s Offset Word8
    prevIdx Offset Word8
    idx]
            | Bool
    otherwise =
                let !(Step Char
    c Offset Word8
    idx') = String -> Offset Word8 -> Step
    next String
    s Offset Word8
    idx
                 in if Char -> Bool
    predicate Char
    c
                        then String -> Offset Word8 -> Offset Word8 -> String
    sub String
    s Offset Word8
    prevIdx Offset Word8
    idx String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : Offset Word8 -> Offset Word8 -> [String]
    loop Offset Word8
    idx' Offset Word8
    idx'
                        else Offset Word8 -> Offset Word8 -> [String]
    loop Offset Word8
    prevIdx Offset Word8
    idx'

    -- | Internal call to make a substring given offset in bytes.
    --
    -- This is unsafe considering that one can create a substring
    -- starting and/or ending on the middle of a UTF8 sequence.
    sub :: String -> Offset8 -> Offset8 -> String
    sub :: String -> Offset Word8 -> Offset Word8 -> String
    sub (String UArray Word8
    ba) Offset Word8
    start Offset Word8
    end = UArray Word8 -> String
    String (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ UArray Word8 -> Offset Word8 -> Offset Word8 -> UArray Word8
    forall ty.
    PrimType ty =>
    UArray ty -> Offset ty -> Offset ty -> UArray ty
    Vec.sub UArray Word8
    ba Offset Word8
    start Offset Word8
    end

    -- | Internal call to split at a given index in offset of bytes.
    --
    -- This is unsafe considering that one can split in the middle of a
    -- UTF8 sequence, so use with care.
    splitIndex :: Offset8 -> String -> (String, String)
    splitIndex :: Offset Word8 -> String -> (String, String)
    splitIndex Offset Word8
    idx (String UArray Word8
    ba) = (UArray Word8 -> String
    String UArray Word8
    v1, UArray Word8 -> String
    String UArray Word8
    v2)
      where (UArray Word8
    v1,UArray Word8
    v2) = CountOf Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
    forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
    C.splitAt (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    idx) UArray Word8
    ba

    -- | Break a string into 2 strings at the location where the predicate return True
    break :: (Char -> Bool) -> String -> (String, String)
    break :: (Char -> Bool) -> String -> (String, String)
    break Char -> Bool
    predicate s :: String
    s@(String UArray Word8
    ba) = (forall s. ST s (String, String)) -> (String, String)
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (String, String)) -> (String, String))
    -> (forall s. ST s (String, String)) -> (String, String)
    forall a b. (a -> b) -> a -> b
    $ UArray Word8
    -> ((Offset Word8 -> Word8) -> ST s (String, String))
    -> ST s (String, String)
    forall (prim :: * -> *) ty a.
    (PrimMonad prim, PrimType ty) =>
    UArray ty -> ((Offset ty -> ty) -> prim a) -> prim a
    Vec.unsafeIndexer UArray Word8
    ba (Offset Word8 -> Word8) -> ST s (String, String)
    forall st. (Offset Word8 -> Word8) -> ST st (String, String)
    go
      where
        !sz :: CountOf Word8
    sz = String -> CountOf Word8
    size String
    s
        end :: Offset Word8
    end = Offset Word8
    forall a. Additive a => a
    azero Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz

        go :: (Offset Word8 -> Word8) -> ST st (String, String)
        go :: forall st. (Offset Word8 -> Word8) -> ST st (String, String)
    go Offset Word8 -> Word8
    getIdx = Offset Word8 -> ST st (String, String)
    loop (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0)
          where
            !nextI :: Offset Word8 -> (Char, Offset Word8)
    nextI = (Offset Word8 -> Word8) -> Offset Word8 -> (Char, Offset Word8)
    nextWithIndexer Offset Word8 -> Word8
    getIdx
            loop :: Offset Word8 -> ST st (String, String)
    loop Offset Word8
    idx
                | Offset Word8
    idx Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end = (String, String) -> ST st (String, String)
    forall a. a -> ST st a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (String
    s, String
    forall a. Monoid a => a
    mempty)
                | Bool
    otherwise  = do
                    let (Char
    c, Offset Word8
    idx') = Offset Word8 -> (Char, Offset Word8)
    nextI Offset Word8
    idx
                    case Char -> Bool
    predicate Char
    c of
                        Bool
    True  -> (String, String) -> ST st (String, String)
    forall a. a -> ST st a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((String, String) -> ST st (String, String))
    -> (String, String) -> ST st (String, String)
    forall a b. (a -> b) -> a -> b
    $ Offset Word8 -> String -> (String, String)
    splitIndex Offset Word8
    idx String
    s
                        Bool
    False -> Offset Word8 -> ST st (String, String)
    loop Offset Word8
    idx'
            {-# INLINE loop #-}
    {-# INLINE [2] break #-}

    breakEnd :: (Char -> Bool) -> String -> (String, String)
    breakEnd :: (Char -> Bool) -> String -> (String, String)
    breakEnd Char -> Bool
    predicate s :: String
    s@(String UArray Word8
    arr)
        | Offset Word8
    k Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end  = (String
    s, String
    forall a. Monoid a => a
    mempty)
        | Bool
    otherwise = Offset Word8 -> String -> (String, String)
    splitIndex (Offset Word8
    k Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Offset a -> Offset a -> Offset a
    `offsetSub` Offset Word8
    start) String
    s
      where
        k :: Offset Word8
    k = (Block Word8 -> Offset Word8)
    -> (FinalPtr Word8 -> Ptr Word8 -> ST Any (Offset Word8))
    -> UArray Word8
    -> Offset Word8
    forall ty a s.
    (Block ty -> a)
    -> (FinalPtr ty -> Ptr ty -> ST s a) -> UArray ty -> a
    C.onBackend Block Word8 -> Offset Word8
    goVec (\FinalPtr Word8
    _ -> Offset Word8 -> ST Any (Offset Word8)
    forall a. a -> ST Any a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Offset Word8 -> ST Any (Offset Word8))
    -> (Ptr Word8 -> Offset Word8)
    -> Ptr Word8
    -> ST Any (Offset Word8)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Ptr Word8 -> Offset Word8
    goAddr) UArray Word8
    arr
        (C.ValidRange !Offset Word8
    start !Offset Word8
    end) = UArray Word8 -> ValidRange Word8
    forall ty. UArray ty -> ValidRange ty
    offsetsValidRange UArray Word8
    arr
        goVec :: Block Word8 -> Offset Word8
    goVec ba :: Block Word8
    ba@(Block !ByteArray#
    _) = let k :: Offset Word8
    k = (Char -> Bool)
    -> Block Word8 -> Offset Word8 -> Offset Word8 -> Offset Word8
    forall container.
    Indexable container Word8 =>
    (Char -> Bool)
    -> container -> Offset Word8 -> Offset Word8 -> Offset Word8
    Alg.revFindIndexPredicate Char -> Bool
    predicate Block Word8
    ba Offset Word8
    start Offset Word8
    end
                            in if Offset Word8
    k Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end then Offset Word8
    end else Block Word8 -> Offset Word8 -> Offset Word8
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> Offset Word8
    UTF8.nextSkip Block Word8
    ba Offset Word8
    k
        goAddr :: Ptr Word8 -> Offset Word8
    goAddr ptr :: Ptr Word8
    ptr@(Ptr !Addr#
    _) =
            let k :: Offset Word8
    k = (Char -> Bool)
    -> Ptr Word8 -> Offset Word8 -> Offset Word8 -> Offset Word8
    forall container.
    Indexable container Word8 =>
    (Char -> Bool)
    -> container -> Offset Word8 -> Offset Word8 -> Offset Word8
    Alg.revFindIndexPredicate Char -> Bool
    predicate Ptr Word8
    ptr Offset Word8
    start Offset Word8
    end
             in if Offset Word8
    k Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end then Offset Word8
    end else Ptr Word8 -> Offset Word8 -> Offset Word8
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> Offset Word8
    UTF8.nextSkip Ptr Word8
    ptr Offset Word8
    k
    {-# INLINE [2] breakEnd #-}

    #if MIN_VERSION_base(4,9,0)
    {-# RULES "break (== 'c')" [3] forall c . break (eqChar c) = breakElem c #-}
    #else
    {-# RULES "break (== 'c')" [3] forall c . break (== c) = breakElem c #-}
    #endif

    -- | Break a string into 2 strings at the first occurence of the character
    breakElem :: Char -> String -> (String, String)
    breakElem :: Char -> String -> (String, String)
    breakElem !Char
    el s :: String
    s@(String UArray Word8
    ba)
        | CountOf Word8
    sz CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf Word8
    0   = (String
    forall a. Monoid a => a
    mempty, String
    forall a. Monoid a => a
    mempty)
        | Bool
    otherwise =
            case Char -> UTF8Char
    asUTF8Char Char
    el of
                UTF8_1 Word8
    w -> let !(UArray Word8
    v1,UArray Word8
    v2) = Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
    forall ty. PrimType ty => ty -> UArray ty -> (UArray ty, UArray ty)
    Vec.breakElem Word8
    w UArray Word8
    ba in (UArray Word8 -> String
    String UArray Word8
    v1, UArray Word8 -> String
    String UArray Word8
    v2)
                UTF8Char
    _        -> (forall s. ST s (String, String)) -> (String, String)
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s (String, String)) -> (String, String))
    -> (forall s. ST s (String, String)) -> (String, String)
    forall a b. (a -> b) -> a -> b
    $ UArray Word8
    -> ((Offset Word8 -> Word8) -> ST s (String, String))
    -> ST s (String, String)
    forall (prim :: * -> *) ty a.
    (PrimMonad prim, PrimType ty) =>
    UArray ty -> ((Offset ty -> ty) -> prim a) -> prim a
    Vec.unsafeIndexer UArray Word8
    ba (Offset Word8 -> Word8) -> ST s (String, String)
    forall st. (Offset Word8 -> Word8) -> ST st (String, String)
    go
      where
        sz :: CountOf Word8
    sz = String -> CountOf Word8
    size String
    s
        end :: Offset Word8
    end = Offset Word8
    forall a. Additive a => a
    azero Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz

        go :: (Offset Word8 -> Word8) -> ST st (String, String)
        go :: forall st. (Offset Word8 -> Word8) -> ST st (String, String)
    go Offset Word8 -> Word8
    getIdx = Offset Word8 -> ST st (String, String)
    loop (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0)
          where
            !nextI :: Offset Word8 -> (Char, Offset Word8)
    nextI = (Offset Word8 -> Word8) -> Offset Word8 -> (Char, Offset Word8)
    nextWithIndexer Offset Word8 -> Word8
    getIdx
            loop :: Offset Word8 -> ST st (String, String)
    loop Offset Word8
    idx
                | Offset Word8
    idx Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end = (String, String) -> ST st (String, String)
    forall a. a -> ST st a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (String
    s, String
    forall a. Monoid a => a
    mempty)
                | Bool
    otherwise  = do
                    let (Char
    c, Offset Word8
    idx') = Offset Word8 -> (Char, Offset Word8)
    nextI Offset Word8
    idx
                    case Char
    el Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    c of
                        Bool
    True  -> (String, String) -> ST st (String, String)
    forall a. a -> ST st a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((String, String) -> ST st (String, String))
    -> (String, String) -> ST st (String, String)
    forall a b. (a -> b) -> a -> b
    $ Offset Word8 -> String -> (String, String)
    splitIndex Offset Word8
    idx String
    s
                        Bool
    False -> Offset Word8 -> ST st (String, String)
    loop Offset Word8
    idx'

    -- | Same as break but cut on a line feed with an optional carriage return.
    --
    -- This is the same operation as 'breakElem LF' dropping the last character of the
    -- string if it's a CR.
    --
    -- Also for efficiency reason (streaming), it returns if the last character was a CR character.
    breakLine :: String -> Either Bool (String, String)
    breakLine :: String -> Either Bool (String, String)
    breakLine (String UArray Word8
    arr) = (UArray Word8 -> String)
    -> (UArray Word8 -> String)
    -> (UArray Word8, UArray Word8)
    -> (String, String)
    forall a b c d. (a -> b) -> (c -> d) -> (a, c) -> (b, d)
    forall (p :: * -> * -> *) a b c d.
    Bifunctor p =>
    (a -> b) -> (c -> d) -> p a c -> p b d
    bimap UArray Word8 -> String
    String UArray Word8 -> String
    String ((UArray Word8, UArray Word8) -> (String, String))
    -> Either Bool (UArray Word8, UArray Word8)
    -> Either Bool (String, String)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> UArray Word8 -> Either Bool (UArray Word8, UArray Word8)
    Vec.breakLine UArray Word8
    arr

    -- | Apply a @predicate@ to the string to return the longest prefix that satisfy the predicate and
    -- the remaining
    span :: (Char -> Bool) -> String -> (String, String)
    span :: (Char -> Bool) -> String -> (String, String)
    span Char -> Bool
    predicate String
    s = (Char -> Bool) -> String -> (String, String)
    break (Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Char -> Bool
    predicate) String
    s

    -- | Apply a @predicate@ to the string to return the longest suffix that satisfy the predicate and
    -- the remaining
    spanEnd :: (Char -> Bool) -> String -> (String, String)
    spanEnd :: (Char -> Bool) -> String -> (String, String)
    spanEnd Char -> Bool
    predicate String
    s = (Char -> Bool) -> String -> (String, String)
    breakEnd (Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Char -> Bool
    predicate) String
    s

    -- | Drop character from the beginning while the predicate is true
    dropWhile :: (Char -> Bool) -> String -> String
    dropWhile :: (Char -> Bool) -> String -> String
    dropWhile Char -> Bool
    predicate = (String, String) -> String
    forall a b. (a, b) -> b
    snd ((String, String) -> String)
    -> (String -> (String, String)) -> String -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . (Char -> Bool) -> String -> (String, String)
    break (Bool -> Bool
    not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Char -> Bool
    predicate)

    -- | Return whereas the string contains a specific character or not
    elem :: Char -> String -> Bool
    elem :: Char -> String -> Bool
    elem !Char
    el s :: String
    s@(String UArray Word8
    ba) =
        case Char -> UTF8Char
    asUTF8Char Char
    el of
            UTF8_1 Word8
    w -> Word8 -> UArray Word8 -> Bool
    forall ty. PrimType ty => ty -> UArray ty -> Bool
    Vec.elem Word8
    w UArray Word8
    ba
            UTF8Char
    _        -> (forall s. ST s Bool) -> Bool
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s Bool) -> Bool) -> (forall s. ST s Bool) -> Bool
    forall a b. (a -> b) -> a -> b
    $ UArray Word8 -> ((Offset Word8 -> Word8) -> ST s Bool) -> ST s Bool
    forall (prim :: * -> *) ty a.
    (PrimMonad prim, PrimType ty) =>
    UArray ty -> ((Offset ty -> ty) -> prim a) -> prim a
    Vec.unsafeIndexer UArray Word8
    ba (Offset Word8 -> Word8) -> ST s Bool
    forall st. (Offset Word8 -> Word8) -> ST st Bool
    go
      where
        sz :: CountOf Word8
    sz = String -> CountOf Word8
    size String
    s
        end :: Offset Word8
    end = Offset Word8
    forall a. Additive a => a
    azero Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz

        go :: (Offset Word8 -> Word8) -> ST st Bool
        go :: forall st. (Offset Word8 -> Word8) -> ST st Bool
    go Offset Word8 -> Word8
    getIdx = Offset Word8 -> ST st Bool
    loop (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0)
          where
            !nextI :: Offset Word8 -> (Char, Offset Word8)
    nextI = (Offset Word8 -> Word8) -> Offset Word8 -> (Char, Offset Word8)
    nextWithIndexer Offset Word8 -> Word8
    getIdx
            loop :: Offset Word8 -> ST st Bool
    loop !Offset Word8
    idx
                | Offset Word8
    idx Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end = Bool -> ST st Bool
    forall a. a -> ST st a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
                | Bool
    otherwise  = do
                    let (Char
    c, Offset Word8
    idx') = Offset Word8 -> (Char, Offset Word8)
    nextI Offset Word8
    idx
                    case Char
    el Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    c of
                        Bool
    True  -> Bool -> ST st Bool
    forall a. a -> ST st a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
                        Bool
    False -> Offset Word8 -> ST st Bool
    loop Offset Word8
    idx'

    -- | Intersperse the character @sep@ between each character in the string
    --
    -- > intersperse ' ' "Hello Foundation"
    -- "H e l l o   F o u n d a t i o n"
    intersperse :: Char -> String -> String
    intersperse :: Char -> String -> String
    intersperse Char
    sep String
    src = case String -> CountOf Char
    length String
    src CountOf Char -> CountOf Char -> Difference (CountOf Char)
    forall a. Subtractive a => a -> a -> Difference a
    - CountOf Char
    1 of
        Maybe (CountOf Char)
    Difference (CountOf Char)
    Nothing   -> String
    src
        Just CountOf Char
    0    -> String
    src
        Just CountOf Char
    gaps -> (forall s. ST s String) -> String
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s String) -> String)
    -> (forall s. ST s String) -> String
    forall a b. (a -> b) -> a -> b
    $ String
    -> CountOf Word8
    -> (String
        -> Offset Char
        -> Offset Word8
        -> MutableString s
        -> Offset Word8
        -> ST s (Offset Word8, Offset Word8))
    -> ST s String
    forall s.
    String
    -> CountOf Word8
    -> (String
        -> Offset Char
        -> Offset Word8
        -> MutableString s
        -> Offset Word8
        -> ST s (Offset Word8, Offset Word8))
    -> ST s String
    unsafeCopyFrom String
    src CountOf Word8
    dstBytes String
    -> Offset Char
    -> Offset Word8
    -> MutableString s
    -> Offset Word8
    -> ST s (Offset Word8, Offset Word8)
    forall s.
    String
    -> Offset Char
    -> Offset Word8
    -> MutableString s
    -> Offset Word8
    -> ST s (Offset Word8, Offset Word8)
    go
            where
              lastSrcI :: Offset Char
              lastSrcI :: Offset Char
    lastSrcI = Offset Char
    0 Offset Char -> CountOf Char -> Offset Char
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Char
    gaps
              dstBytes :: CountOf Word8
    dstBytes = (String -> CountOf Word8
    size String
    src :: CountOf Word8) CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + (CountOf Char
    gaps CountOf Char -> CountOf Word8 -> CountOf Word8
    forall n. IsNatural n => n -> CountOf Word8 -> CountOf Word8
    forall a n. (Additive a, IsNatural n) => n -> a -> a
    `scale` Int -> CountOf Word8
    charToBytes (Char -> Int
    forall a. Enum a => a -> Int
    fromEnum Char
    sep))

              go :: String -> Offset Char -> Offset8 -> MutableString s -> Offset8 -> ST s (Offset8, Offset8)
              go :: forall s.
    String
    -> Offset Char
    -> Offset Word8
    -> MutableString s
    -> Offset Word8
    -> ST s (Offset Word8, Offset Word8)
    go String
    src' Offset Char
    srcI Offset Word8
    srcIdx MutableString s
    dst Offset Word8
    dstIdx
                  | Offset Char
    srcI Offset Char -> Offset Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Char
    lastSrcI = do
                      Offset Word8
    nextDstIdx <- MutableString (PrimState (ST s))
    -> Offset Word8 -> Char -> ST s (Offset Word8)
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    write MutableString s
    MutableString (PrimState (ST s))
    dst Offset Word8
    dstIdx Char
    c
                      (Offset Word8, Offset Word8) -> ST s (Offset Word8, Offset Word8)
    forall a. a -> ST s a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    nextSrcIdx, Offset Word8
    nextDstIdx)
                  | Bool
    otherwise        = do
                      Offset Word8
    nextDstIdx  <- MutableString (PrimState (ST s))
    -> Offset Word8 -> Char -> ST s (Offset Word8)
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    write MutableString s
    MutableString (PrimState (ST s))
    dst Offset Word8
    dstIdx Char
    c
                      Offset Word8
    nextDstIdx' <- MutableString (PrimState (ST s))
    -> Offset Word8 -> Char -> ST s (Offset Word8)
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    write MutableString s
    MutableString (PrimState (ST s))
    dst Offset Word8
    nextDstIdx Char
    sep
                      (Offset Word8, Offset Word8) -> ST s (Offset Word8, Offset Word8)
    forall a. a -> ST s a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8
    nextSrcIdx, Offset Word8
    nextDstIdx')
                where
                  !(Step Char
    c Offset Word8
    nextSrcIdx) = String -> Offset Word8 -> Step
    next String
    src' Offset Word8
    srcIdx

    -- | Allocate a new @String@ with a fill function that has access to the characters of
    --   the source @String@.
    unsafeCopyFrom :: String -- ^ Source string
                   -> CountOf Word8  -- ^ Length of the destination string in bytes
                   -> (String -> Offset Char -> Offset8 -> MutableString s -> Offset8 -> ST s (Offset8, Offset8))
                   -- ^ Function called for each character in the source String
                   -> ST s String -- ^ Returns the filled new string
    unsafeCopyFrom :: forall s.
    String
    -> CountOf Word8
    -> (String
        -> Offset Char
        -> Offset Word8
        -> MutableString s
        -> Offset Word8
        -> ST s (Offset Word8, Offset Word8))
    -> ST s String
    unsafeCopyFrom String
    src CountOf Word8
    dstBytes String
    -> Offset Char
    -> Offset Word8
    -> MutableString s
    -> Offset Word8
    -> ST s (Offset Word8, Offset Word8)
    f = CountOf Word8 -> ST s (MutableString (PrimState (ST s)))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> prim (MutableString (PrimState prim))
    new CountOf Word8
    dstBytes ST s (MutableString s)
    -> (MutableString s -> ST s (MutableString s))
    -> ST s (MutableString s)
    forall a b. ST s a -> (a -> ST s b) -> ST s b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Offset Char
    -> Offset Word8
    -> Offset Word8
    -> (String
        -> Offset Char
        -> Offset Word8
        -> MutableString s
        -> Offset Word8
        -> ST s (Offset Word8, Offset Word8))
    -> MutableString s
    -> ST s (MutableString s)
    fill (Int -> Offset Char
    forall ty. Int -> Offset ty
    Offset Int
    0) (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) String
    -> Offset Char
    -> Offset Word8
    -> MutableString s
    -> Offset Word8
    -> ST s (Offset Word8, Offset Word8)
    f ST s (MutableString s)
    -> (MutableString s -> ST s String) -> ST s String
    forall a b. ST s a -> (a -> ST s b) -> ST s b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= MutableString s -> ST s String
    MutableString (PrimState (ST s)) -> ST s String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze
      where
        srcLen :: CountOf Char
    srcLen = String -> CountOf Char
    length String
    src
        end :: Offset Char
    end = Int -> Offset Char
    forall ty. Int -> Offset ty
    Offset Int
    0 Offset Char -> CountOf Char -> Offset Char
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Char
    srcLen
        fill :: Offset Char
    -> Offset Word8
    -> Offset Word8
    -> (String
        -> Offset Char
        -> Offset Word8
        -> MutableString s
        -> Offset Word8
        -> ST s (Offset Word8, Offset Word8))
    -> MutableString s
    -> ST s (MutableString s)
    fill Offset Char
    srcI Offset Word8
    srcIdx Offset Word8
    dstIdx String
    -> Offset Char
    -> Offset Word8
    -> MutableString s
    -> Offset Word8
    -> ST s (Offset Word8, Offset Word8)
    f' MutableString s
    dst'
            | Offset Char
    srcI Offset Char -> Offset Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Char
    end = MutableString s -> ST s (MutableString s)
    forall a. a -> ST s a
    forall (m :: * -> *) a. Monad m => a -> m a
    return MutableString s
    dst'
            | Bool
    otherwise = do (Offset Word8
    nextSrcIdx, Offset Word8
    nextDstIdx) <- String
    -> Offset Char
    -> Offset Word8
    -> MutableString s
    -> Offset Word8
    -> ST s (Offset Word8, Offset Word8)
    f' String
    src Offset Char
    srcI Offset Word8
    srcIdx MutableString s
    dst' Offset Word8
    dstIdx
                             Offset Char
    -> Offset Word8
    -> Offset Word8
    -> (String
        -> Offset Char
        -> Offset Word8
        -> MutableString s
        -> Offset Word8
        -> ST s (Offset Word8, Offset Word8))
    -> MutableString s
    -> ST s (MutableString s)
    fill (Offset Char
    srcI Offset Char -> Offset Char -> Offset Char
    forall a. Additive a => a -> a -> a
    + Int -> Offset Char
    forall ty. Int -> Offset ty
    Offset Int
    1) Offset Word8
    nextSrcIdx Offset Word8
    nextDstIdx String
    -> Offset Char
    -> Offset Word8
    -> MutableString s
    -> Offset Word8
    -> ST s (Offset Word8, Offset Word8)
    f' MutableString s
    dst'

    -- | Length of a String using CountOf
    --
    -- this size is available in o(n)
    length :: String -> CountOf Char
    length :: String -> CountOf Char
    length (String UArray Word8
    arr)
        | Offset Word8
    start Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end = CountOf Char
    0
        | Bool
    otherwise    = (Block Word8 -> CountOf Char)
    -> (FinalPtr Word8 -> Ptr Word8 -> ST Any (CountOf Char))
    -> UArray Word8
    -> CountOf Char
    forall ty a s.
    (Block ty -> a)
    -> (FinalPtr ty -> Ptr ty -> ST s a) -> UArray ty -> a
    C.onBackend Block Word8 -> CountOf Char
    goVec (\FinalPtr Word8
    _ -> CountOf Char -> ST Any (CountOf Char)
    forall a. a -> ST Any a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (CountOf Char -> ST Any (CountOf Char))
    -> (Ptr Word8 -> CountOf Char)
    -> Ptr Word8
    -> ST Any (CountOf Char)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Ptr Word8 -> CountOf Char
    goAddr) UArray Word8
    arr
      where
        (C.ValidRange !Offset Word8
    start !Offset Word8
    end) = UArray Word8 -> ValidRange Word8
    forall ty. UArray ty -> ValidRange ty
    offsetsValidRange UArray Word8
    arr
        goVec :: Block Word8 -> CountOf Char
    goVec Block Word8
    ma = Block Word8 -> Offset Word8 -> Offset Word8 -> CountOf Char
    forall container.
    (Indexable container Word8, Indexable container Word64) =>
    container -> Offset Word8 -> Offset Word8 -> CountOf Char
    UTF8.length Block Word8
    ma Offset Word8
    start Offset Word8
    end
        goAddr :: Ptr Word8 -> CountOf Char
    goAddr Ptr Word8
    ptr = Ptr Word8 -> Offset Word8 -> Offset Word8 -> CountOf Char
    forall container.
    (Indexable container Word8, Indexable container Word64) =>
    container -> Offset Word8 -> Offset Word8 -> CountOf Char
    UTF8.length Ptr Word8
    ptr Offset Word8
    start Offset Word8
    end

    -- | Replicate a character @c@ @n@ times to create a string of length @n@
    replicate :: CountOf Char -> Char -> String
    replicate :: CountOf Char -> Char -> String
    replicate (CountOf Int
    n) Char
    c = (forall s. ST s String) -> String
    forall a. (forall s. ST s a) -> a
    runST (CountOf Word8 -> ST s (MutableString (PrimState (ST s)))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> prim (MutableString (PrimState prim))
    new CountOf Word8
    nbBytes ST s (MutableString s)
    -> (MutableString s -> ST s String) -> ST s String
    forall a b. ST s a -> (a -> ST s b) -> ST s b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= MutableString s -> ST s String
    MutableString (PrimState (ST s)) -> ST s String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    fill)
      where
        nbBytes :: CountOf Word8
    nbBytes   = Word -> CountOf Word8 -> CountOf Word8
    forall n. IsNatural n => n -> CountOf Word8 -> CountOf Word8
    forall a n. (Additive a, IsNatural n) => n -> a -> a
    scale (Int -> Word
    forall source destination.
    Cast source destination =>
    source -> destination
    cast Int
    n :: Word) CountOf Word8
    sz
        sz :: CountOf Word8
    sz = Int -> CountOf Word8
    charToBytes (Char -> Int
    forall a. Enum a => a -> Int
    fromEnum Char
    c)
        fill :: PrimMonad prim => MutableString (PrimState prim) -> prim String
        fill :: forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    fill MutableString (PrimState prim)
    ms = Offset Word8 -> prim String
    loop (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0)
          where
            loop :: Offset Word8 -> prim String
    loop Offset Word8
    idx
                | Offset Word8
    idx Offset Word8 -> CountOf Word8 -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf Word8
    nbBytes = MutableString (PrimState prim) -> prim String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze MutableString (PrimState prim)
    ms
                | Bool
    otherwise        = MutableString (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    write MutableString (PrimState prim)
    ms Offset Word8
    idx Char
    c prim (Offset Word8) -> (Offset Word8 -> prim String) -> prim String
    forall a b. prim a -> (a -> prim b) -> prim b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Offset Word8 -> prim String
    loop

    -- | Copy the String
    --
    -- The slice of memory is copied to a new slice, making the new string
    -- independent from the original string..
    copy :: String -> String
    copy :: String -> String
    copy (String UArray Word8
    s) = UArray Word8 -> String
    String (UArray Word8 -> UArray Word8
    forall ty. PrimType ty => UArray ty -> UArray ty
    Vec.copy UArray Word8
    s)

    -- | Create a single element String
    singleton :: Char -> String
    singleton :: Char -> String
    singleton Char
    c = (forall s. ST s String) -> String
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s String) -> String)
    -> (forall s. ST s String) -> String
    forall a b. (a -> b) -> a -> b
    $ do
        MutableString s
    ms <- CountOf Word8 -> ST s (MutableString (PrimState (ST s)))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> prim (MutableString (PrimState prim))
    new CountOf Word8
    nbBytes
        Offset Word8
    _  <- MutableString (PrimState (ST s))
    -> Offset Word8 -> Char -> ST s (Offset Word8)
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    write MutableString s
    MutableString (PrimState (ST s))
    ms (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) Char
    c
        MutableString (PrimState (ST s)) -> ST s String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze MutableString s
    MutableString (PrimState (ST s))
    ms
      where
        !nbBytes :: CountOf Word8
    nbBytes = Int -> CountOf Word8
    charToBytes (Char -> Int
    forall a. Enum a => a -> Int
    fromEnum Char
    c)

    -- | Unsafely create a string of up to @sz@ bytes.
    --
    -- The callback @f@ needs to return the number of bytes filled in the underlaying
    -- bytes buffer. No check is made on the callback return values, and if it's not
    -- contained without the bounds, bad things will happen.
    create :: PrimMonad prim => CountOf Word8 -> (MutableString (PrimState prim) -> prim (Offset Word8)) -> prim String
    create :: forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8
    -> (MutableString (PrimState prim) -> prim (Offset Word8))
    -> prim String
    create CountOf Word8
    sz MutableString (PrimState prim) -> prim (Offset Word8)
    f = do
        MutableString (PrimState prim)
    ms     <- CountOf Word8 -> prim (MutableString (PrimState prim))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> prim (MutableString (PrimState prim))
    new CountOf Word8
    sz
        Offset Word8
    filled <- MutableString (PrimState prim) -> prim (Offset Word8)
    f MutableString (PrimState prim)
    ms
        if Offset Word8
    filled Offset Word8 -> CountOf Word8 -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf Word8
    sz
            then MutableString (PrimState prim) -> prim String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze MutableString (PrimState prim)
    ms
            else do
                String
    s <- MutableString (PrimState prim) -> prim String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze MutableString (PrimState prim)
    ms
                let (String UArray Word8
    ba) = String
    s
                String -> prim String
    forall a. a -> prim a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (String -> prim String) -> String -> prim String
    forall a b. (a -> b) -> a -> b
    $ UArray Word8 -> String
    String (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ CountOf Word8 -> UArray Word8 -> UArray Word8
    forall ty. CountOf ty -> UArray ty -> UArray ty
    C.take (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    filled) UArray Word8
    ba

    -- | Monomorphically map the character in a string and return the transformed one
    charMap :: (Char -> Char) -> String -> String
    charMap :: (Char -> Char) -> String -> String
    charMap Char -> Char
    f String
    src
        | CountOf Word8
    srcSz CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf Word8
    0 = String
    forall a. Monoid a => a
    mempty
        | Bool
    otherwise  =
            let !([(String, CountOf Word8)]
    elems, CountOf Word8
    nbBytes) = [(String, CountOf Word8)]
    -> Offset Word8
    -> CountOf Word8
    -> ([(String, CountOf Word8)], CountOf Word8)
    allocateAndFill [] (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) (Int -> CountOf Word8
    forall ty. Int -> CountOf ty
    CountOf Int
    0)
             in (forall s. ST s String) -> String
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s String) -> String)
    -> (forall s. ST s String) -> String
    forall a b. (a -> b) -> a -> b
    $ do
                    MutableString s
    dest <- CountOf Word8 -> ST s (MutableString (PrimState (ST s)))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> prim (MutableString (PrimState prim))
    new CountOf Word8
    nbBytes
                    MutableString (PrimState (ST s))
    -> [(String, CountOf Word8)] -> Offset Word8 -> ST s ()
    forall {m :: * -> *}.
    PrimMonad m =>
    MutableString (PrimState m)
    -> [(String, CountOf Word8)] -> Offset Word8 -> m ()
    copyLoop MutableString s
    MutableString (PrimState (ST s))
    dest [(String, CountOf Word8)]
    elems (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0 Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    nbBytes)
                    MutableString (PrimState (ST s)) -> ST s String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze MutableString s
    MutableString (PrimState (ST s))
    dest
      where
        !srcSz :: CountOf Word8
    srcSz = String -> CountOf Word8
    size String
    src
        srcEnd :: Offset Word8
    srcEnd = Offset Word8
    forall a. Additive a => a
    azero Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    srcSz

        allocateAndFill :: [(String, CountOf Word8)]
                        -> Offset8
                        -> CountOf Word8
                        -> ([(String,CountOf Word8)], CountOf Word8)
        allocateAndFill :: [(String, CountOf Word8)]
    -> Offset Word8
    -> CountOf Word8
    -> ([(String, CountOf Word8)], CountOf Word8)
    allocateAndFill [(String, CountOf Word8)]
    acc Offset Word8
    idx CountOf Word8
    bytesWritten
            | Offset Word8
    idx Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    srcEnd = ([(String, CountOf Word8)]
    acc, CountOf Word8
    bytesWritten)
            | Bool
    otherwise     =
                let (el :: (String, CountOf Word8)
    el@(String
    _,CountOf Word8
    addBytes), Offset Word8
    idx') = (forall s. ST s ((String, CountOf Word8), Offset Word8))
    -> ((String, CountOf Word8), Offset Word8)
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s ((String, CountOf Word8), Offset Word8))
     -> ((String, CountOf Word8), Offset Word8))
    -> (forall s. ST s ((String, CountOf Word8), Offset Word8))
    -> ((String, CountOf Word8), Offset Word8)
    forall a b. (a -> b) -> a -> b
    $ do
                        -- make sure we allocate at least 4 bytes for the destination for the last few bytes
                        -- otherwise allocating less would bring the danger of spinning endlessly
                        -- and never succeeding.
                        let !diffBytes :: Difference (Offset Word8)
    diffBytes = Offset Word8
    srcEnd Offset Word8 -> Offset Word8 -> Difference (Offset Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - Offset Word8
    idx
                            !allocatedBytes :: CountOf Word8
    allocatedBytes = if Difference (Offset Word8)
    CountOf Word8
    diffBytes CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int -> CountOf Word8
    forall ty. Int -> CountOf ty
    CountOf Int
    4 then Int -> CountOf Word8
    forall ty. Int -> CountOf ty
    CountOf Int
    4 else Difference (Offset Word8)
    CountOf Word8
    diffBytes
                        MutableString s
    ms <- CountOf Word8 -> ST s (MutableString (PrimState (ST s)))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> prim (MutableString (PrimState prim))
    new CountOf Word8
    allocatedBytes
                        (CountOf Word8
    dstIdx, Offset Word8
    srcIdx) <- MutableString (PrimState (ST s))
    -> CountOf Word8
    -> Offset Word8
    -> ST s (CountOf Word8, Offset Word8)
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> CountOf Word8
    -> Offset Word8
    -> prim (CountOf Word8, Offset Word8)
    fill MutableString s
    MutableString (PrimState (ST s))
    ms CountOf Word8
    allocatedBytes Offset Word8
    idx
                        String
    s <- MutableString (PrimState (ST s)) -> ST s String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze MutableString s
    MutableString (PrimState (ST s))
    ms
                        ((String, CountOf Word8), Offset Word8)
    -> ST s ((String, CountOf Word8), Offset Word8)
    forall a. a -> ST s a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((String
    s, CountOf Word8
    dstIdx), Offset Word8
    srcIdx)
                 in [(String, CountOf Word8)]
    -> Offset Word8
    -> CountOf Word8
    -> ([(String, CountOf Word8)], CountOf Word8)
    allocateAndFill ((String, CountOf Word8)
    el (String, CountOf Word8)
    -> [(String, CountOf Word8)] -> [(String, CountOf Word8)]
    forall a. a -> [a] -> [a]
    : [(String, CountOf Word8)]
    acc) Offset Word8
    idx' (CountOf Word8
    bytesWritten CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    addBytes)

        fill :: PrimMonad prim
             => MutableString (PrimState prim)
             -> CountOf Word8
             -> Offset8
             -> prim (CountOf Word8, Offset8)
        fill :: forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> CountOf Word8
    -> Offset Word8
    -> prim (CountOf Word8, Offset Word8)
    fill MutableString (PrimState prim)
    mba CountOf Word8
    dsz Offset Word8
    srcIdxOrig =
            Offset Word8 -> Offset Word8 -> prim (CountOf Word8, Offset Word8)
    loop (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) Offset Word8
    srcIdxOrig
          where
            endDst :: Offset Word8
    endDst = (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    dsz
            loop :: Offset Word8 -> Offset Word8 -> prim (CountOf Word8, Offset Word8)
    loop Offset Word8
    dstIdx Offset Word8
    srcIdx
                | Offset Word8
    srcIdx Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    srcEnd = (CountOf Word8, Offset Word8) -> prim (CountOf Word8, Offset Word8)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    dstIdx, Offset Word8
    srcIdx)
                | Offset Word8
    dstIdx Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    endDst = (CountOf Word8, Offset Word8) -> prim (CountOf Word8, Offset Word8)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    dstIdx, Offset Word8
    srcIdx)
                | Bool
    otherwise        =
                    let !(Step Char
    c Offset Word8
    srcIdx') = String -> Offset Word8 -> Step
    next String
    src Offset Word8
    srcIdx
                        c' :: Char
    c' = Char -> Char
    f Char
    c -- the mapped char
                        !nbBytes :: CountOf Word8
    nbBytes = Int -> CountOf Word8
    charToBytes (Char -> Int
    forall a. Enum a => a -> Int
    fromEnum Char
    c')
                     in -- check if we have room in the destination buffer
                        if Offset Word8
    dstIdx Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    nbBytes Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= CountOf Word8 -> Offset Word8
    forall a. CountOf a -> Offset a
    sizeAsOffset CountOf Word8
    dsz
                            then do Offset Word8
    dstIdx' <- MutableString (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    write MutableString (PrimState prim)
    mba Offset Word8
    dstIdx Char
    c'
                                    Offset Word8 -> Offset Word8 -> prim (CountOf Word8, Offset Word8)
    loop Offset Word8
    dstIdx' Offset Word8
    srcIdx'
                            else (CountOf Word8, Offset Word8) -> prim (CountOf Word8, Offset Word8)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    dstIdx, Offset Word8
    srcIdx)

        copyLoop :: MutableString (PrimState m)
    -> [(String, CountOf Word8)] -> Offset Word8 -> m ()
    copyLoop MutableString (PrimState m)
    _   []     (Offset Int
    0) = () -> m ()
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ()
        copyLoop MutableString (PrimState m)
    _   []     Offset Word8
    n          = [Char] -> m ()
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "charMap invalid: " [Char] -> [Char] -> [Char]
    forall a. Semigroup a => a -> a -> a
    <> Offset Word8 -> [Char]
    forall a. Show a => a -> [Char]
    show Offset Word8
    n)
        copyLoop ms :: MutableString (PrimState m)
    ms@(MutableString MUArray Word8 (PrimState m)
    mba) ((String UArray Word8
    ba, CountOf Word8
    sz):[(String, CountOf Word8)]
    xs) Offset Word8
    end = do
            let start :: Offset Word8
    start = Offset Word8
    end Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetMinusE` CountOf Word8
    sz
            MUArray Word8 (PrimState m)
    -> Offset Word8
    -> UArray Word8
    -> Offset Word8
    -> CountOf Word8
    -> m ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim)
    -> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
    Vec.unsafeCopyAtRO MUArray Word8 (PrimState m)
    mba Offset Word8
    start UArray Word8
    ba (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) CountOf Word8
    sz
            MutableString (PrimState m)
    -> [(String, CountOf Word8)] -> Offset Word8 -> m ()
    copyLoop MutableString (PrimState m)
    ms [(String, CountOf Word8)]
    xs Offset Word8
    start

    -- | Append a Char to the end of the String and return this new String
    snoc :: String -> Char -> String
    snoc :: String -> Char -> String
    snoc s :: String
    s@(String UArray Word8
    ba) Char
    c
        | CountOf Word8
    len CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int -> CountOf Word8
    forall ty. Int -> CountOf ty
    CountOf Int
    0 = Char -> String
    singleton Char
    c
        | Bool
    otherwise     = (forall s. ST s String) -> String
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s String) -> String)
    -> (forall s. ST s String) -> String
    forall a b. (a -> b) -> a -> b
    $ do
            MutableString s
    ms <- CountOf Word8 -> ST s (MutableString (PrimState (ST s)))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> prim (MutableString (PrimState prim))
    new (CountOf Word8
    len CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    nbBytes)
            let (MutableString MUArray Word8 s
    mba) = MutableString s
    ms
            MUArray Word8 (PrimState (ST s))
    -> Offset Word8
    -> UArray Word8
    -> Offset Word8
    -> CountOf Word8
    -> ST s ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim)
    -> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
    Vec.unsafeCopyAtRO MUArray Word8 s
    MUArray Word8 (PrimState (ST s))
    mba (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) UArray Word8
    ba (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) CountOf Word8
    len
            Offset Word8
    _ <- MutableString (PrimState (ST s))
    -> Offset Word8 -> Char -> ST s (Offset Word8)
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    write MutableString s
    MutableString (PrimState (ST s))
    ms (Offset Word8
    forall a. Additive a => a
    azero Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    len) Char
    c
            MutableString (PrimState (ST s)) -> ST s String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze MutableString s
    MutableString (PrimState (ST s))
    ms
      where
        !len :: CountOf Word8
    len     = String -> CountOf Word8
    size String
    s
        !nbBytes :: CountOf Word8
    nbBytes = Int -> CountOf Word8
    charToBytes (Char -> Int
    forall a. Enum a => a -> Int
    fromEnum Char
    c)

    -- | Prepend a Char to the beginning of the String and return this new String
    cons :: Char -> String -> String
    cons :: Char -> String -> String
    cons Char
    c s :: String
    s@(String UArray Word8
    ba)
      | CountOf Word8
    len CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int -> CountOf Word8
    forall ty. Int -> CountOf ty
    CountOf Int
    0 = Char -> String
    singleton Char
    c
      | Bool
    otherwise     = (forall s. ST s String) -> String
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s String) -> String)
    -> (forall s. ST s String) -> String
    forall a b. (a -> b) -> a -> b
    $ do
          MutableString s
    ms <- CountOf Word8 -> ST s (MutableString (PrimState (ST s)))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> prim (MutableString (PrimState prim))
    new (CountOf Word8
    len CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    nbBytes)
          let (MutableString MUArray Word8 s
    mba) = MutableString s
    ms
          Offset Word8
    idx <- MutableString (PrimState (ST s))
    -> Offset Word8 -> Char -> ST s (Offset Word8)
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    write MutableString s
    MutableString (PrimState (ST s))
    ms (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) Char
    c
          MUArray Word8 (PrimState (ST s))
    -> Offset Word8
    -> UArray Word8
    -> Offset Word8
    -> CountOf Word8
    -> ST s ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim)
    -> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
    Vec.unsafeCopyAtRO MUArray Word8 s
    MUArray Word8 (PrimState (ST s))
    mba Offset Word8
    idx UArray Word8
    ba (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) CountOf Word8
    len
          MutableString (PrimState (ST s)) -> ST s String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze MutableString s
    MutableString (PrimState (ST s))
    ms
      where
        !len :: CountOf Word8
    len     = String -> CountOf Word8
    size String
    s
        !nbBytes :: CountOf Word8
    nbBytes = Int -> CountOf Word8
    charToBytes (Char -> Int
    forall a. Enum a => a -> Int
    fromEnum Char
    c)

    -- | Extract the String stripped of the last character and the last character if not empty
    --
    -- If empty, Nothing is returned
    unsnoc :: String -> Maybe (String, Char)
    unsnoc :: String -> Maybe (String, Char)
    unsnoc s :: String
    s@(String UArray Word8
    arr)
        | CountOf Word8
    sz CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf Word8
    0   = Maybe (String, Char)
    forall a. Maybe a
    Nothing
        | Bool
    otherwise =
            let !(StepBack Char
    c Offset Word8
    idx) = String -> Offset Word8 -> StepBack
    prev String
    s (CountOf Word8 -> Offset Word8
    forall a. CountOf a -> Offset a
    sizeAsOffset CountOf Word8
    sz)
             in (String, Char) -> Maybe (String, Char)
    forall a. a -> Maybe a
    Just (UArray Word8 -> String
    String (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ CountOf Word8 -> UArray Word8 -> UArray Word8
    forall ty. CountOf ty -> UArray ty -> UArray ty
    Vec.take (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    idx) UArray Word8
    arr, Char
    c)
      where
        sz :: CountOf Word8
    sz = String -> CountOf Word8
    size String
    s

    -- | Extract the First character of a string, and the String stripped of the first character.
    --
    -- If empty, Nothing is returned
    uncons :: String -> Maybe (Char, String)
    uncons :: String -> Maybe (Char, String)
    uncons s :: String
    s@(String UArray Word8
    ba)
        | String -> Bool
    null String
    s    = Maybe (Char, String)
    forall a. Maybe a
    Nothing
        | Bool
    otherwise =
            let !(Step Char
    c Offset Word8
    idx) = String -> Offset Word8 -> Step
    next String
    s Offset Word8
    forall a. Additive a => a
    azero
             in (Char, String) -> Maybe (Char, String)
    forall a. a -> Maybe a
    Just (Char
    c, UArray Word8 -> String
    String (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ CountOf Word8 -> UArray Word8 -> UArray Word8
    forall ty. CountOf ty -> UArray ty -> UArray ty
    Vec.drop (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    idx) UArray Word8
    ba)

    -- | Look for a predicate in the String and return the matched character, if any.
    find :: (Char -> Bool) -> String -> Maybe Char
    find :: (Char -> Bool) -> String -> Maybe Char
    find Char -> Bool
    predicate String
    s = Offset Word8 -> Maybe Char
    loop (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0)
      where
        !sz :: CountOf Word8
    sz = String -> CountOf Word8
    size String
    s
        end :: Offset Word8
    end = Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0 Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz
        loop :: Offset Word8 -> Maybe Char
    loop Offset Word8
    idx
            | Offset Word8
    idx Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end = Maybe Char
    forall a. Maybe a
    Nothing
            | Bool
    otherwise =
                let !(Step Char
    c Offset Word8
    idx') = String -> Offset Word8 -> Step
    next String
    s Offset Word8
    idx
                 in case Char -> Bool
    predicate Char
    c of
                        Bool
    True  -> Char -> Maybe Char
    forall a. a -> Maybe a
    Just Char
    c
                        Bool
    False -> Offset Word8 -> Maybe Char
    loop Offset Word8
    idx'

    -- | Sort the character in a String using a specific sort function
    --
    -- TODO: optimise not going through a list
    sortBy :: (Char -> Char -> Ordering) -> String -> String
    sortBy :: (Char -> Char -> Ordering) -> String -> String
    sortBy Char -> Char -> Ordering
    sortF String
    s = [Item String] -> String
    forall l. IsList l => [Item l] -> l
    fromList ([Item String] -> String) -> [Item String] -> String
    forall a b. (a -> b) -> a -> b
    $ (Item String -> Item String -> Ordering)
    -> [Item String] -> [Item String]
    forall a. (a -> a -> Ordering) -> [a] -> [a]
    Data.List.sortBy Char -> Char -> Ordering
    Item String -> Item String -> Ordering
    sortF ([Item String] -> [Item String]) -> [Item String] -> [Item String]
    forall a b. (a -> b) -> a -> b
    $ String -> [Item String]
    forall l. IsList l => l -> [Item l]
    toList String
    s -- FIXME for tests

    -- | Filter characters of a string using the predicate
    filter :: (Char -> Bool) -> String -> String
    filter :: (Char -> Bool) -> String -> String
    filter Char -> Bool
    predicate (String UArray Word8
    arr) = (forall s. ST s String) -> String
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s String) -> String)
    -> (forall s. ST s String) -> String
    forall a b. (a -> b) -> a -> b
    $ do
        (CountOf Word8
    finalSize, MutableString s
    dst) <- CountOf Word8
    -> (MutableBlock Word8 (PrimState (ST s)) -> ST s (CountOf Word8))
    -> ST s (CountOf Word8, MutableString (PrimState (ST s)))
    forall (prim :: * -> *) a.
    PrimMonad prim =>
    CountOf Word8
    -> (MutableBlock Word8 (PrimState prim) -> prim a)
    -> prim (a, MutableString (PrimState prim))
    newNative CountOf Word8
    sz ((MutableBlock Word8 (PrimState (ST s)) -> ST s (CountOf Word8))
     -> ST s (CountOf Word8, MutableString (PrimState (ST s))))
    -> (MutableBlock Word8 (PrimState (ST s)) -> ST s (CountOf Word8))
    -> ST s (CountOf Word8, MutableString (PrimState (ST s)))
    forall a b. (a -> b) -> a -> b
    $ \(MutableBlock MutableByteArray# (PrimState (ST s))
    mba) ->
            (Block Word8 -> ST s (CountOf Word8))
    -> (FinalPtr Word8 -> ST s (CountOf Word8))
    -> UArray Word8
    -> ST s (CountOf Word8)
    forall (prim :: * -> *) ty a.
    PrimMonad prim =>
    (Block ty -> prim a)
    -> (FinalPtr ty -> prim a) -> UArray ty -> prim a
    C.onBackendPrim (\ba :: Block Word8
    ba@(Block !ByteArray#
    _) -> (Char -> Bool)
    -> CountOf Word8
    -> MutableByteArray# s
    -> Block Word8
    -> Offset Word8
    -> ST s (CountOf Word8)
    forall s container.
    Indexable container Word8 =>
    (Char -> Bool)
    -> CountOf Word8
    -> MutableByteArray# s
    -> container
    -> Offset Word8
    -> ST s (CountOf Word8)
    Alg.copyFilter Char -> Bool
    predicate CountOf Word8
    sz MutableByteArray# s
    MutableByteArray# (PrimState (ST s))
    mba Block Word8
    ba Offset Word8
    start)
                            (\FinalPtr Word8
    fptr -> FinalPtr Word8
    -> (Ptr Word8 -> ST s (CountOf Word8)) -> ST s (CountOf Word8)
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> prim a
    withFinalPtr FinalPtr Word8
    fptr ((Ptr Word8 -> ST s (CountOf Word8)) -> ST s (CountOf Word8))
    -> (Ptr Word8 -> ST s (CountOf Word8)) -> ST s (CountOf Word8)
    forall a b. (a -> b) -> a -> b
    $ \ptr :: Ptr Word8
    ptr@(Ptr !Addr#
    _) -> (Char -> Bool)
    -> CountOf Word8
    -> MutableByteArray# s
    -> Ptr Word8
    -> Offset Word8
    -> ST s (CountOf Word8)
    forall s container.
    Indexable container Word8 =>
    (Char -> Bool)
    -> CountOf Word8
    -> MutableByteArray# s
    -> container
    -> Offset Word8
    -> ST s (CountOf Word8)
    Alg.copyFilter Char -> Bool
    predicate CountOf Word8
    sz MutableByteArray# s
    MutableByteArray# (PrimState (ST s))
    mba Ptr Word8
    ptr Offset Word8
    start)
                            UArray Word8
    arr
        CountOf Word8 -> MutableString (PrimState (ST s)) -> ST s String
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> MutableString (PrimState prim) -> prim String
    freezeShrink CountOf Word8
    finalSize MutableString s
    MutableString (PrimState (ST s))
    dst
      where
        !sz :: CountOf Word8
    sz    = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    arr
        !start :: Offset Word8
    start = UArray Word8 -> Offset Word8
    forall ty. UArray ty -> Offset ty
    C.offset UArray Word8
    arr

    -- | Reverse a string
    reverse :: String -> String
    reverse :: String -> String
    reverse (String UArray Word8
    arr) = (forall s. ST s String) -> String
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s String) -> String)
    -> (forall s. ST s String) -> String
    forall a b. (a -> b) -> a -> b
    $ do
        MutableString s
    s <- CountOf Word8
    -> (MutableBlock Word8 (PrimState (ST s)) -> ST s ())
    -> ST s (MutableString (PrimState (ST s)))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8
    -> (MutableBlock Word8 (PrimState prim) -> prim ())
    -> prim (MutableString (PrimState prim))
    newNative_ (UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    arr) ((MutableBlock Word8 (PrimState (ST s)) -> ST s ())
     -> ST s (MutableString (PrimState (ST s))))
    -> (MutableBlock Word8 (PrimState (ST s)) -> ST s ())
    -> ST s (MutableString (PrimState (ST s)))
    forall a b. (a -> b) -> a -> b
    $ \(MutableBlock MutableByteArray# (PrimState (ST s))
    mba) ->
                (Block Word8 -> ST s ())
    -> (FinalPtr Word8 -> ST s ()) -> UArray Word8 -> ST s ()
    forall (prim :: * -> *) ty a.
    PrimMonad prim =>
    (Block ty -> prim a)
    -> (FinalPtr ty -> prim a) -> UArray ty -> prim a
    C.onBackendPrim
                    (\ba :: Block Word8
    ba@(Block !ByteArray#
    _) -> MutableByteArray# (PrimState (ST s))
    -> Offset Word8
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> ST s ()
    forall (prim :: * -> *) container.
    (PrimMonad prim, Indexable container Word8) =>
    MutableByteArray# (PrimState prim)
    -> Offset Word8
    -> container
    -> Offset Word8
    -> Offset Word8
    -> prim ()
    UTF8.reverse MutableByteArray# (PrimState (ST s))
    mba Offset Word8
    0 Block Word8
    ba Offset Word8
    start Offset Word8
    end)
                    (\FinalPtr Word8
    fptr -> FinalPtr Word8 -> (Ptr Word8 -> ST s ()) -> ST s ()
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> prim a
    withFinalPtr FinalPtr Word8
    fptr ((Ptr Word8 -> ST s ()) -> ST s ())
    -> (Ptr Word8 -> ST s ()) -> ST s ()
    forall a b. (a -> b) -> a -> b
    $ \ptr :: Ptr Word8
    ptr@(Ptr !Addr#
    _) -> MutableByteArray# (PrimState (ST s))
    -> Offset Word8
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> ST s ()
    forall (prim :: * -> *) container.
    (PrimMonad prim, Indexable container Word8) =>
    MutableByteArray# (PrimState prim)
    -> Offset Word8
    -> container
    -> Offset Word8
    -> Offset Word8
    -> prim ()
    UTF8.reverse MutableByteArray# (PrimState (ST s))
    mba Offset Word8
    0 Ptr Word8
    ptr Offset Word8
    start Offset Word8
    end)
                    UArray Word8
    arr
        MutableString (PrimState (ST s)) -> ST s String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze MutableString s
    MutableString (PrimState (ST s))
    s
      where
        !(C.ValidRange Offset Word8
    start Offset Word8
    end) = UArray Word8 -> ValidRange Word8
    forall ty. UArray ty -> ValidRange ty
    C.offsetsValidRange UArray Word8
    arr

    -- | Finds where are the insertion points when we search for a `needle`
    -- within an `haystack`.
    indices :: String -> String -> [Offset8]
    indices :: String -> String -> [Offset Word8]
    indices (String UArray Word8
    ned) (String UArray Word8
    hy) = UArray Word8 -> UArray Word8 -> [Offset Word8]
    forall ty. PrimType ty => UArray ty -> UArray ty -> [Offset ty]
    Vec.indices UArray Word8
    ned UArray Word8
    hy

    -- | Replace all the occurrencies of `needle` with `replacement` in
    -- the `haystack` string.
    replace :: String -> String -> String -> String
    replace :: String -> String -> String -> String
    replace (String UArray Word8
    needle) (String UArray Word8
    replacement) (String UArray Word8
    haystack) =
      UArray Word8 -> String
    String (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ UArray Word8 -> UArray Word8 -> UArray Word8 -> UArray Word8
    forall ty.
    PrimType ty =>
    UArray ty -> UArray ty -> UArray ty -> UArray ty
    Vec.replace UArray Word8
    needle UArray Word8
    replacement UArray Word8
    haystack

    -- | Return the nth character in a String
    --
    -- Compared to an array, the string need to be scanned from the beginning
    -- since the UTF8 encoding is variable.
    index :: String -> Offset Char -> Maybe Char
    index :: String -> Offset Char -> Maybe Char
    index String
    s Offset Char
    n
        | Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Offset Word8
    end = Maybe Char
    forall a. Maybe a
    Nothing
        | Bool
    otherwise  =
            let (Step !Char
    c Offset Word8
    _) = String -> Offset Word8 -> Step
    next String
    s Offset Word8
    ofs
             in Char -> Maybe Char
    forall a. a -> Maybe a
    Just Char
    c
      where
        !nbBytes :: CountOf Word8
    nbBytes = String -> CountOf Word8
    size String
    s
        end :: Offset Word8
    end = Offset Word8
    0 Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    nbBytes
        ofs :: Offset Word8
    ofs = CountOf Char -> String -> Offset Word8
    indexN (Offset Char -> CountOf Char
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Char
    n) String
    s

    -- | Return the index in unit of Char of the first occurence of the predicate returning True
    --
    -- If not found, Nothing is returned
    findIndex :: (Char -> Bool) -> String -> Maybe (Offset Char)
    findIndex :: (Char -> Bool) -> String -> Maybe (Offset Char)
    findIndex Char -> Bool
    predicate String
    s = Offset Char -> Offset Word8 -> Maybe (Offset Char)
    loop Offset Char
    0 Offset Word8
    0
      where
        !sz :: CountOf Word8
    sz = String -> CountOf Word8
    size String
    s
        loop :: Offset Char -> Offset Word8 -> Maybe (Offset Char)
    loop Offset Char
    ofs Offset Word8
    idx
            | Offset Word8
    idx Offset Word8 -> CountOf Word8 -> Bool
    forall ty. Offset ty -> CountOf ty -> Bool
    .==# CountOf Word8
    sz = Maybe (Offset Char)
    forall a. Maybe a
    Nothing
            | Bool
    otherwise   =
                let !(Step Char
    c Offset Word8
    idx') = String -> Offset Word8 -> Step
    next String
    s Offset Word8
    idx
                 in case Char -> Bool
    predicate Char
    c of
                        Bool
    True  -> Offset Char -> Maybe (Offset Char)
    forall a. a -> Maybe a
    Just Offset Char
    ofs
                        Bool
    False -> Offset Char -> Offset Word8 -> Maybe (Offset Char)
    loop (Offset Char
    ofsOffset Char -> Offset Char -> Offset Char
    forall a. Additive a => a -> a -> a
    +Offset Char
    1) Offset Word8
    idx'

    -- | Various String Encoding that can be use to convert to and from bytes
    data Encoding
        = ASCII7
        | UTF8
        | UTF16
        | UTF32
        | ISO_8859_1
        deriving (Typeable, Typeable Encoding
    Typeable Encoding
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> Encoding -> c Encoding)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Encoding)
    -> (Encoding -> Constr)
    -> (Encoding -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Encoding))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Encoding))
    -> ((forall b. Data b => b -> b) -> Encoding -> Encoding)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Encoding -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Encoding -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Encoding -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Encoding -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Encoding -> m Encoding)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Encoding -> m Encoding)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Encoding -> m Encoding)
    -> Data Encoding
    Encoding -> Constr
    Encoding -> DataType
    (forall b. Data b => b -> b) -> Encoding -> Encoding
    forall a.
    Typeable a
    -> (forall (c :: * -> *).
        (forall d b. Data d => c (d -> b) -> d -> c b)
        -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Encoding -> u
    forall u. (forall d. Data d => d -> u) -> Encoding -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Encoding -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Encoding -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Encoding -> m Encoding
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Encoding -> m Encoding
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Encoding
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Encoding -> c Encoding
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Encoding)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Encoding)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Encoding -> c Encoding
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Encoding -> c Encoding
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Encoding
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Encoding
    $ctoConstr :: Encoding -> Constr
    toConstr :: Encoding -> Constr
    $cdataTypeOf :: Encoding -> DataType
    dataTypeOf :: Encoding -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Encoding)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Encoding)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Encoding)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Encoding)
    $cgmapT :: (forall b. Data b => b -> b) -> Encoding -> Encoding
    gmapT :: (forall b. Data b => b -> b) -> Encoding -> Encoding
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Encoding -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Encoding -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Encoding -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Encoding -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Encoding -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Encoding -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Encoding -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Encoding -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Encoding -> m Encoding
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Encoding -> m Encoding
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Encoding -> m Encoding
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Encoding -> m Encoding
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Encoding -> m Encoding
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Encoding -> m Encoding
    Data, Encoding -> Encoding -> Bool
    (Encoding -> Encoding -> Bool)
    -> (Encoding -> Encoding -> Bool) -> Eq Encoding
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Encoding -> Encoding -> Bool
    == :: Encoding -> Encoding -> Bool
    $c/= :: Encoding -> Encoding -> Bool
    /= :: Encoding -> Encoding -> Bool
    Eq, Eq Encoding
    Eq Encoding
    -> (Encoding -> Encoding -> Ordering)
    -> (Encoding -> Encoding -> Bool)
    -> (Encoding -> Encoding -> Bool)
    -> (Encoding -> Encoding -> Bool)
    -> (Encoding -> Encoding -> Bool)
    -> (Encoding -> Encoding -> Encoding)
    -> (Encoding -> Encoding -> Encoding)
    -> Ord Encoding
    Encoding -> Encoding -> Bool
    Encoding -> Encoding -> Ordering
    Encoding -> Encoding -> Encoding
    forall a.
    Eq a
    -> (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: Encoding -> Encoding -> Ordering
    compare :: Encoding -> Encoding -> Ordering
    $c< :: Encoding -> Encoding -> Bool
    < :: Encoding -> Encoding -> Bool
    $c<= :: Encoding -> Encoding -> Bool
    <= :: Encoding -> Encoding -> Bool
    $c> :: Encoding -> Encoding -> Bool
    > :: Encoding -> Encoding -> Bool
    $c>= :: Encoding -> Encoding -> Bool
    >= :: Encoding -> Encoding -> Bool
    $cmax :: Encoding -> Encoding -> Encoding
    max :: Encoding -> Encoding -> Encoding
    $cmin :: Encoding -> Encoding -> Encoding
    min :: Encoding -> Encoding -> Encoding
    Ord, Int -> Encoding -> [Char] -> [Char]
    [Encoding] -> [Char] -> [Char]
    Encoding -> [Char]
    (Int -> Encoding -> [Char] -> [Char])
    -> (Encoding -> [Char])
    -> ([Encoding] -> [Char] -> [Char])
    -> Show Encoding
    forall a.
    (Int -> a -> [Char] -> [Char])
    -> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
    $cshowsPrec :: Int -> Encoding -> [Char] -> [Char]
    showsPrec :: Int -> Encoding -> [Char] -> [Char]
    $cshow :: Encoding -> [Char]
    show :: Encoding -> [Char]
    $cshowList :: [Encoding] -> [Char] -> [Char]
    showList :: [Encoding] -> [Char] -> [Char]
    Show, Int -> Encoding
    Encoding -> Int
    Encoding -> [Encoding]
    Encoding -> Encoding
    Encoding -> Encoding -> [Encoding]
    Encoding -> Encoding -> Encoding -> [Encoding]
    (Encoding -> Encoding)
    -> (Encoding -> Encoding)
    -> (Int -> Encoding)
    -> (Encoding -> Int)
    -> (Encoding -> [Encoding])
    -> (Encoding -> Encoding -> [Encoding])
    -> (Encoding -> Encoding -> [Encoding])
    -> (Encoding -> Encoding -> Encoding -> [Encoding])
    -> Enum Encoding
    forall a.
    (a -> a)
    -> (a -> a)
    -> (Int -> a)
    -> (a -> Int)
    -> (a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> [a])
    -> (a -> a -> a -> [a])
    -> Enum a
    $csucc :: Encoding -> Encoding
    succ :: Encoding -> Encoding
    $cpred :: Encoding -> Encoding
    pred :: Encoding -> Encoding
    $ctoEnum :: Int -> Encoding
    toEnum :: Int -> Encoding
    $cfromEnum :: Encoding -> Int
    fromEnum :: Encoding -> Int
    $cenumFrom :: Encoding -> [Encoding]
    enumFrom :: Encoding -> [Encoding]
    $cenumFromThen :: Encoding -> Encoding -> [Encoding]
    enumFromThen :: Encoding -> Encoding -> [Encoding]
    $cenumFromTo :: Encoding -> Encoding -> [Encoding]
    enumFromTo :: Encoding -> Encoding -> [Encoding]
    $cenumFromThenTo :: Encoding -> Encoding -> Encoding -> [Encoding]
    enumFromThenTo :: Encoding -> Encoding -> Encoding -> [Encoding]
    Enum, Encoding
    Encoding -> Encoding -> Bounded Encoding
    forall a. a -> a -> Bounded a
    $cminBound :: Encoding
    minBound :: Encoding
    $cmaxBound :: Encoding
    maxBound :: Encoding
    Bounded)

    fromEncoderBytes :: ( Encoder.Encoding encoding
                        , PrimType (Encoder.Unit encoding)
                        )
                     => encoding
                     -> UArray Word8
                     -> (String, Maybe ValidationFailure, UArray Word8)
    fromEncoderBytes :: forall encoding.
    (Encoding encoding, PrimType (Unit encoding)) =>
    encoding
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    fromEncoderBytes encoding
    enc UArray Word8
    bytes =
        case (forall s.
     ST
       s (Either (Offset (Unit encoding), Error encoding) (UArray Word8)))
    -> Either (Offset (Unit encoding), Error encoding) (UArray Word8)
    forall a. (forall s. ST s a) -> a
    runST ((forall s.
      ST
        s (Either (Offset (Unit encoding), Error encoding) (UArray Word8)))
     -> Either (Offset (Unit encoding), Error encoding) (UArray Word8))
    -> (forall s.
        ST
          s (Either (Offset (Unit encoding), Error encoding) (UArray Word8)))
    -> Either (Offset (Unit encoding), Error encoding) (UArray Word8)
    forall a b. (a -> b) -> a -> b
    $ encoding
    -> EncoderUTF8
    -> UArray (Unit encoding)
    -> ST
         s
         (Either
            (Offset (Unit encoding), Error encoding)
            (UArray (Unit EncoderUTF8)))
    forall (st :: * -> *) input output.
    (PrimMonad st, Monad st, Encoding input, PrimType (Unit input),
     Encoding output, PrimType (Unit output)) =>
    input
    -> output
    -> UArray (Unit input)
    -> st
         (Either (Offset (Unit input), Error input) (UArray (Unit output)))
    Encoder.convertFromTo encoding
    enc EncoderUTF8
    EncoderUTF8 (UArray Word8 -> UArray (Unit encoding)
    forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
    Vec.recast UArray Word8
    bytes) of
            -- TODO: Don't swallow up specific error (second element of pair)
            -- TODO: Confused why all this recasting is necessary. I "typed hole"-ed my way to get this function to compile.  Feels like there should be a cleaner method.
            Left (Offset (Unit encoding)
    off, Error encoding
    _) ->
                let (UArray (Unit encoding)
    b1, UArray (Unit encoding)
    b2) = CountOf (Unit encoding)
    -> UArray (Unit encoding)
    -> (UArray (Unit encoding), UArray (Unit encoding))
    forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
    Vec.splitAt (Offset (Unit encoding) -> CountOf (Unit encoding)
    forall a. Offset a -> CountOf a
    offsetAsSize Offset (Unit encoding)
    off) (UArray Word8 -> UArray (Unit encoding)
    forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
    Vec.recast UArray Word8
    bytes)
                in (UArray Word8 -> String
    String (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ UArray (Unit encoding) -> UArray Word8
    forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
    Vec.recast UArray (Unit encoding)
    b1, ValidationFailure -> Maybe ValidationFailure
    forall a. a -> Maybe a
    Just ValidationFailure
    BuildingFailure, UArray (Unit encoding) -> UArray Word8
    forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
    Vec.recast UArray (Unit encoding)
    b2)
            Right UArray Word8
    converted -> (UArray Word8 -> String
    String UArray Word8
    converted, Maybe ValidationFailure
    forall a. Maybe a
    Nothing, UArray Word8
    forall a. Monoid a => a
    mempty)

    -- | Convert a ByteArray to a string assuming a specific encoding.
    --
    -- It returns a 3-tuple of:
    --
    -- * The string that has been succesfully converted without any error
    -- * An optional validation error
    -- * The remaining buffer that hasn't been processed (either as a result of an error, or because the encoded sequence is not fully available)
    --
    -- Considering a stream of data that is fetched chunk by chunk, it's valid to assume
    -- that some sequence might fall in a chunk boundary. When converting chunks,
    -- if the error is Nothing and the remaining buffer is not empty, then this buffer
    -- need to be prepended to the next chunk
    fromBytes :: Encoding -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    fromBytes :: Encoding
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    fromBytes Encoding
    ASCII7     UArray Word8
    bytes = ASCII7
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    forall encoding.
    (Encoding encoding, PrimType (Unit encoding)) =>
    encoding
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    fromEncoderBytes ASCII7
    Encoder.ASCII7     UArray Word8
    bytes
    fromBytes Encoding
    ISO_8859_1 UArray Word8
    bytes = ISO_8859_1
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    forall encoding.
    (Encoding encoding, PrimType (Unit encoding)) =>
    encoding
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    fromEncoderBytes ISO_8859_1
    Encoder.ISO_8859_1 UArray Word8
    bytes
    fromBytes Encoding
    UTF16      UArray Word8
    bytes = UTF16
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    forall encoding.
    (Encoding encoding, PrimType (Unit encoding)) =>
    encoding
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    fromEncoderBytes UTF16
    Encoder.UTF16      UArray Word8
    bytes
    fromBytes Encoding
    UTF32      UArray Word8
    bytes = UTF32
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    forall encoding.
    (Encoding encoding, PrimType (Unit encoding)) =>
    encoding
    -> UArray Word8 -> (String, Maybe ValidationFailure, UArray Word8)
    fromEncoderBytes UTF32
    Encoder.UTF32      UArray Word8
    bytes
    fromBytes Encoding
    UTF8       UArray Word8
    bytes
        | UArray Word8 -> Bool
    forall ty. UArray ty -> Bool
    C.null UArray Word8
    bytes = (String
    forall a. Monoid a => a
    mempty, Maybe ValidationFailure
    forall a. Maybe a
    Nothing, UArray Word8
    forall a. Monoid a => a
    mempty)
        | Bool
    otherwise    =
            case UArray Word8
    -> Offset Word8
    -> CountOf Word8
    -> (Offset Word8, Maybe ValidationFailure)
    validate UArray Word8
    bytes (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) (UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    bytes) of
                (Offset Word8
    _, Maybe ValidationFailure
    Nothing)  -> (UArray Word8 -> String
    fromBytesUnsafe UArray Word8
    bytes, Maybe ValidationFailure
    forall a. Maybe a
    Nothing, UArray Word8
    forall a. Monoid a => a
    mempty)
                (Offset Word8
    pos, Just ValidationFailure
    vf) ->
                    let (UArray Word8
    b1, UArray Word8
    b2) = CountOf Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
    forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
    C.splitAt (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    pos) UArray Word8
    bytes
                     in (UArray Word8 -> String
    fromBytesUnsafe UArray Word8
    b1, ValidationFailure -> Maybe ValidationFailure
    toErr ValidationFailure
    vf, UArray Word8
    b2)
      where
        toErr :: ValidationFailure -> Maybe ValidationFailure
    toErr ValidationFailure
    MissingByte         = Maybe ValidationFailure
    forall a. Maybe a
    Nothing
        toErr ValidationFailure
    InvalidHeader       = ValidationFailure -> Maybe ValidationFailure
    forall a. a -> Maybe a
    Just ValidationFailure
    InvalidHeader
        toErr ValidationFailure
    InvalidContinuation = ValidationFailure -> Maybe ValidationFailure
    forall a. a -> Maybe a
    Just ValidationFailure
    InvalidContinuation
        toErr ValidationFailure
    BuildingFailure     = ValidationFailure -> Maybe ValidationFailure
    forall a. a -> Maybe a
    Just ValidationFailure
    BuildingFailure

    -- | Convert a UTF8 array of bytes to a String.
    --
    -- If there's any error in the stream, it will automatically
    -- insert replacement bytes to replace invalid sequences.
    --
    -- In the case of sequence that fall in the middle of 2 chunks,
    -- the remaining buffer is supposed to be preprended to the
    -- next chunk, and resume the parsing.
    fromBytesLenient :: UArray Word8 -> (String, UArray Word8)
    fromBytesLenient :: UArray Word8 -> (String, UArray Word8)
    fromBytesLenient UArray Word8
    bytes
        | UArray Word8 -> Bool
    forall ty. UArray ty -> Bool
    C.null UArray Word8
    bytes = (String
    forall a. Monoid a => a
    mempty, UArray Word8
    forall a. Monoid a => a
    mempty)
        | Bool
    otherwise    =
            case UArray Word8
    -> Offset Word8
    -> CountOf Word8
    -> (Offset Word8, Maybe ValidationFailure)
    validate UArray Word8
    bytes (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) (UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    bytes) of
                (Offset Word8
    _, Maybe ValidationFailure
    Nothing)                   -> (UArray Word8 -> String
    fromBytesUnsafe UArray Word8
    bytes, UArray Word8
    forall a. Monoid a => a
    mempty)
                -- TODO: Should anything be done in the 'BuildingFailure' case?
                (Offset Word8
    _, Just ValidationFailure
    BuildingFailure) -> [Char] -> (String, UArray Word8)
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "fromBytesLenient: FIXME!"
                (Offset Word8
    pos, Just ValidationFailure
    MissingByte) ->
                    let (UArray Word8
    b1,UArray Word8
    b2) = CountOf Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
    forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
    C.splitAt (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    pos) UArray Word8
    bytes
                     in (UArray Word8 -> String
    fromBytesUnsafe UArray Word8
    b1, UArray Word8
    b2)
                (Offset Word8
    pos, Just ValidationFailure
    InvalidHeader) ->
                    let (UArray Word8
    b1,UArray Word8
    b2) = CountOf Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
    forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
    C.splitAt (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    pos) UArray Word8
    bytes
                        (UArray Word8
    _,UArray Word8
    b3)  = CountOf Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
    forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
    C.splitAt CountOf Word8
    1 UArray Word8
    b2
                        (String
    s3, UArray Word8
    r) = UArray Word8 -> (String, UArray Word8)
    fromBytesLenient UArray Word8
    b3
                     in ([String] -> String
    forall a. Monoid a => [a] -> a
    mconcat [UArray Word8 -> String
    fromBytesUnsafe UArray Word8
    b1,String
    replacement, String
    s3], UArray Word8
    r)
                (Offset Word8
    pos, Just ValidationFailure
    InvalidContinuation) ->
                    let (UArray Word8
    b1,UArray Word8
    b2) = CountOf Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
    forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
    C.splitAt (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    pos) UArray Word8
    bytes
                        (UArray Word8
    _,UArray Word8
    b3)  = CountOf Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
    forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
    C.splitAt CountOf Word8
    1 UArray Word8
    b2
                        (String
    s3, UArray Word8
    r) = UArray Word8 -> (String, UArray Word8)
    fromBytesLenient UArray Word8
    b3
                     in ([String] -> String
    forall a. Monoid a => [a] -> a
    mconcat [UArray Word8 -> String
    fromBytesUnsafe UArray Word8
    b1,String
    replacement, String
    s3], UArray Word8
    r)
      where
        -- This is the replacement character U+FFFD used for any invalid header or continuation
        replacement :: String
        !replacement :: String
    replacement = UArray Word8 -> String
    fromBytesUnsafe (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ [Item (UArray Word8)] -> UArray Word8
    forall l. IsList l => [Item l] -> l
    fromList [Word8
    Item (UArray Word8)
    0xef,Word8
    Item (UArray Word8)
    0xbf,Word8
    Item (UArray Word8)
    0xbd]

    -- | Decode a stream of binary chunks containing UTF8 encoding in a list of valid String
    --
    -- Chunk not necessarily contains a valid string, as
    -- a UTF8 sequence could be split over 2 chunks.
    fromChunkBytes :: [UArray Word8] -> [String]
    fromChunkBytes :: [UArray Word8] -> [String]
    fromChunkBytes [UArray Word8]
    l = [UArray Word8] -> [String]
    loop [UArray Word8]
    l
      where
        loop :: [UArray Word8] -> [String]
    loop []         = []
        loop [UArray Word8
    bytes]    =
            case UArray Word8
    -> Offset Word8
    -> CountOf Word8
    -> (Offset Word8, Maybe ValidationFailure)
    validate UArray Word8
    bytes (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) (UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    bytes) of
                (Offset Word8
    _, Maybe ValidationFailure
    Nothing)  -> [UArray Word8 -> String
    fromBytesUnsafe UArray Word8
    bytes]
                (Offset Word8
    _, Just ValidationFailure
    err) -> ValidationFailure -> [String]
    forall {a} {a}. Show a => a -> a
    doErr ValidationFailure
    err
        loop (UArray Word8
    bytes:cs :: [UArray Word8]
    cs@(UArray Word8
    c1:[UArray Word8]
    c2)) =
            case UArray Word8
    -> Offset Word8
    -> CountOf Word8
    -> (Offset Word8, Maybe ValidationFailure)
    validate UArray Word8
    bytes (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) (UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    bytes) of
                (Offset Word8
    _, Maybe ValidationFailure
    Nothing) -> UArray Word8 -> String
    fromBytesUnsafe UArray Word8
    bytes String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : [UArray Word8] -> [String]
    loop [UArray Word8]
    cs
                (Offset Word8
    pos, Just ValidationFailure
    MissingByte) ->
                    let (UArray Word8
    b1,UArray Word8
    b2) = CountOf Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
    forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
    C.splitAt (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    pos) UArray Word8
    bytes
                     in UArray Word8 -> String
    fromBytesUnsafe UArray Word8
    b1 String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : [UArray Word8] -> [String]
    loop ((UArray Word8
    b2 UArray Word8 -> UArray Word8 -> UArray Word8
    forall a. Monoid a => a -> a -> a
    `mappend` UArray Word8
    c1) UArray Word8 -> [UArray Word8] -> [UArray Word8]
    forall a. a -> [a] -> [a]
    : [UArray Word8]
    c2)
                (Offset Word8
    _, Just ValidationFailure
    err) -> ValidationFailure -> [String]
    forall {a} {a}. Show a => a -> a
    doErr ValidationFailure
    err
        doErr :: a -> a
    doErr a
    err = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "fromChunkBytes: " [Char] -> [Char] -> [Char]
    forall a. Semigroup a => a -> a -> a
    <> a -> [Char]
    forall a. Show a => a -> [Char]
    show a
    err)

    -- | Convert a Byte Array representing UTF8 data directly to a string without checking for UTF8 validity
    --
    -- If the input contains invalid sequences, it will trigger runtime async errors when processing data.
    --
    -- In doubt, use 'fromBytes'
    fromBytesUnsafe :: UArray Word8 -> String
    fromBytesUnsafe :: UArray Word8 -> String
    fromBytesUnsafe = UArray Word8 -> String
    String

    toEncoderBytes :: ( Encoder.Encoding encoding
                      , PrimType (Encoder.Unit encoding)
                      , Exception (Encoder.Error encoding)
                      )
                   => encoding
                   -> UArray Word8
                   -> UArray Word8
    toEncoderBytes :: forall encoding.
    (Encoding encoding, PrimType (Unit encoding),
     Exception (Error encoding)) =>
    encoding -> UArray Word8 -> UArray Word8
    toEncoderBytes encoding
    enc UArray Word8
    bytes = UArray (Unit encoding) -> UArray Word8
    forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
    Vec.recast (UArray (Unit encoding) -> UArray Word8)
    -> UArray (Unit encoding) -> UArray Word8
    forall a b. (a -> b) -> a -> b
    $
      case (forall s.
     ST
       s
       (Either
          (Offset Word8, ValidationFailure) (UArray (Unit encoding))))
    -> Either
         (Offset Word8, ValidationFailure) (UArray (Unit encoding))
    forall a. (forall s. ST s a) -> a
    runST ((forall s.
      ST
        s
        (Either
           (Offset Word8, ValidationFailure) (UArray (Unit encoding))))
     -> Either
          (Offset Word8, ValidationFailure) (UArray (Unit encoding)))
    -> (forall s.
        ST
          s
          (Either
             (Offset Word8, ValidationFailure) (UArray (Unit encoding))))
    -> Either
         (Offset Word8, ValidationFailure) (UArray (Unit encoding))
    forall a b. (a -> b) -> a -> b
    $ EncoderUTF8
    -> encoding
    -> UArray (Unit EncoderUTF8)
    -> ST
         s
         (Either
            (Offset (Unit EncoderUTF8), Error EncoderUTF8)
            (UArray (Unit encoding)))
    forall (st :: * -> *) input output.
    (PrimMonad st, Monad st, Encoding input, PrimType (Unit input),
     Encoding output, PrimType (Unit output)) =>
    input
    -> output
    -> UArray (Unit input)
    -> st
         (Either (Offset (Unit input), Error input) (UArray (Unit output)))
    Encoder.convertFromTo EncoderUTF8
    EncoderUTF8 encoding
    enc UArray Word8
    UArray (Unit EncoderUTF8)
    bytes of
        Left (Offset Word8, ValidationFailure)
    _ -> [Char] -> UArray (Unit encoding)
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "toEncoderBytes: FIXME!"
        Right UArray (Unit encoding)
    converted -> UArray (Unit encoding)
    converted

    -- | Convert a String to a bytearray in a specific encoding
    --
    -- if the encoding is UTF8, the underlying buffer is returned without extra allocation or any processing
    --
    -- In any other encoding, some allocation and processing are done to convert.
    toBytes :: Encoding -> String -> UArray Word8
    toBytes :: Encoding -> String -> UArray Word8
    toBytes Encoding
    UTF8       (String UArray Word8
    bytes) = UArray Word8
    bytes
    toBytes Encoding
    ASCII7     (String UArray Word8
    bytes) = ASCII7 -> UArray Word8 -> UArray Word8
    forall encoding.
    (Encoding encoding, PrimType (Unit encoding),
     Exception (Error encoding)) =>
    encoding -> UArray Word8 -> UArray Word8
    toEncoderBytes ASCII7
    Encoder.ASCII7     UArray Word8
    bytes
    toBytes Encoding
    ISO_8859_1 (String UArray Word8
    bytes) = ISO_8859_1 -> UArray Word8 -> UArray Word8
    forall encoding.
    (Encoding encoding, PrimType (Unit encoding),
     Exception (Error encoding)) =>
    encoding -> UArray Word8 -> UArray Word8
    toEncoderBytes ISO_8859_1
    Encoder.ISO_8859_1 UArray Word8
    bytes
    toBytes Encoding
    UTF16      (String UArray Word8
    bytes) = UTF16 -> UArray Word8 -> UArray Word8
    forall encoding.
    (Encoding encoding, PrimType (Unit encoding),
     Exception (Error encoding)) =>
    encoding -> UArray Word8 -> UArray Word8
    toEncoderBytes UTF16
    Encoder.UTF16      UArray Word8
    bytes
    toBytes Encoding
    UTF32      (String UArray Word8
    bytes) = UTF32 -> UArray Word8 -> UArray Word8
    forall encoding.
    (Encoding encoding, PrimType (Unit encoding),
     Exception (Error encoding)) =>
    encoding -> UArray Word8 -> UArray Word8
    toEncoderBytes UTF32
    Encoder.UTF32      UArray Word8
    bytes

    -- | Split lines in a string using newline as separation.
    --
    -- Note that carriage return preceding a newline are also strip for
    -- maximum compatibility between Windows and Unix system.
    lines :: String -> [String]
    lines :: String -> [String]
    lines String
    s =
        case String -> Either Bool (String, String)
    breakLine String
    s of
            Left Bool
    _         -> [String
    s]
            Right (String
    line,String
    r) -> String
    line String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : String -> [String]
    lines String
    r

    -- | Split words in a string using spaces as separation
    --
    -- > words "Hello Foundation"
    -- [ "Hello", "Foundation" ]
    words :: String -> [String]
    words :: String -> [String]
    words = ([Char] -> String) -> [[Char]] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap [Char] -> String
    [Item String] -> String
    forall l. IsList l => [Item l] -> l
    fromList ([[Char]] -> [String])
    -> (String -> [[Char]]) -> String -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . [Char] -> [[Char]]
    Prelude.words ([Char] -> [[Char]]) -> (String -> [Char]) -> String -> [[Char]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . String -> [Char]
    String -> [Item String]
    forall l. IsList l => l -> [Item l]
    toList

    -- | Append a character to a String builder
    builderAppend :: PrimMonad state => Char -> Builder String MutableString Word8 state err ()
    builderAppend :: forall (state :: * -> *) err.
    PrimMonad state =>
    Char -> Builder String MutableString Word8 state err ()
    builderAppend Char
    c = State
      (Offset Word8,
       BuildingState String MutableString Word8 (PrimState state),
       Maybe err)
      state
      ()
    -> Builder String MutableString Word8 state err ()
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a.
    State
      (Offset step,
       BuildingState collection mutCollection step (PrimState state),
       Maybe err)
      state
      a
    -> Builder collection mutCollection step state err a
    Builder (State
       (Offset Word8,
        BuildingState String MutableString Word8 (PrimState state),
        Maybe err)
       state
       ()
     -> Builder String MutableString Word8 state err ())
    -> State
         (Offset Word8,
          BuildingState String MutableString Word8 (PrimState state),
          Maybe err)
         state
         ()
    -> Builder String MutableString Word8 state err ()
    forall a b. (a -> b) -> a -> b
    $ ((Offset Word8,
      BuildingState String MutableString Word8 (PrimState state),
      Maybe err)
     -> state
          ((),
           (Offset Word8,
            BuildingState String MutableString Word8 (PrimState state),
            Maybe err)))
    -> State
         (Offset Word8,
          BuildingState String MutableString Word8 (PrimState state),
          Maybe err)
         state
         ()
    forall s (m :: * -> *) a. (s -> m (a, s)) -> State s m a
    State (((Offset Word8,
       BuildingState String MutableString Word8 (PrimState state),
       Maybe err)
      -> state
           ((),
            (Offset Word8,
             BuildingState String MutableString Word8 (PrimState state),
             Maybe err)))
     -> State
          (Offset Word8,
           BuildingState String MutableString Word8 (PrimState state),
           Maybe err)
          state
          ())
    -> ((Offset Word8,
         BuildingState String MutableString Word8 (PrimState state),
         Maybe err)
        -> state
             ((),
              (Offset Word8,
               BuildingState String MutableString Word8 (PrimState state),
               Maybe err)))
    -> State
         (Offset Word8,
          BuildingState String MutableString Word8 (PrimState state),
          Maybe err)
         state
         ()
    forall a b. (a -> b) -> a -> b
    $ \(Offset Word8
    i, BuildingState String MutableString Word8 (PrimState state)
    st, Maybe err
    e) ->
        if Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    i CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    nbBytes CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    >= BuildingState String MutableString Word8 (PrimState state)
    -> CountOf Word8
    forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state -> CountOf step
    chunkSize BuildingState String MutableString Word8 (PrimState state)
    st
            then do
                String
    cur      <- MutableString (PrimState state) -> CountOf Word8 -> state String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> CountOf Word8 -> prim String
    unsafeFreezeShrink (BuildingState String MutableString Word8 (PrimState state)
    -> MutableString (PrimState state)
    forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state
    -> mutCollection state
    curChunk BuildingState String MutableString Word8 (PrimState state)
    st) (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    i)
                MutableString (PrimState state)
    newChunk <- CountOf Word8 -> state (MutableString (PrimState state))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> prim (MutableString (PrimState prim))
    new (BuildingState String MutableString Word8 (PrimState state)
    -> CountOf Word8
    forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state -> CountOf step
    chunkSize BuildingState String MutableString Word8 (PrimState state)
    st)
                MutableString (PrimState state)
    -> Offset Word8 -> UTF8Char -> state ()
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> UTF8Char -> prim ()
    writeUTF8Char MutableString (PrimState state)
    newChunk (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) UTF8Char
    utf8Char
                ((),
     (Offset Word8,
      BuildingState String MutableString Word8 (PrimState state),
      Maybe err))
    -> state
         ((),
          (Offset Word8,
           BuildingState String MutableString Word8 (PrimState state),
           Maybe err))
    forall a. a -> state a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((), (CountOf Word8 -> Offset Word8
    forall a. CountOf a -> Offset a
    sizeAsOffset CountOf Word8
    nbBytes, BuildingState String MutableString Word8 (PrimState state)
    st { prevChunks :: [String]
    prevChunks     = String
    cur String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : BuildingState String MutableString Word8 (PrimState state)
    -> [String]
    forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state -> [collection]
    prevChunks BuildingState String MutableString Word8 (PrimState state)
    st
                                                      , prevChunksSize :: CountOf Word8
    prevChunksSize = Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    i CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + BuildingState String MutableString Word8 (PrimState state)
    -> CountOf Word8
    forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state -> CountOf step
    prevChunksSize BuildingState String MutableString Word8 (PrimState state)
    st
                                                      , curChunk :: MutableString (PrimState state)
    curChunk       = MutableString (PrimState state)
    newChunk
                                                      }, Maybe err
    e))
            else do
                MutableString (PrimState state)
    -> Offset Word8 -> UTF8Char -> state ()
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim)
    -> Offset Word8 -> UTF8Char -> prim ()
    writeUTF8Char (BuildingState String MutableString Word8 (PrimState state)
    -> MutableString (PrimState state)
    forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state
    -> mutCollection state
    curChunk BuildingState String MutableString Word8 (PrimState state)
    st) Offset Word8
    i UTF8Char
    utf8Char
                ((),
     (Offset Word8,
      BuildingState String MutableString Word8 (PrimState state),
      Maybe err))
    -> state
         ((),
          (Offset Word8,
           BuildingState String MutableString Word8 (PrimState state),
           Maybe err))
    forall a. a -> state a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((), (Offset Word8
    i Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8 -> Offset Word8
    forall a. CountOf a -> Offset a
    sizeAsOffset CountOf Word8
    nbBytes, BuildingState String MutableString Word8 (PrimState state)
    st, Maybe err
    e))
      where
        utf8Char :: UTF8Char
    utf8Char = Char -> UTF8Char
    asUTF8Char Char
    c
        nbBytes :: CountOf Word8
    nbBytes  = UTF8Char -> CountOf Word8
    numBytes UTF8Char
    utf8Char

    -- | Create a new String builder using chunks of @sizeChunksI@
    builderBuild :: PrimMonad m => Int -> Builder String MutableString Word8 m err () -> m (Either err String)
    builderBuild :: forall (m :: * -> *) err.
    PrimMonad m =>
    Int
    -> Builder String MutableString Word8 m err ()
    -> m (Either err String)
    builderBuild Int
    sizeChunksI Builder String MutableString Word8 m err ()
    sb
        | Int
    sizeChunksI Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int
    3 = Int
    -> Builder String MutableString Word8 m err ()
    -> m (Either err String)
    forall (m :: * -> *) err.
    PrimMonad m =>
    Int
    -> Builder String MutableString Word8 m err ()
    -> m (Either err String)
    builderBuild Int
    64 Builder String MutableString Word8 m err ()
    sb
        | Bool
    otherwise        = do
            MutableString (PrimState m)
    firstChunk <- CountOf Word8 -> m (MutableString (PrimState m))
    forall (prim :: * -> *).
    PrimMonad prim =>
    CountOf Word8 -> prim (MutableString (PrimState prim))
    new CountOf Word8
    sizeChunks
            (Offset Word8
    i, BuildingState String MutableString Word8 (PrimState m)
    st, Maybe err
    e) <- ((),
     (Offset Word8,
      BuildingState String MutableString Word8 (PrimState m), Maybe err))
    -> (Offset Word8,
        BuildingState String MutableString Word8 (PrimState m), Maybe err)
    forall a b. (a, b) -> b
    snd (((),
      (Offset Word8,
       BuildingState String MutableString Word8 (PrimState m), Maybe err))
     -> (Offset Word8,
         BuildingState String MutableString Word8 (PrimState m), Maybe err))
    -> m ((),
          (Offset Word8,
           BuildingState String MutableString Word8 (PrimState m), Maybe err))
    -> m (Offset Word8,
          BuildingState String MutableString Word8 (PrimState m), Maybe err)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> State
      (Offset Word8,
       BuildingState String MutableString Word8 (PrimState m), Maybe err)
      m
      ()
    -> (Offset Word8,
        BuildingState String MutableString Word8 (PrimState m), Maybe err)
    -> m ((),
          (Offset Word8,
           BuildingState String MutableString Word8 (PrimState m), Maybe err))
    forall s (m :: * -> *) a. State s m a -> s -> m (a, s)
    runState (Builder String MutableString Word8 m err ()
    -> State
         (Offset Word8,
          BuildingState String MutableString Word8 (PrimState m), Maybe err)
         m
         ()
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a.
    Builder collection mutCollection step state err a
    -> State
         (Offset step,
          BuildingState collection mutCollection step (PrimState state),
          Maybe err)
         state
         a
    runBuilder Builder String MutableString Word8 m err ()
    sb) (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0, [String]
    -> CountOf Word8
    -> MutableString (PrimState m)
    -> CountOf Word8
    -> BuildingState String MutableString Word8 (PrimState m)
    forall collection (mutCollection :: * -> *) step state.
    [collection]
    -> CountOf step
    -> mutCollection state
    -> CountOf step
    -> BuildingState collection mutCollection step state
    BuildingState [] (Int -> CountOf Word8
    forall ty. Int -> CountOf ty
    CountOf Int
    0) MutableString (PrimState m)
    firstChunk CountOf Word8
    sizeChunks, Maybe err
    forall a. Maybe a
    Nothing)
            case Maybe err
    e of
              Just err
    err -> Either err String -> m (Either err String)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (err -> Either err String
    forall a b. a -> Either a b
    Left err
    err)
              Maybe err
    Nothing -> do
                String
    cur <- MutableString (PrimState m) -> CountOf Word8 -> m String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> CountOf Word8 -> prim String
    unsafeFreezeShrink (BuildingState String MutableString Word8 (PrimState m)
    -> MutableString (PrimState m)
    forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state
    -> mutCollection state
    curChunk BuildingState String MutableString Word8 (PrimState m)
    st) (Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    i)
                -- Build final array
                let totalSize :: CountOf Word8
    totalSize = BuildingState String MutableString Word8 (PrimState m)
    -> CountOf Word8
    forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state -> CountOf step
    prevChunksSize BuildingState String MutableString Word8 (PrimState m)
    st CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8 -> CountOf Word8
    forall a. Offset a -> CountOf a
    offsetAsSize Offset Word8
    i
                UArray Word8
    final <- CountOf Word8 -> m (MUArray Word8 (PrimState m))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MUArray ty (PrimState prim))
    Vec.new CountOf Word8
    totalSize m (MUArray Word8 (PrimState m))
    -> (MUArray Word8 (PrimState m) -> m (MUArray Word8 (PrimState m)))
    -> m (MUArray Word8 (PrimState m))
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= CountOf Word8
    -> [String]
    -> MUArray Word8 (PrimState m)
    -> m (MUArray Word8 (PrimState m))
    forall {m :: * -> *}.
    PrimMonad m =>
    CountOf Word8
    -> [String]
    -> MUArray Word8 (PrimState m)
    -> m (MUArray Word8 (PrimState m))
    fillFromEnd CountOf Word8
    totalSize (String
    cur String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    : BuildingState String MutableString Word8 (PrimState m) -> [String]
    forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state -> [collection]
    prevChunks BuildingState String MutableString Word8 (PrimState m)
    st) m (MUArray Word8 (PrimState m))
    -> (MUArray Word8 (PrimState m) -> m (UArray Word8))
    -> m (UArray Word8)
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= MUArray Word8 (PrimState m) -> m (UArray Word8)
    forall (prim :: * -> *) ty.
    PrimMonad prim =>
    MUArray ty (PrimState prim) -> prim (UArray ty)
    Vec.unsafeFreeze
                Either err String -> m (Either err String)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Either err String -> m (Either err String))
    -> (UArray Word8 -> Either err String)
    -> UArray Word8
    -> m (Either err String)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . String -> Either err String
    forall a b. b -> Either a b
    Right (String -> Either err String)
    -> (UArray Word8 -> String) -> UArray Word8 -> Either err String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . UArray Word8 -> String
    String (UArray Word8 -> m (Either err String))
    -> UArray Word8 -> m (Either err String)
    forall a b. (a -> b) -> a -> b
    $ UArray Word8
    final
      where
        sizeChunks :: CountOf Word8
    sizeChunks = Int -> CountOf Word8
    forall ty. Int -> CountOf ty
    CountOf Int
    sizeChunksI

        fillFromEnd :: CountOf Word8
    -> [String]
    -> MUArray Word8 (PrimState m)
    -> m (MUArray Word8 (PrimState m))
    fillFromEnd CountOf Word8
    _    []            MUArray Word8 (PrimState m)
    mba = MUArray Word8 (PrimState m) -> m (MUArray Word8 (PrimState m))
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return MUArray Word8 (PrimState m)
    mba
        fillFromEnd !CountOf Word8
    end (String UArray Word8
    x:[String]
    xs) MUArray Word8 (PrimState m)
    mba = do
            let sz :: CountOf Word8
    sz = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    Vec.length UArray Word8
    x
            let start :: CountOf Word8
    start = CountOf Word8
    end CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. CountOf a -> CountOf a -> CountOf a
    `sizeSub` CountOf Word8
    sz
            MUArray Word8 (PrimState m)
    -> Offset Word8
    -> UArray Word8
    -> Offset Word8
    -> CountOf Word8
    -> m ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MUArray ty (PrimState prim)
    -> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
    Vec.unsafeCopyAtRO MUArray Word8 (PrimState m)
    mba (CountOf Word8 -> Offset Word8
    forall a. CountOf a -> Offset a
    sizeAsOffset CountOf Word8
    start) UArray Word8
    x (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) CountOf Word8
    sz
            CountOf Word8
    -> [String]
    -> MUArray Word8 (PrimState m)
    -> m (MUArray Word8 (PrimState m))
    fillFromEnd CountOf Word8
    start [String]
    xs MUArray Word8 (PrimState m)
    mba

    builderBuild_ :: PrimMonad m => Int -> Builder String MutableString Word8 m () () -> m String
    builderBuild_ :: forall (m :: * -> *).
    PrimMonad m =>
    Int -> Builder String MutableString Word8 m () () -> m String
    builderBuild_ Int
    sizeChunksI Builder String MutableString Word8 m () ()
    sb = (() -> String) -> (String -> String) -> Either () String -> String
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either (\() -> [Char] -> String
    forall a. [Char] -> a
    internalError [Char]
    "impossible output") String -> String
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id (Either () String -> String) -> m (Either () String) -> m String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int
    -> Builder String MutableString Word8 m () ()
    -> m (Either () String)
    forall (m :: * -> *) err.
    PrimMonad m =>
    Int
    -> Builder String MutableString Word8 m err ()
    -> m (Either err String)
    builderBuild Int
    sizeChunksI Builder String MutableString Word8 m () ()
    sb

    stringDewrap :: (Block Word8 -> Offset Word8 -> a)
                 -> (Ptr Word8 -> Offset Word8 -> ST s a)
                 -> String
                 -> a
    stringDewrap :: forall a s.
    (Block Word8 -> Offset Word8 -> a)
    -> (Ptr Word8 -> Offset Word8 -> ST s a) -> String -> a
    stringDewrap Block Word8 -> Offset Word8 -> a
    withBa Ptr Word8 -> Offset Word8 -> ST s a
    withPtr (String UArray Word8
    ba) = (Block Word8 -> Offset Word8 -> a)
    -> (Ptr Word8 -> Offset Word8 -> ST s a) -> UArray Word8 -> a
    forall ty a s.
    (Block ty -> Offset ty -> a)
    -> (Ptr ty -> Offset ty -> ST s a) -> UArray ty -> a
    C.unsafeDewrap Block Word8 -> Offset Word8 -> a
    withBa Ptr Word8 -> Offset Word8 -> ST s a
    withPtr UArray Word8
    ba
    {-# INLINE stringDewrap #-}

    -- | Read an Integer from a String
    --
    -- Consume an optional minus sign and many digits until end of string.
    readIntegral :: (HasNegation i, IntegralUpsize Word8 i, Additive i, Multiplicative i, IsIntegral i) => String -> Maybe i
    readIntegral :: forall i.
    (HasNegation i, IntegralUpsize Word8 i, Additive i,
     Multiplicative i, IsIntegral i) =>
    String -> Maybe i
    readIntegral String
    str
        | CountOf Word8
    sz CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf Word8
    0   = Maybe i
    forall a. Maybe a
    Nothing
        | Bool
    otherwise = (Block Word8 -> Offset Word8 -> Maybe i)
    -> (Ptr Word8 -> Offset Word8 -> ST Any (Maybe i))
    -> String
    -> Maybe i
    forall a s.
    (Block Word8 -> Offset Word8 -> a)
    -> (Ptr Word8 -> Offset Word8 -> ST s a) -> String -> a
    stringDewrap Block Word8 -> Offset Word8 -> Maybe i
    withBa (\ptr :: Ptr Word8
    ptr@(Ptr !Addr#
    _) -> Maybe i -> ST Any (Maybe i)
    forall a. a -> ST Any a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe i -> ST Any (Maybe i))
    -> (Offset Word8 -> Maybe i) -> Offset Word8 -> ST Any (Maybe i)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Ptr Word8 -> Offset Word8 -> Maybe i
    withPtr Ptr Word8
    ptr) String
    str
      where
        !sz :: CountOf Word8
    sz = String -> CountOf Word8
    size String
    str
        withBa :: Block Word8 -> Offset Word8 -> Maybe i
    withBa Block Word8
    ba Offset Word8
    ofs =
            let negativeSign :: Bool
    negativeSign = Block Word8 -> Offset Word8 -> Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> Word8 -> Bool
    UTF8.expectAscii Block Word8
    ba Offset Word8
    ofs Word8
    0x2d
                startOfs :: Offset Word8
    startOfs     = if Bool
    negativeSign then Offset Word8 -> Offset Word8
    forall a. Enum a => a -> a
    succ Offset Word8
    ofs else Offset Word8
    ofs
             in case i
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# i, Bool, Offset Word8 #)
    forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsBA i
    0 Block Word8
    ba Offset Word8
    endOfs Offset Word8
    startOfs of
                    (# i
    acc, Bool
    True, Offset Word8
    endOfs' #) | Offset Word8
    endOfs' Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    startOfs -> i -> Maybe i
    forall a. a -> Maybe a
    Just (i -> Maybe i) -> i -> Maybe i
    forall a b. (a -> b) -> a -> b
    $! if Bool
    negativeSign then i -> i
    forall a. HasNegation a => a -> a
    negate i
    acc else i
    acc
                    (# i, Bool, Offset Word8 #)
    _                                             -> Maybe i
    forall a. Maybe a
    Nothing
          where !endOfs :: Offset Word8
    endOfs = Offset Word8
    ofs Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz
        withPtr :: Ptr Word8 -> Offset Word8 -> Maybe i
    withPtr Ptr Word8
    addr Offset Word8
    ofs =
            let negativeSign :: Bool
    negativeSign = Ptr Word8 -> Offset Word8 -> Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> Word8 -> Bool
    UTF8.expectAscii Ptr Word8
    addr Offset Word8
    ofs Word8
    0x2d
                startOfs :: Offset Word8
    startOfs     = if Bool
    negativeSign then Offset Word8 -> Offset Word8
    forall a. Enum a => a -> a
    succ Offset Word8
    ofs else Offset Word8
    ofs
             in case i
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# i, Bool, Offset Word8 #)
    forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsPtr i
    0 Ptr Word8
    addr Offset Word8
    endOfs Offset Word8
    startOfs of
                    (# i
    acc, Bool
    True, Offset Word8
    endOfs' #) | Offset Word8
    endOfs' Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    startOfs -> i -> Maybe i
    forall a. a -> Maybe a
    Just (i -> Maybe i) -> i -> Maybe i
    forall a b. (a -> b) -> a -> b
    $! if Bool
    negativeSign then i -> i
    forall a. HasNegation a => a -> a
    negate i
    acc else i
    acc
                    (# i, Bool, Offset Word8 #)
    _                                             -> Maybe i
    forall a. Maybe a
    Nothing
          where !endOfs :: Offset Word8
    endOfs = Offset Word8
    ofs Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz
    {-# SPECIALISE readIntegral :: String -> Maybe Integer #-}
    {-# SPECIALISE readIntegral :: String -> Maybe Int #-}

    readInteger :: String -> Maybe Integer
    readInteger :: String -> Maybe Integer
    readInteger = String -> Maybe Integer
    forall i.
    (HasNegation i, IntegralUpsize Word8 i, Additive i,
     Multiplicative i, IsIntegral i) =>
    String -> Maybe i
    readIntegral

    -- | Read a Natural from a String
    --
    -- Consume many digits until end of string.
    readNatural :: String -> Maybe Natural
    readNatural :: String -> Maybe Natural
    readNatural String
    str
        | CountOf Word8
    sz CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf Word8
    0   = Maybe Natural
    forall a. Maybe a
    Nothing
        | Bool
    otherwise = (Block Word8 -> Offset Word8 -> Maybe Natural)
    -> (Ptr Word8 -> Offset Word8 -> ST Any (Maybe Natural))
    -> String
    -> Maybe Natural
    forall a s.
    (Block Word8 -> Offset Word8 -> a)
    -> (Ptr Word8 -> Offset Word8 -> ST s a) -> String -> a
    stringDewrap Block Word8 -> Offset Word8 -> Maybe Natural
    withBa (\ptr :: Ptr Word8
    ptr@(Ptr !Addr#
    _) -> Maybe Natural -> ST Any (Maybe Natural)
    forall a. a -> ST Any a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe Natural -> ST Any (Maybe Natural))
    -> (Offset Word8 -> Maybe Natural)
    -> Offset Word8
    -> ST Any (Maybe Natural)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Ptr Word8 -> Offset Word8 -> Maybe Natural
    withPtr Ptr Word8
    ptr) String
    str
      where
        !sz :: CountOf Word8
    sz = String -> CountOf Word8
    size String
    str
        withBa :: Block Word8 -> Offset Word8 -> Maybe Natural
    withBa Block Word8
    ba Offset Word8
    stringStart =
            case Natural
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# Natural, Bool, Offset Word8 #)
    forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsBA Natural
    0 Block Word8
    ba Offset Word8
    eofs Offset Word8
    stringStart of
                (# Natural
    acc, Bool
    True, Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    stringStart -> Natural -> Maybe Natural
    forall a. a -> Maybe a
    Just Natural
    acc
                (# Natural, Bool, Offset Word8 #)
    _                                              -> Maybe Natural
    forall a. Maybe a
    Nothing
          where eofs :: Offset Word8
    eofs = Offset Word8
    stringStart Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz
        withPtr :: Ptr Word8 -> Offset Word8 -> Maybe Natural
    withPtr Ptr Word8
    addr Offset Word8
    stringStart =
            case Natural
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# Natural, Bool, Offset Word8 #)
    forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsPtr Natural
    0 Ptr Word8
    addr Offset Word8
    eofs Offset Word8
    stringStart of
                (# Natural
    acc, Bool
    True, Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    stringStart -> Natural -> Maybe Natural
    forall a. a -> Maybe a
    Just Natural
    acc
                (# Natural, Bool, Offset Word8 #)
    _                                              -> Maybe Natural
    forall a. Maybe a
    Nothing
          where eofs :: Offset Word8
    eofs = Offset Word8
    stringStart Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz

    -- | Try to read a Double
    readDouble :: String -> Maybe Double
    readDouble :: String -> Maybe Double
    readDouble String
    s =
        String -> ReadFloatingCallback Double -> Maybe Double
    forall a. String -> ReadFloatingCallback a -> Maybe a
    readFloatingExact String
    s (ReadFloatingCallback Double -> Maybe Double)
    -> ReadFloatingCallback Double -> Maybe Double
    forall a b. (a -> b) -> a -> b
    $ \Bool
    isNegative Natural
    integral Word
    floatingDigits Maybe Int
    mExponant ->
            Double -> Maybe Double
    forall a. a -> Maybe a
    Just (Double -> Maybe Double) -> Double -> Maybe Double
    forall a b. (a -> b) -> a -> b
    $ Bool -> Double -> Double
    forall {a}. HasNegation a => Bool -> a -> a
    applySign Bool
    isNegative (Double -> Double) -> Double -> Double
    forall a b. (a -> b) -> a -> b
    $ case (Word
    floatingDigits, Maybe Int
    mExponant) of
                (Word
    0, Maybe Int
    Nothing)              ->                         Natural -> Double
    naturalToDouble Natural
    integral
                (Word
    0, Just Int
    exponent)        -> Int -> Double -> Double
    withExponant Int
    exponent (Double -> Double) -> Double -> Double
    forall a b. (a -> b) -> a -> b
    $ Natural -> Double
    naturalToDouble Natural
    integral
                (Word
    floating, Maybe Int
    Nothing)       ->                         Word -> Double -> Double
    forall {a} {b}.
    (Divisible a, Integral b, Integral a, Num a) =>
    b -> a -> a
    applyFloating Word
    floating (Double -> Double) -> Double -> Double
    forall a b. (a -> b) -> a -> b
    $ Natural -> Double
    naturalToDouble Natural
    integral
                (Word
    floating, Just Int
    exponent) -> Int -> Double -> Double
    withExponant Int
    exponent (Double -> Double) -> Double -> Double
    forall a b. (a -> b) -> a -> b
    $ Word -> Double -> Double
    forall {a} {b}.
    (Divisible a, Integral b, Integral a, Num a) =>
    b -> a -> a
    applyFloating Word
    floating (Double -> Double) -> Double -> Double
    forall a b. (a -> b) -> a -> b
    $ Natural -> Double
    naturalToDouble Natural
    integral
      where
        applySign :: Bool -> a -> a
    applySign Bool
    True = a -> a
    forall a. HasNegation a => a -> a
    negate
        applySign Bool
    False = a -> a
    forall a. a -> a
    forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
    id
        withExponant :: Int -> Double -> Double
    withExponant Int
    e Double
    v = Double
    v Double -> Double -> Double
    forall a. Multiplicative a => a -> a -> a
    * Double -> Int -> Double
    doubleExponant Double
    10 Int
    e
        applyFloating :: b -> a -> a
    applyFloating b
    digits a
    n = a
    n a -> a -> a
    forall a. Divisible a => a -> a -> a
    / (a
    10 a -> b -> a
    forall a b. (Num a, Integral b) => a -> b -> a
    Prelude.^ b
    digits)

    -- | Try to read a floating number as a Rational
    --
    -- Note that for safety reason, only exponent between -10000 and 10000 is allowed
    -- as otherwise DoS/OOM is very likely. if you don't want this behavior,
    -- switching to a scientific type (not provided yet) that represent the
    -- exponent separately is the advised solution.
    readRational :: String -> Maybe Prelude.Rational
    readRational :: String -> Maybe Rational
    readRational String
    s =
        String -> ReadFloatingCallback Rational -> Maybe Rational
    forall a. String -> ReadFloatingCallback a -> Maybe a
    readFloatingExact String
    s (ReadFloatingCallback Rational -> Maybe Rational)
    -> ReadFloatingCallback Rational -> Maybe Rational
    forall a b. (a -> b) -> a -> b
    $ \Bool
    isNegative Natural
    integral Word
    floatingDigits Maybe Int
    mExponant ->
            case Maybe Int
    mExponant of
                Just Int
    exponent
                    | Int
    exponent Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < -Int
    10000 Bool -> Bool -> Bool
    || Int
    exponent Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    10000 -> Maybe Rational
    forall a. Maybe a
    Nothing
                    | Bool
    otherwise                             -> Rational -> Maybe Rational
    forall a. a -> Maybe a
    Just (Rational -> Maybe Rational) -> Rational -> Maybe Rational
    forall a b. (a -> b) -> a -> b
    $ Bool -> Natural -> Integer
    forall {b} {a}.
    (HasNegation b, IntegralUpsize a b) =>
    Bool -> a -> b
    modF Bool
    isNegative Natural
    integral Integer -> Integer -> Rational
    forall a. Integral a => a -> a -> Ratio a
    % (Integer
    10 Integer -> Int -> Integer
    forall a b. (Num a, Integral b) => a -> b -> a
    Prelude.^ (Word -> Int
    forall source destination.
    Cast source destination =>
    source -> destination
    cast Word
    floatingDigits Int -> Int -> Difference Int
    forall a. Subtractive a => a -> a -> Difference a
    - Int
    exponent))
                Maybe Int
    Nothing                                     -> Rational -> Maybe Rational
    forall a. a -> Maybe a
    Just (Rational -> Maybe Rational) -> Rational -> Maybe Rational
    forall a b. (a -> b) -> a -> b
    $ Bool -> Natural -> Integer
    forall {b} {a}.
    (HasNegation b, IntegralUpsize a b) =>
    Bool -> a -> b
    modF Bool
    isNegative Natural
    integral Integer -> Integer -> Rational
    forall a. Integral a => a -> a -> Ratio a
    % (Integer
    10 Integer -> Word -> Integer
    forall a b. (Num a, Integral b) => a -> b -> a
    Prelude.^ Word
    floatingDigits)
      where
        modF :: Bool -> a -> b
    modF Bool
    True  = b -> b
    forall a. HasNegation a => a -> a
    negate (b -> b) -> (a -> b) -> a -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . a -> b
    forall a b. IntegralUpsize a b => a -> b
    integralUpsize
        modF Bool
    False = a -> b
    forall a b. IntegralUpsize a b => a -> b
    integralUpsize

    type ReadFloatingCallback a = Bool      -- sign
                               -> Natural   -- integral part
                               -> Word      -- number of digits in floating section
                               -> Maybe Int -- optional integer representing exponent in base 10
                               -> Maybe a

    -- | Read an Floating like number of the form:
    --
    --   [ '-' ] <numbers> [ '.' <numbers> ] [ ( 'e' | 'E' ) [ '-' ] <number> ]
    --
    -- Call a function with:
    --
    -- * A boolean representing if the number is negative
    -- * The digits part represented as a single natural number (123.456 is represented as 123456)
    -- * The number of digits in the fractional part (e.g. 123.456 => 3)
    -- * The exponent if any
    --
    -- The code is structured as a simple state machine that:
    --
    -- * Optionally Consume a '-' sign
    -- * Consume number for the integral part
    -- * Optionally
    --   * Consume '.'
    --   * Consume remaining digits if not already end of string
    -- * Optionally Consume a 'e' or 'E' follow by an optional '-' and a number
    --
    readFloatingExact :: String -> ReadFloatingCallback a -> Maybe a
    readFloatingExact :: forall a. String -> ReadFloatingCallback a -> Maybe a
    readFloatingExact String
    str ReadFloatingCallback a
    f
        | CountOf Word8
    sz CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf Word8
    0   = Maybe a
    forall a. Maybe a
    Nothing
        | Bool
    otherwise = (Block Word8 -> Offset Word8 -> Maybe a)
    -> (Ptr Word8 -> Offset Word8 -> ST Any (Maybe a))
    -> String
    -> Maybe a
    forall a s.
    (Block Word8 -> Offset Word8 -> a)
    -> (Ptr Word8 -> Offset Word8 -> ST s a) -> String -> a
    stringDewrap Block Word8 -> Offset Word8 -> Maybe a
    withBa Ptr Word8 -> Offset Word8 -> ST Any (Maybe a)
    withPtr String
    str
      where
        !sz :: CountOf Word8
    sz = String -> CountOf Word8
    size String
    str

        withBa :: Block Word8 -> Offset Word8 -> Maybe a
    withBa Block Word8
    ba Offset Word8
    stringStart =
            let !isNegative :: Bool
    isNegative = Block Word8 -> Offset Word8 -> Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> Word8 -> Bool
    UTF8.expectAscii Block Word8
    ba Offset Word8
    stringStart Word8
    0x2d
             in Bool -> Offset Word8 -> Maybe a
    consumeIntegral Bool
    isNegative (if Bool
    isNegative then Offset Word8
    stringStartOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    1 else Offset Word8
    stringStart)
          where
            eofs :: Offset Word8
    eofs = Offset Word8
    stringStart Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz
            consumeIntegral :: Bool -> Offset Word8 -> Maybe a
    consumeIntegral !Bool
    isNegative Offset Word8
    startOfs =
                case Natural
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# Natural, Bool, Offset Word8 #)
    forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsBA Natural
    0 Block Word8
    ba Offset Word8
    eofs Offset Word8
    startOfs of
                    (# Natural
    acc, Bool
    True , Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    startOfs -> ReadFloatingCallback a
    f Bool
    isNegative Natural
    acc Word
    0 Maybe Int
    forall a. Maybe a
    Nothing -- end of stream and no '.'
                    (# Natural
    acc, Bool
    False, Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    startOfs ->
                        if Block Word8 -> Offset Word8 -> Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> Word8 -> Bool
    UTF8.expectAscii Block Word8
    ba Offset Word8
    endOfs Word8
    0x2e
                            then Bool -> Natural -> Offset Word8 -> Maybe a
    consumeFloat Bool
    isNegative Natural
    acc (Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1)
                            else Bool -> Natural -> Word -> Offset Word8 -> Maybe a
    consumeExponant Bool
    isNegative Natural
    acc Word
    0 Offset Word8
    endOfs
                    (# Natural, Bool, Offset Word8 #)
    _                                            -> Maybe a
    forall a. Maybe a
    Nothing

            consumeFloat :: Bool -> Natural -> Offset Word8 -> Maybe a
    consumeFloat Bool
    isNegative Natural
    integral Offset Word8
    startOfs =
                case Natural
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# Natural, Bool, Offset Word8 #)
    forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsBA Natural
    integral Block Word8
    ba Offset Word8
    eofs Offset Word8
    startOfs of
                    (# Natural
    acc, Bool
    True, Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    startOfs -> let (CountOf !Int
    diff) = Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Difference (Offset Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - Offset Word8
    startOfs
                                                                    in ReadFloatingCallback a
    f Bool
    isNegative Natural
    acc (Int -> Word
    forall source destination.
    Cast source destination =>
    source -> destination
    cast Int
    diff) Maybe Int
    forall a. Maybe a
    Nothing
                    (# Natural
    acc, Bool
    False, Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    startOfs -> let (CountOf !Int
    diff) = Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Difference (Offset Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - Offset Word8
    startOfs
                                                                    in Bool -> Natural -> Word -> Offset Word8 -> Maybe a
    consumeExponant Bool
    isNegative Natural
    acc (Int -> Word
    forall source destination.
    Cast source destination =>
    source -> destination
    cast Int
    diff) Offset Word8
    endOfs
                    (# Natural, Bool, Offset Word8 #)
    _                                           -> Maybe a
    forall a. Maybe a
    Nothing

            consumeExponant :: Bool -> Natural -> Word -> Offset Word8 -> Maybe a
    consumeExponant !Bool
    isNegative !Natural
    integral !Word
    floatingDigits !Offset Word8
    startOfs
                | Offset Word8
    startOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    eofs = ReadFloatingCallback a
    f Bool
    isNegative Natural
    integral Word
    floatingDigits Maybe Int
    forall a. Maybe a
    Nothing
                | Bool
    otherwise        =
                    -- consume 'E' or 'e'
                    case Block Word8 -> Offset Word8 -> StepASCII
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> StepASCII
    UTF8.nextAscii Block Word8
    ba Offset Word8
    startOfs of
                        StepASCII Word8
    0x45 -> Offset Word8 -> Maybe a
    consumeExponantSign (Offset Word8
    startOfsOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    1)
                        StepASCII Word8
    0x65 -> Offset Word8 -> Maybe a
    consumeExponantSign (Offset Word8
    startOfsOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    1)
                        StepASCII
    _              -> Maybe a
    forall a. Maybe a
    Nothing
              where
                consumeExponantSign :: Offset Word8 -> Maybe a
    consumeExponantSign Offset Word8
    ofs
                    | Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    eofs = Maybe a
    forall a. Maybe a
    Nothing
                    | Bool
    otherwise   = let exponentNegative :: Bool
    exponentNegative = Block Word8 -> Offset Word8 -> Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> Word8 -> Bool
    UTF8.expectAscii Block Word8
    ba Offset Word8
    ofs Word8
    0x2d
                                     in Bool -> Offset Word8 -> Maybe a
    consumeExponantNumber Bool
    exponentNegative (if Bool
    exponentNegative then Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1 else Offset Word8
    ofs)

                consumeExponantNumber :: Bool -> Offset Word8 -> Maybe a
    consumeExponantNumber Bool
    exponentNegative Offset Word8
    ofs =
                    case Int
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# Int, Bool, Offset Word8 #)
    forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsBA Int
    0 Block Word8
    ba Offset Word8
    eofs Offset Word8
    ofs of
                        (# Int
    acc, Bool
    True, Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    ofs -> ReadFloatingCallback a
    f Bool
    isNegative Natural
    integral Word
    floatingDigits (Int -> Maybe Int
    forall a. a -> Maybe a
    Just (Int -> Maybe Int) -> Int -> Maybe Int
    forall a b. (a -> b) -> a -> b
    $! if Bool
    exponentNegative then Int -> Int
    forall a. HasNegation a => a -> a
    negate Int
    acc else Int
    acc)
                        (# Int, Bool, Offset Word8 #)
    _                                      -> Maybe a
    forall a. Maybe a
    Nothing
        withPtr :: Ptr Word8 -> Offset Word8 -> ST Any (Maybe a)
    withPtr ptr :: Ptr Word8
    ptr@(Ptr !Addr#
    _) Offset Word8
    stringStart = Maybe a -> ST Any (Maybe a)
    forall a. a -> ST Any a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Maybe a -> ST Any (Maybe a)) -> Maybe a -> ST Any (Maybe a)
    forall a b. (a -> b) -> a -> b
    $
            let !isNegative :: Bool
    isNegative = Ptr Word8 -> Offset Word8 -> Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> Word8 -> Bool
    UTF8.expectAscii Ptr Word8
    ptr Offset Word8
    stringStart Word8
    0x2d
             in Bool -> Offset Word8 -> Maybe a
    consumeIntegral Bool
    isNegative (if Bool
    isNegative then Offset Word8
    stringStartOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    1 else Offset Word8
    stringStart)
          where
            eofs :: Offset Word8
    eofs = Offset Word8
    stringStart Offset Word8 -> CountOf Word8 -> Offset Word8
    forall ty. Offset ty -> CountOf ty -> Offset ty
    `offsetPlusE` CountOf Word8
    sz
            consumeIntegral :: Bool -> Offset Word8 -> Maybe a
    consumeIntegral !Bool
    isNegative Offset Word8
    startOfs =
                case Natural
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# Natural, Bool, Offset Word8 #)
    forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsPtr Natural
    0 Ptr Word8
    ptr Offset Word8
    eofs Offset Word8
    startOfs of
                    (# Natural
    acc, Bool
    True , Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    startOfs -> ReadFloatingCallback a
    f Bool
    isNegative Natural
    acc Word
    0 Maybe Int
    forall a. Maybe a
    Nothing -- end of stream and no '.'
                    (# Natural
    acc, Bool
    False, Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    startOfs ->
                        if Ptr Word8 -> Offset Word8 -> Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> Word8 -> Bool
    UTF8.expectAscii Ptr Word8
    ptr Offset Word8
    endOfs Word8
    0x2e
                            then Bool -> Natural -> Offset Word8 -> Maybe a
    consumeFloat Bool
    isNegative Natural
    acc (Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1)
                            else Bool -> Natural -> Word -> Offset Word8 -> Maybe a
    consumeExponant Bool
    isNegative Natural
    acc Word
    0 Offset Word8
    endOfs
                    (# Natural, Bool, Offset Word8 #)
    _                                            -> Maybe a
    forall a. Maybe a
    Nothing

            consumeFloat :: Bool -> Natural -> Offset Word8 -> Maybe a
    consumeFloat Bool
    isNegative Natural
    integral Offset Word8
    startOfs =
                case Natural
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# Natural, Bool, Offset Word8 #)
    forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsPtr Natural
    integral Ptr Word8
    ptr Offset Word8
    eofs Offset Word8
    startOfs of
                    (# Natural
    acc, Bool
    True, Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    startOfs -> let (CountOf !Int
    diff) = Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Difference (Offset Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - Offset Word8
    startOfs
                                                                    in ReadFloatingCallback a
    f Bool
    isNegative Natural
    acc (Int -> Word
    forall source destination.
    Cast source destination =>
    source -> destination
    cast Int
    diff) Maybe Int
    forall a. Maybe a
    Nothing
                    (# Natural
    acc, Bool
    False, Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    startOfs -> let (CountOf !Int
    diff) = Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Difference (Offset Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - Offset Word8
    startOfs
                                                                    in Bool -> Natural -> Word -> Offset Word8 -> Maybe a
    consumeExponant Bool
    isNegative Natural
    acc (Int -> Word
    forall source destination.
    Cast source destination =>
    source -> destination
    cast Int
    diff) Offset Word8
    endOfs
                    (# Natural, Bool, Offset Word8 #)
    _                                           -> Maybe a
    forall a. Maybe a
    Nothing

            consumeExponant :: Bool -> Natural -> Word -> Offset Word8 -> Maybe a
    consumeExponant !Bool
    isNegative !Natural
    integral !Word
    floatingDigits !Offset Word8
    startOfs
                | Offset Word8
    startOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    eofs = ReadFloatingCallback a
    f Bool
    isNegative Natural
    integral Word
    floatingDigits Maybe Int
    forall a. Maybe a
    Nothing
                | Bool
    otherwise        =
                    -- consume 'E' or 'e'
                    case Ptr Word8 -> Offset Word8 -> StepASCII
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> StepASCII
    UTF8.nextAscii Ptr Word8
    ptr Offset Word8
    startOfs of
                        StepASCII Word8
    0x45 -> Offset Word8 -> Maybe a
    consumeExponantSign (Offset Word8
    startOfsOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    1)
                        StepASCII Word8
    0x65 -> Offset Word8 -> Maybe a
    consumeExponantSign (Offset Word8
    startOfsOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Offset Word8
    1)
                        StepASCII
    _              -> Maybe a
    forall a. Maybe a
    Nothing
              where
                consumeExponantSign :: Offset Word8 -> Maybe a
    consumeExponantSign Offset Word8
    ofs
                    | Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    eofs = Maybe a
    forall a. Maybe a
    Nothing
                    | Bool
    otherwise   = let exponentNegative :: Bool
    exponentNegative = Ptr Word8 -> Offset Word8 -> Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> Word8 -> Bool
    UTF8.expectAscii Ptr Word8
    ptr Offset Word8
    ofs Word8
    0x2d
                                     in Bool -> Offset Word8 -> Maybe a
    consumeExponantNumber Bool
    exponentNegative (if Bool
    exponentNegative then Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    + Offset Word8
    1 else Offset Word8
    ofs)

                consumeExponantNumber :: Bool -> Offset Word8 -> Maybe a
    consumeExponantNumber Bool
    exponentNegative Offset Word8
    ofs =
                    case Int
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# Int, Bool, Offset Word8 #)
    forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsPtr Int
    0 Ptr Word8
    ptr Offset Word8
    eofs Offset Word8
    ofs of
                        (# Int
    acc, Bool
    True, Offset Word8
    endOfs #) | Offset Word8
    endOfs Offset Word8 -> Offset Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > Offset Word8
    ofs -> ReadFloatingCallback a
    f Bool
    isNegative Natural
    integral Word
    floatingDigits (Int -> Maybe Int
    forall a. a -> Maybe a
    Just (Int -> Maybe Int) -> Int -> Maybe Int
    forall a b. (a -> b) -> a -> b
    $! if Bool
    exponentNegative then Int -> Int
    forall a. HasNegation a => a -> a
    negate Int
    acc else Int
    acc)
                        (# Int, Bool, Offset Word8 #)
    _                                      -> Maybe a
    forall a. Maybe a
    Nothing

    -- | Take decimal digits and accumulate it in `acc`
    --
    -- The loop starts at the offset specified and finish either when:
    --
    -- * It reach the end of the string
    -- * It reach a non-ASCII character
    -- * It reach an ASCII character that is not a digit (0 to 9)
    --
    -- Otherwise each iterations:
    --
    -- * Transform the ASCII digits into a number
    -- * scale the accumulator by 10
    -- * Add the number (between 0 and 9) to the accumulator
    --
    -- It then returns:
    --
    -- * The new accumulated value
    -- * Whether it stop by end of string or not
    -- * The end offset when the loop stopped
    --
    -- If end offset == start offset then no digits have been consumed by
    -- this function
    decimalDigitsBA :: (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc, Integral acc)
                    => acc
                    -> Block Word8
                    -> Offset Word8 -- end offset
                    -> Offset Word8 -- start offset
                    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsBA :: forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsBA acc
    startAcc Block Word8
    ba !Offset Word8
    endOfs !Offset Word8
    startOfs = acc -> Offset Word8 -> (# acc, Bool, Offset Word8 #)
    loop acc
    startAcc Offset Word8
    startOfs
      where
        loop :: acc -> Offset Word8 -> (# acc, Bool, Offset Word8 #)
    loop !acc
    acc !Offset Word8
    ofs
            | Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    endOfs = (# acc
    acc, Bool
    True, Offset Word8
    ofs #)
            | Bool
    otherwise     =
                case Block Word8 -> Offset Word8 -> StepDigit
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> StepDigit
    UTF8.nextAsciiDigit Block Word8
    ba Offset Word8
    ofs of
                    sg :: StepDigit
    sg@(StepDigit Word8
    d) | StepDigit -> Bool
    isValidStepDigit StepDigit
    sg -> acc -> Offset Word8 -> (# acc, Bool, Offset Word8 #)
    loop (acc
    10 acc -> acc -> acc
    forall a. Multiplicative a => a -> a -> a
    * acc
    acc acc -> acc -> acc
    forall a. Additive a => a -> a -> a
    + Word8 -> acc
    forall a b. IntegralUpsize a b => a -> b
    integralUpsize Word8
    d) (Offset Word8 -> Offset Word8
    forall a. Enum a => a -> a
    succ Offset Word8
    ofs)
                                     | Bool
    otherwise           -> (# acc
    acc, Bool
    False, Offset Word8
    ofs #)
    {-# SPECIALIZE decimalDigitsBA :: Integer -> Block Word8 -> Offset Word8 -> Offset Word8 -> (# Integer, Bool, Offset Word8 #) #-}
    {-# SPECIALIZE decimalDigitsBA :: Natural -> Block Word8 -> Offset Word8 -> Offset Word8 -> (# Natural, Bool, Offset Word8 #) #-}
    {-# SPECIALIZE decimalDigitsBA :: Int -> Block Word8 -> Offset Word8 -> Offset Word8 -> (# Int, Bool, Offset Word8 #) #-}
    {-# SPECIALIZE decimalDigitsBA :: Word -> Block Word8 -> Offset Word8 -> Offset Word8 -> (# Word, Bool, Offset Word8 #) #-}

    -- | same as decimalDigitsBA specialized for ptr #
    decimalDigitsPtr :: (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc, Integral acc)
                     => acc
                     -> Ptr Word8
                     -> Offset Word8 -- end offset
                     -> Offset Word8 -- start offset
                     -> (# acc, Bool, Offset Word8 #)
    decimalDigitsPtr :: forall acc.
    (IntegralUpsize Word8 acc, Additive acc, Multiplicative acc,
     Integral acc) =>
    acc
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> (# acc, Bool, Offset Word8 #)
    decimalDigitsPtr acc
    startAcc Ptr Word8
    ptr !Offset Word8
    endOfs !Offset Word8
    startOfs = acc -> Offset Word8 -> (# acc, Bool, Offset Word8 #)
    loop acc
    startAcc Offset Word8
    startOfs
      where
        loop :: acc -> Offset Word8 -> (# acc, Bool, Offset Word8 #)
    loop !acc
    acc !Offset Word8
    ofs
            | Offset Word8
    ofs Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    endOfs = (# acc
    acc, Bool
    True, Offset Word8
    ofs #)
            | Bool
    otherwise     =
                case Ptr Word8 -> Offset Word8 -> StepDigit
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> StepDigit
    UTF8.nextAsciiDigit Ptr Word8
    ptr Offset Word8
    ofs of
                    sg :: StepDigit
    sg@(StepDigit Word8
    d) | StepDigit -> Bool
    isValidStepDigit StepDigit
    sg -> acc -> Offset Word8 -> (# acc, Bool, Offset Word8 #)
    loop (acc
    10 acc -> acc -> acc
    forall a. Multiplicative a => a -> a -> a
    * acc
    acc acc -> acc -> acc
    forall a. Additive a => a -> a -> a
    + Word8 -> acc
    forall a b. IntegralUpsize a b => a -> b
    integralUpsize Word8
    d) (Offset Word8 -> Offset Word8
    forall a. Enum a => a -> a
    succ Offset Word8
    ofs)
                                     | Bool
    otherwise           -> (# acc
    acc, Bool
    False, Offset Word8
    ofs #)
    {-# SPECIALIZE decimalDigitsPtr :: Integer -> Ptr Word8 -> Offset Word8 -> Offset Word8 -> (# Integer, Bool, Offset Word8 #) #-}
    {-# SPECIALIZE decimalDigitsPtr :: Natural -> Ptr Word8 -> Offset Word8 -> Offset Word8 -> (# Natural, Bool, Offset Word8 #) #-}
    {-# SPECIALIZE decimalDigitsPtr :: Int -> Ptr Word8 -> Offset Word8 -> Offset Word8 -> (# Int, Bool, Offset Word8 #) #-}
    {-# SPECIALIZE decimalDigitsPtr :: Word -> Ptr Word8 -> Offset Word8 -> Offset Word8 -> (# Word, Bool, Offset Word8 #) #-}

    -- | Convert a 'String' 'Char' by 'Char' using a case mapping function.
    caseConvert :: (Char7 -> Char7) -> (Char -> CM) -> String -> String
    caseConvert :: (Char7 -> Char7) -> (Char -> CM) -> String -> String
    caseConvert Char7 -> Char7
    opASCII Char -> CM
    op s :: String
    s@(String UArray Word8
    arr) = (forall s. ST s String) -> String
    forall a. (forall s. ST s a) -> a
    runST ((forall s. ST s String) -> String)
    -> (forall s. ST s String) -> String
    forall a b. (a -> b) -> a -> b
    $ do
      MutableBlock Word8 s
    mba <- CountOf Word8 -> ST s (MutableBlock Word8 (PrimState (ST s)))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MutableBlock ty (PrimState prim))
    MBLK.new CountOf Word8
    iLen
      CountOf Word8
    nL <- (Block Word8 -> ST s (CountOf Word8))
    -> (FinalPtr Word8 -> ST s (CountOf Word8))
    -> UArray Word8
    -> ST s (CountOf Word8)
    forall (prim :: * -> *) ty a.
    PrimMonad prim =>
    (Block ty -> prim a)
    -> (FinalPtr ty -> prim a) -> UArray ty -> prim a
    C.onBackendPrim
            (\Block Word8
    blk  -> MutableBlock Word8 (PrimState (ST s))
    -> Block Word8
    -> Offset Word8
    -> Offset Word8
    -> ST s (CountOf Word8)
    forall container (prim :: * -> *).
    (Indexable container Word8, PrimMonad prim) =>
    MutableBlock Word8 (PrimState prim)
    -> container
    -> Offset Word8
    -> Offset Word8
    -> prim (CountOf Word8)
    go MutableBlock Word8 s
    MutableBlock Word8 (PrimState (ST s))
    mba Block Word8
    blk (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) Offset Word8
    start)
            (\FinalPtr Word8
    fptr -> FinalPtr Word8
    -> (Ptr Word8 -> ST s (CountOf Word8)) -> ST s (CountOf Word8)
    forall (prim :: * -> *) p a.
    PrimMonad prim =>
    FinalPtr p -> (Ptr p -> prim a) -> prim a
    withFinalPtr FinalPtr Word8
    fptr ((Ptr Word8 -> ST s (CountOf Word8)) -> ST s (CountOf Word8))
    -> (Ptr Word8 -> ST s (CountOf Word8)) -> ST s (CountOf Word8)
    forall a b. (a -> b) -> a -> b
    $ \Ptr Word8
    ptr -> MutableBlock Word8 (PrimState (ST s))
    -> Ptr Word8
    -> Offset Word8
    -> Offset Word8
    -> ST s (CountOf Word8)
    forall container (prim :: * -> *).
    (Indexable container Word8, PrimMonad prim) =>
    MutableBlock Word8 (PrimState prim)
    -> container
    -> Offset Word8
    -> Offset Word8
    -> prim (CountOf Word8)
    go MutableBlock Word8 s
    MutableBlock Word8 (PrimState (ST s))
    mba Ptr Word8
    ptr (Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    0) Offset Word8
    start)
            UArray Word8
    arr
      MutableString s -> ST s String
    MutableString (PrimState (ST s)) -> ST s String
    forall (prim :: * -> *).
    PrimMonad prim =>
    MutableString (PrimState prim) -> prim String
    freeze (MutableString s -> ST s String)
    -> (MUArray Word8 s -> MutableString s)
    -> MUArray Word8 s
    -> ST s String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . MUArray Word8 s -> MutableString s
    forall st. MUArray Word8 st -> MutableString st
    MutableString (MUArray Word8 s -> ST s String) -> MUArray Word8 s -> ST s String
    forall a b. (a -> b) -> a -> b
    $ Offset Word8
    -> CountOf Word8 -> MUArrayBackend Word8 s -> MUArray Word8 s
    forall ty st.
    Offset ty -> CountOf ty -> MUArrayBackend ty st -> MUArray ty st
    MVec.MUArray Offset Word8
    0 CountOf Word8
    nL (MutableBlock Word8 s -> MUArrayBackend Word8 s
    forall ty st. MutableBlock ty st -> MUArrayBackend ty st
    C.MUArrayMBA MutableBlock Word8 s
    mba)
      where
        !(C.ValidRange Offset Word8
    start Offset Word8
    end) = UArray Word8 -> ValidRange Word8
    forall ty. UArray ty -> ValidRange ty
    C.offsetsValidRange UArray Word8
    arr
        !iLen :: CountOf Word8
    iLen = CountOf Word8
    1 CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    arr
        go :: (Indexable container Word8, PrimMonad prim)
           => MutableBlock Word8 (PrimState prim)
           -> container
           -> Offset Word8
           -> Offset Word8
           -> prim (CountOf Word8)
        go :: forall container (prim :: * -> *).
    (Indexable container Word8, PrimMonad prim) =>
    MutableBlock Word8 (PrimState prim)
    -> container
    -> Offset Word8
    -> Offset Word8
    -> prim (CountOf Word8)
    go !MutableBlock Word8 (PrimState prim)
    dst !container
    src = MutableBlock Word8 (PrimState prim)
    -> CountOf Word8
    -> CountOf Word8
    -> Offset Word8
    -> Offset Word8
    -> prim (CountOf Word8)
    loop MutableBlock Word8 (PrimState prim)
    dst CountOf Word8
    iLen CountOf Word8
    0
          where
            eSize :: Char -> CountOf Word8
    eSize !Char
    e = if Char
    e Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\0' then CountOf Word8
    0 else Int -> CountOf Word8
    charToBytes (Char -> Int
    forall a. Enum a => a -> Int
    fromEnum Char
    e)
            loop :: MutableBlock Word8 (PrimState prim)
    -> CountOf Word8
    -> CountOf Word8
    -> Offset Word8
    -> Offset Word8
    -> prim (CountOf Word8)
    loop !MutableBlock Word8 (PrimState prim)
    dst !CountOf Word8
    allocLen !CountOf Word8
    nLen !Offset Word8
    dstIdx !Offset Word8
    srcIdx
              | Offset Word8
    srcIdx Offset Word8 -> Offset Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Offset Word8
    end    = CountOf Word8 -> prim (CountOf Word8)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return CountOf Word8
    nLen
              | CountOf Word8
    nLen CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf Word8
    allocLen = prim (CountOf Word8)
    realloc
              | StepASCII -> Bool
    headerIsAscii StepASCII
    h  = do
                    MutableBlock Word8 (PrimState prim)
    -> Offset Word8 -> Char7 -> prim ()
    forall (prim :: * -> *) container.
    (PrimMonad prim, RandomAccess container prim Word8) =>
    container -> Offset Word8 -> Char7 -> prim ()
    UTF8.writeASCII MutableBlock Word8 (PrimState prim)
    dst Offset Word8
    dstIdx (Char7 -> Char7
    opASCII (Char7 -> Char7) -> Char7 -> Char7
    forall a b. (a -> b) -> a -> b
    $ Word8 -> Char7
    Char7 (Word8 -> Char7) -> Word8 -> Char7
    forall a b. (a -> b) -> a -> b
    $ StepASCII -> Word8
    stepAsciiRawValue StepASCII
    h)
                    MutableBlock Word8 (PrimState prim)
    -> CountOf Word8
    -> CountOf Word8
    -> Offset Word8
    -> Offset Word8
    -> prim (CountOf Word8)
    loop MutableBlock Word8 (PrimState prim)
    dst CountOf Word8
    allocLen (CountOf Word8
    nLen CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    1) (Offset Word8
    dstIdxOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    1) (Offset Word8
    srcIdxOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    1)
              | Bool
    otherwise = do
                  let !(CM Char
    c1 Char
    c2 Char
    c3) = Char -> CM
    op Char
    c
                      !(Step Char
    c Offset Word8
    nextSrcIdx) = StepASCII -> container -> Offset Word8 -> Step
    forall container.
    Indexable container Word8 =>
    StepASCII -> container -> Offset Word8 -> Step
    UTF8.nextWith StepASCII
    h container
    src (Offset Word8
    srcIdxOffset Word8 -> Offset Word8 -> Offset Word8
    forall a. Additive a => a -> a -> a
    +Int -> Offset Word8
    forall ty. Int -> Offset ty
    Offset Int
    1)
                  Offset Word8
    nextDstIdx <- MutableBlock Word8 (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    forall (prim :: * -> *) container.
    (PrimMonad prim, RandomAccess container prim Word8) =>
    container -> Offset Word8 -> Char -> prim (Offset Word8)
    UTF8.writeUTF8 MutableBlock Word8 (PrimState prim)
    dst Offset Word8
    dstIdx Char
    c1
                  if Char
    c2 Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\0' -- We keep the most common case loop as short as possible.
                    then MutableBlock Word8 (PrimState prim)
    -> CountOf Word8
    -> CountOf Word8
    -> Offset Word8
    -> Offset Word8
    -> prim (CountOf Word8)
    loop MutableBlock Word8 (PrimState prim)
    dst CountOf Word8
    allocLen (CountOf Word8
    nLen CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + Int -> CountOf Word8
    charToBytes (Char -> Int
    forall a. Enum a => a -> Int
    fromEnum Char
    c1)) Offset Word8
    nextDstIdx Offset Word8
    nextSrcIdx
                    else do
                      let !cSize :: CountOf Word8
    cSize = Char -> CountOf Word8
    eSize Char
    c1 CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + Char -> CountOf Word8
    eSize Char
    c2 CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + Char -> CountOf Word8
    eSize Char
    c3
                      Offset Word8
    nextDstIdx <- MutableBlock Word8 (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    forall (prim :: * -> *) container.
    (PrimMonad prim, RandomAccess container prim Word8) =>
    container -> Offset Word8 -> Char -> prim (Offset Word8)
    UTF8.writeUTF8 MutableBlock Word8 (PrimState prim)
    dst Offset Word8
    nextDstIdx Char
    c2
                      Offset Word8
    nextDstIdx <- if Char
    c3 Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '\0' then Offset Word8 -> prim (Offset Word8)
    forall a. a -> prim a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Offset Word8
    nextDstIdx else MutableBlock Word8 (PrimState prim)
    -> Offset Word8 -> Char -> prim (Offset Word8)
    forall (prim :: * -> *) container.
    (PrimMonad prim, RandomAccess container prim Word8) =>
    container -> Offset Word8 -> Char -> prim (Offset Word8)
    UTF8.writeUTF8 MutableBlock Word8 (PrimState prim)
    dst Offset Word8
    nextDstIdx Char
    c3
                      MutableBlock Word8 (PrimState prim)
    -> CountOf Word8
    -> CountOf Word8
    -> Offset Word8
    -> Offset Word8
    -> prim (CountOf Word8)
    loop MutableBlock Word8 (PrimState prim)
    dst CountOf Word8
    allocLen (CountOf Word8
    nLen CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    cSize) Offset Word8
    nextDstIdx Offset Word8
    nextSrcIdx
              where
                {-# NOINLINE realloc #-}
                realloc :: prim (CountOf Word8)
    realloc = do
                  let nAll :: CountOf Word8
    nAll = CountOf Word8
    allocLen CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    allocLen CountOf Word8 -> CountOf Word8 -> CountOf Word8
    forall a. Additive a => a -> a -> a
    + CountOf Word8
    1
                  MutableBlock Word8 (PrimState prim)
    nDst <- CountOf Word8 -> prim (MutableBlock Word8 (PrimState prim))
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    CountOf ty -> prim (MutableBlock ty (PrimState prim))
    MBLK.new CountOf Word8
    nAll
                  MutableBlock Word8 (PrimState prim)
    -> Offset Word8
    -> MutableBlock Word8 (PrimState prim)
    -> Offset Word8
    -> CountOf Word8
    -> prim ()
    forall (prim :: * -> *) ty.
    (PrimMonad prim, PrimType ty) =>
    MutableBlock ty (PrimState prim)
    -> Offset ty
    -> MutableBlock ty (PrimState prim)
    -> Offset ty
    -> CountOf ty
    -> prim ()
    MBLK.unsafeCopyElements MutableBlock Word8 (PrimState prim)
    nDst Offset Word8
    0 MutableBlock Word8 (PrimState prim)
    dst Offset Word8
    0 CountOf Word8
    nLen
                  MutableBlock Word8 (PrimState prim)
    -> CountOf Word8
    -> CountOf Word8
    -> Offset Word8
    -> Offset Word8
    -> prim (CountOf Word8)
    loop MutableBlock Word8 (PrimState prim)
    nDst CountOf Word8
    nAll CountOf Word8
    nLen Offset Word8
    dstIdx Offset Word8
    srcIdx
                h :: StepASCII
    h = container -> Offset Word8 -> StepASCII
    forall container.
    Indexable container Word8 =>
    container -> Offset Word8 -> StepASCII
    UTF8.nextAscii container
    src Offset Word8
    srcIdx

    -- | Convert a 'String' to the upper-case equivalent.
    upper :: String -> String
    upper :: String -> String
    upper = (Char7 -> Char7) -> (Char -> CM) -> String -> String
    caseConvert Char7 -> Char7
    c7Upper Char -> CM
    upperMapping

    -- | Convert a 'String' to the upper-case equivalent.
    lower :: String -> String
    lower :: String -> String
    lower = (Char7 -> Char7) -> (Char -> CM) -> String -> String
    caseConvert Char7 -> Char7
    c7Lower Char -> CM
    lowerMapping

    -- | Convert a 'String' to the unicode case fold equivalent.
    --
    -- Case folding is mostly used for caseless comparison of strings.
    caseFold :: String -> String
    caseFold :: String -> String
    caseFold = (Char7 -> Char7) -> (Char -> CM) -> String -> String
    caseConvert Char7 -> Char7
    c7Upper Char -> CM
    foldMapping

    -- | Check whether the first string is a prefix of the second string.
    isPrefixOf :: String -> String -> Bool
    isPrefixOf :: String -> String -> Bool
    isPrefixOf (String UArray Word8
    needle) (String UArray Word8
    haystack) = UArray Word8 -> UArray Word8 -> Bool
    forall ty. PrimType ty => UArray ty -> UArray ty -> Bool
    C.isPrefixOf UArray Word8
    needle UArray Word8
    haystack

    -- | Check whether the first string is a suffix of the second string.
    isSuffixOf :: String -> String -> Bool
    isSuffixOf :: String -> String -> Bool
    isSuffixOf (String UArray Word8
    needle) (String UArray Word8
    haystack)
        | CountOf Word8
    needleLen CountOf Word8 -> CountOf Word8 -> Bool
    forall a. Ord a => a -> a -> Bool
    > CountOf Word8
    hayLen = Bool
    False
        | Bool
    otherwise          = UArray Word8
    needle UArray Word8 -> UArray Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf Word8 -> UArray Word8 -> UArray Word8
    forall ty. CountOf ty -> UArray ty -> UArray ty
    C.revTake CountOf Word8
    needleLen UArray Word8
    haystack
      where
        needleLen :: CountOf Word8
    needleLen = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    needle
        hayLen :: CountOf Word8
    hayLen    = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    haystack

    -- | Check whether the first string is contains within the second string.
    --
    -- TODO: implemented the naive way and thus terribly inefficient, reimplement properly
    isInfixOf :: String -> String -> Bool
    isInfixOf :: String -> String -> Bool
    isInfixOf (String UArray Word8
    needle) (String UArray Word8
    haystack)
        = Maybe (CountOf Word8) -> UArray Word8 -> Bool
    loop (CountOf Word8
    hayLen CountOf Word8 -> CountOf Word8 -> Difference (CountOf Word8)
    forall a. Subtractive a => a -> a -> Difference a
    - CountOf Word8
    needleLen) UArray Word8
    haystack
        where
          needleLen :: CountOf Word8
    needleLen = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    needle
          hayLen :: CountOf Word8
    hayLen    = UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    haystack
          loop :: Maybe (CountOf Word8) -> UArray Word8 -> Bool
    loop Maybe (CountOf Word8)
    Nothing    UArray Word8
    _         = Bool
    False
          loop (Just CountOf Word8
    cnt) UArray Word8
    haystack' = UArray Word8
    needle UArray Word8 -> UArray Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    == CountOf Word8 -> UArray Word8 -> UArray Word8
    forall ty. CountOf ty -> UArray ty -> UArray ty
    C.take CountOf Word8
    needleLen UArray Word8
    haystack' Bool -> Bool -> Bool
    || Maybe (CountOf Word8) -> UArray Word8 -> Bool
    loop (CountOf Word8
    cntCountOf Word8 -> CountOf Word8 -> Difference (CountOf Word8)
    forall a. Subtractive a => a -> a -> Difference a
    -CountOf Word8
    1) (CountOf Word8 -> UArray Word8 -> UArray Word8
    forall ty. CountOf ty -> UArray ty -> UArray ty
    C.drop CountOf Word8
    1 UArray Word8
    haystack')

    -- | Try to strip a prefix from the start of a String.
    --
    -- If the prefix is not starting the string, then Nothing is returned,
    -- otherwise the striped string is returned
    stripPrefix :: String -> String -> Maybe String
    stripPrefix :: String -> String -> Maybe String
    stripPrefix (String UArray Word8
    suffix) (String UArray Word8
    arr)
        | UArray Word8 -> UArray Word8 -> Bool
    forall ty. PrimType ty => UArray ty -> UArray ty -> Bool
    C.isPrefixOf UArray Word8
    suffix UArray Word8
    arr = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ UArray Word8 -> String
    String (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ CountOf Word8 -> UArray Word8 -> UArray Word8
    forall ty. CountOf ty -> UArray ty -> UArray ty
    C.drop (UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    suffix) UArray Word8
    arr
        | Bool
    otherwise               = Maybe String
    forall a. Maybe a
    Nothing

    -- | Try to strip a suffix from the end of a String.
    --
    -- If the suffix is not ending the string, then Nothing is returned,
    -- otherwise the striped string is returned
    stripSuffix :: String -> String -> Maybe String
    stripSuffix :: String -> String -> Maybe String
    stripSuffix (String UArray Word8
    prefix) (String UArray Word8
    arr)
        | UArray Word8 -> UArray Word8 -> Bool
    forall ty. PrimType ty => UArray ty -> UArray ty -> Bool
    C.isSuffixOf UArray Word8
    prefix UArray Word8
    arr = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ UArray Word8 -> String
    String (UArray Word8 -> String) -> UArray Word8 -> String
    forall a b. (a -> b) -> a -> b
    $ CountOf Word8 -> UArray Word8 -> UArray Word8
    forall ty. CountOf ty -> UArray ty -> UArray ty
    C.revDrop (UArray Word8 -> CountOf Word8
    forall ty. UArray ty -> CountOf ty
    C.length UArray Word8
    prefix) UArray Word8
    arr
        | Bool
    otherwise               = Maybe String
    forall a. Maybe a
    Nothing

    all :: (Char -> Bool) -> String -> Bool
    all :: (Char -> Bool) -> String -> Bool
    all Char -> Bool
    predicate (String UArray Word8
    arr) = (Block Word8 -> Bool)
    -> (FinalPtr Word8 -> Ptr Word8 -> ST Any Bool)
    -> UArray Word8
    -> Bool
    forall ty a s.
    (Block ty -> a)
    -> (FinalPtr ty -> Ptr ty -> ST s a) -> UArray ty -> a
    C.onBackend Block Word8 -> Bool
    goBA (\FinalPtr Word8
    _ -> Bool -> ST Any Bool
    forall a. a -> ST Any a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Bool -> ST Any Bool)
    -> (Ptr Word8 -> Bool) -> Ptr Word8 -> ST Any Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Ptr Word8 -> Bool
    goAddr) UArray Word8
    arr
      where
        !(C.ValidRange Offset Word8
    start Offset Word8
    end) = UArray Word8 -> ValidRange Word8
    forall ty. UArray ty -> ValidRange ty
    C.offsetsValidRange UArray Word8
    arr
        goBA :: Block Word8 -> Bool
    goBA Block Word8
    ba   = (Char -> Bool)
    -> Block Word8 -> Offset Word8 -> Offset Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    (Char -> Bool) -> container -> Offset Word8 -> Offset Word8 -> Bool
    UTF8.all Char -> Bool
    predicate Block Word8
    ba Offset Word8
    start Offset Word8
    end
        goAddr :: Ptr Word8 -> Bool
    goAddr Ptr Word8
    addr = (Char -> Bool) -> Ptr Word8 -> Offset Word8 -> Offset Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    (Char -> Bool) -> container -> Offset Word8 -> Offset Word8 -> Bool
    UTF8.all Char -> Bool
    predicate Ptr Word8
    addr Offset Word8
    start Offset Word8
    end

    any :: (Char -> Bool) -> String -> Bool
    any :: (Char -> Bool) -> String -> Bool
    any Char -> Bool
    predicate (String UArray Word8
    arr) = (Block Word8 -> Bool)
    -> (FinalPtr Word8 -> Ptr Word8 -> ST Any Bool)
    -> UArray Word8
    -> Bool
    forall ty a s.
    (Block ty -> a)
    -> (FinalPtr ty -> Ptr ty -> ST s a) -> UArray ty -> a
    C.onBackend Block Word8 -> Bool
    goBA (\FinalPtr Word8
    _ -> Bool -> ST Any Bool
    forall a. a -> ST Any a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Bool -> ST Any Bool)
    -> (Ptr Word8 -> Bool) -> Ptr Word8 -> ST Any Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Ptr Word8 -> Bool
    goAddr) UArray Word8
    arr
      where
        !(C.ValidRange Offset Word8
    start Offset Word8
    end) = UArray Word8 -> ValidRange Word8
    forall ty. UArray ty -> ValidRange ty
    C.offsetsValidRange UArray Word8
    arr
        goBA :: Block Word8 -> Bool
    goBA Block Word8
    ba   = (Char -> Bool)
    -> Block Word8 -> Offset Word8 -> Offset Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    (Char -> Bool) -> container -> Offset Word8 -> Offset Word8 -> Bool
    UTF8.any Char -> Bool
    predicate Block Word8
    ba Offset Word8
    start Offset Word8
    end
        goAddr :: Ptr Word8 -> Bool
    goAddr Ptr Word8
    addr = (Char -> Bool) -> Ptr Word8 -> Offset Word8 -> Offset Word8 -> Bool
    forall container.
    Indexable container Word8 =>
    (Char -> Bool) -> container -> Offset Word8 -> Offset Word8 -> Bool
    UTF8.any Char -> Bool
    predicate Ptr Word8
    addr Offset Word8
    start Offset Word8
    end

    -- | Transform string @src@ to base64 binary representation.
    toBase64 :: String -> String
    toBase64 :: String -> String
    toBase64 (String UArray Word8
    src) = UArray Word8 -> String
    fromBytesUnsafe (UArray Word8 -> String)
    -> (Bool -> UArray Word8) -> Bool -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Addr# -> UArray Word8 -> Bool -> UArray Word8
    forall ty.
    PrimType ty =>
    Addr# -> UArray ty -> Bool -> UArray Word8
    Vec.toBase64Internal Addr#
    set UArray Word8
    src (Bool -> String) -> Bool -> String
    forall a b. (a -> b) -> a -> b
    $ Bool
    True
      where
        !set :: Addr#
    set = Addr#
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"#

    -- | Transform string @src@ to URL-safe base64 binary representation.
    -- The result will be either padded or unpadded, depending on the boolean
    -- @padded@ argument.
    toBase64URL :: Bool -> String -> String
    toBase64URL :: Bool -> String -> String
    toBase64URL Bool
    padded (String UArray Word8
    src) = UArray Word8 -> String
    fromBytesUnsafe (UArray Word8 -> String)
    -> (Bool -> UArray Word8) -> Bool -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Addr# -> UArray Word8 -> Bool -> UArray Word8
    forall ty.
    PrimType ty =>
    Addr# -> UArray ty -> Bool -> UArray Word8
    Vec.toBase64Internal Addr#
    set UArray Word8
    src (Bool -> String) -> Bool -> String
    forall a b. (a -> b) -> a -> b
    $ Bool
    padded
      where
        !set :: Addr#
    set = Addr#
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"#

    -- | Transform string @src@ to OpenBSD base64 binary representation.
    toBase64OpenBSD :: String -> String
    toBase64OpenBSD :: String -> String
    toBase64OpenBSD (String UArray Word8
    src) = UArray Word8 -> String
    fromBytesUnsafe (UArray Word8 -> String)
    -> (Bool -> UArray Word8) -> Bool -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
    Category cat =>
    cat b c -> cat a b -> cat a c
    . Addr# -> UArray Word8 -> Bool -> UArray Word8
    forall ty.
    PrimType ty =>
    Addr# -> UArray ty -> Bool -> UArray Word8
    Vec.toBase64Internal Addr#
    set UArray Word8
    src (Bool -> String) -> Bool -> String
    forall a b. (a -> b) -> a -> b
    $ Bool
    False
      where
        !set :: Addr#
    set = Addr#
    "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"#