{-# LANGUAGE BangPatterns
           , RankNTypes #-}

module Data.RadixNTree.Word8.Key
  ( Tsil (..)
  , YtpmeNon (..)
  , Build (..)

  , buildBytes0

  , buildByteString0
  , buildShortByteString0

  , unsafeBuildText0

  , Build1 (..)

  , buildBytes1

  , buildByteString1
  , buildShortByteString1

  , unsafeBuildText1

  , Feed (..)
  , feedBytes0

  , feedByteString0
  , feedShortByteString0
  , feedLazyByteString0

  , feedText0
  , feedLazyText0

  , Feed1 (..)
  , feedBytes1

  , unsafeFeedByteString1
  , unsafeFeedShortByteString1
  , unsafeFeedLazyByteString1

  , unsafeFeedText1
  , unsafeFeedLazyText1
  ) where

import           Data.ByteArray.NonEmpty

import           Control.Monad.ST
import qualified Data.ByteString as BS
import qualified Data.ByteString.Internal as Strict (ByteString (..), unsafeCreate)
import qualified Data.ByteString.Lazy as Lazy (ByteString)
import qualified Data.ByteString.Lazy.Internal as LazyBS (ByteString (..))
import           Data.ByteString.Short.Internal (ShortByteString (..))
import           Data.ByteString.Unsafe
import           Data.List.NonEmpty (NonEmpty (..))
import           Data.Primitive.ByteArray
import qualified Data.Text.Array as Array
import qualified Data.Text.Internal as Strict (Text (..))
import qualified Data.Text.Internal.Lazy as LazyText (Text (..))
import qualified Data.Text.Lazy as Lazy (Text)
import           Data.Word
import           Foreign.Ptr



-- | Snoc-list.
data Tsil a = Lin
            | Snoc (Tsil a) a

-- | Snoc-list with a guaranteed element at the back.
data YtpmeNon a = Tsil a :/ a

-- | Key as stored in the radix tree.
newtype Build = Build
                  -- | List of memory chunks that constitute the key.
                  --
                  --   The first chunk is at the bottom of the list.
                  (Tsil ByteArray)

instance Show Build where
  showsPrec :: Int -> Build -> ShowS
showsPrec Int
d = Int -> [Word8] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
d ([Word8] -> ShowS) -> (Build -> [Word8]) -> Build -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Build -> [Word8]
buildBytes0

-- | Non-empty key as stored in the radix tree.
newtype Build1 = Build1
                   -- | List of memory chunks that constitute the key.
                   --
                   --   The first chunk is at the bottom of the list.
                   (YtpmeNon ByteArray)

instance Show Build1 where
  showsPrec :: Int -> Build1 -> ShowS
showsPrec Int
d Build1
xs = let ~(Word8
y :| [Word8]
ys) = Build1 -> NonEmpty Word8
buildBytes1 Build1
xs
                   in Int -> [Word8] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
d (Word8
yWord8 -> [Word8] -> [Word8]
forall a. a -> [a] -> [a]
:[Word8]
ys)

buildBytes0 :: Build -> [Word8]
buildBytes0 :: Build -> [Word8]
buildBytes0 (Build Tsil ByteArray
xs) = [Word8] -> Tsil ByteArray -> [Word8]
go [] Tsil ByteArray
xs
  where
    go :: [Word8] -> Tsil ByteArray -> [Word8]
go [Word8]
acc Tsil ByteArray
as =
      case Tsil ByteArray
as of
        Snoc Tsil ByteArray
bs ByteArray
a -> [Word8] -> Tsil ByteArray -> [Word8]
go (ByteArray -> [Word8]
Data.ByteArray.NonEmpty.toList ByteArray
a [Word8] -> [Word8] -> [Word8]
forall a. Semigroup a => a -> a -> a
<> [Word8]
acc) Tsil ByteArray
bs
        Tsil ByteArray
Lin       -> [Word8]
acc

buildBytes1 :: Build1 -> NonEmpty Word8
buildBytes1 :: Build1 -> NonEmpty Word8
buildBytes1 (Build1 (Tsil ByteArray
xs :/ ByteArray
x)) = NonEmpty Word8 -> Tsil ByteArray -> NonEmpty Word8
go (ByteArray -> NonEmpty Word8
toNonEmpty ByteArray
x) Tsil ByteArray
xs
  where
    go :: NonEmpty Word8 -> Tsil ByteArray -> NonEmpty Word8
go NonEmpty Word8
acc Tsil ByteArray
as =
      case Tsil ByteArray
as of
        Snoc Tsil ByteArray
bs ByteArray
a -> NonEmpty Word8 -> Tsil ByteArray -> NonEmpty Word8
go (ByteArray -> NonEmpty Word8
toNonEmpty ByteArray
a NonEmpty Word8 -> NonEmpty Word8 -> NonEmpty Word8
forall a. Semigroup a => a -> a -> a
<> NonEmpty Word8
acc) Tsil ByteArray
bs
        Tsil ByteArray
Lin       -> NonEmpty Word8
acc



sizeofBuild0 :: Build -> Int
sizeofBuild0 :: Build -> Int
sizeofBuild0 (Build Tsil ByteArray
xs) = Tsil ByteArray -> Int
go Tsil ByteArray
xs
  where
    go :: Tsil ByteArray -> Int
go Tsil ByteArray
as =
      case Tsil ByteArray
as of
        Snoc Tsil ByteArray
bs ByteArray
arr -> ByteArray -> Int
sizeofByteArray ByteArray
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Tsil ByteArray -> Int
go Tsil ByteArray
bs
        Tsil ByteArray
Lin         -> Int
0

sizeofBuild1 :: Build1 -> Int
sizeofBuild1 :: Build1 -> Int
sizeofBuild1 (Build1 (Tsil ByteArray
xs :/ ByteArray
arr)) = ByteArray -> Int
sizeofByteArray ByteArray
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Build -> Int
sizeofBuild0 (Tsil ByteArray -> Build
Build Tsil ByteArray
xs)

writePtr :: Ptr Word8 -> Int -> Build -> IO ()
writePtr :: Ptr Word8 -> Int -> Build -> IO ()
writePtr Ptr Word8
ptr Int
off0 (Build Tsil ByteArray
xs) = Int -> Tsil ByteArray -> IO ()
forall {m :: * -> *}. PrimMonad m => Int -> Tsil ByteArray -> m ()
go Int
off0 Tsil ByteArray
xs
  where
    go :: Int -> Tsil ByteArray -> m ()
go Int
off Tsil ByteArray
as =
      case Tsil ByteArray
as of
        Snoc Tsil ByteArray
bs ByteArray
arr -> do
          let off' :: Int
off' = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteArray -> Int
sizeofByteArray ByteArray
arr
          Ptr Word8 -> ByteArray -> Int -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
Ptr Word8 -> ByteArray -> Int -> Int -> m ()
copyByteArrayToAddr (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
off') ByteArray
arr Int
0 (ByteArray -> Int
sizeofByteArray ByteArray
arr)
          Int -> Tsil ByteArray -> m ()
go Int
off' Tsil ByteArray
bs

        Tsil ByteArray
Lin         -> () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

writePtr1 :: Ptr Word8 -> Int -> Build1 -> IO ()
writePtr1 :: Ptr Word8 -> Int -> Build1 -> IO ()
writePtr1 Ptr Word8
ptr Int
off (Build1 (Tsil ByteArray
xs :/ ByteArray
arr)) = do
  let off' :: Int
off' = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteArray -> Int
sizeofByteArray ByteArray
arr
  Ptr Word8 -> ByteArray -> Int -> Int -> IO ()
forall (m :: * -> *).
PrimMonad m =>
Ptr Word8 -> ByteArray -> Int -> Int -> m ()
copyByteArrayToAddr (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
off') ByteArray
arr Int
0 (ByteArray -> Int
sizeofByteArray ByteArray
arr)
  Ptr Word8 -> Int -> Build -> IO ()
writePtr Ptr Word8
ptr Int
off' (Tsil ByteArray -> Build
Build Tsil ByteArray
xs)



buildByteString0 :: Build -> Strict.ByteString
buildByteString0 :: Build -> ByteString
buildByteString0 Build
xs =
  let len :: Int
len = Build -> Int
sizeofBuild0 Build
xs
  in Int -> (Ptr Word8 -> IO ()) -> ByteString
Strict.unsafeCreate Int
len (\Ptr Word8
ptr -> Ptr Word8 -> Int -> Build -> IO ()
writePtr Ptr Word8
ptr Int
len Build
xs)

buildByteString1 :: Build1 -> Strict.ByteString
buildByteString1 :: Build1 -> ByteString
buildByteString1 Build1
xs =
  let len :: Int
len = Build1 -> Int
sizeofBuild1 Build1
xs
  in Int -> (Ptr Word8 -> IO ()) -> ByteString
Strict.unsafeCreate Int
len (\Ptr Word8
ptr -> Ptr Word8 -> Int -> Build1 -> IO ()
writePtr1 Ptr Word8
ptr Int
len Build1
xs)



writeArr :: MutableByteArray s -> Int -> Build -> ST s ()
writeArr :: forall s. MutableByteArray s -> Int -> Build -> ST s ()
writeArr MutableByteArray s
marr Int
off0 (Build Tsil ByteArray
xs) = Int -> Tsil ByteArray -> ST s ()
forall {m :: * -> *}.
(PrimState m ~ s, PrimMonad m) =>
Int -> Tsil ByteArray -> m ()
go Int
off0 Tsil ByteArray
xs
  where
    go :: Int -> Tsil ByteArray -> m ()
go Int
off Tsil ByteArray
as =
      case Tsil ByteArray
as of
        Snoc Tsil ByteArray
bs ByteArray
arr -> do
          let off' :: Int
off' = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteArray -> Int
sizeofByteArray ByteArray
arr
          MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray s
MutableByteArray (PrimState m)
marr Int
off' ByteArray
arr Int
0 (ByteArray -> Int
sizeofByteArray ByteArray
arr)
          Int -> Tsil ByteArray -> m ()
go Int
off' Tsil ByteArray
bs

        Tsil ByteArray
Lin         -> () -> m ()
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

writeArr1 :: MutableByteArray s -> Int -> Build1 -> ST s ()
writeArr1 :: forall s. MutableByteArray s -> Int -> Build1 -> ST s ()
writeArr1 MutableByteArray s
marr Int
off (Build1 (Tsil ByteArray
xs :/ ByteArray
arr)) = do
  let off' :: Int
off' = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteArray -> Int
sizeofByteArray ByteArray
arr
  MutableByteArray (PrimState (ST s))
-> Int -> ByteArray -> Int -> Int -> ST s ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
marr Int
off' ByteArray
arr Int
0 (ByteArray -> Int
sizeofByteArray ByteArray
arr)
  MutableByteArray s -> Int -> Build -> ST s ()
forall s. MutableByteArray s -> Int -> Build -> ST s ()
writeArr MutableByteArray s
marr Int
off' (Tsil ByteArray -> Build
Build Tsil ByteArray
xs)



{-# INLINE buildShortByteString0 #-}
buildShortByteString0 :: Build -> ShortByteString
buildShortByteString0 :: Build -> ShortByteString
buildShortByteString0 Build
xs =
  (forall s. ST s ShortByteString) -> ShortByteString
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ShortByteString) -> ShortByteString)
-> (forall s. ST s ShortByteString) -> ShortByteString
forall a b. (a -> b) -> a -> b
$ do
    let len :: Int
