{-# LANGUAGE CPP, MagicHash, UnboxedTuples #-}
module Data.Text.Unsafe
(
inlineInterleaveST
, inlinePerformIO
, unsafeDupablePerformIO
, Iter(..)
, iter
, iter_
, reverseIter
, reverseIter_
, unsafeHead
, unsafeTail
, lengthWord16
, takeWord16
, dropWord16
) where
#if defined(ASSERTS)
import Control.Exception (assert)
import GHC.Stack (HasCallStack)
#endif
import Data.Text.Internal.Encoding.Utf16 (chr2)
import Data.Text.Internal (Text(..))
import Data.Text.Internal.Unsafe (inlineInterleaveST, inlinePerformIO)
import Data.Text.Internal.Unsafe.Char (unsafeChr)
import qualified Data.Text.Array as A
import GHC.IO (unsafeDupablePerformIO)
unsafeHead :: Text -> Char
unsafeHead :: Text -> Char
unsafeHead (Text Array
arr Int
off Int
_len)
| Word16
m Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
< Word16
0xD800 Bool -> Bool -> Bool
|| Word16
m Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
> Word16
0xDBFF = Word16 -> Char
unsafeChr Word16
m
| Bool
otherwise = Word16 -> Word16 -> Char
chr2 Word16
m Word16
n
where m :: Word16
m = Array -> Int -> Word16
A.unsafeIndex Array
arr Int
off
n :: Word16
n = Array -> Int -> Word16
A.unsafeIndex Array
arr (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
{-# INLINE unsafeHead #-}
unsafeTail :: Text -> Text
unsafeTail :: Text -> Text
unsafeTail t :: Text
t@(Text Array
arr Int
off Int
len) =
#if defined(ASSERTS)
assert (d <= len) $
#endif
Array -> Int -> Int -> Text
Text Array
arr (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
d) (Int
lenInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
d)
where d :: Int
d = Text -> Int -> Int
iter_ Text
t Int
0
{-# INLINE unsafeTail #-}
data Iter = Iter {-# UNPACK #-} !Char {-# UNPACK #-} !Int
iter ::
#if defined(ASSERTS)
HasCallStack =>
#endif
Text -> Int -> Iter
iter :: Text -> Int -> Iter
iter (Text Array
arr Int
off Int
_len) Int
i
| Word16
m Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
< Word16
0xD800 Bool -> Bool -> Bool
|| Word16
m Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
> Word16
0xDBFF = Char -> Int -> Iter
Iter (Word16 -> Char
unsafeChr Word16
m) Int
1
| Bool
otherwise = Char -> Int -> Iter
Iter (Word16 -> Word16 -> Char
chr2 Word16
m Word16
n) Int
2
where m :: Word16
m = Array -> Int -> Word16
A.unsafeIndex Array
arr Int
j
n :: Word16
n = Array -> Int -> Word16
A.unsafeIndex Array
arr Int
k
j :: Int
j = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i
k :: Int
k = Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
{-# INLINE iter #-}
iter_ :: Text -> Int -> Int
iter_ :: Text -> Int -> Int
iter_ (Text Array
arr Int
off Int
_len) Int
i | Word16
m Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
< Word16
0xD800 Bool -> Bool -> Bool
|| Word16
m Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
> Word16
0xDBFF = Int
1
| Bool
otherwise = Int
2
where m :: Word16
m = Array -> Int -> Word16
A.unsafeIndex Array
arr (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i)
{-# INLINE iter_ #-}
reverseIter :: Text -> Int -> (Char,Int)
reverseIter :: Text -> Int -> (Char, Int)
reverseIter (Text Array
arr Int
off Int
_len) Int
i
| Word16
m Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
< Word16
0xDC00 Bool -> Bool -> Bool
|| Word16
m Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
> Word16
0xDFFF = (Word16 -> Char
unsafeChr Word16
m, -Int
1)
| Bool
otherwise = (Word16 -> Word16 -> Char
chr2 Word16
n Word16
m, -Int
2)
where m :: Word16
m = Array -> Int -> Word16
A.unsafeIndex Array
arr Int
j
n :: Word16
n = Array -> Int -> Word16
A.unsafeIndex Array
arr Int
k
j :: Int
j = Int
off Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i
k :: Int
k = Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
{-# INLINE reverseIter #-}
reverseIter_ :: Text -> Int -> Int
reverseIter_ :: Text -> Int -> Int
reverseIter_ (Text Array
arr Int
off Int
_len) Int
i
| Word16
m Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
< Word16
0xDC00 Bool -> Bool -> Bool
|| Word16
m Word16 -> Word16 -> Bool
forall a. Ord a => a -> a -> Bool
> Word16
0xDFFF = -Int
1
| Bool
otherwise = -Int
2
where m :: Word16
m = Array -> Int -> Word16
A.unsafeIndex Array
arr (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
i)
{-# INLINE reverseIter_ #-}
lengthWord16 :: Text -> Int
lengthWord16 :: Text -> Int
lengthWord16 (Text Array
_arr Int
_off Int
len) = Int
len
{-# INLINE lengthWord16 #-}
takeWord16 :: Int -> Text -> Text
takeWord16 :: Int -> Text -> Text
takeWord16 Int
k (Text Array
arr Int
off Int
_len) = Array -> Int -> Int -> Text
Text Array
arr Int
off Int
k
{-# INLINE takeWord16 #-}
dropWord16 :: Int -> Text -> Text
dropWord16 :: Int -> Text -> Text
dropWord16 Int
k (Text Array
arr Int
off Int
len) = Array -> Int -> Int -> Text
Text Array
arr (Int
offInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
k) (Int
lenInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
k)
{-# INLINE dropWord16 #-}