{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE BinaryLiterals #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GADTSyntax #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UnboxedTuples #-}

module Data.Bytes.Parser.Internal
  ( Parser (..)
  , Result (..)
  , InternalStep (..)
  , Bytes#
  , ST#
  , Result#
  , unfailing
  , uneffectful
  , uneffectful#
  , uneffectfulInt#
  , boxBytes
  , unboxBytes
  , unboxResult
  , fail
  , indexLatinCharArray
  , upcastUnitSuccess
  -- Swapping
  , swapArray16
  , swapArray32
  , swapArray64
  , swapArray128
  , swapArray256
  ) where

import Prelude hiding (any, fail, length, takeWhile)

import Control.Applicative (Alternative)
import Control.Monad.ST (runST)
import Data.Bytes.Types (Bytes (..))
import Data.Kind (Type)
import Data.Primitive (ByteArray (ByteArray))
import Data.Word (Word8)
import GHC.Exts (ByteArray#, Char (C#), Int (I#), Int#, RuntimeRep, State#, TYPE)

import qualified Control.Applicative
import qualified Control.Monad
import qualified Data.Primitive as PM
import qualified GHC.Exts as Exts

-- | A non-resumable parser.
newtype Parser :: forall (r :: RuntimeRep). Type -> Type -> TYPE r -> Type where
  Parser ::
    forall (r :: RuntimeRep) (e :: Type) (s :: Type) (a :: TYPE r).
    {forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser :: (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)} ->
    Parser e s a

-- The result of running a parser. Used internally.
data Result e a
  = Failure e
  | -- An error message indicating what went wrong.
    Success !a !Int !Int

-- The parsed value, the offset after the last consumed byte, and the
-- number of bytes remaining in parsed slice.

data InternalStep a = InternalStep !a !Int !Int

uneffectful :: (Bytes -> Result e a) -> Parser e s a
{-# INLINE uneffectful #-}
uneffectful :: forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful Bytes -> Result e a
f =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
    (\(# ByteArray#, Int#, Int# #)
b State# s
s0 -> (# State# s
s0, Result e a -> Result# e a
forall e a. Result e a -> Result# e a
unboxResult (Bytes -> Result e a
f ((# ByteArray#, Int#, Int# #) -> Bytes
boxBytes (# ByteArray#, Int#, Int# #)
b)) #))

-- This is like uneffectful but for parsers that always succeed.
-- These combinators typically have names that begin with @try@.
unfailing :: (Bytes -> InternalStep a) -> Parser e s a
{-# INLINE unfailing #-}
unfailing :: forall a e s. (Bytes -> InternalStep a) -> Parser e s a
unfailing Bytes -> InternalStep a
f =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
    (\(# ByteArray#, Int#, Int# #)
b State# s
s0 -> (# State# s
s0, case Bytes -> InternalStep a
f ((# ByteArray#, Int#, Int# #) -> Bytes
boxBytes (# ByteArray#, Int#, Int# #)
b) of InternalStep a
a (I# Int#
off) (I# Int#
len) -> (# | (# a
a, Int#
off, Int#
len #) #) #))

boxBytes :: Bytes# -> Bytes
{-# INLINE boxBytes #-}
boxBytes :: (# ByteArray#, Int#, Int# #) -> Bytes
boxBytes (# ByteArray#
a, Int#
b, Int#
c #) = ByteArray -> Int -> Int -> Bytes
Bytes (ByteArray# -> ByteArray
ByteArray ByteArray#
a) (Int# -> Int
I# Int#
b) (Int# -> Int
I# Int#
c)

unboxBytes :: Bytes -> Bytes#
{-# INLINE unboxBytes #-}
unboxBytes :: Bytes -> (# ByteArray#, Int#, Int# #)
unboxBytes (Bytes (ByteArray ByteArray#
a) (I# Int#
b) (I# Int#
c)) = (# ByteArray#
a, Int#
b, Int#
c #)

type Bytes# = (# ByteArray#, Int#, Int# #)
type ST# s (a :: TYPE r) = State# s -> (# State# s, a #)
type Result# e (a :: TYPE r) =
  (#
    e |
    (# a, Int#, Int# #) -- ints are offset and length
  #)

unboxResult :: Result e a -> Result# e a
{-# INLINE unboxResult #-}
unboxResult :: forall e a. Result e a -> Result# e a
unboxResult (Success a
a (I# Int#
b) (I# Int#
c)) = (# | (# a
a, Int#
b, Int#
c #) #)
unboxResult (Failure e
e) = (# e
e | #)

{- | Combines the error messages using '<>' when both
parsers fail.
-}
instance (Monoid e) => Alternative (Parser e s) where
  {-# INLINE empty #-}
  {-# INLINE (<|>) #-}
  empty :: forall a. Parser e s a
empty = e -> Parser e s a
forall e s a. e -> Parser e s a
fail e
forall a. Monoid a => a
mempty
  Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f <|> :: forall a. Parser e s a -> Parser e s a -> Parser e s a
<|> Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
g =
    ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
      ( \(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
          (# State# s
s1, Result# e a
r0 #) -> case Result# e a
r0 of
            (# e
eRight | #) -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
g (# ByteArray#, Int#, Int# #)
x State# s
s1 of
              (# State# s
s2, Result# e a
r1 #) -> case Result# e a
r1 of
                (# e
eLeft | #) -> (# State# s
s2, (# e
eRight e -> e -> e
forall a. Semigroup a => a -> a -> a
<> e
eLeft | #) #)
                (# | (# a, Int#, Int# #)
r #) -> (# State# s
s2, (# | (# a, Int#, Int# #)
r #) #)
            (# | (# a, Int#, Int# #)
r #) -> (# State# s
s1, (# | (# a, Int#, Int# #)
r #) #)
      )

-- | Fail with the provided error message.
fail ::
  -- | Error message
  e ->
  Parser e s a
{-# INLINE fail #-}
fail :: forall e s a. e -> Parser e s a
fail e
e = (Bytes -> Result e a) -> Parser e s a
forall e a s. (Bytes -> Result e a) -> Parser e s a
uneffectful ((Bytes -> Result e a) -> Parser e s a)
-> (Bytes -> Result e a) -> Parser e s a
forall a b. (a -> b) -> a -> b
$ \Bytes
_ -> e -> Result e a
forall e a. e -> Result e a
Failure e
e

instance Applicative (Parser e s) where
  pure :: forall a. a -> Parser e s a
pure = a -> Parser e s a
forall a e s. a -> Parser e s a
pureParser
  <*> :: forall a b. Parser e s (a -> b) -> Parser e s a -> Parser e s b
(<*>) = Parser e s (a -> b) -> Parser e s a -> Parser e s b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
Control.Monad.ap

instance Monad (Parser e s) where
  {-# INLINE (>>=) #-}
  >>= :: forall a b. Parser e s a -> (a -> Parser e s b) -> Parser e s b
(>>=) = Parser e s a -> (a -> Parser e s b) -> Parser e s b
forall e s a b. Parser e s a -> (a -> Parser e s b) -> Parser e s b
bindParser

instance Functor (Parser e s) where
  {-# INLINE fmap #-}
  fmap :: forall a b. (a -> b) -> Parser e s a -> Parser e s b
fmap a -> b
f (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
g) =
    ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e b))
-> Parser e s b
forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
      ( \(# ByteArray#, Int#, Int# #)
x State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
g (# ByteArray#, Int#, Int# #)
x State# s
s0 of
          (# State# s
s1, Result# e a
r #) -> case Result# e a
r of
            (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
            (# | (# a
a, Int#
b, Int#
c #) #) -> (# State# s
s1, (# | (# a -> b
f a
a, Int#
b, Int#
c #) #) #)
      )

indexLatinCharArray :: ByteArray -> Int -> Char
{-# INLINE indexLatinCharArray #-}
indexLatinCharArray :: ByteArray -> Int -> Char
indexLatinCharArray (ByteArray ByteArray#
arr) (I# Int#
off) =
  Char# -> Char
C# (ByteArray# -> Int# -> Char#
Exts.indexCharArray# ByteArray#
arr Int#
off)

uneffectful# :: (Bytes -> Result# e a) -> Parser e s a
{-# INLINE uneffectful# #-}
uneffectful# :: forall e a s. (Bytes -> Result# e a) -> Parser e s a
uneffectful# Bytes -> Result# e a
f =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
    (\(# ByteArray#, Int#, Int# #)
b State# s
s0 -> (# State# s
s0, (Bytes -> Result# e a
f ((# ByteArray#, Int#, Int# #) -> Bytes
boxBytes (# ByteArray#, Int#, Int# #)
b)) #))

uneffectfulInt# :: (Bytes -> Result# e Int#) -> Parser e s Int#
{-# INLINE uneffectfulInt# #-}
uneffectfulInt# :: forall e s. (Bytes -> Result# e Int#) -> Parser e s Int#
uneffectfulInt# Bytes -> Result# e Int#
f =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e Int#))
-> Parser e s Int#
forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
    (\(# ByteArray#, Int#, Int# #)
b State# s
s0 -> (# State# s
s0, (Bytes -> Result# e Int#
f ((# ByteArray#, Int#, Int# #) -> Bytes
boxBytes (# ByteArray#, Int#, Int# #)
b)) #))

upcastUnitSuccess :: (# Int#, Int# #) -> Result# e ()
{-# INLINE upcastUnitSuccess #-}
upcastUnitSuccess :: forall e. (# Int#, Int# #) -> Result# e ()
upcastUnitSuccess (# Int#
b, Int#
c #) = (# | (# (), Int#
b, Int#
c #) #)

swapArray16 :: Bytes -> ByteArray
swapArray16 :: Bytes -> ByteArray
swapArray16 (Bytes {ByteArray
array :: ByteArray
$sel:array:Bytes :: Bytes -> ByteArray
array, Int
offset :: Int
$sel:offset:Bytes :: Bytes -> Int
offset, Int
length :: Int
$sel:length:Bytes :: Bytes -> Int
length}) = (forall s. ST s ByteArray) -> ByteArray
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ByteArray) -> ByteArray)
-> (forall s. ST s ByteArray) -> ByteArray
forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray (PrimState (ST s))
dst <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
PM.newByteArray Int
length
  let go :: Int -> Int -> t -> ST s ()
go !Int
ixSrc !Int
ixDst !t
len =
        if t
len t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
0
          then do
            let v0 :: Word8
v0 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array Int
ixSrc :: Word8
                v1 :: Word8
v1 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) :: Word8
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst Int
ixDst Word8
v1
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Word8
v0
            Int -> Int -> t -> ST s ()
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) (t
len t -> t -> t
forall a. Num a => a -> a -> a
- t
2)
          else () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  Int -> Int -> Int -> ST s ()
forall {t}. (Ord t, Num t) => Int -> Int -> t -> ST s ()
go Int
offset Int
0 Int
length
  MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
PM.unsafeFreezeByteArray MutableByteArray (PrimState (ST s))
dst

swapArray32 :: Bytes -> ByteArray
swapArray32 :: Bytes -> ByteArray
swapArray32 (Bytes {ByteArray
$sel:array:Bytes :: Bytes -> ByteArray
array :: ByteArray
array, Int
$sel:offset:Bytes :: Bytes -> Int
offset :: Int
offset, Int
$sel:length:Bytes :: Bytes -> Int
length :: Int
length}) = (forall s. ST s ByteArray) -> ByteArray
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ByteArray) -> ByteArray)
-> (forall s. ST s ByteArray) -> ByteArray
forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray (PrimState (ST s))
dst <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
PM.newByteArray Int
length
  let go :: Int -> Int -> t -> ST s ()
go !Int
ixSrc !Int
ixDst !t
len =
        if t
len t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
0
          then do
            let v0 :: Word8
v0 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array Int
ixSrc :: Word8
                v1 :: Word8
v1 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) :: Word8
                v2 :: Word8
v2 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) :: Word8
                v3 :: Word8
v3 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3) :: Word8
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst Int
ixDst Word8
v3
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Word8
v2
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Word8
v1
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3) Word8
v0
            Int -> Int -> t -> ST s ()
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
4) (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
4) (t
len t -> t -> t
forall a. Num a => a -> a -> a
- t
4)
          else () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  Int -> Int -> Int -> ST s ()
forall {t}. (Ord t, Num t) => Int -> Int -> t -> ST s ()
go Int
offset Int
0 Int
length
  MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
PM.unsafeFreezeByteArray MutableByteArray (PrimState (ST s))
dst

swapArray64 :: Bytes -> ByteArray
swapArray64 :: Bytes -> ByteArray
swapArray64 (Bytes {ByteArray
$sel:array:Bytes :: Bytes -> ByteArray
array :: ByteArray
array, Int
$sel:offset:Bytes :: Bytes -> Int
offset :: Int
offset, Int
$sel:length:Bytes :: Bytes -> Int
length :: Int
length}) = (forall s. ST s ByteArray) -> ByteArray
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ByteArray) -> ByteArray)
-> (forall s. ST s ByteArray) -> ByteArray
forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray (PrimState (ST s))
dst <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
PM.newByteArray Int
length
  let go :: Int -> Int -> t -> ST s ()
go !Int
ixSrc !Int
ixDst !t
len =
        if t
len t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
0
          then do
            let v0 :: Word8
v0 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array Int
ixSrc :: Word8
                v1 :: Word8
v1 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) :: Word8
                v2 :: Word8
v2 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) :: Word8
                v3 :: Word8
v3 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3) :: Word8
                v4 :: Word8
v4 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
4) :: Word8
                v5 :: Word8
v5 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
5) :: Word8
                v6 :: Word8
v6 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6) :: Word8
                v7 :: Word8
v7 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7) :: Word8
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst Int
ixDst Word8
v7
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Word8
v6
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Word8
v5
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3) Word8
v4
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
4) Word8
v3
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
5) Word8
v2
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6) Word8
v1
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7) Word8
v0
            Int -> Int -> t -> ST s ()
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8) (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8) (t
len t -> t -> t
forall a. Num a => a -> a -> a
- t
8)
          else () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  Int -> Int -> Int -> ST s ()
forall {t}. (Ord t, Num t) => Int -> Int -> t -> ST s ()
go Int
offset Int
0 Int
length
  MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
PM.unsafeFreezeByteArray MutableByteArray (PrimState (ST s))
dst

swapArray128 :: Bytes -> ByteArray
swapArray128 :: Bytes -> ByteArray
swapArray128 (Bytes {ByteArray
$sel:array:Bytes :: Bytes -> ByteArray
array :: ByteArray
array, Int
$sel:offset:Bytes :: Bytes -> Int
offset :: Int
offset, Int
$sel:length:Bytes :: Bytes -> Int
length :: Int
length}) = (forall s. ST s ByteArray) -> ByteArray
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ByteArray) -> ByteArray)
-> (forall s. ST s ByteArray) -> ByteArray
forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray (PrimState (ST s))
dst <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
PM.newByteArray Int
length
  let go :: Int -> Int -> t -> ST s ()
go !Int
ixSrc !Int
ixDst !t
len =
        if t
len t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
0
          then do
            let v0 :: Word8
v0 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array Int
ixSrc :: Word8
                v1 :: Word8
v1 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) :: Word8
                v2 :: Word8
v2 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) :: Word8
                v3 :: Word8
v3 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3) :: Word8
                v4 :: Word8
v4 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
4) :: Word8
                v5 :: Word8
v5 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
5) :: Word8
                v6 :: Word8
v6 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6) :: Word8
                v7 :: Word8
v7 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7) :: Word8
                v8 :: Word8
v8 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8) :: Word8
                v9 :: Word8
v9 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
9) :: Word8
                v10 :: Word8
v10 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
10) :: Word8
                v11 :: Word8
v11 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
11) :: Word8
                v12 :: Word8
v12 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
12) :: Word8
                v13 :: Word8
v13 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
13) :: Word8
                v14 :: Word8
v14 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
14) :: Word8
                v15 :: Word8
v15 = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
15) :: Word8
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst Int
ixDst Word8
v15
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Word8
v14
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
2) Word8
v13
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
3) Word8
v12
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
4) Word8
v11
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
5) Word8
v10
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
6) Word8
v9
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7) Word8
v8
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
8) Word8
v7
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
9) Word8
v6
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
10) Word8
v5
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
11) Word8
v4
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
12) Word8
v3
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
13) Word8
v2
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
14) Word8
v1
            MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
15) Word8
v0
            Int -> Int -> t -> ST s ()
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
16) (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
16) (t
len t -> t -> t
forall a. Num a => a -> a -> a
- t
16)
          else () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  Int -> Int -> Int -> ST s ()
forall {t}. (Ord t, Num t) => Int -> Int -> t -> ST s ()
go Int
offset Int
0 Int
length
  MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
PM.unsafeFreezeByteArray MutableByteArray (PrimState (ST s))
dst

swapArray256 :: Bytes -> ByteArray
swapArray256 :: Bytes -> ByteArray
swapArray256 (Bytes {ByteArray
$sel:array:Bytes :: Bytes -> ByteArray
array :: ByteArray
array, Int
$sel:offset:Bytes :: Bytes -> Int
offset :: Int
offset, Int
$sel:length:Bytes :: Bytes -> Int
length :: Int
length}) = (forall s. ST s ByteArray) -> ByteArray
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s ByteArray) -> ByteArray)
-> (forall s. ST s ByteArray) -> ByteArray
forall a b. (a -> b) -> a -> b
$ do
  MutableByteArray (PrimState (ST s))
dst <- Int -> ST s (MutableByteArray (PrimState (ST s)))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
PM.newByteArray Int
length
  let go :: Int -> Int -> t -> ST s ()
go !Int
ixSrc !Int
ixDst !t
len =
        if t
len t -> t -> Bool
forall a. Ord a => a -> a -> Bool
> t
0
          then do
            let loop :: Int -> ST s ()
loop !Int
i
                  | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
32 = do
                      let v :: Word8
v = ByteArray -> Int -> Word8
forall a. Prim a => ByteArray -> Int -> a
PM.indexByteArray ByteArray
array (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i) :: Word8
                      MutableByteArray (PrimState (ST s)) -> Int -> Word8 -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
PM.writeByteArray MutableByteArray (PrimState (ST s))
dst (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int
31 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i)) Word8
v
                      Int -> ST s ()
loop (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
                  | Bool
otherwise = () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
            Int -> ST s ()
loop Int
0
            Int -> Int -> t -> ST s ()
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
32) (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
32) (t
len t -> t -> t
forall a. Num a => a -> a -> a
- t
32)
          else () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  Int -> Int -> Int -> ST s ()
forall {t}. (Ord t, Num t) => Int -> Int -> t -> ST s ()
go Int
offset Int
0 Int
length
  MutableByteArray (PrimState (ST s)) -> ST s ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m ByteArray
PM.unsafeFreezeByteArray MutableByteArray (PrimState (ST s))
dst

pureParser :: a -> Parser e s a
{-# INLINE pureParser #-}
pureParser :: forall a e s. a -> Parser e s a
pureParser a
a =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
    (\(# ByteArray#
_, Int#
b, Int#
c #) State# s
s -> (# State# s
s, (# | (# a
a, Int#
b, Int#
c #) #) #))

bindParser :: Parser e s a -> (a -> Parser e s b) -> Parser e s b
{-# INLINE bindParser #-}
bindParser :: forall e s a b. Parser e s a -> (a -> Parser e s b) -> Parser e s b
bindParser (Parser (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f) a -> Parser e s b
g =
  ((# ByteArray#, Int#, Int# #) -> ST# s (Result# e b))
-> Parser e s b
forall e s a.
((# ByteArray#, Int#, Int# #) -> ST# s (Result# e a))
-> Parser e s a
Parser
    ( \x :: (# ByteArray#, Int#, Int# #)
x@(# ByteArray#
arr, Int#
_, Int#
_ #) State# s
s0 -> case (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
f (# ByteArray#, Int#, Int# #)
x State# s
s0 of
        (# State# s
s1, Result# e a
r0 #) -> case Result# e a
r0 of
          (# e
e | #) -> (# State# s
s1, (# e
e | #) #)
          (# | (# a
y, Int#
b, Int#
c #) #) ->
            Parser e s b -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e b)
forall e s a.
Parser e s a -> (# ByteArray#, Int#, Int# #) -> ST# s (Result# e a)
runParser (a -> Parser e s b
g a
y) (# ByteArray#
arr, Int#
b, Int#
c #) State# s
s1
    )