Skip to content

Commit f077e98

Browse files
committed
Use integer-conversion
1 parent a9a4a84 commit f077e98

File tree

7 files changed

+58
-152
lines changed

7 files changed

+58
-152
lines changed

aeson.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ library
7979
Data.Aeson.Encoding.Builder
8080
Data.Aeson.Internal.ByteString
8181
Data.Aeson.Internal.Functions
82-
Data.Aeson.Internal.Integer
8382
Data.Aeson.Internal.Prelude
8483
Data.Aeson.Internal.Text
8584
Data.Aeson.Internal.TH
@@ -121,6 +120,7 @@ library
121120
, dlist >=1.0 && <1.1
122121
, hashable >=1.3.5.0 && <1.5
123122
, indexed-traversable >=0.1.2 && <0.2
123+
, integer-conversion >=0.1 && <0.2
124124
, OneTuple >=0.4.1.1 && <0.5
125125
, primitive >=0.8.0.0 && <0.9
126126
, QuickCheck >=2.14.3 && <2.15

attoparsec-iso8601/attoparsec-iso8601.cabal

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,51 @@
1-
name: attoparsec-iso8601
2-
version: 1.1.0.1
3-
synopsis: Parsing of ISO 8601 dates, originally from aeson
4-
description: Parsing of ISO 8601 dates, originally from aeson.
5-
license: BSD3
6-
license-file: LICENSE
7-
category: Parsing
8-
copyright: (c) 2011-2016 Bryan O'Sullivan
9-
(c) 2011 MailRank, Inc.
10-
author: Bryan O'Sullivan <[email protected]>
11-
maintainer: Adam Bergmark <[email protected]>
12-
stability: experimental
13-
cabal-version: >=1.10
14-
homepage: https://github.com/haskell/aeson
15-
bug-reports: https://github.com/haskell/aeson/issues
16-
build-type: Simple
17-
tested-with: GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.4, GHC == 8.10.7, GHC == 9.0.2, GHC ==9.2.8, GHC==9.4.5, GHC ==9.6.2
1+
name: attoparsec-iso8601
2+
version: 1.1.0.1
3+
synopsis: Parsing of ISO 8601 dates, originally from aeson
4+
description: Parsing of ISO 8601 dates, originally from aeson.
5+
license: BSD3
6+
license-file: LICENSE
7+
category: Parsing
8+
copyright:
9+
(c) 2011-2016 Bryan O'Sullivan
10+
(c) 2011 MailRank, Inc.
11+
12+
author: Bryan O'Sullivan <[email protected]>
13+
maintainer: Adam Bergmark <[email protected]>
14+
stability: experimental
15+
cabal-version: >=1.10
16+
homepage: https://github.com/haskell/aeson
17+
bug-reports: https://github.com/haskell/aeson/issues
18+
build-type: Simple
19+
tested-with:
20+
GHC ==8.2.2
21+
|| ==8.4.4
22+
|| ==8.6.5
23+
|| ==8.8.4
24+
|| ==8.10.7
25+
|| ==9.0.2
26+
|| ==9.2.8
27+
|| ==9.4.5
28+
|| ==9.6.2
29+
1830
extra-source-files:
19-
README.md
2031
changelog.md
32+
README.md
2133

2234
library
23-
hs-source-dirs: src
24-
default-language: Haskell2010
25-
ghc-options: -Wall
35+
hs-source-dirs: src
36+
default-language: Haskell2010
37+
ghc-options: -Wall
2638
exposed-modules:
27-
Data.Attoparsec.Time.Internal
2839
Data.Attoparsec.Time
40+
Data.Attoparsec.Time.Internal
41+
2942
build-depends:
30-
attoparsec >= 0.14.2 && < 0.15,
31-
base >= 4.10.0.0 && < 5,
32-
time-compat >= 1.9.4 && < 1.10,
33-
text >= 1.2.3.0 && < 1.3.0.0 || >= 2.0 && <2.1,
34-
time >= 1.6.0.1 && < 1.13
43+
attoparsec >=0.14.2 && <0.15
44+
, base >=4.10.0.0 && <5
45+
, integer-conversion >=0.1 && <0.2
46+
, text >=1.2.3.0 && <1.3.0.0 || >=2.0 && <2.1
47+
, time >=1.6.0.1 && <1.13
48+
, time-compat >=1.9.4 && <1.10
3549