len = Build -> Int
sizeofBuild0 Build
xs
    MutableByteArray s
marr <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray Int
len
    MutableByteArray s -> Int -> Build -> ST s ()
forall s. MutableByteArray s -> Int -> Build -> ST s ()
writeArr MutableByteArray s
marr Int
len Build
xs
    ByteArray ByteArray#
arr <- MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
marr
    ShortByteString -> ST s ShortByteString
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ShortByteString -> ST s ShortByteString)
-> ShortByteString -> ST s ShortByteString
forall a b. (a -> b) -> a -> b
$ ByteArray# -> ShortByteString
SBS ByteArray#
arr

{-# INLINE buildShortByteString1 #-}
buildShortByteString1 :: Build1 -> ShortByteString
buildShortByteString1 :: Build1 -> ShortByteString
buildShortByteString1 Build1
xs =
  (forall s. ST s ShortByteString) -> ShortByteString
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ShortByteString) -> ShortByteString)
-> (forall s. ST s ShortByteString) -> ShortByteString
forall a b. (a -> b) -> a -> b
$ do
    let len :: Int
len = Build1 -> Int
sizeofBuild1 Build1
xs
    MutableByteArray s
marr <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray Int
len
    MutableByteArray s -> Int -> Build1 -> ST s ()
