module Data.Repa.Convert.Format.Numeric
( IntAsc (..)
, IntAsc0 (..)
, DoubleAsc (..)
, DoubleFixedPack (..))
where
import Data.Repa.Convert.Internal.Format
import Data.Repa.Convert.Internal.Packable
import GHC.Exts
import Data.Word
import qualified Data.Repa.Scalar.Int as S
import qualified Data.Repa.Scalar.Double as S
import qualified Foreign.ForeignPtr as F
import qualified Foreign.Marshal.Utils as F
import qualified Foreign.Ptr as F
import Prelude hiding (fail)
#include "repa-convert.h"
data IntAsc = IntAsc deriving (Eq, Show)
instance Format IntAsc where
type Value IntAsc = Int
fieldCount _ = 1
{-# INLINE minSize #-}
minSize _ = 1
{-# INLINE fieldCount #-}
fixedSize _ = Nothing
{-# INLINE fixedSize #-}
packedSize _ _ = Just 20
{-# INLINE packedSize #-}
instance Packable IntAsc where
packer IntAsc (I# v) dst _fails k
= do len <- S.storeInt# dst v
let !(Ptr dst') = F.plusPtr (Ptr dst) len
k dst'
{-# INLINE packer #-}
instance Unpackable IntAsc where
unpacker IntAsc start end _stop fail eat
= let !len = I# (minusAddr# end start) in
if len > 0
then do
S.loadInt (pw8 start) len
fail
(\val (I# off) -> eat (plusAddr# start off) val)
else fail
{-# INLINE unpacker #-}
data IntAsc0 = IntAsc0 Int deriving (Eq, Show)
instance Format IntAsc0 where
type Value IntAsc0 = Int
fieldCount _ = 1
minSize _ = 1
fixedSize _ = Nothing
packedSize (IntAsc0 n) _ = Just (n + 20)
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable IntAsc0 where
packer (IntAsc0 (I# pad)) (I# v) dst _fails k
= do len <- S.storeIntPad# dst v pad
let !(Ptr dst') = F.plusPtr (Ptr dst) len
k dst'
{-# INLINE packer #-}
instance Unpackable IntAsc0 where
unpacker (IntAsc0 _) start end _stop fail eat
= let !len = I# (minusAddr# end start) in
if len > 0
then do
S.loadInt (pw8 start) len
fail
(\val (I# off) -> eat (plusAddr# start off) val)
else fail
{-# INLINE unpacker #-}
data DoubleAsc = DoubleAsc deriving (Eq, Show)
instance Format DoubleAsc where
type Value DoubleAsc = Double
fieldCount _ = 1
minSize _ = 1
fixedSize _ = Nothing
packedSize _ _ = Just 24
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable DoubleAsc where
packer DoubleAsc v dst _fails k
= do (fptr, len) <- S.storeDoubleShortest v
F.withForeignPtr fptr $ \ptr
-> F.copyBytes (Ptr dst) ptr len
let !(Ptr dst') = F.plusPtr (Ptr dst) len
k dst'
{-# INLINE packer #-}
instance Unpackable DoubleAsc where
unpacker DoubleAsc start end _stop fail eat
= let !len = I# (minusAddr# end start) in
if len > 0
then do
(v, I# o) <- S.loadDouble (pw8 start) len
eat (plusAddr# start o) v
else fail
{-# INLINE unpacker #-}
data DoubleFixedPack = DoubleFixedPack Int deriving (Eq, Show)
instance Format DoubleFixedPack where
type Value DoubleFixedPack = Double
fieldCount _ = 1
minSize _ = 1
fixedSize _ = Nothing
packedSize (DoubleFixedPack prec) _
= Just (24 + prec)
{-# INLINE minSize #-}
{-# INLINE fieldCount #-}
{-# INLINE fixedSize #-}
{-# INLINE packedSize #-}
instance Packable DoubleFixedPack where
packer (DoubleFixedPack prec) v dst _fails k
= do (fptr, len) <- S.storeDoubleFixed prec v
F.withForeignPtr fptr $ \ptr
-> F.copyBytes (Ptr dst) ptr len
let !(Ptr dst') = F.plusPtr (Ptr dst) len
k dst'
{-# INLINE packer #-}
instance Unpackable DoubleFixedPack where
unpacker (DoubleFixedPack _) start end _stop fail eat
= let !len = I# (minusAddr# end start) in
if len > 0
then do
(v, I# o) <- S.loadDouble (pw8 start) len
eat (plusAddr# start o) v
else fail
{-# INLINE unpacker #-}
pw8 :: Addr# -> Ptr Word8
pw8 addr = Ptr addr
{-# INLINE pw8 #-}