module Data.Repa.Scalar.Int
(
loadInt
, loadInt#
, loadIntWith#
, storeInt)
where
import Data.Word
import Data.Char
import GHC.Exts
import qualified Data.ByteString.Internal as BS
import qualified Data.Double.Conversion.ByteString as DC
import qualified Foreign.ForeignPtr as F
import qualified Foreign.Storable as F
loadInt :: Ptr Word8
-> Int
-> IO (Maybe (Int, Int))
loadInt !ptr (I# len)
= case loadInt# ptr len of
(# 0#, _, _ #) -> return $ Nothing
(# _, n, ix #) -> return $ Just (I# n, I# ix)
loadInt#
:: Ptr Word8
-> Int#
-> (# Int#, Int#, Int# #)
loadInt# buf len
= let peek8 ix
= case BS.accursedUnutterablePerformIO (F.peekByteOff buf (I# ix)) of
(w8 :: Word8) -> case fromIntegral w8 of
I# i -> i
in loadIntWith# peek8 len
loadIntWith#
:: (Int# -> Int#)
-> Int#
-> (# Int#, Int#, Int# #)
loadIntWith# !get len
= start 0#
where
start !ix
| 1# <- ix >=# len = (# 0#, 0#, 0# #)
| otherwise = sign ix
sign !ix
| !s <- get 0#
= case chr $ fromIntegral (I# s) of
'-' -> loop 1# (ix +# 1#) 0#
'+' -> loop 2# (ix +# 1#) 0#
_ -> loop 0# ix 0#
loop !neg !ix !n
| 1# <- ix >=# len
= end neg ix n
| otherwise
= case get ix of
w | 1# <- w >=# 0x30#
, 1# <- w <=# 0x039#
-> loop neg ( ix +# 1#)
((n *# 10#) +# (w -# 0x30#))
| otherwise
-> end neg ix n
end !neg !ix !n
| 1# <- ix ==# 0#
, 1# <- neg ==# 0#
= (# 0#, 0#, 0# #)
| 1# <- ix ==# 1#
, 1# <- neg /=# 0#
= (# 0#, 0#, 0# #)
| 1# <- neg ==# 1#
, I# n' <- negate (I# n)
= (# 1#, n', ix #)
| otherwise
= (# 1#, n, ix #)
storeInt :: Int -> IO (F.ForeignPtr Word8)
storeInt i
= case DC.toFixed 0 (fromIntegral i) of
BS.PS p _ _ -> return p