module NHC.FFI
( Storable
( sizeOf -- :: a -> Int
, alignment -- :: a -> Int
, peekElemOff -- :: Ptr a -> Int -> IO a
, pokeElemOff -- :: Ptr a -> Int -> a -> IO ()
, peekByteOff -- :: Ptr b -> Int -> IO a
, pokeByteOff -- :: Ptr b -> Int -> a -> IO ()
, peek -- :: Ptr a -> IO a
, poke -- :: Ptr a -> a -> IO ()
, destruct -- :: Ptr a -> IO ()
)
) where
import Int (Int8, Int16, Int32, Int64)
import Word (Word8, Word16, Word32, Word64)
import Ptr (Ptr, plusPtr, castPtr)
--import StablePtr (StablePtr)
--import CTypes
--import CTypesISO
class Storable a where
-- Yields the storage requirements (in bytes) of the argument.
-- * Never uses its argument.
sizeOf :: a -> Int
-- Yields the alignment constraint of the argument.
-- * An alignment constraint x is fulfilled by any address divisible by x.
-- * Never uses its argument.
alignment :: a -> Int
-- Read/write elements from an array of elements of the given type.
peekElemOff :: Ptr a -> Int -> IO a
pokeElemOff :: Ptr a -> Int -> a -> IO ()
-- The same with *byte* offsets.
peekByteOff :: Ptr b -> Int -> IO a
pokeByteOff :: Ptr b -> Int -> a -> IO ()
-- ... and with no offsets at all.
peek :: Ptr a -> IO a
poke :: Ptr a -> a -> IO ()
-- Free memory associated with the object
-- (except the object pointer itself).
destruct :: Ptr a -> IO ()
-- circular default instances
peekElemOff = peekElemOff_ undefined
where peekElemOff_ :: Storable a => a -> Ptr a -> Int -> IO a
peekElemOff_ undef ptr off = peekByteOff ptr (off * sizeOf undef)
pokeElemOff ptr off val = pokeByteOff ptr (off * sizeOf val) val
peekByteOff ptr off = peek (ptr `plusPtr` off)
pokeByteOff ptr off = poke (ptr `plusPtr` off)
peek ptr = peekElemOff ptr 0
poke ptr = pokeElemOff ptr 0
-- Note that the various `peek' and `poke' functions might require properly
-- aligned addresses to function correctly. This is architecture dependent;
-- thus, portable code should ensure that when peeking or poking values of
-- some type `a', the alignment constraint for `a', as given by the function
-- alignment is fulfilled.
destruct _ = return ()
----------------------------------------------------------------------
-- system-dependent instances
instance Storable Bool where
sizeOf = const 1
alignment = const 1
peek p = readCharAtAddr (castPtr p) >>= return . toEnum . fromEnum
poke p = writeCharAtAddr (castPtr p) . toEnum . fromEnum
foreign import ccall readCharAtAddr :: Ptr Char -> IO Char
foreign import ccall writeCharAtAddr :: Ptr Char -> Char -> IO ()
instance Storable Char where
sizeOf = const 1
alignment = const 1
peek = readCharAtAddr
poke = writeCharAtAddr
foreign import ccall readIntAtAddr :: Ptr Int -> IO Int
foreign import ccall writeIntAtAddr :: Ptr Int -> Int -> IO ()
instance Storable Int where
sizeOf = const 4
alignment = const 4
peek = readIntAtAddr
poke = writeIntAtAddr
foreign import ccall readAddrAtAddr :: Ptr (Ptr a) -> IO (Ptr a)
foreign import ccall writeAddrAtAddr :: Ptr (Ptr a) -> Ptr a -> IO ()
instance Storable (Ptr a) where
sizeOf = const 4
alignment = const 4
peek = readAddrAtAddr
poke = writeAddrAtAddr
foreign import ccall readFloatAtAddr :: Ptr Float -> IO Float
foreign import ccall writeFloatAtAddr :: Ptr Float -> Float -> IO ()
instance Storable Float where
sizeOf = const 4
alignment = const 4
peek = readFloatAtAddr
poke = writeFloatAtAddr
foreign import ccall readDoubleAtAddr :: Ptr Double -> IO Double
foreign import ccall writeDoubleAtAddr :: Ptr Double -> Double -> IO ()
instance Storable Double where
sizeOf = const 8
alignment = const 8
peek = readDoubleAtAddr
poke = writeDoubleAtAddr
foreign import ccall readWord8AtAddr :: Ptr Word8 -> IO Word8
foreign import ccall writeWord8AtAddr :: Ptr Word8 -> Word8 -> IO ()
instance Storable Word8 where
sizeOf = const 1
alignment = sizeOf -- not sure about this
peek = readWord8AtAddr
poke = writeWord8AtAddr
foreign import ccall readWord16AtAddr :: Ptr Word16 -> IO Word16
foreign import ccall writeWord16AtAddr :: Ptr Word16 -> Word16 -> IO ()
instance Storable Word16 where
sizeOf = const 2
alignment = sizeOf -- not sure about this
peek = readWord16AtAddr
poke = writeWord16AtAddr
foreign import ccall readWord32AtAddr :: Ptr Word32 -> IO Word32
foreign import ccall writeWord32AtAddr :: Ptr Word32 -> Word32 -> IO ()
instance Storable Word32 where
sizeOf = const 4
alignment = sizeOf -- not sure about this
peek = readWord32AtAddr
poke = writeWord32AtAddr
foreign import ccall readWord64AtAddr :: Ptr Word64 -> IO Word64
foreign import ccall writeWord64AtAddr :: Ptr Word64 -> Word64 -> IO ()
instance Storable Word64 where
sizeOf = const 8
alignment = sizeOf -- not sure about this
peek = readWord64AtAddr
poke = writeWord64AtAddr
foreign import ccall readInt8AtAddr :: Ptr Int8 -> IO Int8
foreign import ccall writeInt8AtAddr :: Ptr Int8 -> Int8 -> IO ()
instance Storable Int8 where
sizeOf = const 1
alignment = sizeOf -- not sure about this
peek = readInt8AtAddr
poke = writeInt8AtAddr
foreign import ccall readInt16AtAddr :: Ptr Int16 -> IO Int16
foreign import ccall writeInt16AtAddr :: Ptr Int16 -> Int16 -> IO ()
instance Storable Int16 where
sizeOf = const 2
alignment = sizeOf -- not sure about this
peek = readInt16AtAddr
poke = writeInt16AtAddr
foreign import ccall readInt32AtAddr :: Ptr Int32 -> IO Int32
foreign import ccall writeInt32AtAddr :: Ptr Int32 -> Int32 -> IO ()
instance Storable Int32 where
sizeOf = const 4
alignment = sizeOf -- not sure about this
peek = readInt32AtAddr
poke = writeInt32AtAddr
foreign import ccall readInt64AtAddr :: Ptr Int64 -> IO Int64
foreign import ccall writeInt64AtAddr :: Ptr Int64 -> Int64 -> IO ()
instance Storable Int64 where
sizeOf = const 8
alignment = sizeOf -- not sure about this
peek = readInt64AtAddr
poke = writeInt64AtAddr
---------------------------------------------------------------------------
|