@@ -26,7 +26,8 @@ module Streamly.Mem.Array.Types
26 , unsafeInlineIO
26 , unsafeInlineIO
27 , withNewArray
27 , withNewArray
28 , newArray
28 , newArray
29− , unsafeAppend
29+ , unsafeSnoc
30 , shrinkToFit
31 , shrinkToFit
@@ -215,15 +216,39 @@ withNewArray count f = do
215-- Internal routine for when the array is being created. Appends one item at
216-- Internal routine for when the array is being created. Appends one item at
216-- the end of the array. Useful when sequentially writing a stream to the
217-- the end of the array. Useful when sequentially writing a stream to the
217-- array. DOES NOT CHECK THE ARRAY BOUNDS.
218-- array. DOES NOT CHECK THE ARRAY BOUNDS.
218−{-# INLINE unsafeAppend #-}
219+{-# INLINE unsafeSnoc #-}
219−unsafeAppend :: forall a. Storable a => Array a -> a -> IO (Array a)
220+unsafeSnoc :: forall a. Storable a => Array a -> a -> IO (Array a)
220−unsafeAppend arr@Array{..} x = do
221+unsafeSnoc arr@Array{..} x = do
221 when (aEnd == aBound) $
222 when (aEnd == aBound) $
222 error "BUG: unsafeAppend: writing beyond array bounds"
223 error "BUG: unsafeAppend: writing beyond array bounds"
223 poke aEnd x
224 poke aEnd x
224 touchForeignPtr aStart
225 touchForeignPtr aStart
225 return $ arr {aEnd = aEnd `plusPtr` (sizeOf (undefined :: a))}
226 return $ arr {aEnd = aEnd `plusPtr` (sizeOf (undefined :: a))}
229+snoc :: forall a. Storable a => Array a -> a -> Array a
230+snoc arr@Array {..} x = unsafePerformIO $
233+ let oldStart = unsafeForeignPtrToPtr aStart
234+ size = aEnd `minusPtr` oldStart
235+ newSize = (size + (sizeOf (undefined :: a)))
236+ newPtr <- mallocPlainForeignPtrAlignedBytes newSize (alignment (undefined :: a))
237+ withForeignPtr newPtr $ \pNew -> do
238+ memcpy (castPtr pNew) (castPtr oldStart) size
239+ poke (pNew `plusPtr` size) x
240+ touchForeignPtr aStart
243+ , aEnd = pNew `plusPtr` (size + sizeOf (undefined :: a))
244+ , aBound = pNew `plusPtr` newSize
248+ touchForeignPtr aStart
249+ return $ arr {aEnd = aEnd `plusPtr` (sizeOf (undefined :: a))}
227-- | Remove the free space from an Array.
252-- | Remove the free space from an Array.
228shrinkToFit :: forall a. Storable a => Array a -> IO (Array a)
253shrinkToFit :: forall a. Storable a => Array a -> IO (Array a)
229shrinkToFit arr@Array{..} = do
254shrinkToFit arr@Array{..} = do