forall s. MutableByteArray s -> Int -> Build1 -> ST s ()
writeArr1 MutableByteArray s
marr Int
len Build1
xs
    ByteArray ByteArray#
arr <- MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
marr
    ShortByteString -> ST s ShortByteString
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ShortByteString -> ST s ShortByteString)
-> ShortByteString -> ST s ShortByteString
forall a b. (a -> b) -> a -> b
$ ByteArray# -> ShortByteString
SBS ByteArray#
arr

{-# INLINE unsafeBuildText0 #-}
unsafeBuildText0 :: Build -> Strict.Text
unsafeBuildText0 :: Build -> Text
unsafeBuildText0 Build
xs =
  (forall s. ST s Text) -> Text
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s Text) -> Text) -> (forall s. ST s Text) -> Text
forall a b. (a -> b) -> a -> b
$ do
    let len :: Int
len = Build -> Int
sizeofBuild0 Build
xs
    MutableByteArray s
marr <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray Int
len
    MutableByteArray s -> Int -> Build -> ST s ()
forall s. MutableByteArray s -> Int -> Build -> ST s ()
writeArr MutableByteArray s
marr Int
len Build
xs
    ByteArray ByteArray#
arr <- MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
marr
    Text -> ST s Text
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> ST s Text) -> Text -> ST s Text
forall a b. (a -> b) -> a -> b
$ Array -> Int -> Int -> Text
Strict.Text (ByteArray# -> Array
Array.ByteArray ByteArray#
arr) Int
0 Int
len

