{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Data.Primitive.ByteArray
  ( -- * Types
    ByteArray(..)
  , MutableByteArray(..)
  , A.ByteArray#
  , A.MutableByteArray#
    -- * Allocation
  , newByteArray
  , newPinnedByteArray
  , newAlignedPinnedByteArray
  , resizeMutableByteArray
  , shrinkMutableByteArray
    -- * Element access
  , readByteArray
  , writeByteArray
  , indexByteArray
    -- * Constructing
  , A.emptyByteArray
  , A.byteArrayFromList
  , A.byteArrayFromListN
    -- * Folding
  , A.foldrByteArray
    -- * Comparing
  , compareByteArrays
    -- * Freezing and thawing
  , freezeByteArray
  , thawByteArray
  , A.runByteArray
  , unsafeFreezeByteArray
  , A.unsafeThawByteArray
    -- * Block operations
  , copyByteArray
  , copyMutableByteArray
  , copyByteArrayToPtr
  , copyMutableByteArrayToPtr
  , copyByteArrayToAddr
  , copyMutableByteArrayToAddr
  , moveByteArray
  , setByteArray
  , fillByteArray
  , cloneByteArray
  , cloneMutableByteArray
  -- * Information
  , A.sizeofByteArray
  , A.sizeofMutableByteArray
  , A.getSizeofMutableByteArray
  , A.sameMutableByteArray
  , A.isByteArrayPinned
  , A.isMutableByteArrayPinned
  , A.byteArrayContents
  , A.mutableByteArrayContents
  ) where

import Control.Monad.Primitive (PrimMonad,PrimState)
import Control.Exception (throw, ArrayException(..))
import Data.Primitive.Types (Prim, Ptr, sizeOf)
import Data.Proxy (Proxy(..))
import Data.Word (Word8)
import "primitive" Data.Primitive.ByteArray (ByteArray, MutableByteArray)
import qualified "primitive" Data.Primitive.ByteArray as A
import qualified Data.List as L
import GHC.Stack

check :: HasCallStack => String -> Bool -> a -> a
check :: String -> Bool -> a -> a
check String
_      Bool
True  a
x = a
x
check String
errMsg Bool
False a
_ = ArrayException -> a
forall a e. Exception e => e -> a
throw (String -> ArrayException
IndexOutOfBounds (String -> ArrayException) -> String -> ArrayException
forall a b. (a -> b) -> a -> b
$ String
"Data.Primitive.ByteArray." String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
errMsg String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\n" String -> String -> String
forall a. [a] -> [a] -> [a]
++ CallStack -> String
prettyCallStack CallStack
HasCallStack => CallStack
callStack)

elementSizeofByteArray :: forall a. Prim a => Proxy a -> ByteArray -> Int
elementSizeofByteArray :: Proxy a -> ByteArray -> Int
elementSizeofByteArray Proxy a
_ ByteArray
arr = ByteArray -> Int
A.sizeofByteArray ByteArray
arr Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` a -> Int
forall a. Prim a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a)

getElementSizeofMutableByteArray :: forall m a. (PrimMonad m, Prim a)
  => Proxy a -> MutableByteArray (PrimState m) -> m Int
getElementSizeofMutableByteArray :: Proxy a -> MutableByteArray (PrimState m) -> m Int
getElementSizeofMutableByteArray Proxy a
_ MutableByteArray (PrimState m)
arr = do
  Int
sz <- MutableByteArray (PrimState m) -> m Int
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m Int
A.getSizeofMutableByteArray MutableByteArray (PrimState m)
arr
  Int -> m Int
forall (m :: * -> *) a. Monad m => a -> m a
return (Int
sz Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` a -> Int
forall a. Prim a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a))

newByteArray :: (HasCallStack, PrimMonad m) => Int -> m (MutableByteArray (PrimState m))
newByteArray :: Int -> m (MutableByteArray (PrimState m))
newByteArray Int
n =
    String
-> Bool
-> m (MutableByteArray (PrimState m))
-> m (MutableByteArray (PrimState m))
forall a. HasCallStack => String -> Bool -> a -> a
check String
"newByteArray: negative size" (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0)
  (m (MutableByteArray (PrimState m))
 -> m (MutableByteArray (PrimState m)))
