-- | Helpers for working with 'Text' in UTF-16 code units module Data.Rope.UTF16.Internal.Text where import Data.Text(Text) import qualified Data.Text.Array as Array import qualified Data.Text.Internal as Text import qualified Data.Text.Unsafe as Unsafe clamp16 :: Int -> Text -> Int clamp16 i t@(Text.Text arr off _len) | i <= 0 = 0 | i >= len = len | isLowSurrogate = i - 1 | otherwise = i where cp = Array.unsafeIndex arr (off + i) isLowSurrogate = 0xDC00 <= cp && cp <= 0xDFFF len = Unsafe.lengthWord16 t take16 :: Int -> Text -> Text take16 n t = Unsafe.takeWord16 (clamp16 n t) t drop16 :: Int -> Text -> Text drop16 n t = Unsafe.dropWord16 (clamp16 n t) t split16At :: Int -> Text -> (Text, Text) split16At n t = (Unsafe.takeWord16 n' t, Unsafe.dropWord16 n' t) where n' = clamp16 n t chunks16Of :: Int -> Text -> [Text] chunks16Of n t | len == 0 = [] | len <= n = [t] | otherwise = pre : chunks16Of n post where (pre, post) = split16At n t len = Unsafe.lengthWord16 t