{-# INLINE unsafeBuildText1 #-}
unsafeBuildText1 :: Build1 -> Strict.Text
unsafeBuildText1 :: Build1 -> Text
unsafeBuildText1 Build1
xs =
  (forall s. ST s Text) -> Text
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s Text) -> Text) -> (forall s. ST s Text) -> Text
forall a b. (a -> b) -> a -> b
$ do
    let len :: Int
len = Build1 -> Int
sizeofBuild1 Build1
xs
    MutableByteArray s
marr <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
newByteArray Int
len
    MutableByteArray s -> Int -> Build1 -> ST s ()
forall s. MutableByteArray s -> Int -> Build1 -> ST s ()
writeArr1 MutableByteArray s
marr Int
len Build1
xs
    ByteArray ByteArray#
arr <- MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray s
MutableByteArray (PrimState (ST s))
marr
    Text -> ST s Text
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> ST s Text) -> Text -> ST s Text
forall a b. (a -> b) -> a -> b
$ Array -> Int -> Int -> Text
Strict.Text (ByteArray# -> Array
Array.ByteArray ByteArray#
arr) Int
0 Int
len



-- | Key as a sequence of individual bytes.
newtype Feed = Feed
                 -- | @destroy@ part of the @destroy/unfoldr@ rule.
                 (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)

