{-# LANGUAGE UnboxedTuples #-}
#include "inline.hs"
module Streamly.Internal.Data.Array.Foreign
(
Array
, A.fromPtr
, A.fromAddr#
, A.fromCString#
, A.fromListN
, A.fromList
, fromStreamN
, fromStream
, A.writeN
, A.writeNAligned
, A.write
, writeLastN
, A.toList
, A.toStream
, A.toStreamRev
, read
, producer
, unsafeRead
, A.readRev
, length
, null
, last
, getIndex
, A.unsafeIndex
, writeIndex
, unsafeSlice
, streamTransform
, cast
, unsafeCast
, unsafeAsPtr
, asBytes
, unsafeAsCString
, streamFold
, fold
)
where
import Control.Monad (when)
import Control.Monad.IO.Class (MonadIO(..))
#if !(MIN_VERSION_base(4,11,0))
import Data.Semigroup ((<>))
#endif
import Data.Word (Word8)
import Foreign.C.String (CString)
import Foreign.ForeignPtr (castForeignPtr)
import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)
import Foreign.Ptr (plusPtr, castPtr)
import Foreign.Storable (Storable(..))
import Prelude hiding (length, null, last, map, (!!), read, concat)
import GHC.ForeignPtr (ForeignPtr(..))
import GHC.Ptr (Ptr(..))
import GHC.Prim (touch#)
import GHC.IO (IO(..))
import Streamly.Internal.BaseCompat
import Streamly.Internal.Data.Array.Foreign.Type (Array(..), length)
import Streamly.Internal.Data.Fold.Type (Fold(..))
import Streamly.Internal.Data.Producer.Type (Producer)
import Streamly.Internal.Data.Stream.Serial (SerialT)
import Streamly.Internal.Data.Tuple.Strict (Tuple3'(..))
import Streamly.Internal.Data.Unfold.Type (Unfold(..))
import qualified Streamly.Internal.Data.Array.Foreign.Mut.Type as MA
import qualified Streamly.Internal.Data.Array.Foreign.Type as A
import qualified Streamly.Internal.Data.Fold as FL
import qualified Streamly.Internal.Data.Stream.Prelude as P
import qualified Streamly.Internal.Data.Stream.Serial as Serial
import qualified Streamly.Internal.Data.Stream.StreamD as D
import qualified Streamly.Internal.Data.Unfold as Unfold
import qualified Streamly.Internal.Data.Producer.Type as Producer
import qualified Streamly.Internal.Ring.Foreign as RB
#if MIN_VERSION_base(4,10,0)
import Foreign.ForeignPtr (plusForeignPtr)
#else
import GHC.Base (Int(..), plusAddr#)
import GHC.ForeignPtr (ForeignPtr(..))
plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b
plusForeignPtr (ForeignPtr addr c) (I# d) = ForeignPtr (plusAddr# addr d) c
#endif
{-# INLINE fromStreamN #-}
fromStreamN :: (MonadIO m, Storable a) => Int -> SerialT m a -> m (Array a)
fromStreamN :: Int -> SerialT m a -> m (Array a)
fromStreamN Int
n SerialT m a
m = do
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ [Char] -> m ()
forall a. HasCallStack => [Char] -> a
error [Char]
"writeN: negative write count specified"
Int -> Stream m a -> m (Array a)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> Stream m a -> m (Array a)
A.fromStreamDN Int
n (Stream m a -> m (Array a)) -> Stream m a -> m (Array a)
forall a b. (a -> b) -> a -> b
$ SerialT m a -> Stream m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(IsStream t, Monad m) =>
t m a -> Stream m a
D.toStreamD SerialT m a
m
{-# INLINE fromStream #-}
fromStream :: (MonadIO m, Storable a) => SerialT m a -> m (Array a)
fromStream :: SerialT m a -> m (Array a)
fromStream = Fold m a (Array a) -> SerialT m a -> m (Array a)
forall (m :: * -> *) (t :: (* -> *) -> * -> *) a b.
(Monad m, IsStream t) =>
Fold m a b -> t m a -> m b
P.fold Fold m a (Array a)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Fold m a (Array a)
A.write
{-# INLINE_NORMAL read #-}
read :: forall m a. (Monad m, Storable a) => Unfold m (Array a) a
read :: Unfold m (Array a) a
read = (Array a -> Array a)
-> Unfold m (Array a) a -> Unfold m (Array a) a
forall a c (m :: * -> *) b.
(a -> c) -> Unfold m c b -> Unfold m a b
Unfold.lmap Array a -> Array a
forall a. Array a -> Array a
A.unsafeThaw Unfold m (Array a) a
forall (m :: * -> *) a.
(Monad m, Storable a) =>
Unfold m (Array a) a
MA.read
{-# INLINE_NORMAL producer #-}
producer :: forall m a. (Monad m, Storable a) => Producer m (Array a) a
producer :: Producer m (Array a) a
producer = (Array a -> Array a)
-> (Array a -> Array a)
-> Producer m (Array a) a
-> Producer m (Array a) a
forall (m :: * -> *) a c b.
Functor m =>
(a -> c) -> (c -> a) -> Producer m c b -> Producer m a b
Producer.translate Array a -> Array a
forall a. Array a -> Array a
A.unsafeThaw Array a -> Array a
forall a. Array a -> Array a
A.unsafeFreeze Producer m (Array a) a
forall (m :: * -> *) a.
(Monad m, Storable a) =>
Producer m (Array a) a
MA.producer
{-# INLINE_NORMAL unsafeRead #-}
unsafeRead :: forall m a. (Monad m, Storable a) => Unfold m (Array a) a
unsafeRead :: Unfold m (Array a) a
unsafeRead = (ForeignPtr a -> m (Step (ForeignPtr a) a))
-> (Array a -> m (ForeignPtr a)) -> Unfold m (Array a) a
forall (m :: * -> *) a b s.
(s -> m (Step s b)) -> (a -> m s) -> Unfold m a b
Unfold ForeignPtr a -> m (Step (ForeignPtr a) a)
forall (m :: * -> *) a a a.
(Monad m, Storable a) =>
ForeignPtr a -> m (Step (ForeignPtr a) a)
step Array a -> m (ForeignPtr a)
forall (m :: * -> *) a. Monad m => Array a -> m (ForeignPtr a)
inject
where
inject :: Array a -> m (ForeignPtr a)
inject (Array ForeignPtr a
fp Ptr a
_) = ForeignPtr a -> m (ForeignPtr a)
forall (m :: * -> *) a. Monad m => a -> m a
return ForeignPtr a
fp
{-# INLINE_LATE step #-}
step :: ForeignPtr a -> m (Step (ForeignPtr a) a)
step (ForeignPtr Addr#
p ForeignPtrContents
contents) = do
let !x :: a
x = IO a -> a
forall a. IO a -> a
A.unsafeInlineIO (IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ do
a
r <- Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek (Addr# -> Ptr a
forall a. Addr# -> Ptr a
Ptr Addr#
p)
ForeignPtrContents -> IO ()
forall a. a -> IO ()
touch ForeignPtrContents
contents
a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
let !(Ptr Addr#
p1) = Addr# -> Ptr Any
forall a. Addr# -> Ptr a
Ptr Addr#
p Ptr Any -> Int -> Ptr Any
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` a -> Int
forall a. Storable a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a)
Step (ForeignPtr a) a -> m (Step (ForeignPtr a) a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (ForeignPtr a) a -> m (Step (ForeignPtr a) a))
-> Step (ForeignPtr a) a -> m (Step (ForeignPtr a) a)
forall a b. (a -> b) -> a -> b
$ a -> ForeignPtr a -> Step (ForeignPtr a) a
forall s a. a -> s -> Step s a
D.Yield a
x (Addr# -> ForeignPtrContents -> ForeignPtr a
forall a. Addr# -> ForeignPtrContents -> ForeignPtr a
ForeignPtr Addr#
p1 ForeignPtrContents
contents)
touch :: a -> IO ()
touch a
r = (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, () #)) -> IO ())
-> (State# RealWorld -> (# State# RealWorld, () #)) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s -> case a -> State# RealWorld -> State# RealWorld
forall a. a -> State# RealWorld -> State# RealWorld
touch# a
r State# RealWorld
s of State# RealWorld
s' -> (# State# RealWorld
s', () #)
{-# INLINE null #-}
null :: Storable a => Array a -> Bool
null :: Array a -> Bool
null Array a
arr = Array a -> Int
forall a. Storable a => Array a -> Int
length Array a
arr Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
{-# INLINE last #-}
last :: Storable a => Array a -> Maybe a
last :: Array a -> Maybe a
last Array a
arr = Array a -> Int -> Maybe a
forall a. Storable a => Array a -> Int -> Maybe a
getIndex Array a
arr (Array a -> Int
forall a. Storable a => Array a -> Int
length Array a
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
{-# INLINE writeLastN #-}
writeLastN :: (Storable a, MonadIO m) => Int -> Fold m a (Array a)
writeLastN :: Int -> Fold m a (Array a)
writeLastN Int
n
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = (() -> Array a) -> Fold m a () -> Fold m a (Array a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Array a -> () -> Array a
forall a b. a -> b -> a
const Array a
forall a. Monoid a => a
mempty) Fold m a ()
forall (m :: * -> *) a. Monad m => Fold m a ()
FL.drain
| Bool
otherwise = Array a -> Array a
forall a. Array a -> Array a
A.unsafeFreeze (Array a -> Array a) -> Fold m a (Array a) -> Fold m a (Array a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Tuple3' (Ring a) (Ptr a) Int
-> a -> m (Step (Tuple3' (Ring a) (Ptr a) Int) (Array a)))
-> m (Step (Tuple3' (Ring a) (Ptr a) Int) (Array a))
-> (Tuple3' (Ring a) (Ptr a) Int -> m (Array a))
-> Fold m a (Array a)
forall (m :: * -> *) a b s.
(s -> a -> m (Step s b))
-> m (Step s b) -> (s -> m b) -> Fold m a b
Fold Tuple3' (Ring a) (Ptr a) Int
-> a -> m (Step (Tuple3' (Ring a) (Ptr a) Int) (Array a))
forall (m :: * -> *) a c b.
(MonadIO m, Storable a, Num c) =>
Tuple3' (Ring a) (Ptr a) c
-> a -> m (Step (Tuple3' (Ring a) (Ptr a) c) b)
step m (Step (Tuple3' (Ring a) (Ptr a) Int) (Array a))
forall b. m (Step (Tuple3' (Ring a) (Ptr a) Int) b)
initial Tuple3' (Ring a) (Ptr a) Int -> m (Array a)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Tuple3' (Ring a) (Ptr a) Int -> m (Array a)
done
where
step :: Tuple3' (Ring a) (Ptr a) c
-> a -> m (Step (Tuple3' (Ring a) (Ptr a) c) b)
step (Tuple3' Ring a
rb Ptr a
rh c
i) a
a = do
Ptr a
rh1 <- IO (Ptr a) -> m (Ptr a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ptr a) -> m (Ptr a)) -> IO (Ptr a) -> m (Ptr a)
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> a -> IO (Ptr a)
forall a. Storable a => Ring a -> Ptr a -> a -> IO (Ptr a)
RB.unsafeInsert Ring a
rb Ptr a
rh a
a
Step (Tuple3' (Ring a) (Ptr a) c) b
-> m (Step (Tuple3' (Ring a) (Ptr a) c) b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Step (Tuple3' (Ring a) (Ptr a) c) b
-> m (Step (Tuple3' (Ring a) (Ptr a) c) b))
-> Step (Tuple3' (Ring a) (Ptr a) c) b
-> m (Step (Tuple3' (Ring a) (Ptr a) c) b)
forall a b. (a -> b) -> a -> b
$ Tuple3' (Ring a) (Ptr a) c -> Step (Tuple3' (Ring a) (Ptr a) c) b
forall s b. s -> Step s b
FL.Partial (Tuple3' (Ring a) (Ptr a) c -> Step (Tuple3' (Ring a) (Ptr a) c) b)
-> Tuple3' (Ring a) (Ptr a) c
-> Step (Tuple3' (Ring a) (Ptr a) c) b
forall a b. (a -> b) -> a -> b
$ Ring a -> Ptr a -> c -> Tuple3' (Ring a) (Ptr a) c
forall a b c. a -> b -> c -> Tuple3' a b c
Tuple3' Ring a
rb Ptr a
rh1 (c
i c -> c -> c
forall a. Num a => a -> a -> a
+ c
1)
initial :: m (Step (Tuple3' (Ring a) (Ptr a) Int) b)
initial =
let f :: (a, b) -> Step (Tuple3' a b Int) b
f (a
a, b
b) = Tuple3' a b Int -> Step (Tuple3' a b Int) b
forall s b. s -> Step s b
FL.Partial (Tuple3' a b Int -> Step (Tuple3' a b Int) b)
-> Tuple3' a b Int -> Step (Tuple3' a b Int) b
forall a b. (a -> b) -> a -> b
$ a -> b -> Int -> Tuple3' a b Int
forall a b c. a -> b -> c -> Tuple3' a b c
Tuple3' a
a b
b (Int
0 :: Int)
in ((Ring a, Ptr a) -> Step (Tuple3' (Ring a) (Ptr a) Int) b)
-> m (Ring a, Ptr a) -> m (Step (Tuple3' (Ring a) (Ptr a) Int) b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Ring a, Ptr a) -> Step (Tuple3' (Ring a) (Ptr a) Int) b
forall a b b. (a, b) -> Step (Tuple3' a b Int) b
f (m (Ring a, Ptr a) -> m (Step (Tuple3' (Ring a) (Ptr a) Int) b))
-> m (Ring a, Ptr a) -> m (Step (Tuple3' (Ring a) (Ptr a) Int) b)
forall a b. (a -> b) -> a -> b
$ IO (Ring a, Ptr a) -> m (Ring a, Ptr a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Ring a, Ptr a) -> m (Ring a, Ptr a))
-> IO (Ring a, Ptr a) -> m (Ring a, Ptr a)
forall a b. (a -> b) -> a -> b
$ Int -> IO (Ring a, Ptr a)
forall a. Storable a => Int -> IO (Ring a, Ptr a)
RB.new Int
n
done :: Tuple3' (Ring a) (Ptr a) Int -> m (Array a)
done (Tuple3' Ring a
rb Ptr a
rh Int
i) = do
Array a
arr <- IO (Array a) -> m (Array a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Array a) -> m (Array a)) -> IO (Array a) -> m (Array a)
forall a b. (a -> b) -> a -> b
$ Int -> IO (Array a)
forall a. Storable a => Int -> IO (Array a)
MA.newArray Int
n
Int
-> Ptr a
-> (Array a -> a -> m (Array a))
-> Array a
-> Ring a
-> m (Array a)
forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Int -> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
foldFunc Int
i Ptr a
rh Array a -> a -> m (Array a)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Array a -> a -> m (Array a)
snoc' Array a
arr Ring a
rb
snoc' :: Array a -> a -> m (Array a)
snoc' Array a
b a
a = IO (Array a) -> m (Array a)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Array a) -> m (Array a)) -> IO (Array a) -> m (Array a)
forall a b. (a -> b) -> a -> b
$ Array a -> a -> IO (Array a)
forall a. Storable a => Array a -> a -> IO (Array a)
MA.unsafeSnoc Array a
b a
a
foldFunc :: Int -> Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
foldFunc Int
i
| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n = Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
RB.unsafeFoldRingM
| Bool
otherwise = Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
forall (m :: * -> *) a b.
(MonadIO m, Storable a) =>
Ptr a -> (b -> a -> m b) -> b -> Ring a -> m b
RB.unsafeFoldRingFullM
{-# INLINE unsafeSlice #-}
unsafeSlice ::
forall a. Storable a
=> Int
-> Int
-> Array a
-> Array a
unsafeSlice :: Int -> Int -> Array a -> Array a
unsafeSlice Int
start Int
len (Array ForeignPtr a
fp Ptr a
_) =
let size :: Int
size = a -> Int
forall a. Storable a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a)
fp1 :: ForeignPtr b
fp1 = ForeignPtr a
fp ForeignPtr a -> Int -> ForeignPtr b
forall a b. ForeignPtr a -> Int -> ForeignPtr b
`plusForeignPtr` (Int
start Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
size)
end :: Ptr b
end = ForeignPtr Any -> Ptr Any
forall a. ForeignPtr a -> Ptr a
unsafeForeignPtrToPtr ForeignPtr Any
forall b. ForeignPtr b
fp1 Ptr Any -> Int -> Ptr b
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
size)
in ForeignPtr a -> Ptr a -> Array a
forall a. ForeignPtr a -> Ptr a -> Array a
Array ForeignPtr a
forall b. ForeignPtr b
fp1 Ptr a
forall b. Ptr b
end
{-# INLINE getIndex #-}
getIndex :: Storable a => Array a -> Int -> Maybe a
getIndex :: Array a -> Int -> Maybe a
getIndex Array a
arr Int
i =
if 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
> Array a -> Int
forall a. Storable a => Array a -> Int
length Array a
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
then Maybe a
forall a. Maybe a
Nothing
else IO (Maybe a) -> Maybe a
forall a. IO a -> a
A.unsafeInlineIO (IO (Maybe a) -> Maybe a) -> IO (Maybe a) -> Maybe a
forall a b. (a -> b) -> a -> b
$
ForeignPtr a -> (Ptr a -> IO (Maybe a)) -> IO (Maybe a)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr (Array a -> ForeignPtr a
forall a. Array a -> ForeignPtr a
aStart Array a
arr) ((Ptr a -> IO (Maybe a)) -> IO (Maybe a))
-> (Ptr a -> IO (Maybe a)) -> IO (Maybe a)
forall a b. (a -> b) -> a -> b
$ \Ptr a
p -> a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> IO a -> IO (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr a
p Int
i
{-# INLINE writeIndex #-}
writeIndex :: (MonadIO m, Storable a) => Array a -> Int -> a -> m ()
writeIndex :: Array a -> Int -> a -> m ()
writeIndex Array a
arr Int
i a
a = do
let maxIndex :: Int
maxIndex = Array a -> Int
forall a. Storable a => Array a -> Int
length Array a
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
then [Char] -> m ()
forall a. HasCallStack => [Char] -> a
error [Char]
"writeIndex: negative array index"
else if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
maxIndex
then [Char] -> m ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> m ()) -> [Char] -> m ()
forall a b. (a -> b) -> a -> b
$ [Char]
"writeIndex: specified array index " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i
[Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" is beyond the maximum index " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
maxIndex
else
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> (Ptr a -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr (Array a -> ForeignPtr a
forall a. Array a -> ForeignPtr a
aStart Array a
arr) ((Ptr a -> IO ()) -> IO ()) -> (Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr a
p ->
Ptr a -> Int -> a -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr a
p Int
i a
a
{-# INLINE streamTransform #-}
streamTransform :: forall m a b. (MonadIO m, Storable a, Storable b)
=> (SerialT m a -> SerialT m b) -> Array a -> m (Array b)
streamTransform :: (SerialT m a -> SerialT m b) -> Array a -> m (Array b)
streamTransform SerialT m a -> SerialT m b
f Array a
arr =
Fold m b (Array b) -> SerialT m b -> m (Array b)
forall (m :: * -> *) (t :: (* -> *) -> * -> *) a b.
(Monad m, IsStream t) =>
Fold m a b -> t m a -> m b
P.fold (Int -> Int -> Fold m b (Array b)
forall (m :: * -> *) a.
(MonadIO m, Storable a) =>
Int -> Int -> Fold m a (Array a)
A.toArrayMinChunk (a -> Int
forall a. Storable a => a -> Int
alignment (a
forall a. HasCallStack => a
undefined :: a)) (Array a -> Int
forall a. Storable a => Array a -> Int
length Array a
arr))
(SerialT m b -> m (Array b)) -> SerialT m b -> m (Array b)
forall a b. (a -> b) -> a -> b
$ SerialT m a -> SerialT m b
f (Array a -> SerialT m a
forall (m :: * -> *) (t :: (* -> *) -> * -> *) a.
(Monad m, IsStream t, Storable a) =>
Array a -> t m a
A.toStream Array a
arr)
unsafeCast ::
#ifdef DEVBUILD
Storable b =>
#endif
Array a -> Array b
unsafeCast :: Array a -> Array b
unsafeCast (Array ForeignPtr a
start Ptr a
end) = ForeignPtr b -> Ptr b -> Array b
forall a. ForeignPtr a -> Ptr a -> Array a
Array (ForeignPtr a -> ForeignPtr b
forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr ForeignPtr a
start) (Ptr a -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr Ptr a
end)
asBytes :: Array a -> Array Word8
asBytes :: Array a -> Array Word8
asBytes = Array a -> Array Word8
forall a b. Array a -> Array b
unsafeCast
cast :: forall a b. (Storable b) => Array a -> Maybe (Array b)
cast :: Array a -> Maybe (Array b)
cast Array a
arr =
let len :: Int
len = Array a -> Int
forall a. Array a -> Int
A.byteLength Array a
arr
r :: Int
r = Int
len Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` b -> Int
forall a. Storable a => a -> Int
sizeOf (b
forall a. HasCallStack => a
undefined :: b)
in if Int
r Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
0
then Maybe (Array b)
forall a. Maybe a
Nothing
else Array b -> Maybe (Array b)
forall a. a -> Maybe a
Just (Array b -> Maybe (Array b)) -> Array b -> Maybe (Array b)
forall a b. (a -> b) -> a -> b
$ Array a -> Array b
forall a b. Array a -> Array b
unsafeCast Array a
arr
unsafeAsPtr :: Array a -> (Ptr b -> IO c) -> IO c
unsafeAsPtr :: Array a -> (Ptr b -> IO c) -> IO c
unsafeAsPtr Array{Ptr a
ForeignPtr a
aEnd :: forall a. Array a -> Ptr a
aEnd :: Ptr a
aStart :: ForeignPtr a
aStart :: forall a. Array a -> ForeignPtr a
..} Ptr b -> IO c
act = do
ForeignPtr a -> (Ptr a -> IO c) -> IO c
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr a
aStart ((Ptr a -> IO c) -> IO c) -> (Ptr a -> IO c) -> IO c
forall a b. (a -> b) -> a -> b
$ \Ptr a
ptr -> Ptr b -> IO c
act (Ptr a -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr Ptr a
ptr)
unsafeAsCString :: Array a -> (CString -> IO b) -> IO b
unsafeAsCString :: Array a -> (CString -> IO b) -> IO b
unsafeAsCString Array a
arr CString -> IO b
act = do
let Array{Ptr Word8
ForeignPtr Word8
aEnd :: Ptr Word8
aStart :: ForeignPtr Word8
aEnd :: forall a. Array a -> Ptr a
aStart :: forall a. Array a -> ForeignPtr a
..} = Array a -> Array Word8
forall a. Array a -> Array Word8
asBytes Array a
arr Array Word8 -> Array Word8 -> Array Word8
forall a. Semigroup a => a -> a -> a
<> [Word8] -> Array Word8
forall a. Storable a => [a] -> Array a
A.fromList [Word8
0]
ForeignPtr Word8 -> (Ptr Word8 -> IO b) -> IO b
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr Word8
aStart ((Ptr Word8 -> IO b) -> IO b) -> (Ptr Word8 -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr -> CString -> IO b
act (Ptr Word8 -> CString
forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
ptr)
{-# INLINE fold #-}
fold :: forall m a b. (MonadIO m, Storable a) => Fold m a b -> Array a -> m b
fold :: Fold m a b -> Array a -> m b
fold Fold m a b
f Array a
arr = Fold m a b -> SerialT m a -> m b
forall (m :: * -> *) (t :: (* -> *) -> * -> *) a b.
(Monad m, IsStream t) =>
Fold m a b -> t m a -> m b
P.fold Fold m a b
f (Array a -> SerialT m a
forall (m :: * -> *) (t :: (* -> *) -> * -> *) a.
(Monad m, IsStream t, Storable a) =>
Array a -> t m a
A.toStream Array a
arr :: Serial.SerialT m a)
{-# INLINE streamFold #-}
streamFold :: (MonadIO m, Storable a) => (SerialT m a -> m b) -> Array a -> m b
streamFold :: (SerialT m a -> m b) -> Array a -> m b
streamFold SerialT m a -> m b
f Array a
arr = SerialT m a -> m b
f (Array a -> SerialT m a
forall (m :: * -> *) (t :: (* -> *) -> * -> *) a.
(Monad m, IsStream t, Storable a) =>
Array a -> t m a
A.toStream Array a
arr)