{-# LANGUAGE CPP, MagicHash, BangPatterns #-}
module Data.Text.Internal.Encoding.Utf8
(
ord2
, ord3
, ord4
, chr2
, chr3
, chr4
, validate1
, validate2
, validate3
, validate4
) where
#if defined(TEST_SUITE)
# undef ASSERTS
#endif
#if defined(ASSERTS)
import Control.Exception (assert)
#endif
import Data.Bits ((.&.))
import Data.Text.Internal.Unsafe.Char (ord)
import Data.Text.Internal.Unsafe.Shift (shiftR)
import GHC.Exts
import GHC.Word (Word8(..))
default(Int)
between :: Word8
-> Word8
-> Word8
-> Bool
between :: Word8 -> Word8 -> Word8 -> Bool
between Word8
x Word8
y Word8
z = Word8
x Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
>= Word8
y Bool -> Bool -> Bool
&& Word8
x Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
z
{-# INLINE between #-}
ord2 :: Char -> (Word8,Word8)
ord2 :: Char -> (Word8, Word8)
ord2 Char
c =
#if defined(ASSERTS)
assert (n >= 0x80 && n <= 0x07ff)
#endif
(Word8
x1,Word8
x2)
where
n :: Int
n = Char -> Int
ord Char
c
x1 :: Word8
x1 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ (Int
n Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
`shiftR` Int
6) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0xC0
x2 :: Word8
x2 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0x80
ord3 :: Char -> (Word8,Word8,Word8)
ord3 :: Char -> (Word8, Word8, Word8)
ord3 Char
c =
#if defined(ASSERTS)
assert (n >= 0x0800 && n <= 0xffff)
#endif
(Word8
x1,Word8
x2,Word8
x3)
where
n :: Int
n = Char -> Int
ord Char
c
x1 :: Word8
x1 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ (Int
n Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
`shiftR` Int
12) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0xE0
x2 :: Word8
x2 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ ((Int
n Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
`shiftR` Int
6) Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0x80
x3 :: Word8
x3 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0x80
ord4 :: Char -> (Word8,Word8,Word8,Word8)
ord4 :: Char -> (Word8, Word8, Word8, Word8)
ord4 Char
c =
#if defined(ASSERTS)
assert (n >= 0x10000)
#endif
(Word8
x1,Word8
x2,Word8
x3,Word8
x4)
where
n :: Int
n = Char -> Int
ord Char
c
x1 :: Word8
x1 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ (Int
n Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
`shiftR` Int
18) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0xF0
x2 :: Word8
x2 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ ((Int
n Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
`shiftR` Int
12) Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0x80
x3 :: Word8
x3 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ ((Int
n Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
`shiftR` Int
6) Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0x80
x4 :: Word8
x4 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ (Int
n Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3F) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0x80
chr2 :: Word8 -> Word8 -> Char
chr2 :: Word8 -> Word8 -> Char
chr2 (W8# Word#
x1#) (W8# Word#
x2#) = Char# -> Char
C# (Int# -> Char#
chr# (Int#
z1# Int# -> Int# -> Int#
+# Int#
z2#))
where
!y1# :: Int#
y1# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWordCompat# Word#
x1#)
!y2# :: Int#
y2# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWordCompat# Word#
x2#)
!z1# :: Int#
z1# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y1# Int# -> Int# -> Int#
-# Int#
0xC0#) Int#
6#
!z2# :: Int#
z2# = Int#
y2# Int# -> Int# -> Int#
-# Int#
0x80#
{-# INLINE chr2 #-}
chr3 :: Word8 -> Word8 -> Word8 -> Char
chr3 :: Word8 -> Word8 -> Word8 -> Char
chr3 (W8# Word#
x1#) (W8# Word#
x2#) (W8# Word#
x3#) = Char# -> Char
C# (Int# -> Char#
chr# (Int#
z1# Int# -> Int# -> Int#
+# Int#
z2# Int# -> Int# -> Int#
+# Int#
z3#))
where
!y1# :: Int#
y1# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWordCompat# Word#
x1#)
!y2# :: Int#
y2# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWordCompat# Word#
x2#)
!y3# :: Int#
y3# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWordCompat# Word#
x3#)
!z1# :: Int#
z1# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y1# Int# -> Int# -> Int#
-# Int#
0xE0#) Int#
12#
!z2# :: Int#
z2# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y2# Int# -> Int# -> Int#
-# Int#
0x80#) Int#
6#
!z3# :: Int#
z3# = Int#
y3# Int# -> Int# -> Int#
-# Int#
0x80#
{-# INLINE chr3 #-}
chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char
chr4 :: Word8 -> Word8 -> Word8 -> Word8 -> Char
chr4 (W8# Word#
x1#) (W8# Word#
x2#) (W8# Word#
x3#) (W8# Word#
x4#) =
Char# -> Char
C# (Int# -> Char#
chr# (Int#
z1# Int# -> Int# -> Int#
+# Int#
z2# Int# -> Int# -> Int#
+# Int#
z3# Int# -> Int# -> Int#
+# Int#
z4#))
where
!y1# :: Int#
y1# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWordCompat# Word#
x1#)
!y2# :: Int#
y2# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWordCompat# Word#
x2#)
!y3# :: Int#
y3# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWordCompat# Word#
x3#)
!y4# :: Int#
y4# = Word# -> Int#
word2Int# (Word# -> Word#
word8ToWordCompat# Word#
x4#)
!z1# :: Int#
z1# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y1# Int# -> Int# -> Int#
-# Int#
0xF0#) Int#
18#
!z2# :: Int#
z2# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y2# Int# -> Int# -> Int#
-# Int#
0x80#) Int#
12#
!z3# :: Int#
z3# = Int# -> Int# -> Int#
uncheckedIShiftL# (Int#
y3# Int# -> Int# -> Int#
-# Int#
0x80#) Int#
6#
!z4# :: Int#
z4# = Int#
y4# Int# -> Int# -> Int#
-# Int#
0x80#
{-# INLINE chr4 #-}
validate1 :: Word8 -> Bool
validate1 :: Word8 -> Bool
validate1 Word8
x1 = Word8
x1 Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Word8
0x7F
{-# INLINE validate1 #-}
validate2 :: Word8 -> Word8 -> Bool
validate2 :: Word8 -> Word8 -> Bool
validate2 Word8
x1 Word8
x2 = Word8 -> Word8 -> Word8 -> Bool
between Word8
x1 Word8
0xC2 Word8
0xDF Bool -> Bool -> Bool
&& Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0xBF
{-# INLINE validate2 #-}
validate3 :: Word8 -> Word8 -> Word8 -> Bool
{-# INLINE validate3 #-}
validate3 :: Word8 -> Word8 -> Word8 -> Bool
validate3 Word8
x1 Word8
x2 Word8
x3 = Bool
validate3_1 Bool -> Bool -> Bool
|| Bool
validate3_2 Bool -> Bool -> Bool
|| Bool
validate3_3 Bool -> Bool -> Bool
|| Bool
validate3_4
where
validate3_1 :: Bool
validate3_1 = (Word8
x1 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0xE0) Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0xA0 Word8
0xBF Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF
validate3_2 :: Bool
validate3_2 = Word8 -> Word8 -> Word8 -> Bool
between Word8
x1 Word8
0xE1 Word8
0xEC Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF
validate3_3 :: Bool
validate3_3 = Word8
x1 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0xED Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0x9F Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF
validate3_4 :: Bool
validate3_4 = Word8 -> Word8 -> Word8 -> Bool
between Word8
x1 Word8
0xEE Word8
0xEF Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF
validate4 :: Word8 -> Word8 -> Word8 -> Word8 -> Bool
{-# INLINE validate4 #-}
validate4 :: Word8 -> Word8 -> Word8 -> Word8 -> Bool
validate4 Word8
x1 Word8
x2 Word8
x3 Word8
x4 = Bool
validate4_1 Bool -> Bool -> Bool
|| Bool
validate4_2 Bool -> Bool -> Bool
|| Bool
validate4_3
where
validate4_1 :: Bool
validate4_1 = Word8
x1 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0xF0 Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x90 Word8
0xBF Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x4 Word8
0x80 Word8
0xBF
validate4_2 :: Bool
validate4_2 = Word8 -> Word8 -> Word8 -> Bool
between Word8
x1 Word8
0xF1 Word8
0xF3 Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x4 Word8
0x80 Word8
0xBF
validate4_3 :: Bool
validate4_3 = Word8
x1 Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0xF4 Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x2 Word8
0x80 Word8
0x8F Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x3 Word8
0x80 Word8
0xBF Bool -> Bool -> Bool
&&
Word8 -> Word8 -> Word8 -> Bool
between Word8
x4 Word8
0x80 Word8
0xBF
#if MIN_VERSION_base(4,16,0)
word8ToWordCompat# :: Word8# -> Word#
word8ToWordCompat# = word8ToWord#
#else
word8ToWordCompat# :: Word# -> Word#
word8ToWordCompat# :: Word# -> Word#
word8ToWordCompat# Word#
x = Word#
x
#endif