{-# INLINE vomit #-}
vomit :: (x -> Step a x) -> x -> [a]
vomit :: forall x a. (x -> Step a x) -> x -> [a]
vomit x -> Step a x
step = x -> [a]
go
  where
    go :: x -> [a]
go x
s =
      case x -> Step a x
step x
s of
        More a
w x
ws -> a
w a -> [a] -> [a]
forall a. a -> [a] -> [a]
: x -> [a]
go x
ws
        Step a x
Done      -> []

instance Show Feed where
  showsPrec :: Int -> Feed -> ShowS
showsPrec Int
d (Feed forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a
f) = Int -> [Word8] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
d ([Word8] -> ShowS) -> [Word8] -> ShowS
forall a b. (a -> b) -> a -> b
$ (forall x. (x -> Step Word8 x) -> x -> [Word8]) -> [Word8]
forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a
f (x -> Step Word8 x) -> x -> [Word8]
forall x. (x -> Step Word8 x) -> x -> [Word8]
forall x a. (x -> Step a x) -> x -> [a]
vomit

noFeed :: Feed
noFeed :: Feed
noFeed = (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a) -> Feed
Feed ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f -> (() -> Step Word8 ()) -> () -> a
forall x. (x -> Step Word8 x) -> x -> a
f (\()
_ -> Step Word8 ()
forall a b. Step a b
Done) ()

{-# INLINE feedBytes0 #-}
feedBytes0 :: [Word8] -> Feed
feedBytes0 :: [Word8] -> Feed
feedBytes0 [Word8]
ws0 = (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a) -> Feed
Feed ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f -> ([Word8] -> Step Word8 [Word8]) -> [Word8] -> a
forall x. (x -> Step Word8 x) -> x -> a
f [Word8] -> Step Word8 [Word8]
forall {a}. [a] -> Step a [a]
go [Word8]
ws0
  where
    go :: [a] -> Step a [a]
go (a
w:[a]
ws) = a -> [a] -> Step a [a]
forall a b. a -> b -> Step a b
More a
w [a]
ws
    go []     = Step a [a]
forall a b. Step a b
Done



-- | Key as a non-empty sequence of individual bytes.
data Feed1 = Feed1
               -- | First byte of the key.
               {-# UNPACK #-} !Word8

               -- | @destroy@ part of the @destroy/unfoldr@ rule.
               (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)

instance Show Feed1 where
  showsPrec :: Int -> Feed1 -> ShowS
showsPrec Int
d (Feed1 Word8
w0 forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a
f) = Int -> NonEmpty Word8 -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
d (NonEmpty Word8 -> ShowS) -> NonEmpty Word8 -> ShowS
forall a b. (a -> b) -> a -> b
$ Word8
w0 Word8 -> [Word8] -> NonEmpty Word8
forall a. a -> [a] -> NonEmpty a
:| (forall x. (x -> Step Word8 x) -> x -> [Word8]) -> [Word8]
forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a
f (x -> Step Word8 x) -> x -> [Word8]
forall x. (x -> Step Word8 x) -> x -> [Word8]
forall x a. (x -> Step a x) -> x -> [a]
vomit

{-# INLINE feedBytes1 #-}
feedBytes1 :: NonEmpty Word8 -> Feed1
feedBytes1 :: NonEmpty Word8 -> Feed1
feedBytes1 (Word8
w0 :| [Word8]
ws) =
  let Feed forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a
f = [Word8] -> Feed
feedBytes0 [Word8]
ws
  in Word8
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed1
Feed1 Word8
w0 (forall x. (x -> Step Word8 x) -> x -> a) -> a
forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a
f




stepByteString :: Strict.ByteString -> Int -> Step Word8 Int
stepByteString :: ByteString -> Int -> Step Word8 Int
stepByteString ByteString
bs = Int -> Step Word8 Int
go
  where
    go :: Int -> Step Word8 Int
go Int
n =
      if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= ByteString -> Int
BS.length ByteString
bs
        then Step Word8 Int
forall a b. Step a b
Done
        else let !n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
             in Word8 -> Int -> Step Word8 Int
forall a b. a -> b -> Step a b
More (ByteString -> Int -> Word8
unsafeIndex ByteString
bs Int
n) Int
n'

{-# INLINE feedByteString0 #-}
feedByteString0 :: Strict.ByteString -> Feed
feedByteString0 :: ByteString -> Feed
feedByteString0 ByteString
bs = (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a) -> Feed
Feed ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f -> (Int -> Step Word8 Int) -> Int -> a
forall x. (x -> Step Word8 x) -> x -> a
f (ByteString -> Int -> Step Word8 Int
stepByteString ByteString
bs) Int
0

{-# INLINE unsafeFeedByteString1 #-}
unsafeFeedByteString1 :: Strict.ByteString -> Feed1
unsafeFeedByteString1 :: ByteString -> Feed1
unsafeFeedByteString1 ByteString
bs = Word8
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed1
Feed1 (ByteString -> Int -> Word8
unsafeIndex ByteString
bs Int
0) (\forall x. (x -> Step Word8 x) -> x -> a
f -> (Int -> Step Word8 Int) -> Int -> a
forall x. (x -> Step Word8 x) -> x -> a
f (ByteString -> Int -> Step Word8 Int
stepByteString ByteString
bs) Int
1)



stepByteArray :: ByteArray -> Int -> Int -> Step Word8 Int
stepByteArray :: ByteArray -> Int -> Int -> Step Word8 Int
stepByteArray ByteArray
arr Int
len = Int -> Step Word8 Int
forall {a}. Prim a => Int -> Step a Int
go
  where
    go :: Int -> Step a Int
go Int
n =
      if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
len
        then Step a Int
forall a b. Step a b
Done
        else let !n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
             in a -> Int -> Step a Int
forall a b. a -> b -> Step a b
More (ByteArray -> Int -> a
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
arr Int
n) Int
n'

{-# INLINE feedShortByteString0 #-}
feedShortByteString0 :: ShortByteString -> Feed
feedShortByteString0 :: ShortByteString -> Feed
feedShortByteString0 (SBS ByteArray#
arr) =
  (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a) -> Feed
Feed ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f ->
    (Int -> Step Word8 Int) -> Int -> a
forall x. (x -> Step Word8 x) -> x -> a
f (ByteArray -> Int -> Int -> Step Word8 Int
stepByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
arr) (Int -> Int -> Step Word8 Int) -> Int -> Int -> Step Word8 Int
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int
sizeofByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
arr)) Int
0

{-# INLINE unsafeFeedShortByteString1 #-}
unsafeFeedShortByteString1 :: ShortByteString -> Feed1
unsafeFeedShortByteString1 :: ShortByteString -> Feed1
unsafeFeedShortByteString1 (SBS ByteArray#
arr) =
  Word8
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed1
Feed1 (ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
indexByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
arr) Int
0) ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed1)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed1
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f ->
    (Int -> Step Word8 Int) -> Int -> a
forall x. (x -> Step Word8 x) -> x -> a
f (ByteArray -> Int -> Int -> Step Word8 Int
stepByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
arr) (Int -> Int -> Step Word8 Int) -> Int -> Int -> Step Word8 Int
forall a b. (a -> b) -> a -> b
$ ByteArray -> Int
sizeofByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
arr)) Int
1



{-# INLINE feedText0 #-}
feedText0 :: Strict.Text -> Feed
feedText0 :: Text -> Feed
feedText0 (Strict.Text (Array.ByteArray ByteArray#
arr) Int
n Int
len) =
  (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a) -> Feed
Feed ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f ->
    (Int -> Step Word8 Int) -> Int -> a
forall x. (x -> Step Word8 x) -> x -> a
f (ByteArray -> Int -> Int -> Step Word8 Int
stepByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
arr) Int
len) Int
n

{-# INLINE unsafeFeedText1 #-}
unsafeFeedText1 :: Strict.Text -> Feed1
unsafeFeedText1 :: Text -> Feed1
unsafeFeedText1 (Strict.Text (Array.ByteArray ByteArray#
arr) Int
n Int
len) =
  Word8
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed1
Feed1 (ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
indexByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
arr) Int
n) ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed1)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed1
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f ->
    let !n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
    in (Int -> Step Word8 Int) -> Int -> a
forall x. (x -> Step Word8 x) -> x -> a
f (ByteArray -> Int -> Int -> Step Word8 Int
stepByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
arr) Int
len) Int
n'



