@@ -17,7 +17,7 @@ module Data.Aeson.Encode.Number
17import Data.Monoid (mappend, mempty)
17import Data.Monoid (mappend, mempty)
18import Data.Attoparsec.Number (Number(..))
18import Data.Attoparsec.Number (Number(..))
19import Blaze.ByteString.Builder
19import Blaze.ByteString.Builder
20−import GHC.Num (quotRemInt, quotRemInteger)
20+import GHC.Num (quotRemInteger)
21import GHC.Types (Int(..))
21import GHC.Types (Int(..))
22import qualified Text.Show.ByteString as S
22import qualified Text.Show.ByteString as S
@@ -29,6 +29,12 @@ import GHC.Integer.GMP.Internals
33+# define PAIR(a,b) (# a,b #)
35+# define PAIR(a,b) (a,b)
32fromNumber :: Number -> Builder
38fromNumber :: Number -> Builder
33fromNumber (I i) = integer i
39fromNumber (I i) = integer i
34fromNumber (D d) = fromLazyByteString (S.show d)
40fromNumber (D d) = fromLazyByteString (S.show d)
@@ -36,48 +42,35 @@ fromNumber (D d) = fromLazyByteString (S.show d)
36integer :: Integer -> Builder
42integer :: Integer -> Builder
37integer (S# i#) = int (I# i#)
43integer (S# i#) = int (I# i#)
39− | i < 0 = fromWord8 45 `mappend` go (-i)
45+ | i < 0 = minus `mappend` go (-i)
40 | otherwise = go i
46 | otherwise = go i
42 go n | n < maxInt = int (fromInteger n)
48 go n | n < maxInt = int (fromInteger n)
43 | otherwise = putH (splitf (maxInt * maxInt) n)
49 | otherwise = putH (splitf (maxInt * maxInt) n)
45− splitf :: Integer -> Integer -> [Integer]
46 splitf p n
51 splitf p n
47− | p > n = [n]
52+ | p > n = [n]
48− | otherwise = splith p (splitf (p*p) n)
53+ | otherwise = splith p (splitf (p*p) n)
50− splith :: Integer -> [Integer] -> [Integer]
51− splith _ [ ] = error "splith: the impossible happened."
52 splith p (n:ns) = case n `quotRemInteger` p of
55 splith p (n:ns) = case n `quotRemInteger` p of
59− then q : r : splitb p ns
56+ PAIR(q,r) | q > 0 -> q : r : splitb p ns
60− else r : splitb p ns
57+ | otherwise -> r : splitb p ns
61− splitb :: Integer -> [Integer] -> [Integer]
58+ splith _ _ = error "splith: the impossible happened."
63 splitb p (n:ns) = case n `quotRemInteger` p of
60 splitb p (n:ns) = case n `quotRemInteger` p of
69− q : r : splitb p ns
61+ PAIR(q,r) -> q : r : splitb p ns
71int :: Int -> Builder
64int :: Int -> Builder
73− | i < 0 = fromWord8 45 `mappend` go (-i)
66+ | i < 0 = minus `mappend` go (-i)
74 | otherwise = go i
67 | otherwise = go i
76 go n | n < 10 = digit n
69 go n | n < 10 = digit n
77 | otherwise = go (n `rem` 10) `mappend` digit (n `quot` 10)
70 | otherwise = go (n `rem` 10) `mappend` digit (n `quot` 10)
79digit :: Int -> Builder
72digit :: Int -> Builder
80−digit n = fromWord8 (fromIntegral n + 48)
73+digit n = fromWord8 $! fromIntegral n + 48
82data T = T !Integer !Int
75data T = T !Integer !Int
@@ -92,28 +85,18 @@ T maxInt maxDigits =
93putH :: [Integer] -> Builder
86putH :: [Integer] -> Builder
94putH (n:ns) = case n `quotRemInteger` maxInt of
87putH (n:ns) = case n `quotRemInteger` maxInt of
95−#ifdef INTEGER_GMP
88+ PAIR(x,y)
100− let q = fromInteger q'
103− then int q `mappend` pblock r `mappend` putB ns
89+ | q > 0 -> int q `mappend` pblock r `mappend` putB ns
104− else int r `mappend` putB ns
90+ | otherwise -> int r `mappend` putB ns
91+ where q = fromInteger x
105putH _ = error "putH: the impossible happened"
93putH _ = error "putH: the impossible happened"
107putB :: [Integer] -> Builder
95putB :: [Integer] -> Builder
108putB (n:ns) = case n `quotRemInteger` maxInt of
96putB (n:ns) = case n `quotRemInteger` maxInt of
114− let q = fromInteger q'
116− in pblock q `mappend` pblock r `mappend` putB ns
97+ PAIR(x,y) -> pblock q `mappend` pblock r `mappend` putB ns
98+ where q = fromInteger x
117putB _ = mempty
100putB _ = mempty
119pblock :: Int -> Builder
102pblock :: Int -> Builder
@@ -122,4 +105,8 @@ pblock = go maxDigits
123 | d == 1 = digit n
106 | d == 1 = digit n
124 | otherwise = go (d-1) q `mappend` digit r
107 | otherwise = go (d-1) q `mappend` digit r
125− where (q, r) = n `quotRemInt` 10
108+ where q = n `quot` 10