on master help sign in
Merge pull request #595 from jprider63/master
f3495ecAdam Bergmark
pure/Data/Aeson/Parser/UnescapePure.hs+8−13
@@ -119,8 +119,6 @@ decode UtfTail1 point word = case word of
119 w | 0x80 <= w && w <= 0xbf -> (UtfGround, setByte1 point word)
119 w | 0x80 <= w && w <= 0xbf -> (UtfGround, setByte1 point word)
120 _ -> throwDecodeError
120 _ -> throwDecodeError
121
121
122−{-# INLINE decode #-}
123−
124decodeHex :: Word8 -> Word16
122decodeHex :: Word8 -> Word16
125decodeHex 48 = 0 -- '0'
123decodeHex 48 = 0 -- '0'
126decodeHex 49 = 1 -- '1'
124decodeHex 49 = 1 -- '1'
@@ -145,12 +143,12 @@ decodeHex 101 = 14 -- 'e'
145decodeHex 70 = 15 -- 'F'
143decodeHex 70 = 15 -- 'F'
146decodeHex 102 = 15 -- 'f'
144decodeHex 102 = 15 -- 'f'
147decodeHex _ = throwDecodeError
145decodeHex _ = throwDecodeError
148−{-# INLINE decodeHex #-}
149
146
150unescapeText' :: ByteString -> Text
147unescapeText' :: ByteString -> Text
151unescapeText' bs = runText $ \done -> do
148unescapeText' bs = runText $ \done -> do
152 dest <- A.new len
149 dest <- A.new len
150+
153− (pos, finalState) <- B.foldl' (f' dest) (return (0, StateNone)) bs
151+ (pos, finalState) <- loop dest (0, StateNone) 0
154
152
155 -- Check final state. Currently pos gets only increased over time, so this check should catch overflows.
153 -- Check final state. Currently pos gets only increased over time, so this check should catch overflows.
156 when ( finalState /= StateNone || pos > len)
154 when ( finalState /= StateNone || pos > len)
@@ -172,11 +170,12 @@ unescapeText' bs = runText $ \done -> do
172 (st', p) ->
170 (st', p) ->
173 return (pos, StateUtf st' p)
171 return (pos, StateUtf st' p)
174
172
175− {-# INLINE runUtf #-}
173+ loop :: A.MArray s -> (Int, State) -> Int -> ST s (Int, State)
176−
174+ loop _ ps i | i >= len = return ps
175+ loop dest ps i = do
176+ let c = B.index bs i -- JP: We can use unsafe index once we prove bounds with Liquid Haskell.
177− f' dest m c = m >>= \s -> f dest s c
177+ ps' <- f dest ps c
178−
178+ loop dest ps' $ i+1
179− {-# INLINE f' #-}
180
179
181 -- No pending state.
180 -- No pending state.
182 f dest (pos, StateNone) c = runUtf dest pos UtfGround 0 c
181 f dest (pos, StateNone) c = runUtf dest pos UtfGround 0 c
@@ -253,8 +252,6 @@ unescapeText' bs = runText $ \done -> do
253 else
252 else
254 writeAndReturn dest pos u StateNone
253 writeAndReturn dest pos u StateNone
255
254
256− {-# INLINE f #-}
257−
258write :: A.MArray s -> Int -> Word16 -> ST s ()
255write :: A.MArray s -> Int -> Word16 -> ST s ()
259write dest pos char =
256write dest pos char =
260 A.unsafeWrite dest pos char
257 A.unsafeWrite dest pos char
@@ -270,8 +267,6 @@ throwDecodeError :: a
270throwDecodeError =
267throwDecodeError =
271 let desc = "Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream" in
268 let desc = "Data.Text.Internal.Encoding.decodeUtf8: Invalid UTF-8 stream" in
272 throw (DecodeError desc Nothing)
269 throw (DecodeError desc Nothing)
273−{-# INLINE throwDecodeError #-}
274
270
275unescapeText :: ByteString -> Either UnicodeException Text
271unescapeText :: ByteString -> Either UnicodeException Text
276unescapeText = unsafeDupablePerformIO . try . evaluate . unescapeText'
272unescapeText = unsafeDupablePerformIO . try . evaluate . unescapeText'
277−{-# INLINE unescapeText #-}