@@ -120,6 +120,13 @@ module Streamly.Internal.Memory.Array
120 -- * Immutable Transformations
120 -- * Immutable Transformations
121 , streamTransform
121 , streamTransform
123 -- * Folding Arrays
130 -- * Folding Arrays
124 , streamFold
131 , streamFold
@@ -129,11 +136,16 @@ module Streamly.Internal.Memory.Array
132−import Control.Monad (when)
139+import Control.Monad (when)
133import Control.Monad.IO.Class (MonadIO(..))
140import Control.Monad.IO.Class (MonadIO(..))
141+#if !(MIN_VERSION_base(4,11,0))
142+import Data.Semigroup ((<>))
144+import Data.Word (Word8)
134-- import Data.Functor.Identity (Identity)
145-- import Data.Functor.Identity (Identity)
146+import Foreign.C.String (CString)
135−import Foreign.ForeignPtr (withForeignPtr, touchForeignPtr)
147+import Foreign.ForeignPtr (withForeignPtr, touchForeignPtr, castForeignPtr)
136−import Foreign.Ptr (plusPtr)
148+import Foreign.Ptr (plusPtr, castPtr)
137import Foreign.Storable (Storable(..))
149import Foreign.Storable (Storable(..))
138import Prelude hiding (length, null, last, map, (!!), read, concat)
150import Prelude hiding (length, null, last, map, (!!), read, concat)
@@ -488,6 +500,66 @@ streamTransform f arr =
488 P.runFold (A.toArrayMinChunk (alignment (undefined :: a)) (length arr))
500 P.runFold (A.toArrayMinChunk (alignment (undefined :: a)) (length arr))
489 $ f (toStream arr)
501 $ f (toStream arr)
503+-------------------------------------------------------------------------------
505+-------------------------------------------------------------------------------
507+-- | Cast an array having elements of type @a@ into an array having elements of
508+-- type @b@. The array size must be a multiple of the size of type @b@
509+-- otherwise accessing the last element of the array may result into a crash or
514+unsafeCast :: Array a -> Array b
515+unsafeCast (Array start end) = Array (castForeignPtr start) (castPtr end)
517+-- | Cast an array into a Word8 array
521+castWord8 :: Array a -> Array Word8
522+castWord8 = unsafeCast
524+-- | Cast an array having elements of type @a@ into an array having elements of
525+-- type @b@. The length of the array should be a multiple of the size of the
526+-- target element otherwise 'Nothing' is returned.
530+cast :: forall a b. (Storable b) => Array a -> Maybe (Array b)
532+ let len = A.byteLength arr
533+ r = len `mod` sizeOf (undefined :: b)
536+ else Just $ unsafeCast arr
538+-- | Use the array as @Ptr a@.
544+withPtr :: Array a -> (Ptr b -> IO c) -> IO c
545+withPtr Array{..} act = do
546+ withForeignPtr aStart $ \ptr -> act (castPtr ptr)
548+-- | Convert the array into a null terminated CString Ptr.
554+withCString :: Array a -> (CString -> IO b) -> IO b
555+withCString arr act = do
556+ let Array{..} = castWord8 arr <> A.fromList [0]
557+ withForeignPtr aStart $ \ptr -> act (castPtr ptr)
559+-------------------------------------------------------------------------------
561+-------------------------------------------------------------------------------
491-- | Fold an array using a 'Fold'.
563-- | Fold an array using a 'Fold'.
493-- /Internal/
565-- /Internal/