{-# LANGUAGE CPP #-}

module PtrPoker.Compat.Text where

#if MIN_VERSION_text(2,0,0)
import qualified Data.Text.Array as TextArray
import qualified Data.Text.Encoding as TextEncoding
import qualified Data.Text.Internal as TextInternal
import PtrPoker.Prelude

{-# INLINE destruct #-}
destruct :: (ByteArray# -> Int -> Int -> x) -> Text -> x
destruct k (TextInternal.Text (TextArray.ByteArray arr) off len) = k arr off len

{-# INLINE utf8EncodingSize #-}
utf8EncodingSize :: Text -> Int
utf8EncodingSize = destruct $ \_arr _off len -> len

{-# INLINEABLE encodeInUtf8 #-}
encodeInUtf8 :: Text -> ByteString
encodeInUtf8 t = TextEncoding.encodeUtf8 t

{-# INLINE pokeInUtf8 #-}
pokeInUtf8 :: Text -> Ptr Word8 -> IO (Ptr Word8)
pokeInUtf8 (TextInternal.Text arr off len) p =
  stToIO (TextArray.copyToPointer arr off p len) $> plusPtr p len
#else
import qualified Data.ByteString.Internal as ByteStringInternal
import qualified Data.Text.Array as TextArray
import qualified Data.Text.Internal as TextInternal
import qualified PtrPoker.Ffi as Ffi
import PtrPoker.Prelude

{-# INLINE destruct #-}
destruct :: (ByteArray# -> Int -> Int -> x) -> Text -> x
destruct :: forall x. (ByteArray# -> Int -> Int -> x) -> Text -> x
destruct ByteArray# -> Int -> Int -> x
k (TextInternal.Text (TextArray.Array ByteArray#
arr) Int
off Int
len) =
  ByteArray# -> Int -> Int -> x
k ByteArray#
arr Int
off Int
len

{-# INLINEABLE utf8EncodingSize #-}
utf8EncodingSize :: Text -> Int
utf8EncodingSize :: Text -> Int
utf8EncodingSize (TextInternal.Text (TextArray.Array ByteArray#
arr) Int
off Int
len) =
  ByteArray# -> CSize -> CSize -> IO CInt
Ffi.countTextAllocationSize
    ByteArray#
arr
    (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
off)
    (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
    forall a b. a -> (a -> b) -> b
& forall a. IO a -> a
unsafeDupablePerformIO
    forall a b. a -> (a -> b) -> b
& forall a b. (Integral a, Num b) => a -> b
fromIntegral

{-# INLINEABLE encodeInUtf8 #-}
encodeInUtf8 :: Text -> ByteString
encodeInUtf8 :: Text -> ByteString
encodeInUtf8 (TextInternal.Text (TextArray.Array ByteArray#
arr) Int
off Int
len) =
  if Int
len forall a. Eq a => a -> a -> Bool
== Int
0
    then forall a. Monoid a => a
mempty
    else Int -> (Ptr Word8 -> IO Int) -> ByteString
ByteStringInternal.unsafeCreateUptoN (Int
len forall a. Num a => a -> a -> a
* Int
3) forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr -> do
      Ptr Word8
postPtr <- forall a. a -> a
inline Ptr Word8 -> ByteArray# -> CSize -> CSize -> IO (Ptr Word8)
Ffi.encodeText Ptr Word8
ptr ByteArray#
arr (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
off) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
      forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b. Ptr a -> Ptr b -> Int
minusPtr Ptr Word8
postPtr Ptr Word8
ptr)

{-# INLINE pokeInUtf8 #-}
pokeInUtf8 :: Text -> Ptr Word8 -> IO (Ptr Word8)
pokeInUtf8 :: Text -> Ptr Word8 -> IO (Ptr Word8)
pokeInUtf8 (TextInternal.Text (TextArray.Array ByteArray#
arr) Int
off Int
len) Ptr Word8
p =
  Ptr Word8 -> ByteArray# -> CSize -> CSize -> IO (Ptr Word8)
Ffi.encodeText Ptr Word8
p ByteArray#
arr (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
off) (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
#endif