module Data.Repa.Convert.Format.Binary
( Format (..)
, Word8be (..), Int8be (..)
, Word16be (..), Int16be (..)
, Word32be (..), Int32be (..)
, Word64be (..), Int64be (..)
, Float32be (..)
, Float64be (..))
where
import Data.Repa.Convert.Internal.Format
import Data.Repa.Convert.Internal.Packable
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
import GHC.Exts
import Prelude hiding (fail)
#include "repa-convert.h"
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
packer _ x dst _fails k
= do S.poke (Ptr dst) (fromIntegral x :: Word8)
let !(Ptr dst') = S.plusPtr (Ptr dst) 1
k dst'
{-# INLINE packer #-}
instance Unpackable Word8be where
unpacker _ start _end _stop _fail eat
= do x <- S.peek (pw8 start)
eat (plusAddr# start 1#) (fromIntegral x)
{-# INLINE unpacker #-}
w8 :: Integral a => a -> Word8
w8 = fromIntegral
{-# INLINE w8 #-}
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
packer Int8be x buf k
= packer Word8be (w8 x) buf k
{-# INLINE packer #-}
instance Unpackable Int8be where
unpacker Int8be start end stop fail eat
= unpacker Word8be start end stop fail
$ \addr v -> eat addr (i8 v)
{-# INLINE unpacker #-}
i8 :: Integral a => a -> Int8
i8 = fromIntegral
{-# INLINE i8 #-}
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
packer Word16be x dst _fails k
= do S.poke (Ptr dst) (w8 ((w16 x .&. 0x0ff00) `shiftR` 8))
S.pokeByteOff (Ptr dst) 1 (w8 ((w16 x .&. 0x000ff)))
let !(Ptr dst') = S.plusPtr (Ptr dst) 2
k dst'
{-# INLINE packer #-}
instance Unpackable Word16be where
unpacker Word16be start _end _stop _fail eat
= do x0 :: Word8 <- S.peek (pw8 start)
x1 :: Word8 <- S.peekByteOff (pw8 start) 1
eat (plusAddr# start 2#)
(w16 ((w16 x0 `shiftL` 8) .|. w16 x1))
{-# INLINE unpacker #-}
w16 :: Integral a => a -> Word16
w16 = fromIntegral
{-# INLINE w16 #-}
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
packer Int16be x buf k
= packer Word16be (w16 x) buf k
{-# INLINE packer #-}
instance Unpackable Int16be where
unpacker Int16be start end stop fail eat
= unpacker Word16be start end stop fail
$ \addr v -> eat addr (i16 v)
{-# INLINE unpacker #-}
i16 :: Integral a => a -> Int16
i16 = fromIntegral
{-# INLINE i16 #-}
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
packer Word32be x dst _fails k
= do S.poke (Ptr dst) (w8 ((w32 x .&. 0x0ff000000) `shiftR` 24))
S.pokeByteOff (Ptr dst) 1 (w8 ((w32 x .&. 0x000ff0000) `shiftR` 16))
S.pokeByteOff (Ptr dst) 2 (w8 ((w32 x .&. 0x00000ff00) `shiftR` 8))
S.pokeByteOff (Ptr dst) 3 (w8 ((w32 x .&. 0x0000000ff)))
let !(Ptr dst') = S.plusPtr (Ptr dst) 4
k dst'
{-# INLINE packer #-}
instance Unpackable Word32be where
unpacker Word32be start _end _fail _stop eat
= do x0 :: Word8 <- S.peek (pw8 start)
x1 :: Word8 <- S.peekByteOff (pw8 start) 1
x2 :: Word8 <- S.peekByteOff (pw8 start) 2
x3 :: Word8 <- S.peekByteOff (pw8 start) 3
eat (plusAddr# start 4#)
(w32 ( (w32 x0 `shiftL` 24)
.|. (w32 x1 `shiftL` 16)
.|. (w32 x2 `shiftL` 8)
.|. (w32 x3)))
{-# INLINE unpacker #-}
w32 :: Integral a => a -> Word32
w32 = fromIntegral
{-# INLINE w32 #-}
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
packer Int32be x buf k
= packer Word32be (w32 x) buf k
{-# INLINE packer #-}
instance Unpackable Int32be where
unpacker Int32be start end stop fail eat
= unpacker Word32be start end stop fail
$ \addr v -> eat addr (i32 v)
{-# INLINE unpacker #-}
i32 :: Integral a => a -> Int32
i32 = fromIntegral
{-# INLINE i32 #-}
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
packer Word64be x dst _fails k
= do S.poke (Ptr dst) (w8 ((w64 x .&. 0x0ff00000000000000) `shiftR` 56))
S.pokeByteOff (Ptr dst) 1 (w8 ((w64 x .&. 0x000ff000000000000) `shiftR` 48))
S.pokeByteOff (Ptr dst) 2 (w8 ((w64 x .&. 0x00000ff0000000000) `shiftR` 40))
S.pokeByteOff (Ptr dst) 3 (w8 ((w64 x .&. 0x0000000ff00000000) `shiftR` 32))
S.pokeByteOff (Ptr dst) 4 (w8 ((w64 x .&. 0x000000000ff000000) `shiftR` 24))
S.pokeByteOff (Ptr dst) 5 (w8 ((w64 x .&. 0x00000000000ff0000) `shiftR` 16))
S.pokeByteOff (Ptr dst) 6 (w8 ((w64 x .&. 0x0000000000000ff00) `shiftR` 8))
S.pokeByteOff (Ptr dst) 7 (w8 ((w64 x .&. 0x000000000000000ff) ))
let !(Ptr dst') = S.plusPtr (Ptr dst) 8
k dst'
{-# INLINE packer #-}
instance Unpackable Word64be where
unpacker Word64be start _end _fail _stop eat
= do x0 :: Word8 <- S.peek (pw8 start)
x1 :: Word8 <- S.peekByteOff (pw8 start) 1
x2 :: Word8 <- S.peekByteOff (pw8 start) 2
x3 :: Word8 <- S.peekByteOff (pw8 start) 3
x4 :: Word8 <- S.peekByteOff (pw8 start) 4
x5 :: Word8 <- S.peekByteOff (pw8 start) 5
x6 :: Word8 <- S.peekByteOff (pw8 start) 6
x7 :: Word8 <- S.peekByteOff (pw8 start) 7
eat (plusAddr# 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 unpacker #-}
w64 :: Integral a => a -> Word64
w64 = fromIntegral
{-# INLINE w64 #-}
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
packer Int64be x buf k
= packer Word64be (w64 x) buf k
{-# INLINE packer #-}
instance Unpackable Int64be where
unpacker Int64be start end stop fail eat
= unpacker Word64be start end stop fail
$ \addr v -> eat addr (i64 v)
{-# INLINE unpacker #-}
i64 :: Integral a => a -> Int64
i64 = fromIntegral
{-# INLINE i64 #-}
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
packer Float32be x buf k
= packer Word32be (floatToWord32 x) buf k
{-# INLINE packer #-}
instance Unpackable Float32be where
unpacker Float32be start end stop fail eat
= unpacker Word32be start end stop fail
$ \addr v -> eat addr (word32ToFloat v)
{-# INLINE unpacker #-}
floatToWord32 :: Float -> Word32
floatToWord32 d
= Prim.unsafeInlineIO
$ S.alloca $ \buf ->
do S.poke (S.castPtr buf) d
S.peek buf
{-# INLINE floatToWord32 #-}
word32ToFloat :: Word32 -> Float
word32ToFloat w
= Prim.unsafeInlineIO
$ S.alloca $ \buf ->
do S.poke (S.castPtr buf) w
S.peek buf
{-# INLINE word32ToFloat #-}
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
packer Float64be x start fails eat
= packer Word64be (doubleToWord64 x) start fails eat
{-# INLINE packer #-}
instance Unpackable Float64be where
unpacker Float64be start end stop fail eat
= unpacker Word64be start end stop fail
$ \addr v -> eat addr (word64ToDouble v)
{-# INLINE unpacker #-}
doubleToWord64 :: Double -> Word64
doubleToWord64 d
= Prim.unsafeInlineIO
$ S.alloca $ \buf ->
do S.poke (S.castPtr buf) d
S.peek buf
{-# INLINE doubleToWord64 #-}
word64ToDouble :: Word64 -> Double
word64ToDouble w
= Prim.unsafeInlineIO
$ S.alloca $ \buf ->
do S.poke (S.castPtr buf) w
S.peek buf
{-# INLINE word64ToDouble #-}
pw8 :: Addr# -> Ptr Word8
pw8 addr = Ptr addr
{-# INLINE pw8 #-}