prim-0.1.0.0: src/String/C/UTF8.hs
{-# language BangPatterns #-}
module String.C.UTF8 where
import qualified String
import String.C
import Prelude hiding (Char)
import GHC.Types (Char(..),isTrue#,Bool(..))
-- There's really no point in inlining this for the same reasons as
-- unpack. See Note [Inlining unpack#] above for details.
unpack# :: S -> String.List
{-# NOINLINE CONLIKE unpack# #-}
unpack# addr
= unpack 0#
where
-- We take care to strictly evaluate the character decoding as
-- indexCharOffAddr# is marked with the can_fail flag and
-- consequently GHC won't evaluate the expression unless it is absolutely
-- needed.
unpack nh
| isTrue# (ch `eqChar#` '\0'# ) = []
| isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpack (nh +# 1#)
| isTrue# (ch `leChar#` '\xDF'#) =
let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +#
(ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#)))
in c : unpack (nh +# 2#)
| isTrue# (ch `leChar#` '\xEF'#) =
let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +#
((ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#) `uncheckedIShiftL#` 6#) +#
(ord# (indexCharOffAddr# addr (nh +# 2#)) -# 0x80#)))
in c : unpack (nh +# 3#)
| True =
let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +#
((ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#) `uncheckedIShiftL#` 12#) +#
((ord# (indexCharOffAddr# addr (nh +# 2#)) -# 0x80#) `uncheckedIShiftL#` 6#) +#
(ord# (indexCharOffAddr# addr (nh +# 3#)) -# 0x80#)))
in c : unpack (nh +# 4#)
where
!ch = indexCharOffAddr# addr nh