flatparse-0.2.2.0: src/FlatParse/Internal.hs
module FlatParse.Internal (readInt, readInteger) where
import qualified Data.ByteString.Char8 as B
import qualified Data.ByteString.Internal as B
import GHC.Exts
import GHC.ForeignPtr
import GHC.Integer.GMP.Internals (Integer(..))
mul10 :: Int# -> Int#
mul10 n = uncheckedIShiftL# n 3# +# uncheckedIShiftL# n 1#
{-# inline mul10 #-}
readInt' :: Int# -> Addr# -> Addr# -> (# Int#, Addr# #)
readInt' acc s end = case eqAddr# s end of
1# -> (# acc, s #)
_ -> case indexWord8OffAddr# s 0# of
w | 1# <- leWord# 48## w, 1# <- leWord# w 57## ->
readInt' (mul10 acc +# (word2Int# w -# 48#)) (plusAddr# s 1#) end
_ -> (# acc, s #)
-- | Read an `Int` from the input, as a non-empty digit sequence. The `Int` may
-- overflow in the result.
readInt :: Addr# -> Addr# -> (# (##) | (# Int#, Addr# #) #)
readInt eob s = case readInt' 0# s eob of
(# n, s' #) | 1# <- eqAddr# s s' -> (# (##) | #)
| otherwise -> (# | (# n, s' #) #)
{-# inline readInt #-}
-- | Read an `Integer` from the input, as a non-empty digit sequence.
readInteger :: ForeignPtrContents -> Addr# -> Addr# -> (# (##) | (# Integer, Addr# #) #)
readInteger fp eob s = case readInt' 0# s eob of
(# n, s' #)
| 1# <- eqAddr# s s' -> (# (##) | #)
| 1# <- minusAddr# s' s <=# 18# -> (# | (# S# n, s' #) #)
| otherwise -> case B.readInteger (B.PS (ForeignPtr s fp) 0 (I# (minusAddr# s' s))) of
Nothing -> (# (##) | #)
Just (i, _) -> (# | (# i, s' #) #)
{-# inline readInteger #-}