@@ -1,7 +1,7 @@
1−{-# LANGUAGE BangPatterns, Rank2Types #-}
1+{-# LANGUAGE BangPatterns, MagicHash, Rank2Types #-}
22-- |
33-- Module : Data.Text.Fusion.Common
4−-- Copyright : (c) Bryan O'Sullivan 2009
4+-- Copyright : (c) Bryan O'Sullivan 2009, 2012
55--
66-- License : BSD-style
77-- Maintainer : bos@serpentine.com, rtomharper@googlemail.com,
@@ -17,6 +17,7 @@ module Data.Text.Fusion.Common
1717 singleton
1818 , streamList
1919 , unstreamList
20+ , streamCString#
2021
2122 -- * Basic interface
2223 , cons
@@ -104,10 +105,13 @@ import Prelude (Bool(..), Char, Eq(..), Int, Integral, Maybe(..),
104105 (&&), fromIntegral, otherwise)
105106import qualified Data.List as L
106107import qualified Prelude as P
108+import Data.Bits (shiftL)
107109import Data.Int (Int64)
108110import Data.Text.Fusion.Internal
109111import Data.Text.Fusion.CaseMapping (foldMapping, lowerMapping, upperMapping)
110112import Data.Text.Fusion.Size
113+import GHC.Prim (Addr#, chr#, indexCharOffAddr#, ord#)
114+import GHC.Types (Char(..), Int(..))
111115
112116singleton :: Char -> Stream Char
113117singleton c = Stream next False 1
@@ -131,6 +135,35 @@ unstreamList (Stream next s0 _len) = unfold s0
131135
132136{-# RULES "STREAM streamList/unstreamList fusion" forall s. streamList (unstreamList s) = s #-}
133137
138+-- | Stream the UTF-8-like packed encoding used by GHC to represent
139+-- constant strings in generated code.
140+--
141+-- This encoding uses the byte sequence "\xc0\x80" to represent NUL,
142+-- and the string is NUL-terminated.
143+streamCString# :: Addr# -> Stream Char
144+streamCString# addr = Stream step 0 unknownSize
145+ where
146+ step !i
147+ | b == 0 = Done
148+ | b <= 0x7f = Yield (C# b#) (i+1)
149+ | b <= 0xdf = let !c = chr $ ((b-0xc0) `shiftL` 6) + next 1
150+ in Yield c (i+2)
151+ | b <= 0xef = let !c = chr $ ((b-0xe0) `shiftL` 12) +
152+ (next 1 `shiftL` 6) +
153+ next 2
154+ in Yield c (i+3)
155+ | otherwise = let !c = chr $ ((b-0xf0) `shiftL` 18) +
156+ (next 1 `shiftL` 12) +
157+ (next 2 `shiftL` 6) +
158+ next 3
159+ in Yield c (i+4)
160+ where b = I# (ord# b#)
161+ next n = I# (ord# (at# (i+n))) - 0x80
162+ b# = at# i
163+ at# (I# i#) = indexCharOffAddr# addr i#
164+ chr (I# i#) = C# (chr# i#)
165+{-# INLINE [0] streamCString# #-}
166+
134167-- ----------------------------------------------------------------------------
135168-- * Basic stream functions
136169