Skip to content

Commit

Permalink
Doc and INLINABLE
Browse files Browse the repository at this point in the history
  • Loading branch information
hsyl20 committed Jan 12, 2024
1 parent a2decd7 commit c2b2ff5
Showing 1 changed file with 24 additions and 17 deletions.
41 changes: 24 additions & 17 deletions Data/ByteString/Internal/Pure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -264,22 +264,23 @@ reverseBytesInplace !p1 !p2

-- | Decode signed number as decimal
decodeSignedDec :: (Eq a, Num a, Integral a) => a -> Ptr Word8 -> IO (Ptr Word8)
{-# INLINABLE decodeSignedDec #-} -- for specialization
decodeSignedDec !x !buf
| x >= 0 = decodeUnsignedDec x buf
| otherwise = do
-- we cannot negate directly as 0 - (minBound :: Int) = minBound
-- So we write the sign and the first digit.
pokeByteOff buf 0 '-'
case quotRem x (-10) of
(q,r) -> do
putDigit buf 1 (fromIntegral (abs r))
case q of
0 -> pure (plusPtr buf 2)
_ -> decodeUnsignedDec' q (plusPtr buf 1) (plusPtr buf 2)
let !(q,r) = quotRem x (-10)
putDigit buf 1 (fromIntegral (abs r))
case q of
0 -> pure (plusPtr buf 2)
_ -> decodeUnsignedDec' q (plusPtr buf 1) (plusPtr buf 2)


-- | Decode positive number as decimal
decodeUnsignedDec :: (Eq a, Num a, Integral a) => a -> Ptr Word8 -> IO (Ptr Word8)
{-# INLINABLE decodeUnsignedDec #-} -- for specialization
decodeUnsignedDec !v !next_ptr = decodeUnsignedDec' v next_ptr next_ptr

-- | Decode positive number as little-endian decimal, then reverse it.
Expand All @@ -288,18 +289,20 @@ decodeUnsignedDec !v !next_ptr = decodeUnsignedDec' v next_ptr next_ptr
-- (e.g. used by decodeSignedDec to avoid overflows)
--
decodeUnsignedDec' :: (Eq a, Num a, Integral a) => a -> Ptr Word8 -> Ptr Word8 -> IO (Ptr Word8)
decodeUnsignedDec' !v !orig_ptr !next_ptr = case divMod v 10 of
(q,r) -> do
putDigit next_ptr 0 (fromIntegral r)
case q of
0 -> do
-- reverse written digits
reverseBytesInplace orig_ptr next_ptr
-- return pointer after our digits
pure (plusPtr next_ptr 1)
_ -> decodeUnsignedDec' q orig_ptr (plusPtr next_ptr 1)
{-# INLINABLE decodeUnsignedDec' #-} -- for specialization
decodeUnsignedDec' !v !orig_ptr !next_ptr = do
let !(q,r) = divMod v 10
putDigit next_ptr 0 (fromIntegral r)
case q of
0 -> do
-- reverse written digits
reverseBytesInplace orig_ptr next_ptr
-- return pointer after our digits
pure (plusPtr next_ptr 1)
_ -> decodeUnsignedDec' q orig_ptr (plusPtr next_ptr 1)

decodeUnsignedDecPadded :: (Eq a, Num a, Integral a) => Int -> a -> Ptr Word8 -> IO ()
{-# INLINABLE decodeUnsignedDecPadded #-} -- for specialization
decodeUnsignedDecPadded !max_width !v !buf = do
let !(q,r) = divMod v 10
putDigit buf (max_width - 1) (fromIntegral r)
Expand All @@ -315,15 +318,19 @@ decodeUnsignedDecPadded !max_width !v !buf = do

-- | Decode positive number as hexadecimal
decodeUnsignedHex :: (Eq a, Num a, Integral a, Bits a) => a -> Ptr Word8 -> IO (Ptr Word8)
{-# INLINABLE decodeUnsignedHex #-} -- for specialization
decodeUnsignedHex !v !next_ptr = decodeUnsignedHex' v next_ptr next_ptr

-- | Decode positive number as little-endian hexdecimal, then reverse it.
--
-- Take two pointers (orig_ptr, next_ptr) to support already decoded digits
decodeUnsignedHex' :: (Eq a, Num a, Integral a, Bits a) => a -> Ptr Word8 -> Ptr Word8 -> IO (Ptr Word8)
{-# INLINABLE decodeUnsignedHex' #-} -- for specialization
decodeUnsignedHex' !v !orig_ptr !next_ptr = do
putDigit next_ptr 0 (fromIntegral (v .&. 0x0F))
-- (q,r) = divMod v 16, but faster
let !q = v `shiftR` 4
let !r = v .&. 0x0F
putDigit next_ptr 0 (fromIntegral r)
case q of
0 -> do
-- reverse written digits
Expand Down

0 comments on commit c2b2ff5

Please sign in to comment.