module Data.Repa.Scalar.Double
(
loadDouble
, storeDoubleShortest
, storeDoubleFixed)
where
import Data.Word
import GHC.Exts
import qualified Data.ByteString.Internal as BS
import qualified Data.Double.Conversion.ByteString as DC
import qualified Foreign.Ptr as F
import qualified Foreign.ForeignPtr as F
import qualified Foreign.Storable as F
import qualified Foreign.Marshal.Alloc as F
import qualified Foreign.Marshal.Utils as F
loadDouble
:: Ptr Word8
-> Int
-> IO (Double, Int)
loadDouble :: Ptr Word8 -> Int -> IO (Double, Int)
loadDouble !Ptr Word8
pIn !Int
len
= Int -> (Ptr Word8 -> IO (Double, Int)) -> IO (Double, Int)
forall a b. Int -> (Ptr a -> IO b) -> IO b
F.allocaBytes (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) ((Ptr Word8 -> IO (Double, Int)) -> IO (Double, Int))
-> (Ptr Word8 -> IO (Double, Int)) -> IO (Double, Int)
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
pBuf ->
(Ptr (Ptr Word8) -> IO (Double, Int)) -> IO (Double, Int)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
F.alloca ((Ptr (Ptr Word8) -> IO (Double, Int)) -> IO (Double, Int))
-> (Ptr (Ptr Word8) -> IO (Double, Int)) -> IO (Double, Int)
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr Word8)
pRes ->
do
Ptr Word8 -> Ptr Word8 -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
F.copyBytes Ptr Word8
pBuf Ptr Word8
pIn (Int -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
Ptr Word8 -> Int -> Word8 -> IO ()
forall b. Ptr b -> Int -> Word8 -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
F.pokeByteOff Ptr Word8
pBuf Int
len (Word8
0 :: Word8)
let !d :: Double
d = Ptr Word8 -> Ptr (Ptr Word8) -> Double
strtod Ptr Word8
pBuf Ptr (Ptr Word8)
pRes
Ptr Word8
res <- Ptr (Ptr Word8) -> IO (Ptr Word8)
forall a. Storable a => Ptr a -> IO a
F.peek Ptr (Ptr Word8)
pRes
(Double, Int) -> IO (Double, Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Double
d, Ptr Word8
res Ptr Word8 -> Ptr Word8 -> Int
forall a b. Ptr a -> Ptr b -> Int
`F.minusPtr` Ptr Word8
pBuf)
{-# INLINE loadDouble #-}
foreign import ccall unsafe
strtod :: Ptr Word8 -> Ptr (Ptr Word8) -> Double
storeDoubleShortest :: Double -> IO (F.ForeignPtr Word8, Int)
storeDoubleShortest :: Double -> IO (ForeignPtr Word8, Int)
storeDoubleShortest Double
d
= case Double -> ByteString
DC.toShortest Double
d of
BS.PS ForeignPtr Word8
p Int
_ Int
n -> (ForeignPtr Word8, Int) -> IO (ForeignPtr Word8, Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8
p, Int
n)
{-# INLINE storeDoubleShortest #-}
storeDoubleFixed :: Int -> Double -> IO (F.ForeignPtr Word8, Int)
storeDoubleFixed :: Int -> Double -> IO (ForeignPtr Word8, Int)
storeDoubleFixed !Int
prec !Double
d
= case Int -> Double -> ByteString
DC.toFixed Int
prec Double
d of
BS.PS ForeignPtr Word8
p Int
_ Int
n -> (ForeignPtr Word8, Int) -> IO (ForeignPtr Word8, Int)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8
p, Int
n)
{-# INLINE storeDoubleFixed #-}