module Data.Repa.Convert.Format.Numeric ( IntAsc (..) , IntAsc0 (..) , DoubleAsc (..)) where import Data.Repa.Convert.Format.Base import Data.Repa.Convert.Format.Lists 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) ------------------------------------------------------------------------------------------- IntAsc -- | Human-readable ASCII Integer. data IntAsc = IntAsc deriving (Eq, Show) instance Format IntAsc where type Value IntAsc = Int fieldCount _ = 1 minSize _ = 1 fixedSize _ = Nothing -- Max length of a pretty printed 64-bit Int is 20 bytes including sign. packedSize _ _ = Just 20 {-# INLINE minSize #-} {-# INLINE fieldCount #-} {-# INLINE fixedSize #-} {-# INLINE packedSize #-} instance Packable IntAsc where -- ISSUE #43: Avoid intermediate lists when packing Ints and Strings. pack IntAsc v = pack VarAsc (show v) {-# INLINE pack #-} unpack IntAsc = Unpacker $ \start end _stop fail eat -> let !len = F.minusPtr end start in if len > 0 then do r <- S.loadInt start len case r of Just (n, o) -> eat (F.plusPtr start o) n Nothing -> fail else fail {-# INLINE unpack #-} ------------------------------------------------------------------------------------------- IntAsc -- | Human-readable ASCII integer, with leading zeros. data IntAsc0 = IntAsc0 Int deriving (Eq, Show) instance Format IntAsc0 where type Value IntAsc0 = Int fieldCount _ = 1 minSize _ = 1 fixedSize _ = Nothing -- Max length of a pretty printed 64-bit Int is 20 bytes including sign. packedSize (IntAsc0 n) _ = Just (n + 20) {-# INLINE minSize #-} {-# INLINE fieldCount #-} {-# INLINE fixedSize #-} {-# INLINE packedSize #-} instance Packable IntAsc0 where -- ISSUE #43: Avoid intermediate lists when packing Ints and Strings. pack (IntAsc0 n) v = let s = show v s' = replicate (n - length s) '0' ++ s in pack VarAsc s' {-# INLINE pack #-} unpack (IntAsc0 _) = Unpacker $ \start end _stop fail eat -> let !len = F.minusPtr end start in if len > 0 then do r <- S.loadInt start len case r of Just (n, o) -> eat (F.plusPtr start o) n Nothing -> fail else fail {-# INLINE unpack #-} ----------------------------------------------------------------------------------------- DoubleAsc -- | Human-readable ASCII Double. data DoubleAsc = DoubleAsc deriving (Eq, Show) instance Format DoubleAsc where type Value DoubleAsc = Double fieldCount _ = 1 minSize _ = 1 fixedSize _ = Nothing -- Max length of a pretty-printed 64-bit double is 64 bytes. packedSize _ _ = Just 24 {-# INLINE minSize #-} {-# INLINE fieldCount #-} {-# INLINE fixedSize #-} {-# INLINE packedSize #-} instance Packable DoubleAsc where pack DoubleAsc v = Packer $ \buf k -> do (fptr, len) <- S.storeDoubleShortest v F.withForeignPtr fptr $ \ptr -> F.copyBytes buf ptr len k (F.plusPtr buf len) {-# INLINE pack #-} unpack DoubleAsc = Unpacker $ \start end _stop fail eat -> let !len = F.minusPtr end start in if len > 0 then do (v, o) <- S.loadDouble start len eat (F.plusPtr start o) v else fail {-# INLINE unpack #-}