@@ -62,6 +62,20 @@ import qualified Data.ByteString.Lazy as L
6262import qualified Data.ByteString.Unsafe as B
6363import qualified Data.HashMap.Strict as H
6464
65+#define BACKSLASH 92
66+#define CLOSE_CURLY 125
67+#define CLOSE_SQUARE 93
68+#define COMMA 44
69+#define DOUBLE_QUOTE 34
70+#define OPEN_CURLY 123
71+#define OPEN_SQUARE 91
72+#define C_0 48
73+#define C_9 57
74+#define C_A 65
75+#define C_F 70
76+#define C_a 97
77+#define C_f 102
78+
6579-- | Parse a top-level JSON value. This must be either an object or
6680-- an array, per RFC 4627.
6781--
@@ -83,8 +97,8 @@ json' = json_ object_' array_'
8397
8498json_ :: Parser Value -> Parser Value -> Parser Value
8599json_ obj ary = do
86− w <- skipSpace *> A.satisfy (\w -> w == 123 || w == 91)
87− if w == 123
100+ w <- skipSpace *> A.satisfy (\w -> w == OPEN_CURLY || w == OPEN_SQUARE)
101+ if w == OPEN_CURLY
88102 then obj
89103 else ary
90104{-# INLINE json_ #-}
@@ -105,7 +119,7 @@ objectValues :: Parser Text -> Parser Value -> Parser (H.HashMap Text Value)
105119objectValues str val = do
106120 skipSpace
107121 let pair = liftA2 (,) (str <* skipSpace) (char ':' *> skipSpace *> val)
108− H.fromList <$> commaSeparated pair closeCurly
122+ H.fromList <$> commaSeparated pair CLOSE_CURLY
109123{-# INLINE objectValues #-}
110124
111125array_ :: Parser Value
@@ -125,8 +139,8 @@ commaSeparated item endByte = do
125139 where
126140 loop = do
127141 v <- item <* skipSpace
128− ch <- A.satisfy $ \w -> w == comma || w == endByte
129− if ch == comma
142+ ch <- A.satisfy $ \w -> w == COMMA || w == endByte
143+ if ch == COMMA
130144 then skipSpace >> (v:) <$> loop
131145 else return [v]
132146{-# INLINE commaSeparated #-}
@@ -134,7 +148,7 @@ commaSeparated item endByte = do
134148arrayValues :: Parser Value -> Parser (Vector Value)
135149arrayValues val = do
136150 skipSpace
137− Vector.fromList <$> commaSeparated val closeSquare
151+ Vector.fromList <$> commaSeparated val CLOSE_SQUARE
138152{-# INLINE arrayValues #-}
139153
140154-- | Parse any JSON value. You should usually 'json' in preference to
@@ -181,37 +195,25 @@ value' = most <|> num
181195 !n <- rational
182196 return (Number n)
183197
184−backslash, closeCurly, closeSquare, comma, doubleQuote :: Word8
185−backslash = 92
186−closeCurly = 125
187−closeSquare = 93
188−comma = 44
189−doubleQuote = 34
190−{-# INLINE backslash #-}
191−{-# INLINE closeCurly #-}
192−{-# INLINE closeSquare #-}
193−{-# INLINE comma #-}
194−{-# INLINE doubleQuote #-}
195−
196198-- | Parse a quoted JSON string.
197199jstring :: Parser Text
198−jstring = A.word8 doubleQuote *> jstring_
200+jstring = A.word8 DOUBLE_QUOTE *> jstring_
199201
200202-- | Parse a string without a leading quote.
201203jstring_ :: Parser Text
202204jstring_ = {-# SCC "jstring_" #-} do
203205 s <- A.scan False $ \s c -> if s then Just False
204− else if c == doubleQuote
206+ else if c == DOUBLE_QUOTE
205207 then Nothing
206− else Just (c == backslash)
207− _ <- A.word8 doubleQuote
208− s' <- if backslash `B.elem` s
208+ else Just (c == BACKSLASH)
209+ _ <- A.word8 DOUBLE_QUOTE
210+ s1 <- if BACKSLASH `B.elem` s
209211 then case Z.parse unescape s of
210212 Right r -> return r
211213 Left err -> fail err
212214 else return s
213215
214− case decodeUtf8' s' of
216+ case decodeUtf8' s1 of
215217 Right r -> return r
216218 Left err -> fail $ show err
217219
@@ -220,7 +222,7 @@ jstring_ = {-# SCC "jstring_" #-} do
220222unescape :: Z.Parser ByteString
221223unescape = toByteString <$> go mempty where
222224 go acc = do
223− h <- Z.takeWhile (/=backslash)
225+ h <- Z.takeWhile (/=BACKSLASH)
224226 let rest = do
225227 start <- Z.take 2
226228 let !slash = B.unsafeHead start
@@ -228,7 +230,7 @@ unescape = toByteString <$> go mempty where
228230 escape = case B.findIndex (==t) "\"\\/ntbrfu" of
229231 Just i -> i
230232 _ -> 255
231− if slash /= backslash || escape == 255
233+ if slash /= BACKSLASH || escape == 255
232234 then fail "invalid JSON escape sequence"
233235 else do
234236 let cont m = go (acc `mappend` byteString h `mappend` m)
@@ -255,10 +257,10 @@ unescape = toByteString <$> go mempty where
255257hexQuad :: Z.Parser Int
256258hexQuad = do
257259 s <- Z.take 4
258− let hex n | w >= 48 && w <= 57 = w - 48
259− | w >= 97 && w <= 122 = w - 87
260− | w >= 65 && w <= 90 = w - 55
261− | otherwise = 255
260+ let hex n | w >= C_0 && w <= C_9 = w - C_0
261+ | w >= C_a && w <= C_f = w - 87
262+ | w >= C_A && w <= C_F = w - 55
263+ | otherwise = 255
262264 where w = fromIntegral $ B.unsafeIndex s n
263265 a = hex 0; b = hex 1; c = hex 2; d = hex 3
264266 if (a .|. b .|. c .|. d) /= 255