3650
source-repository head
3751
type: git

attoparsec-iso8601/src/Data/Attoparsec/Time.hs

Lines changed: 4 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ module Data.Attoparsec.Time
2626
import Control.Applicative ((<|>))
2727
import Control.Monad (void, when)
2828
import Data.Attoparsec.Text (Parser, char, digit, option, anyChar, peekChar, peekChar', takeWhile1, satisfy)
29-
import Data.Attoparsec.Time.Internal (toPico)
3029
import Data.Bits ((.&.))
3130
import Data.Char (isDigit, ord)
32-
import Data.Fixed (Pico)
31+
import Data.Fixed (Pico, Fixed (..))
3332
import Data.Int (Int64)
33+
import Data.Integer.Conversion (textToInteger)
3434
import Data.Maybe (fromMaybe)
3535
import Data.Time.Calendar (Day, fromGregorianValid)
3636
import Data.Time.Calendar.Compat (Year)
@@ -92,7 +92,7 @@ year = do
9292
if T.length ds < 4 then
9393
fail "expected year with at least 4 digits"
9494
else
95-
pure (txtToInteger ds)
95+
pure (textToInteger ds)
9696

9797
-- | Parse a two-digit integer (e.g. day of month, hour).
9898
twoDigits :: Parser Int
@@ -126,7 +126,7 @@ seconds = do
126126
return $! parsePicos real t
127127
_ -> return $! fromIntegral real
128128
where
129-
parsePicos a0 t = toPico (fromIntegral (t' * 10^n))
129+
parsePicos a0 t = MkFixed (fromIntegral (t' * 10^n))
130130
where T n t' = T.foldl' step (T 12 (fromIntegral a0)) t
131131
step ma@(T m a) c
132132
| m <= 0 = ma
@@ -194,53 +194,3 @@ zonedTime = Local.ZonedTime <$> localTime <*> (fromMaybe utc <$> timeZone)
194194

195195
utc :: Local.TimeZone
196196
utc = Local.TimeZone 0 False ""
197-
198-
------------------ Copy-pasted and adapted from base ------------------------
199-
200-
txtToInteger :: T.Text -> Integer
201-
txtToInteger bs
202-
| l > 40 = valInteger 10 l [ fromIntegral (ord w - 48) | w <- T.unpack bs ]
203-
| otherwise = txtToIntegerSimple bs
204-
where
205-
l = T.length bs
206-
207-
txtToIntegerSimple :: T.Text -> Integer
208-
txtToIntegerSimple = T.foldl' step 0 where
209-
step a b = a * 10 + fromIntegral (ord b - 48) -- 48 = '0'
210-
211-
-- A sub-quadratic algorithm for Integer. Pairs of adjacent radix b
212-
-- digits are combined into a single radix b^2 digit. This process is
213-
-- repeated until we are left with a single digit. This algorithm
214-
-- performs well only on large inputs, so we use the simple algorithm
215-
-- for smaller inputs.
216-
valInteger :: Integer -> Int -> [Integer] -> Integer
217-
valInteger = go
218-
where
219-
go :: Integer -> Int -> [Integer] -> Integer
220-
go _ _ [] = 0
221-
go _ _ [d] = d
222-
go b l ds
223-
| l > 40 = b' `seq` go b' l' (combine b ds')
224-
| otherwise = valSimple b ds
225-
where
226-
-- ensure that we have an even number of digits
227-
-- before we call combine:
228-
ds' = if even l then ds else 0 : ds
229-
b' = b * b
230-
l' = (l + 1) `quot` 2
231-
232-
combine b (d1 : d2 : ds) = d `seq` (d : combine b ds)
233-
where
234-
d = d1 * b + d2
235-
combine _ [] = []
236-
combine _ [_] = errorWithoutStackTrace "this should not happen"
237-
238-
-- The following algorithm is only linear for types whose Num operations
239-
-- are in constant time.
240-
valSimple :: Integer -> [Integer] -> Integer
241-
valSimple base = go 0
242-
where
243-
go r [] = r
244-
go r (d : ds) = r' `seq` go r' ds
245-
where
246-
r' = r * base + fromIntegral d

src/Data/Aeson/Decoding/ByteString.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module Data.Aeson.Decoding.ByteString (
1010

1111
import Data.ByteString (ByteString)
1212
import Data.Char (chr)
13+
import Data.Integer.Conversion (byteStringToInteger)
1314
import Data.Text (Text)
1415
import Data.Word (Word8)
1516

@@ -20,7 +21,6 @@ import qualified Data.Scientific as Sci
2021

2122
import Data.Aeson.Decoding.Internal
2223
import Data.Aeson.Decoding.Tokens
23-
import Data.Aeson.Internal.Integer
2424
import Data.Aeson.Internal.Text (unsafeDecodeASCII)
2525
import Data.Aeson.Internal.Word8
2626
import Data.Aeson.Parser.Unescape (unescapeText)
@@ -209,7 +209,7 @@ scanNumberLiteral kont err bs0 = state_start bs0 where
209209
| W8_e == w8 || W8_E == w8 -> go_sci int 0 bs'
210210
| otherwise -> kont (NumInteger int) bs
211211
where
212-
int = bsToInteger (BS.Unsafe.unsafeTake n bs0)
212+
int = byteStringToInteger (BS.Unsafe.unsafeTake n bs0)
213213

214214
go_dec :: Integer -> ByteString -> r
215215
go_dec !int !bs1 = case BS.uncons bs1 of
@@ -226,7 +226,7 @@ scanNumberLiteral kont err bs0 = state_start bs0 where
226226
| W8_e == w8 || W8_E == w8 -> go_sci coef (negate n) bs'
227227
| otherwise -> kont (NumDecimal dec) bs
228228
where
229-
frac = bsToInteger (BS.Unsafe.unsafeTake n bs1)
229+
frac = byteStringToInteger (BS.Unsafe.unsafeTake n bs1)
230230
coef = int * 10 ^ n + frac
231231
dec = Sci.scientific coef (negate n)
232232

@@ -254,7 +254,7 @@ scanNumberLiteral kont err bs0 = state_start bs0 where
254254
| W8_0 <= w8, w8 <= W8_9 -> go_sci_pos coef exp10 bs2 (n + 1) bs'
255255
| otherwise -> kont (NumScientific sci) bs
256256
where
257-
exp10' = fromInteger (bsToInteger (BS.Unsafe.unsafeTake n bs2))
257+
exp10' = fromInteger (byteStringToInteger (BS.Unsafe.unsafeTake n bs2))
258258
sci = Sci.scientific coef (exp10 + exp10')
259259

260260
go_sci_neg :: Integer -> Int -> ByteString -> Int -> ByteString -> r
@@ -264,7 +264,7 @@ scanNumberLiteral kont err bs0 = state_start bs0 where
264264
| W8_0 <= w8, w8 <= W8_9 -> go_sci_neg coef exp10 bs2 (n + 1) bs'
265265
| otherwise -> kont (NumScientific sci) bs
266266
where
267-
exp10' = fromInteger (bsToInteger (BS.Unsafe.unsafeTake n bs2))
267+
exp10' = fromInteger (byteStringToInteger (BS.Unsafe.unsafeTake n bs2))
268268
sci = Sci.scientific coef (exp10 - exp10')
269269

270270
errEnd = err "Unexpected end-of-input while parsing number literal"

src/Data/Aeson/Decoding/ByteString/Lazy.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module Data.Aeson.Decoding.ByteString.Lazy (
1010

1111
import Data.ByteString.Lazy (ByteString)
1212
import Data.Char (chr)
13+
import Data.Integer.Conversion (byteStringToInteger)
1314
import Data.Text (Text)
1415
import Data.Word (Word8)
1516

@@ -20,7 +21,6 @@ import qualified Data.Scientific as Sci
2021

2122
import Data.Aeson.Decoding.Internal
2223
import Data.Aeson.Decoding.Tokens
23-
import Data.Aeson.Internal.Integer
2424
import Data.Aeson.Internal.Text (unsafeDecodeASCII)
2525
import Data.Aeson.Internal.Word8
2626
import Data.Aeson.Parser.Unescape (unescapeText)
@@ -215,7 +215,7 @@ scanNumberLiteral kont err bs0 = state_start bs0 where
215215
| W8_e == w8 || W8_E == w8 -> go_sci int 0 bs'
216216
| otherwise -> kont (NumInteger int) bs
217217
where
218-
int = bsToInteger (lbsTake n bs0)
218+
int = byteStringToInteger (lbsTake n bs0)
219219

220220
go_dec :: Integer -> ByteString -> r
221221
go_dec !int !bs1 = case LBS.uncons bs1 of
@@ -232,7 +232,7 @@ scanNumberLiteral kont err bs0 = state_start bs0 where
232232
| W8_e == w8 || W8_E == w8 -> go_sci coef (negate n) bs'
233233
| otherwise -> kont (NumDecimal dec) bs
234234
where
235-
frac = bsToInteger (lbsTake n bs1)
235+
frac = byteStringToInteger (lbsTake n bs1)
236236
coef = int * 10 ^ n + frac
237237
dec = Sci.scientific coef (negate n)
238238

@@ -260,7 +260,7 @@ scanNumberLiteral kont err bs0 = state_start bs0 where
260260
| W8_0 <= w8, w8 <= W8_9 -> go_sci_pos coef exp10 bs2 (n + 1) bs'
261261
| otherwise -> kont (NumScientific sci) bs
262262
where
263-
exp10' = fromInteger (bsToInteger (lbsTake n bs2))
263+
exp10' = fromInteger (byteStringToInteger (lbsTake n bs2))
264264
sci = Sci.scientific coef (exp10 + exp10')
265265

266266
go_sci_neg :: Integer -> Int -> ByteString -> Int -> ByteString -> r
@@ -270,7 +270,7 @@ scanNumberLiteral kont err bs0 = state_start bs0 where
270270
| W8_0 <= w8, w8 <= W8_9 -> go_sci_neg coef exp10 bs2 (n + 1) bs'
271271
| otherwise -> kont (NumScientific sci) bs
272272
where
273-
exp10' = fromInteger (bsToInteger (lbsTake n bs2))
273+
exp10' = fromInteger (byteStringToInteger (lbsTake n bs2))
274274
sci = Sci.scientific coef (exp10 - exp10')
275275

276276
errEnd = err "Unexpected end-of-input while parsing number literal"

src/Data/Aeson/Internal/Integer.hs

Lines changed: 0 additions & 58 deletions
This file was deleted.

src/Data/Aeson/Parser/Internal.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import Data.Aeson.Types.Internal (IResult(..), JSONPath, Object, Result(..), Val
5050
import qualified Data.Aeson.KeyMap as KM
5151
import qualified Data.Aeson.Key as Key
5252
import Data.Attoparsec.ByteString.Char8 (Parser, char, decimal, endOfInput, isDigit_w8, signed, string)
53+
import Data.Integer.Conversion (byteStringToInteger)
5354
import qualified Data.Vector as Vector (empty, fromList, fromListN, reverse)
5455
import qualified Data.Attoparsec.ByteString as A
5556
import qualified Data.Attoparsec.Lazy as L
@@ -61,7 +62,6 @@ import qualified Data.ByteString.Lazy.Char8 as C
6162
import qualified Data.ByteString.Builder as B
6263
import qualified Data.Scientific as Sci
6364
import Data.Aeson.Parser.Unescape (unescapeText)
64-
import Data.Aeson.Internal.Integer
6565
import Data.Aeson.Internal.Text
6666
import Data.Aeson.Internal.Word8
6767

@@ -440,7 +440,7 @@ decimal0 = do
440440
digits <- A.takeWhile1 isDigit_w8
441441
if B.length digits > 1 && B.unsafeHead digits == W8_0
442442
then fail "leading zero"
443-
else return (bsToInteger digits)
443+
else return (byteStringToInteger digits)
444444

445445
-- | Parse a JSON number.
446446
scientific :: Parser Scientific

0 commit comments

Comments
 (0)