on bb59622 help sign in
1 file changed+16−41
since splitsnapshots
unifiedsplit
Data/Aeson/Parser/Internal.hs+16−41
Data/Aeson/Parser/Internal.hs+16−41
@@ -2,12 +2,9 @@
22{-# LANGUAGE CPP #-}
33{-# LANGUAGE NoImplicitPrelude #-}
44{-# LANGUAGE OverloadedStrings #-}
5−#if MIN_VERSION_ghc_prim(0,3,1)
6−{-# LANGUAGE MagicHash #-}
7−#endif
85#if __GLASGOW_HASKELL__ <= 710 && __GLASGOW_HASKELL__ >= 706
96-- Work around a compiler bug
10−{-# OPTIONS_GHC -fsimpl-tick-factor=200 #-}
7+{-# OPTIONS_GHC -fsimpl-tick-factor=300 #-}
118#endif
129-- |
1310-- Module: Data.Aeson.Parser.Internal
@@ -58,8 +55,10 @@ import Data.Aeson.Types.Internal (IResult(..), JSONPath, Object, Result(..), Val
5855import Data.Attoparsec.ByteString.Char8 (Parser, char, decimal, endOfInput, isDigit_w8, signed, string)
5956import Data.Function (fix)
6057import Data.Functor.Compat (($>))
58+import Data.Bits (testBit)
6159import Data.Scientific (Scientific)
6260import Data.Text (Text)
61+import qualified Data.Text.Encoding as TE
6362import Data.Vector (Vector)
6463import qualified Data.Vector as Vector (empty, fromList, fromListN, reverse)
6564import qualified Data.Attoparsec.ByteString as A
@@ -71,12 +70,6 @@ import qualified Data.HashMap.Strict as H
7170import qualified Data.Scientific as Sci
7271import Data.Aeson.Parser.Unescape (unescapeText)
7372
74−#if MIN_VERSION_ghc_prim(0,3,1)
75−import GHC.Base (Int#, (==#), isTrue#, word2Int#, orI#, andI#)
76−import GHC.Word (Word8(W8#))
77−import qualified Data.Text.Encoding as TE
78−#endif
79−
8073#define BACKSLASH 92
8174#define CLOSE_CURLY 125
8275#define CLOSE_SQUARE 93
@@ -323,37 +316,20 @@ jstring = A.word8 DOUBLE_QUOTE *> jstring_
323316-- | Parse a string without a leading quote.
324317jstring_ :: Parser Text
325318{-# INLINE jstring_ #-}
326−jstring_ = {-# SCC "jstring_" #-} do
327−#if MIN_VERSION_ghc_prim(0,3,1)
328− (s, S _ escaped) <- A.runScanner startState go <* A.anyWord8
329− -- We escape only if there are
330− -- non-ascii (over 7bit) characters or backslash present.
331− --
332− -- Note: if/when text will have fast ascii -> text conversion
333− -- (e.g. uses utf8 encoding) we can have further speedup.
334− if isTrue# escaped
335− then case unescapeText s of
336− Right r -> return r
337− Left err -> fail $ show err
338− else return (TE.decodeUtf8 s)
339− where
340− startState = S 0# 0#
341− go (S skip escaped) (W8# c)
342− | isTrue# skip = Just (S 0# escaped')
343− | isTrue# (w ==# 34#) = Nothing -- double quote
344− | otherwise = Just (S skip' escaped')
345− where
346− w = word2Int# c
347− skip' = w ==# 92# -- backslash
348− escaped' = escaped
349− `orI#` (w `andI#` 0x80# ==# 0x80#) -- c >= 0x80
350− `orI#` skip'
351− `orI#` (w `andI#` 0x1f# ==# w) -- c < 0x20
352−
353−data S = S Int# Int#
354−#else
319+jstring_ = do
320+ s <- A.takeWhile (\w -> w /= DOUBLE_QUOTE && w /= BACKSLASH && not (testBit w 7))
321+ let txt = TE.decodeUtf8 s
322+ w <- A.peekWord8
323+ case w of
324+ Nothing -> fail "string without end"
325+ Just DOUBLE_QUOTE -> A.anyWord8 $> txt
326+ _ -> jstringSlow s
327+
328+jstringSlow :: B.ByteString -> Parser Text
329+{-# INLINE jstringSlow #-}
330+jstringSlow s' = {-# SCC "jstringSlow" #-} do
355331 s <- A.scan startState go <* A.anyWord8
356− case unescapeText s of
332+ case unescapeText (B.append s' s) of
357333 Right r -> return r
358334 Left err -> fail $ show err
359335 where
@@ -364,7 +340,6 @@ data S = S Int# Int#
364340 | otherwise = let a' = c == backslash
365341 in Just a'
366342 where backslash = BACKSLASH
367−#endif
368343
369344decodeWith :: Parser Value -> (Value -> Result a) -> L.ByteString -> Maybe a
370345decodeWith p to s =