@@ -1,4 +1,7 @@
11{-# LANGUAGE BangPatterns, CPP, OverloadedStrings #-}
2+#if MIN_VERSION_ghc_prim(0,3,1)
3+{-# LANGUAGE MagicHash #-}
4+#endif
25
36-- |
47-- Module: Data.Aeson.Parser.Internal
@@ -56,6 +59,11 @@ import qualified Data.ByteString.Internal as B
5659import qualified Data.ByteString.Unsafe as B
5760import qualified Data.HashMap.Strict as H
5861
62+#if MIN_VERSION_ghc_prim(0,3,1)
63+import GHC.Base (Int#, (==#), isTrue#, orI#, word2Int#)
64+import GHC.Word (Word8(W8#))
65+#endif
66+
5967#define BACKSLASH 92
6068#define CLOSE_CURLY 125
6169#define CLOSE_SQUARE 93
@@ -200,28 +208,41 @@ value' = do
200208jstring :: Parser Text
201209jstring = A.word8 DOUBLE_QUOTE *> jstring_
202210
203−data S = S !Bool !Bool
204−
205211-- | Parse a string without a leading quote.
206212jstring_ :: Parser Text
213+{-# INLINE jstring_ #-}
207214jstring_ = {-# SCC "jstring_" #-} do
208− (s, S _ escaped) <- A.runScanner (S False False) go
215+ (s, fin) <- A.runScanner (S 0# 0#) go
209216 _ <- A.anyWord8
210− s1 <- if escaped
211− then case unescape s of
212− Right r -> return r
213− Left err -> fail err
214− else return s
217+ s1 <- if isEscaped fin
218+ then case unescape s of
219+ Right r -> return r
220+ Left err -> fail err
221+ else return s
215222 case decodeUtf8' s1 of
216223 Right r -> return r
217224 Left err -> fail $ show err
225+#if MIN_VERSION_ghc_prim(0,3,1)
226+ where
227+ isEscaped (S _ escaped) = isTrue# escaped
228+ go (S a b) (W8# c)
229+ | isTrue# a = Just (S 0# b)
230+ | isTrue# (word2Int# c ==# 34#) = Nothing
231+ | otherwise = let a' = word2Int# c ==# 92#
232+ in Just (S a' (orI# a' b))
233+
234+data S = S Int# Int#
235+#else
218236 where go (S a b) c
219237 | a = Just (S False b)
220238 | c == DOUBLE_QUOTE = Nothing
221239 | otherwise = let a' = c == backSlash
222240 in Just (S a' (a' || b))
223241 where backSlash = BACKSLASH
224−{-# INLINE jstring_ #-}
242+ isEscaped (S _ escaped) = escaped
243+
244+data S = S !Bool !Bool
245+#endif
225246
226247unescape :: ByteString -> Either String ByteString
227248unescape s = unsafePerformIO $ do