@@ -1,7 +1,7 @@
1{-# LANGUAGE BangPatterns #-}
1{-# LANGUAGE BangPatterns #-}
4−-- Module : Data.Text.Encoding
4+-- Module : Data.Text.Encoding.Fusion
5-- Copyright : (c) Tom Harper 2008-2009,
5-- Copyright : (c) Tom Harper 2008-2009,
6-- (c) Bryan O'Sullivan 2009,
6-- (c) Bryan O'Sullivan 2009,
7-- (c) Duncan Coutts 2009
7-- (c) Duncan Coutts 2009
@@ -28,23 +28,15 @@ module Data.Text.Encoding.Fusion
28 -- * Unstreaming
28 -- * Unstreaming
29 , unstream
29 , unstream
31− -- * Restreaming
31+ , module Data.Text.Encoding.Fusion.Common
32− -- Restreaming is the act of converting from one 'Stream'
33− -- representation to another.
41import Control.Exception (assert)
34import Control.Exception (assert)
42−import Data.Bits (shiftL, shiftR, (.&.))
35+import Data.Bits (shiftL)
43import Data.ByteString as B
36import Data.ByteString as B
44import Data.ByteString.Internal (ByteString(..), mallocByteString, memcpy)
37import Data.ByteString.Internal (ByteString(..), mallocByteString, memcpy)
45−import Data.Char (ord)
46import Data.Text.Fusion (Step(..), Stream(..))
38import Data.Text.Fusion (Step(..), Stream(..))
47−import Data.Text.Fusion.Internal (M(..))
39+import Data.Text.Encoding.Fusion.Common
48import Data.Text.UnsafeChar (unsafeChr, unsafeChr8, unsafeChr32)
40import Data.Text.UnsafeChar (unsafeChr, unsafeChr8, unsafeChr32)
49import Data.Word (Word8, Word16, Word32)
41import Data.Word (Word8, Word16, Word32)
50import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
42import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
@@ -56,12 +48,6 @@ import qualified Data.Text.Encoding.Utf8 as U8
56import qualified Data.Text.Encoding.Utf16 as U16
48import qualified Data.Text.Encoding.Utf16 as U16
57import qualified Data.Text.Encoding.Utf32 as U32
49import qualified Data.Text.Encoding.Utf32 as U32
62−data S s = S {-# UNPACK #-} !s
63− {-# UNPACK #-} !M8 {-# UNPACK #-} !M8 {-# UNPACK #-} !M8
65streamASCII :: ByteString -> Stream Char
51streamASCII :: ByteString -> Stream Char
66streamASCII bs = Stream next 0 l
52streamASCII bs = Stream next 0 l
@@ -172,129 +158,6 @@ streamUtf32LE bs = Stream next 0 l
172 idx = fromIntegral . B.unsafeIndex bs :: Int -> Word32
158 idx = fromIntegral . B.unsafeIndex bs :: Int -> Word32
173{-# INLINE [0] streamUtf32LE #-}
159{-# INLINE [0] streamUtf32LE #-}
175−-- | /O(n)/ Convert a Stream Char into a UTF-8 encoded Stream Word8.
176−restreamUtf8 :: Stream Char -> Stream Word8
177−restreamUtf8 (Stream next0 s0 len) =
178− Stream next (S s0 N N N) (len*2)
181− next (S s N N N) = case next0 s of
183− Skip s' -> Skip (S s' N N N)
185− | n <= 0x7F -> Yield c (S xs N N N)
186− | n <= 0x07FF -> Yield a2 (S xs (J b2) N N)
187− | n <= 0xFFFF -> Yield a3 (S xs (J b3) (J c3) N)
188− | otherwise -> Yield a4 (S xs (J b4) (J c4) (J d4))
193− (a3,b3,c3) = U8.ord3 x
194− (a4,b4,c4,d4) = U8.ord4 x
195− next (S s (J x2) N N) = Yield x2 (S s N N N)
196− next (S s (J x2) x3 N) = Yield x2 (S s x3 N N)
197− next (S s (J x2) x3 x4) = Yield x2 (S s x3 x4 N)
198− next _ = internalError "restreamUtf8"
199−{-# INLINE restreamUtf8 #-}
201−restreamUtf16BE :: Stream Char -> Stream Word8
202−restreamUtf16BE (Stream next0 s0 len) =
203− Stream next (S s0 N N N) (len*2)
206− next (S s N N N) = case next0 s of
208− Skip s' -> Skip (S s' N N N)
210− | n < 0x10000 -> Yield (fromIntegral $ n `shiftR` 8) $
211− S xs (J $ fromIntegral n) N N
212− | otherwise -> Yield c1 $
213− S xs (J c2) (J c3) (J c4)
217− c1 = fromIntegral (n1 `shiftR` 18 + 0xD8)
218− c2 = fromIntegral (n1 `shiftR` 10)
220− c3 = fromIntegral (n2 `shiftR` 8 + 0xDC)
221− c4 = fromIntegral n2
222− next (S s (J x2) N N) = Yield x2 (S s N N N)
223− next (S s (J x2) x3 N) = Yield x2 (S s x3 N N)
224− next (S s (J x2) x3 x4) = Yield x2 (S s x3 x4 N)
225− next _ = internalError "restreamUtf16BE"
226−{-# INLINE restreamUtf16BE #-}
228−restreamUtf16LE :: Stream Char -> Stream Word8
229−restreamUtf16LE (Stream next0 s0 len) =
230− Stream next (S s0 N N N) (len*2)
233− next (S s N N N) = case next0 s of
235− Skip s' -> Skip (S s' N N N)
237− | n < 0x10000 -> Yield (fromIntegral n) $
238− S xs (J (fromIntegral $ shiftR n 8)) N N
239− | otherwise -> Yield c1 $
240− S xs (J c2) (J c3) (J c4)
244− c2 = fromIntegral (shiftR n1 18 + 0xD8)
245− c1 = fromIntegral (shiftR n1 10)
247− c4 = fromIntegral (shiftR n2 8 + 0xDC)
248− c3 = fromIntegral n2
249− next (S s (J x2) N N) = Yield x2 (S s N N N)
250− next (S s (J x2) x3 N) = Yield x2 (S s x3 N N)
251− next (S s (J x2) x3 x4) = Yield x2 (S s x3 x4 N)
252− next _ = internalError "restreamUtf16LE"
253−{-# INLINE restreamUtf16LE #-}
255−restreamUtf32BE :: Stream Char -> Stream Word8
256−restreamUtf32BE (Stream next0 s0 len) =
257− Stream next (S s0 N N N) (len*2)
260− next (S s N N N) = case next0 s of
262− Skip s' -> Skip (S s' N N N)
263− Yield x xs -> Yield c1 (S xs (J c2) (J c3) (J c4))
266− c1 = fromIntegral $ shiftR n 24
267− c2 = fromIntegral $ shiftR n 16
268− c3 = fromIntegral $ shiftR n 8
270− next (S s (J x2) N N) = Yield x2 (S s N N N)
271− next (S s (J x2) x3 N) = Yield x2 (S s x3 N N)
272− next (S s (J x2) x3 x4) = Yield x2 (S s x3 x4 N)
273− next _ = internalError "restreamUtf32BE"
274−{-# INLINE restreamUtf32BE #-}
276−restreamUtf32LE :: Stream Char -> Stream Word8
277−restreamUtf32LE (Stream next0 s0 len) =
278− Stream next (S s0 N N N) (len*2)
281− next (S s N N N) = case next0 s of
283− Skip s' -> Skip (S s' N N N)
284− Yield x xs -> Yield c1 (S xs (J c2) (J c3) (J c4))
287− c4 = fromIntegral $ shiftR n 24
288− c3 = fromIntegral $ shiftR n 16
289− c2 = fromIntegral $ shiftR n 8
291− next (S s (J x2) N N) = Yield x2 (S s N N N)
292− next (S s (J x2) x3 N) = Yield x2 (S s x3 N N)
293− next (S s (J x2) x3 x4) = Yield x2 (S s x3 x4 N)
294− next _ = internalError "restreamUtf32LE"
295−{-# INLINE restreamUtf32LE #-}
298-- | /O(n)/ Convert a 'Stream' 'Word8' to a 'ByteString'.
161-- | /O(n)/ Convert a 'Stream' 'Word8' to a 'ByteString'.
299unstream :: Stream Word8 -> ByteString
162unstream :: Stream Word8 -> ByteString
300unstream (Stream next s0 len) = unsafePerformIO $ do
163unstream (Stream next s0 len) = unsafePerformIO $ do
@@ -325,10 +188,6 @@ unstream (Stream next s0 len) = unsafePerformIO $ do
325 memcpy dest' src' (fromIntegral destLen)
188 memcpy dest' src' (fromIntegral destLen)
326 return dest
189 return dest
328−internalError :: String -> a
330− error $ "Data.Text.Encoding.Fusion." ++ func ++ ": internal error"
332encodingError :: String -> a
191encodingError :: String -> a
333encodingError encoding =
192encodingError encoding =
334 error $ "Data.Text.Encoding.Fusion: Bad " ++ encoding ++ " stream"
193 error $ "Data.Text.Encoding.Fusion: Bad " ++ encoding ++ " stream"