-> m (MutableByteArray (PrimState m))
-> m (MutableByteArray (PrimState m))
forall a b. (a -> b) -> a -> b
$ String
-> Bool
-> m (MutableByteArray (PrimState m))
-> m (MutableByteArray (PrimState m))
forall a. HasCallStack => String -> Bool -> a -> a
check (String
"newByteArray: requested " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" bytes") (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1024Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
1024Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
1024)
  (m (MutableByteArray (PrimState m))
 -> m (MutableByteArray (PrimState m)))
-> m (MutableByteArray (PrimState m))
-> m (MutableByteArray (PrimState m))
forall a b. (a -> b) -> a -> b
$ Int -> m (MutableByteArray (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
A.newByteArray Int
n

newPinnedByteArray :: (HasCallStack, PrimMonad m) => Int -> m (MutableByteArray (PrimState m))
newPinnedByteArray :: Int -> m (MutableByteArray (PrimState m))
newPinnedByteArray Int
n = String
-> Bool
-> m (MutableByteArray (PrimState m))
-> m (MutableByteArray (PrimState m))
forall a. HasCallStack => String -> Bool -> a -> a
check String
"newPinnedByteArray: negative size" (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (Int -> m (MutableByteArray (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
Int -> m (MutableByteArray (PrimState m))
A.newPinnedByteArray Int
n)

newAlignedPinnedByteArray :: (HasCallStack, PrimMonad m) => Int -> Int -> m (MutableByteArray (PrimState m))
newAlignedPinnedByteArray :: Int -> Int -> m (MutableByteArray (PrimState m))
newAlignedPinnedByteArray Int
n Int
k = String
-> Bool
-> m (MutableByteArray (PrimState m))
-> m (MutableByteArray (PrimState m))
forall a. HasCallStack => String -> Bool -> a -> a
check String
"newAlignedPinnedByteArray: negative size" (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (Int -> Int -> m (MutableByteArray (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
Int -> Int -> m (MutableByteArray (PrimState m))
A.newAlignedPinnedByteArray Int
n Int
k)

-- | After a call to 'resizeMutableByteArray', the original reference to
-- the mutable array should not be used again. This cannot truly be enforced
-- except by linear types. To attempt to enforce this, we always make a
-- copy of the mutable primitive array and intentionally corrupt the original
-- of the original one. The strategy used here to corrupt the array is
-- simply to write @0xFF@ to every byte.
resizeMutableByteArray :: PrimMonad m => MutableByteArray (PrimState m) -> Int -> m (MutableByteArray (PrimState m))
resizeMutableByteArray :: MutableByteArray (PrimState m)
-> Int -> m (MutableByteArray (PrimState m))
resizeMutableByteArray MutableByteArray (PrimState m)
marr Int
n = String
-> Bool
-> m (MutableByteArray (PrimState m))
-> m (MutableByteArray (PrimState m))
forall a. HasCallStack => String -> Bool -> a -> a
check String
"resizeMutableByteArray: negative size" (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0) (m (MutableByteArray (PrimState m))
 -> m (MutableByteArray (PrimState m)))
-> m (MutableByteArray (PrimState m))
-> m (MutableByteArray (PrimState m))
forall a b. (a -> b) -> a -> b
$ do
  let sz :: Int
sz = MutableByteArray (PrimState m) -> Int
forall s. MutableByteArray s -> Int
A.sizeofMutableByteArray MutableByteArray (PrimState m)
marr
  MutableByteArray (PrimState m)
marr' <- MutableByteArray (PrimState m)
-> Int -> Int -> m (MutableByteArray (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> Int -> m (MutableByteArray (PrimState m))
A.cloneMutableByteArray MutableByteArray (PrimState m)
marr Int
0 Int
sz
  MutableByteArray (PrimState m) -> Int -> Int -> Word8 -> m ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> Int -> Word8 -> m ()
A.fillByteArray MutableByteArray (PrimState m)
marr Int
0 Int
sz Word8
0xFF
  MutableByteArray (PrimState m)
-> m (MutableByteArray (PrimState m))
forall (m :: * -> *) a. Monad m => a -> m a
return MutableByteArray (PrimState m)
marr'

shrinkMutableByteArray :: (HasCallStack, PrimMonad m)
  => MutableByteArray (PrimState m)
  -> Int -- ^ new size
  -> m ()
shrinkMutableByteArray :: MutableByteArray (PrimState m) -> Int -> m ()
shrinkMutableByteArray MutableByteArray (PrimState m)
marr Int
n = do
  Int
old <- MutableByteArray (PrimState m) -> m Int
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m Int
A.getSizeofMutableByteArray MutableByteArray (PrimState m)
marr
  String -> Bool -> m () -> m ()
forall a. HasCallStack => String -> Bool -> a -> a
check String
"shrinkMutableByteArray: illegal new size" (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
old) (MutableByteArray (PrimState m) -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> m ()
A.shrinkMutableByteArray MutableByteArray (PrimState m)
marr Int
n)

readByteArray :: forall m a. (HasCallStack, Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> m a
readByteArray :: MutableByteArray (PrimState m) -> Int -> m a
readByteArray MutableByteArray (PrimState m)
marr Int
i = do
  Int
siz <- Proxy a -> MutableByteArray (PrimState m) -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Proxy a -> MutableByteArray (PrimState m) -> m Int
getElementSizeofMutableByteArray (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a) MutableByteArray (PrimState m)
marr
  String -> Bool -> m a -> m a
forall a. HasCallStack => String -> Bool -> a -> a
check String
"readByteArray: index out of bounds" (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
siz) (MutableByteArray (PrimState m) -> Int -> m a
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> m a
A.readByteArray MutableByteArray (PrimState m)
marr Int
i)

writeByteArray :: forall m a. (HasCallStack, Prim a, PrimMonad m) => MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray :: MutableByteArray (PrimState m) -> Int -> a -> m ()
writeByteArray MutableByteArray (PrimState m)
marr Int
i a
x = do
  Int
siz <- Proxy a -> MutableByteArray (PrimState m) -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Proxy a -> MutableByteArray (PrimState m) -> m Int
getElementSizeofMutableByteArray (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a) MutableByteArray (PrimState m)
marr
  let explain :: String
explain = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat
        [ String
"[size: "
        , Int -> String
forall a. Show a => a -> String
show Int
siz
        , String
", index: "
        , Int -> String
forall a. Show a => a -> String
show Int
i
        , String
", elem_sz: "
        , Int -> String
forall a. Show a => a -> String
show (a -> Int
forall a. Prim a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a))
        , String
"]"
        ]
  String -> Bool -> m () -> m ()
forall a. HasCallStack => String -> Bool -> a -> a
check (String
"writeByteArray: index out of bounds " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
explain)
    (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
siz)
    (MutableByteArray (PrimState m) -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> a -> m ()
A.writeByteArray MutableByteArray (PrimState m)
marr Int
i a
x)

-- This one is a little special. We allow users to index past the
-- end of the byte array as long as the content grabbed is within
-- the last machine word of the byte array.
indexByteArray :: forall a. (HasCallStack, Prim a) => ByteArray -> Int -> a
indexByteArray :: ByteArray -> Int -> a
indexByteArray ByteArray
arr Int
i = String -> Bool -> a -> a
forall a. HasCallStack => String -> Bool -> a -> a
check String
"indexByteArray: index out of bounds"
  (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Proxy a -> ByteArray -> Int
forall a. Prim a => Proxy a -> ByteArray -> Int
elementSizeofByteArray (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a) ByteArray
arr)
  (ByteArray -> Int -> a
forall a. Prim a => ByteArray -> Int -> a
A.indexByteArray ByteArray
arr Int
i)

compareByteArrays :: ByteArray -> Int -> ByteArray -> Int -> Int -> Ordering
compareByteArrays :: ByteArray -> Int -> ByteArray -> Int -> Int -> Ordering
compareByteArrays ByteArray
arr1 Int
off1 ByteArray
arr2 Int
off2 Int
len = String -> Bool -> Ordering -> Ordering
forall a. HasCallStack => String -> Bool -> a -> a
check String
"compareByteArrays: index range out of bounds"
  (Int
off1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
off2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
off1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteArray -> Int
A.sizeofByteArray ByteArray
arr1 Bool -> Bool -> Bool
&& Int
off2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteArray -> Int
A.sizeofByteArray ByteArray
arr2)
  (ByteArray -> Int -> ByteArray -> Int -> Int -> Ordering
A.compareByteArrays ByteArray
arr1 Int
off1 ByteArray
arr2 Int
off2 Int
len)

freezeByteArray
  :: (HasCallStack, PrimMonad m)
  => MutableByteArray (PrimState m) -- ^ source
  -> Int                            -- ^ offset
  -> Int                            -- ^ length
  -> m ByteArray
freezeByteArray :: MutableByteArray (PrimState m) -> Int -> Int -> m ByteArray
freezeByteArray MutableByteArray (PrimState m)
marr Int
s Int
l = String -> Bool -> m ByteArray -> m ByteArray
forall a. HasCallStack => String -> Bool -> a -> a
check String
"freezeByteArray: index range of out bounds"
  (Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= MutableByteArray (PrimState m) -> Int
forall s. MutableByteArray s -> Int
A.sizeofMutableByteArray MutableByteArray (PrimState m)
marr)
  (MutableByteArray (PrimState m) -> Int -> Int -> m ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> Int -> m ByteArray
A.freezeByteArray MutableByteArray (PrimState m)
marr Int
s Int
l)

thawByteArray
  :: (HasCallStack, PrimMonad m)
  => ByteArray -- ^ source
  -> Int       -- ^ offset
  -> Int       -- ^ length
  -> m (MutableByteArray (PrimState m))
thawByteArray :: ByteArray -> Int -> Int -> m (MutableByteArray (PrimState m))
thawByteArray ByteArray
arr Int
s Int
l = String
-> Bool
-> m (MutableByteArray (PrimState m))
-> m (MutableByteArray (PrimState m))
forall a. HasCallStack => String -> Bool -> a -> a
check String
"thawByteArray: index range of out bounds"
  (Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteArray -> Int
A.sizeofByteArray ByteArray
arr)
  (ByteArray -> Int -> Int -> m (MutableByteArray (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
ByteArray -> Int -> Int -> m (MutableByteArray (PrimState m))
A.thawByteArray ByteArray
arr Int
s Int
l)

-- | This corrupts the contents of the argument array by writing @0xFF@ to every byte.
unsafeFreezeByteArray
  :: (HasCallStack, PrimMonad m)
  => MutableByteArray (PrimState m)
  -> m ByteArray
unsafeFreezeByteArray :: MutableByteArray (PrimState m) -> m ByteArray
unsafeFreezeByteArray MutableByteArray (PrimState m)
marr = do
  let sz :: Int
sz = MutableByteArray (PrimState m) -> Int
forall s. MutableByteArray s -> Int
A.sizeofMutableByteArray MutableByteArray (PrimState m)
marr
  ByteArray
arr <- MutableByteArray (PrimState m) -> Int -> Int -> m ByteArray
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> Int -> m ByteArray
A.freezeByteArray MutableByteArray (PrimState m)
marr Int
0 Int
sz
  MutableByteArray (PrimState m) -> Int -> Int -> Word8 -> m ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> Int -> Int -> Word8 -> m ()
A.fillByteArray MutableByteArray (PrimState m)
marr Int
0 Int
sz Word8
0xFF
  ByteArray -> m ByteArray
forall (m :: * -> *) a. Monad m => a -> m a
return ByteArray
arr

copyByteArray :: forall m. (HasCallStack, PrimMonad m)
  => MutableByteArray (PrimState m) -- ^ destination array
  -> Int -- ^ offset into destination array
  -> ByteArray -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of elements to copy
  -> m ()
copyByteArray :: MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
copyByteArray MutableByteArray (PrimState m)
marr Int
s1 ByteArray
arr Int
s2 Int
l = do
  let siz :: Int
siz = MutableByteArray (PrimState m) -> Int
forall s. MutableByteArray s -> Int
A.sizeofMutableByteArray MutableByteArray (PrimState m)
marr
  String -> Bool -> m () -> m ()
forall a. HasCallStack => String -> Bool -> a -> a
check String
"copyByteArray: index range of out bounds"
    (Int
s1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
siz Bool -> Bool -> Bool
&& Int
s2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteArray -> Int
A.sizeofByteArray ByteArray
arr)
    (MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> ByteArray -> Int -> Int -> m ()
A.copyByteArray MutableByteArray (PrimState m)
marr Int
s1 ByteArray
arr Int
s2 Int
l)

copyMutableByteArray :: forall m. (HasCallStack, PrimMonad m)
  => MutableByteArray (PrimState m) -- ^ destination array
  -> Int -- ^ offset into destination array
  -> MutableByteArray (PrimState m) -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of elements to copy
  -> m ()
copyMutableByteArray :: MutableByteArray (PrimState m)
-> Int -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
copyMutableByteArray MutableByteArray (PrimState m)
marr1 Int
s1 MutableByteArray (PrimState m)
marr2 Int
s2 Int
l = do
  let siz1 :: Int
siz1 = MutableByteArray (PrimState m) -> Int
forall s. MutableByteArray s -> Int
A.sizeofMutableByteArray MutableByteArray (PrimState m)
marr1
  let siz2 :: Int
siz2 = MutableByteArray (PrimState m) -> Int
forall s. MutableByteArray s -> Int
A.sizeofMutableByteArray MutableByteArray (PrimState m)
marr2
  String -> Bool -> m () -> m ()
forall a. HasCallStack => String -> Bool -> a -> a
check String
"copyMutableByteArray: index range of out bounds"
    (Int
s1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
siz1 Bool -> Bool -> Bool
&& Int
s2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
siz2)
    (MutableByteArray (PrimState m)
-> Int -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
A.copyMutableByteArray MutableByteArray (PrimState m)
marr1 Int
s1 MutableByteArray (PrimState m)
marr2 Int
s2 Int
l)

copyByteArrayToPtr :: forall m a. (HasCallStack, PrimMonad m, Prim a)
  => Ptr a -- ^ destination pointer
  -> ByteArray -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of elements to copy
  -> m ()
copyByteArrayToPtr :: Ptr a -> ByteArray -> Int -> Int -> m ()
copyByteArrayToPtr Ptr a
ptr ByteArray
arr Int
s Int
l = do
  let srcSz :: Int
srcSz = Proxy a -> ByteArray -> Int
forall a. Prim a => Proxy a -> ByteArray -> Int
elementSizeofByteArray (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a) ByteArray
arr
  let explain :: String
explain = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat
        [ String
"[src_sz: "
        , Int -> String
forall a. Show a => a -> String
show Int
srcSz
        , String
", src_off: "
        , Int -> String
forall a. Show a => a -> String
show Int
s
        , String
", len: "
        , Int -> String
forall a. Show a => a -> String
show Int
l
        , String
"]"
        ]
  String -> Bool -> m () -> m ()
forall a. HasCallStack => String -> Bool -> a -> a
check (String
"copyByteArrayToPtr: index range of out bounds " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
explain)
    (Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
srcSz)
    (Ptr a -> ByteArray -> Int -> Int -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Ptr a -> ByteArray -> Int -> Int -> m ()
A.copyByteArrayToPtr Ptr a
ptr ByteArray
arr Int
s Int
l)

copyMutableByteArrayToPtr :: forall m a. (HasCallStack, PrimMonad m, Prim a)
  => Ptr a -- ^ destination pointer
  -> MutableByteArray (PrimState m) -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of elements to copy
  -> m ()
copyMutableByteArrayToPtr :: Ptr a -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
copyMutableByteArrayToPtr Ptr a
ptr MutableByteArray (PrimState m)
marr Int
s Int
l = do
  Int
srcSz <- Proxy a -> MutableByteArray (PrimState m) -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Proxy a -> MutableByteArray (PrimState m) -> m Int
getElementSizeofMutableByteArray (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a) MutableByteArray (PrimState m)
marr
  let explain :: String
explain = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat
        [ String
"[src_sz: "
        , Int -> String
forall a. Show a => a -> String
show Int
srcSz
        , String
", src_off: "
        , Int -> String
forall a. Show a => a -> String
show Int
s
        , String
", len: "
        , Int -> String
forall a. Show a => a -> String
show Int
l
        , String
"]"
        ]
  String -> Bool -> m () -> m ()
forall a. HasCallStack => String -> Bool -> a -> a
check (String
"copyMutableByteArrayToPtr: index range of out bounds " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
explain)
    (Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
srcSz)
    (Ptr a -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Ptr a -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
A.copyMutableByteArrayToPtr Ptr a
ptr MutableByteArray (PrimState m)
marr Int
s Int
l)

copyByteArrayToAddr :: (HasCallStack, PrimMonad m)
  => Ptr Word8 -- ^ destination pointer
  -> ByteArray -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of bytes to copy
  -> m ()
copyByteArrayToAddr :: Ptr Word8 -> ByteArray -> Int -> Int -> m ()
copyByteArrayToAddr Ptr Word8
ptr ByteArray
arr Int
s Int
l = do
  let srcSz :: Int
srcSz = ByteArray -> Int
A.sizeofByteArray ByteArray
arr
  let explain :: String
explain = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat
        [ String
"[src_sz: "
        , Int -> String
forall a. Show a => a -> String
show Int
srcSz
        , String
", src_off: "
        , Int -> String
forall a. Show a => a -> String
show Int
s
        , String
", len: "
        , Int -> String
forall a. Show a => a -> String
show Int
l
        , String
"]"
        ]
  String -> Bool -> m () -> m ()
forall a. HasCallStack => String -> Bool -> a -> a
check (String
"copyByteArrayToAddr: index range of out bounds " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
explain)
    (Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
srcSz)
    (Ptr Word8 -> ByteArray -> Int -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
Ptr Word8 -> ByteArray -> Int -> Int -> m ()
A.copyByteArrayToAddr Ptr Word8
ptr ByteArray
arr Int
s Int
l)

copyMutableByteArrayToAddr :: (HasCallStack, PrimMonad m)
  => Ptr Word8 -- ^ destination pointer
  -> MutableByteArray (PrimState m) -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of bytes to copy
  -> m ()
copyMutableByteArrayToAddr :: Ptr Word8 -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
copyMutableByteArrayToAddr Ptr Word8
ptr MutableByteArray (PrimState m)
marr Int
s Int
l = do
  Int
srcSz <- MutableByteArray (PrimState m) -> m Int
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m) -> m Int
A.getSizeofMutableByteArray MutableByteArray (PrimState m)
marr
  let explain :: String
explain = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
L.concat
        [ String
"[src_sz: "
        , Int -> String
forall a. Show a => a -> String
show Int
srcSz
        , String
", src_off: "
        , Int -> String
forall a. Show a => a -> String
show Int
s
        , String
", len: "
        , Int -> String
forall a. Show a => a -> String
show Int
l
        , String
"]"
        ]
  String -> Bool -> m () -> m ()
forall a. HasCallStack => String -> Bool -> a -> a
check (String
"copyMutableByteArrayToAddr: index range of out bounds " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
explain)
    (Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
srcSz)
    (Ptr Word8 -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
Ptr Word8 -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
A.copyMutableByteArrayToAddr Ptr Word8
ptr MutableByteArray (PrimState m)
marr Int
s Int
l)

moveByteArray :: forall m. (HasCallStack, PrimMonad m)
  => MutableByteArray (PrimState m) -- ^ destination array
  -> Int -- ^ offset into destination array
  -> MutableByteArray (PrimState m) -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of bytes to copy
  -> m ()
moveByteArray :: MutableByteArray (PrimState m)
-> Int -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
moveByteArray MutableByteArray (PrimState m)
marr1 Int
s1 MutableByteArray (PrimState m)
marr2 Int
s2 Int
l = do
  let siz1 :: Int
siz1 = MutableByteArray (PrimState m) -> Int
forall s. MutableByteArray s -> Int
A.sizeofMutableByteArray MutableByteArray (PrimState m)
marr1
  let siz2 :: Int
siz2 = MutableByteArray (PrimState m) -> Int
forall s. MutableByteArray s -> Int
A.sizeofMutableByteArray MutableByteArray (PrimState m)
marr2
  String -> Bool -> m () -> m ()
forall a. HasCallStack => String -> Bool -> a -> a
check String
"moveByteArray: index range of out bounds"
    (Int
s1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
siz1 Bool -> Bool -> Bool
&& Int
s2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
siz2)
    (MutableByteArray (PrimState m)
-> Int -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> MutableByteArray (PrimState m) -> Int -> Int -> m ()
A.moveByteArray MutableByteArray (PrimState m)
marr1 Int
s1 MutableByteArray (PrimState m)
marr2 Int
s2 Int
l)

fillByteArray :: (HasCallStack, PrimMonad m)
  => MutableByteArray (PrimState m) -- ^ array to fill
  -> Int -- ^ offset into array
  -> Int -- ^ number of bytes to fill
  -> Word8 -- ^ byte to fill with
  -> m ()
fillByteArray :: MutableByteArray (PrimState m) -> Int -> Int -> Word8 -> m ()
fillByteArray = MutableByteArray (PrimState m) -> Int -> Int -> Word8 -> m ()
forall (m :: * -> *) a.
(HasCallStack, Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> Int -> a -> m ()
setByteArray

setByteArray :: forall m a. (HasCallStack, Prim a, PrimMonad m)
  => MutableByteArray (PrimState m) -- ^ array to fill
  -> Int -- ^ offset into array
  -> Int -- ^ number of values to fill
  -> a -- ^ value to fill with
  -> m ()
setByteArray :: MutableByteArray (PrimState m) -> Int -> Int -> a -> m ()
setByteArray MutableByteArray (PrimState m)
dst Int
doff Int
sz a
x = do
  Int
siz <- Proxy a -> MutableByteArray (PrimState m) -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Proxy a -> MutableByteArray (PrimState m) -> m Int
getElementSizeofMutableByteArray (Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a) MutableByteArray (PrimState m)
dst
  String -> Bool -> m () -> m ()
forall a. HasCallStack => String -> Bool -> a -> a
check String
"setByteArray: index range of out bounds"
    (Int
doff Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
doff Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
sz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
siz)
    (MutableByteArray (PrimState m) -> Int -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutableByteArray (PrimState m) -> Int -> Int -> a -> m ()
A.setByteArray MutableByteArray (PrimState m)
dst Int
doff Int
sz a
x)

cloneByteArray :: HasCallStack
  => ByteArray -- ^ source array
  -> Int       -- ^ offset into source array
  -> Int       -- ^ number of bytes to copy
  -> ByteArray
cloneByteArray :: ByteArray -> Int -> Int -> ByteArray
cloneByteArray ByteArray
arr Int
s Int
l = String -> Bool -> ByteArray -> ByteArray
forall a. HasCallStack => String -> Bool -> a -> a
check String
"cloneByteArray: index range of out bounds"
  (Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ByteArray -> Int
A.sizeofByteArray ByteArray
arr)
  (ByteArray -> Int -> Int -> ByteArray
A.cloneByteArray ByteArray
arr Int
s Int
l)

cloneMutableByteArray :: (HasCallStack, PrimMonad m)
  => MutableByteArray (PrimState m) -- ^ source array
  -> Int                            -- ^ offset into source array
  -> Int                            -- ^ number of bytes to copy
  -> m (MutableByteArray (PrimState m))
cloneMutableByteArray :: MutableByteArray (PrimState m)
-> Int -> Int -> m (MutableByteArray (PrimState m))
cloneMutableByteArray MutableByteArray (PrimState m)
marr Int
s Int
l = String
-> Bool
-> m (MutableByteArray (PrimState m))
-> m (MutableByteArray (PrimState m))
forall a. HasCallStack => String -> Bool -> a -> a
check String
"cloneMutableByteArray: index range of out bounds"
  (Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0 Bool -> Bool -> Bool
&& Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= MutableByteArray (PrimState m) -> Int
forall s. MutableByteArray s -> Int
A.sizeofMutableByteArray MutableByteArray (PrimState m)
marr)
  (MutableByteArray (PrimState m)
-> Int -> Int -> m (MutableByteArray (PrimState m))
forall (m :: * -> *).
PrimMonad m =>
MutableByteArray (PrimState m)
-> Int -> Int -> m (MutableByteArray (PrimState m))
A.cloneMutableByteArray MutableByteArray (PrimState m)
marr Int
s Int
l)