on master help sign in
Use a more heavily packed state type for lazy UTF-8 decoding.

--HG-- extra : convert_revision : 3f584489954bdf639dacc06b688ce8474dbe3c2d

commitc841e7a114f894814f64e749ff69d6dbbebaa52d authorBryan O'Sullivan <bos@serpentine.com> dateTue 15 Dec 2009, 08:38 (17 years ago) parent2c4a9c7
1 file changed+26−25
Data/Text/Lazy/Encoding/Fusion.hs+26−25
Data/Text/Lazy/Encoding/Fusion.hs+26−25
@@ -35,7 +35,7 @@ import qualified Data.ByteString.Unsafe as B
3535import Data.Text.Encoding.Fusion.Common
3636import Data.Text.Encoding.Error
3737import Data.Text.Fusion (Step(..), Stream(..))
38−import Data.Text.Fusion.Internal (M(..), PairS(..), S(..))
38+import Data.Text.Fusion.Internal (PairS(..))
3939import Data.Text.Fusion.Size
4040import Data.Text.UnsafeChar (unsafeChr8)
4141import Data.Word (Word8)
@@ -47,21 +47,26 @@ import Data.ByteString.Internal (mallocByteString, memcpy)
4747import Control.Exception (assert)
4848import qualified Data.ByteString.Internal as B
4949
50+data S = S0
51+ | S1 {-# UNPACK #-} !Word8
52+ | S2 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
53+ | S3 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
54+ | S4 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8 {-# UNPACK #-} !Word8
55+
5056-- | /O(n)/ Convert a lazy 'ByteString' into a 'Stream Char', using
5157-- UTF-8 encoding.
5258streamUtf8 :: OnDecodeError -> ByteString -> Stream Char
53−streamUtf8 onErr bs0 = Stream next (bs0 :*: empty :*: 0) unknownSize
59+streamUtf8 onErr bs0 = Stream next (bs0 :*: S0 :*: 0) unknownSize
5460 where
55− empty = S N N N N
56− next (bs@(Chunk ps _) :*: S N _ _ _ :*: i)
61+ next (bs@(Chunk ps _) :*: S0 :*: i)
5762 | i < len && U8.validate1 a =
58− Yield (unsafeChr8 a) (bs :*: empty :*: i+1)
63+ Yield (unsafeChr8 a) (bs :*: S0 :*: i+1)
5964 | i + 1 < len && U8.validate2 a b =
60− Yield (U8.chr2 a b) (bs :*: empty :*: i+2)
65+ Yield (U8.chr2 a b) (bs :*: S0 :*: i+2)
6166 | i + 2 < len && U8.validate3 a b c =
62− Yield (U8.chr3 a b c) (bs :*: empty :*: i+3)
67+ Yield (U8.chr3 a b c) (bs :*: S0 :*: i+3)
6368 | i + 4 < len && U8.validate4 a b c d =
64− Yield (U8.chr4 a b c d) (bs :*: empty :*: i+4)
69+ Yield (U8.chr4 a b c d) (bs :*: S0 :*: i+4)
6570 where len = B.length ps
6671 a = B.unsafeIndex ps i
6772 b = B.unsafeIndex ps (i+1)
@@ -69,28 +74,24 @@ streamUtf8 onErr bs0 = Stream next (bs0 :*: empty :*: 0) unknownSize
6974 d = B.unsafeIndex ps (i+3)
7075 next st@(bs :*: s :*: i) =
7176 case s of
72− S (J a) N _ _ | U8.validate1 a ->
73− Yield (unsafeChr8 a) es
74− S (J a) (J b) N _ | U8.validate2 a b ->
75− Yield (U8.chr2 a b) es
76− S (J a) (J b) (J c) N | U8.validate3 a b c ->
77− Yield (U8.chr3 a b c) es
78− S (J a) (J b) (J c) (J d) | U8.validate4 a b c d ->
79− Yield (U8.chr4 a b c d) es
77+ S1 a | U8.validate1 a -> Yield (unsafeChr8 a) es
78+ S2 a b | U8.validate2 a b -> Yield (U8.chr2 a b) es
79+ S3 a b c | U8.validate3 a b c -> Yield (U8.chr3 a b c) es
80+ S4 a b c d | U8.validate4 a b c d -> Yield (U8.chr4 a b c d) es
8081 _ -> consume st
81− where es = bs :*: empty :*: i
82+ where es = bs :*: S0 :*: i
8283 consume (bs@(Chunk ps rest) :*: s :*: i)
8384 | i >= B.length ps = consume (rest :*: s :*: 0)
8485 | otherwise =
8586 case s of
86− S N _ _ _ -> next (bs :*: S x N N N :*: i+1)
87− S a N _ _ -> next (bs :*: S a x N N :*: i+1)
88− S a b N _ -> next (bs :*: S a b x N :*: i+1)
89− S a b c N -> next (bs :*: S a b c x :*: i+1)
90− S (J a) b c d -> decodeError "streamUtf8" "UTF-8" onErr (Just a)
91− (bs :*: S b c d N :*: i+1)
92− where x = J (B.unsafeIndex ps i)
93− consume (Empty :*: S N _ _ _ :*: _) = Done
87+ S0 -> next (bs :*: S1 x :*: i+1)
88+ S1 a -> next (bs :*: S2 a x :*: i+1)
89+ S2 a b -> next (bs :*: S3 a b x :*: i+1)
90+ S3 a b c -> next (bs :*: S4 a b c x :*: i+1)
91+ S4 a b c d -> decodeError "streamUtf8" "UTF-8" onErr (Just a)
92+ (bs :*: S3 b c d :*: i+1)
93+ where x = B.unsafeIndex ps i
94+ consume (Empty :*: S0 :*: _) = Done
9495 consume st = decodeError "streamUtf8" "UTF-8" onErr Nothing st
9596{-# INLINE [0] streamUtf8 #-}
9697