data CarryBS = CarryBS Int Strict.ByteString Lazy.ByteString

{-# INLINE stepLazyByteString #-}
stepLazyByteString :: CarryBS -> Step Word8 CarryBS
stepLazyByteString :: CarryBS -> Step Word8 CarryBS
stepLazyByteString (CarryBS Int
n ByteString
bs ByteString
lbs) =
  if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= ByteString -> Int
BS.length ByteString
bs
    then case ByteString
lbs of
           LazyBS.Chunk ByteString
bs' ByteString
lbs' -> CarryBS -> Step Word8 CarryBS
stepLazyByteString (Int -> ByteString -> ByteString -> CarryBS
CarryBS Int
0 ByteString
bs' ByteString
lbs')
           ByteString
LazyBS.Empty          -> Step Word8 CarryBS
forall a b. Step a b
Done

    else let !n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
         in Word8 -> CarryBS -> Step Word8 CarryBS
forall a b. a -> b -> Step a b
More (ByteString -> Int -> Word8
unsafeIndex ByteString
bs Int
n) (Int -> ByteString -> ByteString -> CarryBS
CarryBS Int
n' ByteString
bs ByteString
lbs)

{-# INLINE feedLazyByteString0 #-}
feedLazyByteString0 :: Lazy.ByteString -> Feed
feedLazyByteString0 :: ByteString -> Feed
feedLazyByteString0 ByteString
b =
  case ByteString
b of
    ByteString
LazyBS.Empty        -> Feed
noFeed
    LazyBS.Chunk ByteString
bs ByteString
lbs -> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a) -> Feed
Feed ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f -> (CarryBS -> Step Word8 CarryBS) -> CarryBS -> a
forall x. (x -> Step Word8 x) -> x -> a
f CarryBS -> Step Word8 CarryBS
stepLazyByteString (Int -> ByteString -> ByteString -> CarryBS
CarryBS Int
0 ByteString
bs ByteString
lbs)

{-# INLINE unsafeFeedLazyByteString1 #-}
unsafeFeedLazyByteString1 :: Strict.ByteString -> Lazy.ByteString -> Feed1
unsafeFeedLazyByteString1 :: ByteString -> ByteString -> Feed1
unsafeFeedLazyByteString1 ByteString
bs ByteString
lbs =
  Word8
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed1
Feed1 (ByteString -> Int -> Word8
unsafeIndex ByteString
bs Int
0) ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed1)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed1
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f ->
    (CarryBS -> Step Word8 CarryBS) -> CarryBS -> a
forall x. (x -> Step Word8 x) -> x -> a
f CarryBS -> Step Word8 CarryBS
stepLazyByteString (Int -> ByteString -> ByteString -> CarryBS
CarryBS Int
1 ByteString
bs ByteString
lbs)



data CarryTxt = CarryTxt Int Int ByteArray Lazy.Text

{-# INLINE stepLazyText #-}
stepLazyText :: CarryTxt -> Step Word8 CarryTxt
stepLazyText :: CarryTxt -> Step Word8 CarryTxt
stepLazyText (CarryTxt Int
n Int
len ByteArray
arr Text
t) =
  if Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
len
    then case Text
t of
           LazyText.Chunk (Strict.Text (Array.ByteArray ByteArray#
arr') Int
n' Int
len') Text
t' ->
             CarryTxt -> Step Word8 CarryTxt
stepLazyText (Int -> Int -> ByteArray -> Text -> CarryTxt
CarryTxt Int
n' Int
len' (ByteArray# -> ByteArray
ByteArray ByteArray#
arr') Text
t')

           Text
LazyText.Empty -> Step Word8 CarryTxt
forall a b. Step a b
Done

    else let !n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
         in Word8 -> CarryTxt -> Step Word8 CarryTxt
forall a b. a -> b -> Step a b
More (ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
indexByteArray ByteArray
arr Int
n) (Int -> Int -> ByteArray -> Text -> CarryTxt
CarryTxt Int
n' Int
len ByteArray
arr Text
t)

{-# INLINE feedLazyText0 #-}
feedLazyText0 :: Lazy.Text -> Feed
feedLazyText0 :: Text -> Feed
feedLazyText0 Text
t =
  case Text
t of
    Text
LazyText.Empty                                                -> Feed
noFeed
    LazyText.Chunk (Strict.Text (Array.ByteArray ByteArray#
arr) Int
n Int
len) Text
ltxt ->
      (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a) -> Feed
Feed ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f -> (CarryTxt -> Step Word8 CarryTxt) -> CarryTxt -> a
forall x. (x -> Step Word8 x) -> x -> a
f CarryTxt -> Step Word8 CarryTxt
stepLazyText (Int -> Int -> ByteArray -> Text -> CarryTxt
CarryTxt Int
n Int
len (ByteArray# -> ByteArray
ByteArray ByteArray#
arr) Text
ltxt)

{-# INLINE unsafeFeedLazyText1 #-}
unsafeFeedLazyText1 :: Strict.Text -> Lazy.Text -> Feed1
unsafeFeedLazyText1 :: Text -> Text -> Feed1
unsafeFeedLazyText1 (Strict.Text (Array.ByteArray ByteArray#
arr) Int
n Int
len) Text
ltxt =
  Word8
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed1
Feed1 (ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
indexByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
arr) Int
n) ((forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
 -> Feed1)
-> (forall a. (forall x. (x -> Step Word8 x) -> x -> a) -> a)
-> Feed1
forall a b. (a -> b) -> a -> b
$ \forall x. (x -> Step Word8 x) -> x -> a
f ->
    let !n' :: Int
n' = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
    in (CarryTxt -> Step Word8 CarryTxt) -> CarryTxt -> a
forall x. (x -> Step Word8 x) -> x -> a
f CarryTxt -> Step Word8 CarryTxt
stepLazyText (Int -> Int -> ByteArray -> Text -> CarryTxt
CarryTxt Int
n' Int
len (ByteArray# -> ByteArray
ByteArray ByteArray#
arr) Text
ltxt)