{-# LANGUAGE MagicHash, UnliftedFFITypes #-}
------------------------------------------------------------------------------- |-- Module : Data.Array.IO-- Copyright : (c) The University of Glasgow 2001-- License : BSD-style (see the file libraries/base/LICENSE)---- Maintainer : libraries@haskell.org-- Stability : experimental-- Portability : non-portable (uses Data.Array.MArray)---- Mutable boxed and unboxed arrays in the IO monad.-------------------------------------------------------------------------------
module Data.Array.IO (
-- * @IO@ arrays with boxed elements
IOArray, -- instance of: Eq, Typeable-- * @IO@ arrays with unboxed elements
IOUArray, -- instance of: Eq, Typeable-- * Overloaded mutable array interface
module Data.Array.MArray,
-- * Doing I\/O with @IOUArray@s
hGetArray, -- :: Handle -> IOUArray Int Word8 -> Int -> IO Int
hPutArray, -- :: Handle -> IOUArray Int Word8 -> Int -> IO ()
) where
import Data.Array.Base
import Data.Array.IO.Internals
import Data.Array.MArray
import System.IO.Error
import Foreign
import Foreign.C
import GHC.Exts (MutableByteArray#, RealWorld)
import GHC.IO.Handle
import GHC.IO.Exception
-- ----------------------------------------------------------------------------- hGetArray-- | Reads a number of 'Word8's from the specified 'Handle' directly-- into an array.hGetArray
:: Handle-- ^ Handle to read from
-> IOUArrayIntWord8-- ^ Array in which to place the values
-> Int-- ^ Number of 'Word8's to read
-> IOInt-- ^ Returns: the number of 'Word8's actually-- read, which might be smaller than the number requested-- if the end of file was reached.hGetArrayhandle (IOUArray (STUArray_l_unptr)) count
| count==0 = return0
| count<0||count>n = illegalBufferSizehandle"hGetArray"count
| otherwise = do
-- we would like to read directly into the buffer, but we can't-- be sure that the MutableByteArray# is pinned, so we have to-- allocate a separate area of memory and copy.allocaBytescount$ \p -> do
r <- hGetBufhandlepcount
_ <- memcpy_ba_ptrptrp (fromIntegralr)
returnrforeign import ccall unsafe "memcpy"
memcpy_ba_ptr :: MutableByteArray# RealWorld -> Ptr a -> CSize -> IO (Ptr ())-- ----------------------------------------------------------------------------- hPutArray-- | Writes an array of 'Word8' to the specified 'Handle'.hPutArray
:: Handle-- ^ Handle to write to
-> IOUArrayIntWord8-- ^ Array to write from
-> Int-- ^ Number of 'Word8's to write
-> IO()hPutArrayhandle (IOUArray (STUArray_l_unraw)) count
| count==0 = return()
| count<0||count>n = illegalBufferSizehandle"hPutArray"count
| otherwise = do
-- as in hGetArray, we would like to use the array directly, but-- we can't be sure that the MutableByteArray# is pinned.allocaBytescount$ \p -> do
_ <- memcpy_ptr_bapraw (fromIntegralcount)
hPutBufhandlepcountforeign import ccall unsafe "memcpy"
memcpy_ptr_ba :: Ptr a -> MutableByteArray# RealWorld -> CSize -> IO (Ptr ())-- ----------------------------------------------------------------------------- Internal UtilsillegalBufferSize :: Handle -> String -> Int -> IOaillegalBufferSizehandlefnsz =
ioException (ioeSetErrorString
(mkIOErrorInvalidArgumentfn (Justhandle) Nothing)
("illegal buffer size "++showsPrec9 (sz::Int) []))