repa-convert-4.2.0.1: Data/Repa/Convert/Format/Binary.hs
-- | Atomic binary formats.
module Data.Repa.Convert.Format.Binary
( Format (..)
, Word8be (..), Int8be (..)
, Word16be (..), Int16be (..)
, Word32be (..), Int32be (..)
, Word64be (..), Int64be (..)
, Float32be (..)
, Float64be (..))
where
import Data.Repa.Convert.Format.Base
import Data.Bits
import Data.Int as V
import Data.Word as V
import qualified Foreign.Storable as S
import qualified Foreign.Marshal.Alloc as S
import qualified Foreign.Ptr as S
import qualified Control.Monad.Primitive as Prim
------------------------------------------------------------------------------------------- Word8be
-- | Big-endian 8-bit unsigned word.
data Word8be = Word8be deriving (Eq, Show)
instance Format Word8be where
type Value Word8be = Word8
fieldCount _ = 1
minSize _ = 1
fixedSize _ = Just 1
packedSize _ _ = Just 1
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable Word8be where
pack Word8be x
= Packer $ \buf k
-> do S.poke buf (fromIntegral x)
k (S.plusPtr buf 1)
{-# INLINE pack #-}
unpack Word8be
= Unpacker $ \start _end _stop _fail eat
-> do x <- S.peek start
eat (S.plusPtr start 1) (fromIntegral x)
{-# INLINE unpack #-}
w8 :: Integral a => a -> Word8
w8 = fromIntegral
{-# INLINE w8 #-}
------------------------------------------------------------------------------------------- Int8be
-- | Big-endian 8-bit signed integer.
data Int8be = Int8be deriving (Eq, Show)
instance Format Int8be where
type Value Int8be = V.Int8
fieldCount _ = 1
minSize _ = 1
fixedSize _ = Just 1
packedSize _ _ = Just 1
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable Int8be where
pack Int8be x = pack Word8be (w8 x)
unpack Int8be = fmap i8 (unpack Word8be)
{-# INLINE pack #-}
{-# INLINE unpack #-}
i8 :: Integral a => a -> Int8
i8 = fromIntegral
{-# INLINE i8 #-}
------------------------------------------------------------------------------------------ Word16be
-- | Big-endian 32-bit unsigned word.
data Word16be = Word16be deriving (Eq, Show)
instance Format Word16be where
type Value Word16be = V.Word16
fieldCount _ = 1
minSize _ = 2
fixedSize _ = Just 2
packedSize _ _ = Just 2
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable Word16be where
pack Word16be x
= Packer $ \buf k
-> do S.poke buf (w8 ((w16 x .&. 0x0ff00) `shiftR` 8))
S.pokeByteOff buf 1 (w8 ((w16 x .&. 0x000ff)))
k (S.plusPtr buf 2)
{-# INLINE pack #-}
unpack Word16be
= Unpacker $ \start _end _stop _fail eat
-> do x0 :: Word8 <- S.peek start
x1 :: Word8 <- S.peekByteOff start 1
eat (S.plusPtr start 2)
(w16 ((w16 x0 `shiftL` 8) .|. w16 x1))
{-# INLINE unpack #-}
w16 :: Integral a => a -> Word16
w16 = fromIntegral
{-# INLINE w16 #-}
------------------------------------------------------------------------------------------- Int16be
--- | Big-endian 16-bit signed integer.
data Int16be = Int16be deriving (Eq, Show)
instance Format Int16be where
type Value Int16be = V.Int16
fieldCount _ = 1
minSize _ = 2
fixedSize _ = Just 2
packedSize _ _ = Just 2
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable Int16be where
pack Int16be x = pack Word16be (w16 x)
unpack Int16be = fmap i16 (unpack Word16be)
{-# INLINE pack #-}
{-# INLINE unpack #-}
i16 :: Integral a => a -> Int16
i16 = fromIntegral
{-# INLINE i16 #-}
------------------------------------------------------------------------------------------ Word32be
-- | Big-endian 32-bit unsigned word.
data Word32be = Word32be deriving (Eq, Show)
instance Format Word32be where
type Value Word32be = V.Word32
fieldCount _ = 1
minSize _ = 4
fixedSize _ = Just 4
packedSize _ _ = Just 4
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable Word32be where
pack Word32be x
= Packer $ \buf k
-> do S.poke buf (w8 ((w32 x .&. 0x0ff000000) `shiftR` 24))
S.pokeByteOff buf 1 (w8 ((w32 x .&. 0x000ff0000) `shiftR` 16))
S.pokeByteOff buf 2 (w8 ((w32 x .&. 0x00000ff00) `shiftR` 8))
S.pokeByteOff buf 3 (w8 ((w32 x .&. 0x0000000ff)))
k (S.plusPtr buf 4)
{-# INLINE pack #-}
unpack Word32be
= Unpacker $ \start _end _fail _stop eat
-> do x0 :: Word8 <- S.peek start
x1 :: Word8 <- S.peekByteOff start 1
x2 :: Word8 <- S.peekByteOff start 2
x3 :: Word8 <- S.peekByteOff start 3
eat (S.plusPtr start 4)
(w32 ( (w32 x0 `shiftL` 24)
.|. (w32 x1 `shiftL` 16)
.|. (w32 x2 `shiftL` 8)
.|. (w32 x3)))
{-# INLINE unpack #-}
w32 :: Integral a => a -> Word32
w32 = fromIntegral
{-# INLINE w32 #-}
------------------------------------------------------------------------------------------- Int32be
-- | Big-endian 32-bit signed integer.
data Int32be = Int32be deriving (Eq, Show)
instance Format Int32be where
type Value Int32be = V.Int32
fieldCount _ = 1
minSize _ = 4
fixedSize _ = Just 4
packedSize _ _ = Just 4
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable Int32be where
pack Int32be x = pack Word32be (w32 x)
unpack Int32be = fmap i32 (unpack Word32be)
{-# INLINE pack #-}
{-# INLINE unpack #-}
i32 :: Integral a => a -> Int32
i32 = fromIntegral
{-# INLINE i32 #-}
------------------------------------------------------------------------------------------ Word64be
-- | Big-endian 64-bit unsigned word.
data Word64be = Word64be deriving (Eq, Show)
instance Format Word64be where
type Value Word64be = V.Word64
fieldCount _ = 1
minSize _ = 8
fixedSize _ = Just 8
packedSize _ _ = Just 8
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable Word64be where
pack Word64be x
= Packer $ \buf k
-> do S.poke buf (w8 ((w64 x .&. 0x0ff00000000000000) `shiftR` 56))
S.pokeByteOff buf 1 (w8 ((w64 x .&. 0x000ff000000000000) `shiftR` 48))
S.pokeByteOff buf 2 (w8 ((w64 x .&. 0x00000ff0000000000) `shiftR` 40))
S.pokeByteOff buf 3 (w8 ((w64 x .&. 0x0000000ff00000000) `shiftR` 32))
S.pokeByteOff buf 4 (w8 ((w64 x .&. 0x000000000ff000000) `shiftR` 24))
S.pokeByteOff buf 5 (w8 ((w64 x .&. 0x00000000000ff0000) `shiftR` 16))
S.pokeByteOff buf 6 (w8 ((w64 x .&. 0x0000000000000ff00) `shiftR` 8))
S.pokeByteOff buf 7 (w8 ((w64 x .&. 0x000000000000000ff) ))
k (S.plusPtr buf 8)
{-# INLINE pack #-}
unpack Word64be
= Unpacker $ \start _end _fail _stop eat
-> do x0 :: Word8 <- S.peek start
x1 :: Word8 <- S.peekByteOff start 1
x2 :: Word8 <- S.peekByteOff start 2
x3 :: Word8 <- S.peekByteOff start 3
x4 :: Word8 <- S.peekByteOff start 4
x5 :: Word8 <- S.peekByteOff start 5
x6 :: Word8 <- S.peekByteOff start 6
x7 :: Word8 <- S.peekByteOff start 7
eat (S.plusPtr start 8)
(w64 ( (w64 x0 `shiftL` 56)
.|. (w64 x1 `shiftL` 48)
.|. (w64 x2 `shiftL` 40)
.|. (w64 x3 `shiftL` 32)
.|. (w64 x4 `shiftL` 24)
.|. (w64 x5 `shiftL` 16)
.|. (w64 x6 `shiftL` 8)
.|. (w64 x7 )))
{-# INLINE unpack #-}
w64 :: Integral a => a -> Word64
w64 = fromIntegral
{-# INLINE w64 #-}
------------------------------------------------------------------------------------------- Int64be
-- | Big-endian 64-bit signed integer.
data Int64be = Int64be deriving (Eq, Show)
instance Format Int64be where
type Value Int64be = V.Int64
fieldCount _ = 1
minSize _ = 8
fixedSize _ = Just 8
packedSize _ _ = Just 8
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable Int64be where
pack Int64be x = pack Word64be (w64 x)
unpack Int64be = fmap i64 (unpack Word64be)
{-# INLINE pack #-}
{-# INLINE unpack #-}
i64 :: Integral a => a -> Int64
i64 = fromIntegral
{-# INLINE i64 #-}
----------------------------------------------------------------------------------------- Float32be
-- | Big-endian 32-bit IEEE 754 float.
data Float32be = Float32be deriving (Eq, Show)
instance Format Float32be where
type Value Float32be = Float
fieldCount _ = 1
minSize _ = 4
fixedSize _ = Just 4
packedSize _ _ = Just 4
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable Float32be where
pack Float32be x = pack Word32be (floatToWord32 x)
unpack Float32be = fmap word32ToFloat (unpack Word32be)
{-# INLINE pack #-}
{-# INLINE unpack #-}
-- | Bitwise cast of `Float` to `Word32`.
--
-- The resulting `Word32` contains the representation of the `Float`,
-- rather than it's value.
floatToWord32 :: Float -> Word32
floatToWord32 d
= Prim.unsafeInlineIO
$ S.alloca $ \buf ->
do S.poke (S.castPtr buf) d
S.peek buf
{-# INLINE floatToWord32 #-}
-- | Inverse of `doubleToFloat32`
word32ToFloat :: Word32 -> Float
word32ToFloat w
= Prim.unsafeInlineIO
$ S.alloca $ \buf ->
do S.poke (S.castPtr buf) w
S.peek buf
{-# INLINE word32ToFloat #-}
----------------------------------------------------------------------------------------- Float64be
-- | Big-endian 64-bit IEEE 754 float.
data Float64be = Float64be deriving (Eq, Show)
instance Format Float64be where
type Value Float64be = Double
fieldCount _ = 1
minSize _ = 8
fixedSize _ = Just 8
packedSize _ _ = Just 8
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable Float64be where
pack Float64be x = pack Word64be (doubleToWord64 x)
unpack Float64be = fmap word64ToDouble (unpack Word64be)
{-# INLINE pack #-}
{-# INLINE unpack #-}
-- | Bitwise cast of `Double` to `Word64`.
--
-- The resulting `Word64` contains the representation of the `Double`,
-- rather than it's value.
doubleToWord64 :: Double -> Word64
doubleToWord64 d
= Prim.unsafeInlineIO
$ S.alloca $ \buf ->
do S.poke (S.castPtr buf) d
S.peek buf
{-# INLINE doubleToWord64 #-}
-- | Inverse of `doubleToWord64`
word64ToDouble :: Word64 -> Double
word64ToDouble w
= Prim.unsafeInlineIO
$ S.alloca $ \buf ->
do S.poke (S.castPtr buf) w
S.peek buf
{-# INLINE word64ToDouble #-}