@@ -4,7 +4,8 @@
44-- Module : Data.Text.Encoding.Fusion.Common
55-- Copyright : (c) Tom Harper 2008-2009,
66-- (c) Bryan O'Sullivan 2009,
7−-- (c) Duncan Coutts 2009
7+-- (c) Duncan Coutts 2009,
8+-- (c) Jasper Van der Jeugt 2011
89--
910-- License : BSD-style
1011-- Maintainer : bos@serpentine.com, rtomharper@googlemail.com,
@@ -29,7 +30,7 @@ module Data.Text.Encoding.Fusion.Common
2930
3031import Data.Bits ((.&.))
3132import Data.Text.Fusion (Step(..), Stream(..))
32−import Data.Text.Fusion.Internal (M(..), S(..))
33+import Data.Text.Fusion.Internal (RS(..))
3334import Data.Text.UnsafeChar (ord)
3435import Data.Text.UnsafeShift (shiftR)
3536import Data.Word (Word8)
@@ -37,126 +38,110 @@ import qualified Data.Text.Encoding.Utf8 as U8
3738
3839-- | /O(n)/ Convert a Stream Char into a UTF-8 encoded Stream Word8.
3940restreamUtf8 :: Stream Char -> Stream Word8
40−restreamUtf8 (Stream next0 s0 len) =
41− Stream next (S s0 N N N) (len*2)
42− where
43− {-# INLINE next #-}
44− next (S s N N N) = case next0 s of
45− Done -> Done
46− Skip s' -> Skip (S s' N N N)
47− Yield x xs
48− | n <= 0x7F -> Yield c (S xs N N N)
49− | n <= 0x07FF -> Yield a2 (S xs (J b2) N N)
50− | n <= 0xFFFF -> Yield a3 (S xs (J b3) (J c3) N)
51− | otherwise -> Yield a4 (S xs (J b4) (J c4) (J d4))
52− where
53− n = ord x
54− c = fromIntegral n
55− (a2,b2) = U8.ord2 x
56− (a3,b3,c3) = U8.ord3 x
57− (a4,b4,c4,d4) = U8.ord4 x
58− next (S s (J x2) N N) = Yield x2 (S s N N N)
59− next (S s (J x2) x3 N) = Yield x2 (S s x3 N N)
60− next (S s (J x2) x3 x4) = Yield x2 (S s x3 x4 N)
61− next _ = internalError "restreamUtf8"
41+restreamUtf8 (Stream next0 s0 len) = Stream next (RS0 s0) (len * 2)
42+ where
43+ next (RS0 s) = case next0 s of
44+ Done -> Done
45+ Skip s' -> Skip (RS0 s')
46+ Yield x s'
47+ | n <= 0x7F -> Yield c (RS0 s')
48+ | n <= 0x07FF -> Yield a2 (RS1 s' b2)
49+ | n <= 0xFFFF -> Yield a3 (RS2 s' b3 c3)
50+ | otherwise -> Yield a4 (RS3 s' b4 c4 d4)
51+ where
52+ n = ord x
53+ c = fromIntegral n
54+ (a2,b2) = U8.ord2 x
55+ (a3,b3,c3) = U8.ord3 x
56+ (a4,b4,c4,d4) = U8.ord4 x
57+ next (RS1 s x2) = Yield x2 (RS0 s)
58+ next (RS2 s x2 x3) = Yield x2 (RS1 s x3)
59+ next (RS3 s x2 x3 x4) = Yield x2 (RS2 s x3 x4)
60+ {-# INLINE next #-}
6261{-# INLINE restreamUtf8 #-}
6362
6463restreamUtf16BE :: Stream Char -> Stream Word8
65−restreamUtf16BE (Stream next0 s0 len) =
66− Stream next (S s0 N N N) (len*2)
67− where
68− {-# INLINE next #-}
69− next (S s N N N) = case next0 s of
70− Done -> Done
71− Skip s' -> Skip (S s' N N N)
72− Yield x xs
73− | n < 0x10000 -> Yield (fromIntegral $ n `shiftR` 8) $
74− S xs (J $ fromIntegral n) N N
75− | otherwise -> Yield c1 $
76− S xs (J c2) (J c3) (J c4)
77− where
78− n = ord x
79− n1 = n - 0x10000
80− c1 = fromIntegral (n1 `shiftR` 18 + 0xD8)
81− c2 = fromIntegral (n1 `shiftR` 10)
82− n2 = n1 .&. 0x3FF
83− c3 = fromIntegral (n2 `shiftR` 8 + 0xDC)
84− c4 = fromIntegral n2
85− next (S s (J x2) N N) = Yield x2 (S s N N N)
86− next (S s (J x2) x3 N) = Yield x2 (S s x3 N N)
87− next (S s (J x2) x3 x4) = Yield x2 (S s x3 x4 N)
88− next _ = internalError "restreamUtf16BE"
64+restreamUtf16BE (Stream next0 s0 len) = Stream next (RS0 s0) (len * 2)
65+ where
66+ next (RS0 s) = case next0 s of
67+ Done -> Done
68+ Skip s' -> Skip (RS0 s')
69+ Yield x s'
70+ | n < 0x10000 -> Yield (fromIntegral $ n `shiftR` 8) $
71+ RS1 s' (fromIntegral n)
72+ | otherwise -> Yield c1 $ RS3 s' c2 c3 c4
73+ where
74+ n = ord x
75+ n1 = n - 0x10000
76+ c1 = fromIntegral (n1 `shiftR` 18 + 0xD8)
77+ c2 = fromIntegral (n1 `shiftR` 10)
78+ n2 = n1 .&. 0x3FF
79+ c3 = fromIntegral (n2 `shiftR` 8 + 0xDC)
80+ c4 = fromIntegral n2
81+ next (RS1 s x2) = Yield x2 (RS0 s)
82+ next (RS2 s x2 x3) = Yield x2 (RS1 s x3)
83+ next (RS3 s x2 x3 x4) = Yield x2 (RS2 s x3 x4)
84+ {-# INLINE next #-}
8985{-# INLINE restreamUtf16BE #-}
9086
9187restreamUtf16LE :: Stream Char -> Stream Word8
92−restreamUtf16LE (Stream next0 s0 len) =
93− Stream next (S s0 N N N) (len*2)
94− where
95− {-# INLINE next #-}
96− next (S s N N N) = case next0 s of
97− Done -> Done
98− Skip s' -> Skip (S s' N N N)
99− Yield x xs
100− | n < 0x10000 -> Yield (fromIntegral n) $
101− S xs (J (fromIntegral $ shiftR n 8)) N N
102− | otherwise -> Yield c1 $
103− S xs (J c2) (J c3) (J c4)
104− where
105− n = ord x
106− n1 = n - 0x10000
107− c2 = fromIntegral (shiftR n1 18 + 0xD8)
108− c1 = fromIntegral (shiftR n1 10)
109− n2 = n1 .&. 0x3FF
110− c4 = fromIntegral (shiftR n2 8 + 0xDC)
111− c3 = fromIntegral n2
112− next (S s (J x2) N N) = Yield x2 (S s N N N)
113− next (S s (J x2) x3 N) = Yield x2 (S s x3 N N)
114− next (S s (J x2) x3 x4) = Yield x2 (S s x3 x4 N)
115− next _ = internalError "restreamUtf16LE"
88+restreamUtf16LE (Stream next0 s0 len) = Stream next (RS0 s0) (len * 2)
89+ where
90+ next (RS0 s) = case next0 s of
91+ Done -> Done
92+ Skip s' -> Skip (RS0 s')
93+ Yield x s'
94+ | n < 0x10000 -> Yield (fromIntegral n) $
95+ RS1 s' (fromIntegral $ shiftR n 8)
96+ | otherwise -> Yield c1 $ RS3 s' c2 c3 c4
97+ where
98+ n = ord x
99+ n1 = n - 0x10000
100+ c2 = fromIntegral (shiftR n1 18 + 0xD8)
101+ c1 = fromIntegral (shiftR n1 10)
102+ n2 = n1 .&. 0x3FF
103+ c4 = fromIntegral (shiftR n2 8 + 0xDC)
104+ c3 = fromIntegral n2
105+ next (RS1 s x2) = Yield x2 (RS0 s)
106+ next (RS2 s x2 x3) = Yield x2 (RS1 s x3)
107+ next (RS3 s x2 x3 x4) = Yield x2 (RS2 s x3 x4)
108+ {-# INLINE next #-}
116109{-# INLINE restreamUtf16LE #-}
117110
118111restreamUtf32BE :: Stream Char -> Stream Word8
119−restreamUtf32BE (Stream next0 s0 len) =
120− Stream next (S s0 N N N) (len*2)
121− where
122− {-# INLINE next #-}
123− next (S s N N N) = case next0 s of
112+restreamUtf32BE (Stream next0 s0 len) = Stream next (RS0 s0) (len * 2)
113+ where
114+ next (RS0 s) = case next0 s of
124115 Done -> Done
125− Skip s' -> Skip (S s' N N N)
126− Yield x xs -> Yield c1 (S xs (J c2) (J c3) (J c4))
116+ Skip s' -> Skip (RS0 s')
117+ Yield x s' -> Yield c1 (RS3 s' c2 c3 c4)
127118 where
128119 n = ord x
129120 c1 = fromIntegral $ shiftR n 24
130121 c2 = fromIntegral $ shiftR n 16
131122 c3 = fromIntegral $ shiftR n 8
132123 c4 = fromIntegral n
133− next (S s (J x2) N N) = Yield x2 (S s N N N)
134− next (S s (J x2) x3 N) = Yield x2 (S s x3 N N)
135− next (S s (J x2) x3 x4) = Yield x2 (S s x3 x4 N)
136− next _ = internalError "restreamUtf32BE"
124+ next (RS1 s x2) = Yield x2 (RS0 s)
125+ next (RS2 s x2 x3) = Yield x2 (RS1 s x3)
126+ next (RS3 s x2 x3 x4) = Yield x2 (RS2 s x3 x4)
127+ {-# INLINE next #-}
137128{-# INLINE restreamUtf32BE #-}
138129
139130restreamUtf32LE :: Stream Char -> Stream Word8
140−restreamUtf32LE (Stream next0 s0 len) =
141− Stream next (S s0 N N N) (len*2)
142− where
143− {-# INLINE next #-}
144− next (S s N N N) = case next0 s of
131+restreamUtf32LE (Stream next0 s0 len) = Stream next (RS0 s0) (len * 2)
132+ where
133+ next (RS0 s) = case next0 s of
145134 Done -> Done
146− Skip s' -> Skip (S s' N N N)
147− Yield x xs -> Yield c1 (S xs (J c2) (J c3) (J c4))
135+ Skip s' -> Skip (RS0 s')
136+ Yield x s' -> Yield c1 (RS3 s' c2 c3 c4)
148137 where
149138 n = ord x
150139 c4 = fromIntegral $ shiftR n 24
151140 c3 = fromIntegral $ shiftR n 16
152141 c2 = fromIntegral $ shiftR n 8
153142 c1 = fromIntegral n
154− next (S s (J x2) N N) = Yield x2 (S s N N N)
155− next (S s (J x2) x3 N) = Yield x2 (S s x3 N N)
156− next (S s (J x2) x3 x4) = Yield x2 (S s x3 x4 N)
157− next _ = internalError "restreamUtf32LE"
143+ next (RS1 s x2) = Yield x2 (RS0 s)
144+ next (RS2 s x2 x3) = Yield x2 (RS1 s x3)
145+ next (RS3 s x2 x3 x4) = Yield x2 (RS2 s x3 x4)
146+ {-# INLINE next #-}
158147{-# INLINE restreamUtf32LE #-}
159−
160−internalError :: String -> a
161−internalError func =
162− error $ "Data.Text.Encoding.Fusion.Common." ++ func ++ ": internal error"