@@ -28,6 +28,9 @@ module Data.Text.Encoding
28 , decodeUtf32LE
28 , decodeUtf32LE
29 , decodeUtf32BE
29 , decodeUtf32BE
31+ -- ** Catchable failure
31 -- ** Controllable error handling
34 -- ** Controllable error handling
32 , decodeUtf8With
35 , decodeUtf8With
33 , decodeUtf16LEWith
36 , decodeUtf16LEWith
@@ -43,11 +46,12 @@ module Data.Text.Encoding
43 , encodeUtf32BE
46 , encodeUtf32BE
49+import Control.Exception (evaluate, try)
46import Data.Bits ((.&.))
50import Data.Bits ((.&.))
47import Data.ByteString as B
51import Data.ByteString as B
48import Data.ByteString.Internal as B
52import Data.ByteString.Internal as B
49import Data.ByteString.Unsafe as B
53import Data.ByteString.Unsafe as B
50−import Data.Text.Encoding.Error (OnDecodeError, strictDecode)
54+import Data.Text.Encoding.Error (OnDecodeError, UnicodeException, strictDecode)
51import Data.Text.Internal (Text(..), textP)
55import Data.Text.Internal (Text(..), textP)
52import Data.Text.UnsafeChar (ord, unsafeWrite)
56import Data.Text.UnsafeChar (ord, unsafeWrite)
53import Data.Text.UnsafeShift (shiftL, shiftR)
57import Data.Text.UnsafeShift (shiftL, shiftR)
@@ -116,18 +120,26 @@ decodeUtf8With onErr bs = textP (fst a) 0 (snd a)
116 desc = "Data.Text.Encoding.decodeUtf8: Invalid UTF-8 stream"
120 desc = "Data.Text.Encoding.decodeUtf8: Invalid UTF-8 stream"
117{-# INLINE[0] decodeUtf8With #-}
121{-# INLINE[0] decodeUtf8With #-}
119−-- | Decode a 'ByteString' containing UTF-8 encoded text.
123+-- | Decode a 'ByteString' containing known-valid UTF-8 encoded text.
121-- If the input contains any invalid UTF-8 data, an exception will be
125-- If the input contains any invalid UTF-8 data, an exception will be
126+-- thrown that cannot be caught in pure code. For more control over
122−-- thrown. For more control over the handling of invalid data, use
127+-- the handling of invalid data, use 'decodeUtf8'' or
123-- 'decodeUtf8With'.
128-- 'decodeUtf8With'.
124decodeUtf8 :: ByteString -> Text
129decodeUtf8 :: ByteString -> Text
125decodeUtf8 = decodeUtf8With strictDecode
130decodeUtf8 = decodeUtf8With strictDecode
126{-# INLINE[0] decodeUtf8 #-}
131{-# INLINE[0] decodeUtf8 #-}
128{-# RULES "STREAM stream/decodeUtf8 fusion" [1]
132{-# RULES "STREAM stream/decodeUtf8 fusion" [1]
129 forall bs. F.stream (decodeUtf8 bs) = E.streamUtf8 strictDecode bs #-}
133 forall bs. F.stream (decodeUtf8 bs) = E.streamUtf8 strictDecode bs #-}
135+-- | Decode a 'ByteString' containing UTF-8 encoded text..
137+-- If the input contains any invalid UTF-8 data, the relevant
138+-- exception will be returned, otherwise the decoded text.
139+decodeUtf8' :: ByteString -> Either UnicodeException Text
140+decodeUtf8' = unsafePerformIO . try . evaluate . decodeUtf8With strictDecode
141+{-# INLINE decodeUtf8' #-}
131-- | Encode text using UTF-8 encoding.
143-- | Encode text using UTF-8 encoding.
132encodeUtf8 :: Text -> ByteString
144encodeUtf8 :: Text -> ByteString
133encodeUtf8 (Text arr off len) = unsafePerformIO $ do
145encodeUtf8 (Text arr off len) = unsafePerformIO $ do