module Data.Text.Unsafe
(
iter
, iter_
, reverseIter
, unsafeHead
, unsafeTail
) where
import Control.Exception (assert)
import Data.Text.Internal (Text(..))
import Data.Text.UnsafeChar (unsafeChr)
import Data.Text.Encoding.Utf16 (chr2)
import qualified Data.Text.Array as A
unsafeHead :: Text -> Char
unsafeHead (Text arr off len)
| m < 0xD800 || m > 0xDBFF = unsafeChr m
| otherwise = chr2 m n
where m = assert (len > 0) $ A.unsafeIndex arr off
n = assert (len > 1) $ A.unsafeIndex arr (off+1)
unsafeTail :: Text -> Text
unsafeTail t@(Text arr off len) =
assert (d <= len) $ Text arr (off+d) (lend)
where d = iter_ t 0
iter :: Text -> Int -> (Char,Int)
iter (Text arr off len) i
| m < 0xD800 || m > 0xDBFF = (unsafeChr m, 1)
| otherwise = (chr2 m n, 2)
where m = assert (i < len) $ A.unsafeIndex arr j
n = assert (i + 1 < len) $ A.unsafeIndex arr k
j = assert (i >= 0) $ off + i
k = j + 1
iter_ :: Text -> Int -> Int
iter_ (Text arr off len) i | m < 0xD800 || m > 0xDBFF = 1
| otherwise = 2
where m = assert (i >= 0 && i < len) $ A.unsafeIndex arr (off+i)
reverseIter :: Text -> Int -> (Char,Int)
reverseIter (Text arr off len) i
| m < 0xDC00 || m > 0xDFFF = (unsafeChr m, 1)
| otherwise = (chr2 n m, 2)
where m = assert (i < len) $ A.unsafeIndex arr j
n = assert (i 1 >= 0) $ A.unsafeIndex arr k
j = assert (i >= 0) $ off + i
k = j 1