{-# LANGUAGE BangPatterns #-}
module Data.Text.Internal.Encoding.Fusion.Common
(
restreamUtf16LE
, restreamUtf16BE
, restreamUtf32LE
, restreamUtf32BE
) where
import Data.Bits ((.&.))
import Data.Text.Internal.Fusion (Step(..), Stream(..))
import Data.Text.Internal.Fusion.Types (RS(..))
import Data.Text.Internal.Unsafe.Char (ord)
import Data.Text.Internal.Unsafe.Shift (shiftR)
import Data.Word (Word8)
restreamUtf16BE :: Stream Char -> Stream Word8
restreamUtf16BE :: Stream Char -> Stream Word8
restreamUtf16BE (Stream s -> Step s Char
next0 s
s0 Size
len) = (RS s -> Step (RS s) Word8) -> RS s -> Size -> Stream Word8
forall a s. (s -> Step s a) -> s -> Size -> Stream a
Stream RS s -> Step (RS s) Word8
next (s -> RS s
forall s. s -> RS s
RS0 s
s0) (Size
len Size -> Size -> Size
forall a. Num a => a -> a -> a
* Size
2)
where
next :: RS s -> Step (RS s) Word8
next (RS0 s
s) = case s -> Step s Char
next0 s
s of
Step s Char
Done -> Step (RS s) Word8
forall s a. Step s a
Done
Skip s
s' -> RS s -> Step (RS s) Word8
forall s a. s -> Step s a
Skip (s -> RS s
forall s. s -> RS s
RS0 s
s')
Yield Char
x s
s'
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0x10000 -> Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield (Int -> Word8
intToWord8 (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
8) (RS s -> Step (RS s) Word8) -> RS s -> Step (RS s) Word8
forall a b. (a -> b) -> a -> b
$
s -> Word8 -> RS s
forall s. s -> Word8 -> RS s
RS1 s
s' (Int -> Word8
intToWord8 Int
n)
| Bool
otherwise -> Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
c1 (RS s -> Step (RS s) Word8) -> RS s -> Step (RS s) Word8
forall a b. (a -> b) -> a -> b
$ s -> Word8 -> Word8 -> Word8 -> RS s
forall s. s -> Word8 -> Word8 -> Word8 -> RS s
RS3 s
s' Word8
c2 Word8
c3 Word8
c4
where
n :: Int
n = Char -> Int
ord Char
x
n1 :: Int
n1 = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
0x10000
c1 :: Word8
c1 = Int -> Word8
intToWord8 (Int
n1 Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
`shiftR` Int
18 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0xD8)
c2 :: Word8
c2 = Int -> Word8
intToWord8 (Int
n1 Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
`shiftR` Int
10)
n2 :: Int
n2 = Int
n1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3FF
c3 :: Word8
c3 = Int -> Word8
intToWord8 (Int
n2 Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
`shiftR` Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0xDC)
c4 :: Word8
c4 = Int -> Word8
intToWord8 Int
n2
next (RS1 s
s Word8
x2) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> RS s
forall s. s -> RS s
RS0 s
s)
next (RS2 s
s Word8
x2 Word8
x3) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> Word8 -> RS s
forall s. s -> Word8 -> RS s
RS1 s
s Word8
x3)
next (RS3 s
s Word8
x2 Word8
x3 Word8
x4) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> Word8 -> Word8 -> RS s
forall s. s -> Word8 -> Word8 -> RS s
RS2 s
s Word8
x3 Word8
x4)
{-# INLINE next #-}
{-# INLINE restreamUtf16BE #-}
restreamUtf16LE :: Stream Char -> Stream Word8
restreamUtf16LE :: Stream Char -> Stream Word8
restreamUtf16LE (Stream s -> Step s Char
next0 s
s0 Size
len) = (RS s -> Step (RS s) Word8) -> RS s -> Size -> Stream Word8
forall a s. (s -> Step s a) -> s -> Size -> Stream a
Stream RS s -> Step (RS s) Word8
next (s -> RS s
forall s. s -> RS s
RS0 s
s0) (Size
len Size -> Size -> Size
forall a. Num a => a -> a -> a
* Size
2)
where
next :: RS s -> Step (RS s) Word8
next (RS0 s
s) = case s -> Step s Char
next0 s
s of
Step s Char
Done -> Step (RS s) Word8
forall s a. Step s a
Done
Skip s
s' -> RS s -> Step (RS s) Word8
forall s a. s -> Step s a
Skip (s -> RS s
forall s. s -> RS s
RS0 s
s')
Yield Char
x s
s'
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0x10000 -> Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield (Int -> Word8
intToWord8 Int
n) (RS s -> Step (RS s) Word8) -> RS s -> Step (RS s) Word8
forall a b. (a -> b) -> a -> b
$
s -> Word8 -> RS s
forall s. s -> Word8 -> RS s
RS1 s
s' (Int -> Word8
intToWord8 (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
shiftR Int
n Int
8)
| Bool
otherwise -> Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
c1 (RS s -> Step (RS s) Word8) -> RS s -> Step (RS s) Word8
forall a b. (a -> b) -> a -> b
$ s -> Word8 -> Word8 -> Word8 -> RS s
forall s. s -> Word8 -> Word8 -> Word8 -> RS s
RS3 s
s' Word8
c2 Word8
c3 Word8
c4
where
n :: Int
n = Char -> Int
ord Char
x
n1 :: Int
n1 = Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
0x10000
c2 :: Word8
c2 = Int -> Word8
intToWord8 (Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
shiftR Int
n1 Int
18 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0xD8)
c1 :: Word8
c1 = Int -> Word8
intToWord8 (Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
shiftR Int
n1 Int
10)
n2 :: Int
n2 = Int
n1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
0x3FF
c4 :: Word8
c4 = Int -> Word8
intToWord8 (Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
shiftR Int
n2 Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
0xDC)
c3 :: Word8
c3 = Int -> Word8
intToWord8 Int
n2
next (RS1 s
s Word8
x2) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> RS s
forall s. s -> RS s
RS0 s
s)
next (RS2 s
s Word8
x2 Word8
x3) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> Word8 -> RS s
forall s. s -> Word8 -> RS s
RS1 s
s Word8
x3)
next (RS3 s
s Word8
x2 Word8
x3 Word8
x4) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> Word8 -> Word8 -> RS s
forall s. s -> Word8 -> Word8 -> RS s
RS2 s
s Word8
x3 Word8
x4)
{-# INLINE next #-}
{-# INLINE restreamUtf16LE #-}
restreamUtf32BE :: Stream Char -> Stream Word8
restreamUtf32BE :: Stream Char -> Stream Word8
restreamUtf32BE (Stream s -> Step s Char
next0 s
s0 Size
len) = (RS s -> Step (RS s) Word8) -> RS s -> Size -> Stream Word8
forall a s. (s -> Step s a) -> s -> Size -> Stream a
Stream RS s -> Step (RS s) Word8
next (s -> RS s
forall s. s -> RS s
RS0 s
s0) (Size
len Size -> Size -> Size
forall a. Num a => a -> a -> a
* Size
2)
where
next :: RS s -> Step (RS s) Word8
next (RS0 s
s) = case s -> Step s Char
next0 s
s of
Step s Char
Done -> Step (RS s) Word8
forall s a. Step s a
Done
Skip s
s' -> RS s -> Step (RS s) Word8
forall s a. s -> Step s a
Skip (s -> RS s
forall s. s -> RS s
RS0 s
s')
Yield Char
x s
s' -> Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
c1 (s -> Word8 -> Word8 -> Word8 -> RS s
forall s. s -> Word8 -> Word8 -> Word8 -> RS s
RS3 s
s' Word8
c2 Word8
c3 Word8
c4)
where
n :: Int
n = Char -> Int
ord Char
x
c1 :: Word8
c1 = Int -> Word8
intToWord8 (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
shiftR Int
n Int
24
c2 :: Word8
c2 = Int -> Word8
intToWord8 (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
shiftR Int
n Int
16
c3 :: Word8
c3 = Int -> Word8
intToWord8 (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
shiftR Int
n Int
8
c4 :: Word8
c4 = Int -> Word8
intToWord8 Int
n
next (RS1 s
s Word8
x2) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> RS s
forall s. s -> RS s
RS0 s
s)
next (RS2 s
s Word8
x2 Word8
x3) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> Word8 -> RS s
forall s. s -> Word8 -> RS s
RS1 s
s Word8
x3)
next (RS3 s
s Word8
x2 Word8
x3 Word8
x4) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> Word8 -> Word8 -> RS s
forall s. s -> Word8 -> Word8 -> RS s
RS2 s
s Word8
x3 Word8
x4)
{-# INLINE next #-}
{-# INLINE restreamUtf32BE #-}
restreamUtf32LE :: Stream Char -> Stream Word8
restreamUtf32LE :: Stream Char -> Stream Word8
restreamUtf32LE (Stream s -> Step s Char
next0 s
s0 Size
len) = (RS s -> Step (RS s) Word8) -> RS s -> Size -> Stream Word8
forall a s. (s -> Step s a) -> s -> Size -> Stream a
Stream RS s -> Step (RS s) Word8
next (s -> RS s
forall s. s -> RS s
RS0 s
s0) (Size
len Size -> Size -> Size
forall a. Num a => a -> a -> a
* Size
2)
where
next :: RS s -> Step (RS s) Word8
next (RS0 s
s) = case s -> Step s Char
next0 s
s of
Step s Char
Done -> Step (RS s) Word8
forall s a. Step s a
Done
Skip s
s' -> RS s -> Step (RS s) Word8
forall s a. s -> Step s a
Skip (s -> RS s
forall s. s -> RS s
RS0 s
s')
Yield Char
x s
s' -> Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
c1 (s -> Word8 -> Word8 -> Word8 -> RS s
forall s. s -> Word8 -> Word8 -> Word8 -> RS s
RS3 s
s' Word8
c2 Word8
c3 Word8
c4)
where
n :: Int
n = Char -> Int
ord Char
x
c4 :: Word8
c4 = Int -> Word8
intToWord8 (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
shiftR Int
n Int
24
c3 :: Word8
c3 = Int -> Word8
intToWord8 (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
shiftR Int
n Int
16
c2 :: Word8
c2 = Int -> Word8
intToWord8 (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. UnsafeShift a => a -> Int -> a
shiftR Int
n Int
8
c1 :: Word8
c1 = Int -> Word8
intToWord8 Int
n
next (RS1 s
s Word8
x2) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> RS s
forall s. s -> RS s
RS0 s
s)
next (RS2 s
s Word8
x2 Word8
x3) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> Word8 -> RS s
forall s. s -> Word8 -> RS s
RS1 s
s Word8
x3)
next (RS3 s
s Word8
x2 Word8
x3 Word8
x4) = Word8 -> RS s -> Step (RS s) Word8
forall s a. a -> s -> Step s a
Yield Word8
x2 (s -> Word8 -> Word8 -> RS s
forall s. s -> Word8 -> Word8 -> RS s
RS2 s
s Word8
x3 Word8
x4)
{-# INLINE next #-}
{-# INLINE restreamUtf32LE #-}
intToWord8 :: Int -> Word8
intToWord8 :: Int -> Word8
intToWord8 = Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral