{-# LANGUAGE CPP, GeneralizedNewtypeDeriving, MagicHash #-}
module Data.Text.Foreign
(
I8
, fromPtr
, fromPtr0
, useAsPtr
, asForeignPtr
, withCString
, peekCStringLen
, withCStringLen
, lengthWord8
, unsafeCopyToPtr
, dropWord8
, takeWord8
) where
import Control.Monad.ST.Unsafe (unsafeSTToIO)
import Data.ByteString.Unsafe (unsafePackCStringLen, unsafeUseAsCStringLen)
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import Data.Text.Internal (Text(..), empty)
import Data.Text.Internal.Unsafe (unsafeWithForeignPtr)
import Data.Text.Show (addrLen)
import Data.Text.Unsafe (lengthWord8)
import Data.Word (Word8)
import Foreign.C.String (CString, CStringLen)
import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtrArray)
import Foreign.Marshal.Alloc (allocaBytes)
import Foreign.Ptr (Ptr, castPtr)
import Foreign.Storable (pokeByteOff)
import GHC.Exts (Ptr(..))
import qualified Data.Text.Array as A
newtype I8 = I8 Int
deriving (I8
forall a. a -> a -> Bounded a
maxBound :: I8
$cmaxBound :: I8
minBound :: I8
$cminBound :: I8
Bounded, Int -> I8
I8 -> Int
I8 -> [I8]
I8 -> I8
I8 -> I8 -> [I8]
I8 -> I8 -> I8 -> [I8]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: I8 -> I8 -> I8 -> [I8]
$cenumFromThenTo :: I8 -> I8 -> I8 -> [I8]
enumFromTo :: I8 -> I8 -> [I8]
$cenumFromTo :: I8 -> I8 -> [I8]
enumFromThen :: I8 -> I8 -> [I8]
$cenumFromThen :: I8 -> I8 -> [I8]
enumFrom :: I8 -> [I8]
$cenumFrom :: I8 -> [I8]
fromEnum :: I8 -> Int
$cfromEnum :: I8 -> Int
toEnum :: Int -> I8
$ctoEnum :: Int -> I8
pred :: I8 -> I8
$cpred :: I8 -> I8
succ :: I8 -> I8
$csucc :: I8 -> I8
Enum, I8 -> I8 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: I8 -> I8 -> Bool
$c/= :: I8 -> I8 -> Bool
== :: I8 -> I8 -> Bool
$c== :: I8 -> I8 -> Bool
Eq, Enum I8
Real I8
I8 -> Integer
I8 -> I8 -> (I8, I8)
I8 -> I8 -> I8
forall a.
Real a
-> Enum a
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
toInteger :: I8 -> Integer
$ctoInteger :: I8 -> Integer
divMod :: I8 -> I8 -> (I8, I8)
$cdivMod :: I8 -> I8 -> (I8, I8)
quotRem :: I8 -> I8 -> (I8, I8)
$cquotRem :: I8 -> I8 -> (I8, I8)
mod :: I8 -> I8 -> I8
$cmod :: I8 -> I8 -> I8
div :: I8 -> I8 -> I8
$cdiv :: I8 -> I8 -> I8
rem :: I8 -> I8 -> I8
$crem :: I8 -> I8 -> I8
quot :: I8 -> I8 -> I8
$cquot :: I8 -> I8 -> I8
Integral, Integer -> I8
I8 -> I8
I8 -> I8 -> I8
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> I8
$cfromInteger :: Integer -> I8
signum :: I8 -> I8
$csignum :: I8 -> I8
abs :: I8 -> I8
$cabs :: I8 -> I8
negate :: I8 -> I8
$cnegate :: I8 -> I8
* :: I8 -> I8 -> I8
$c* :: I8 -> I8 -> I8
- :: I8 -> I8 -> I8
$c- :: I8 -> I8 -> I8
+ :: I8 -> I8 -> I8
$c+ :: I8 -> I8 -> I8
Num, Eq I8
I8 -> I8 -> Bool
I8 -> I8 -> Ordering
I8 -> I8 -> I8
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: I8 -> I8 -> I8
$cmin :: I8 -> I8 -> I8
max :: I8 -> I8 -> I8
$cmax :: I8 -> I8 -> I8
>= :: I8 -> I8 -> Bool
$c>= :: I8 -> I8 -> Bool
> :: I8 -> I8 -> Bool
$c> :: I8 -> I8 -> Bool
<= :: I8 -> I8 -> Bool
$c<= :: I8 -> I8 -> Bool
< :: I8 -> I8 -> Bool
$c< :: I8 -> I8 -> Bool
compare :: I8 -> I8 -> Ordering
$ccompare :: I8 -> I8 -> Ordering
Ord, ReadPrec [I8]
ReadPrec I8
Int -> ReadS I8
ReadS [I8]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [I8]
$creadListPrec :: ReadPrec [I8]
readPrec :: ReadPrec I8
$creadPrec :: ReadPrec I8
readList :: ReadS [I8]
$creadList :: ReadS [I8]
readsPrec :: Int -> ReadS I8
$creadsPrec :: Int -> ReadS I8
Read, Num I8
Ord I8
I8 -> Rational
forall a. Num a -> Ord a -> (a -> Rational) -> Real a
toRational :: I8 -> Rational
$ctoRational :: I8 -> Rational
Real, Int -> I8 -> ShowS
[I8] -> ShowS
I8 -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [I8] -> ShowS
$cshowList :: [I8] -> ShowS
show :: I8 -> String
$cshow :: I8 -> String
showsPrec :: Int -> I8 -> ShowS
$cshowsPrec :: Int -> I8 -> ShowS
Show)
fromPtr :: Ptr Word8
-> I8
-> IO Text
fromPtr :: Ptr Word8 -> I8 -> IO Text
fromPtr Ptr Word8
ptr (I8 Int
len) = forall s a. ST s a -> IO a
unsafeSTToIO forall a b. (a -> b) -> a -> b
$ do
MArray Any
dst <- forall s. Int -> ST s (MArray s)
A.new Int
len
forall s. MArray s -> Int -> Ptr Word8 -> Int -> ST s ()
A.copyFromPointer MArray Any
dst Int
0 Ptr Word8
ptr Int
len
Array
arr <- forall s. MArray s -> ST s Array
A.unsafeFreeze MArray Any
dst
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! Array -> Int -> Int -> Text
Text Array
arr Int
0 Int
len
fromPtr0 :: Ptr Word8
-> IO Text
fromPtr0 :: Ptr Word8 -> IO Text
fromPtr0 ptr :: Ptr Word8
ptr@(Ptr Addr#
addr#) = Ptr Word8 -> I8 -> IO Text
fromPtr Ptr Word8
ptr (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Addr# -> Int
addrLen Addr#
addr#))
takeWord8 :: I8 -> Text -> Text
takeWord8 :: I8 -> Text -> Text
takeWord8 = (forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. I8 -> Text -> (Text, Text)
splitAtWord8
dropWord8 :: I8 -> Text -> Text
dropWord8 :: I8 -> Text -> Text
dropWord8 = (forall a b. (a, b) -> b
snd forall b c a. (b -> c) -> (a -> b) -> a -> c
.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. I8 -> Text -> (Text, Text)
splitAtWord8
splitAtWord8 :: I8 -> Text -> (Text, Text)
splitAtWord8 :: I8 -> Text -> (Text, Text)
splitAtWord8 (I8 Int
n) t :: Text
t@(Text Array
arr Int
off Int
len)
| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = (Text
empty, Text
t)
| Int
n forall a. Ord a => a -> a -> Bool
>= Int
len Bool -> Bool -> Bool
|| Int
m forall a. Ord a => a -> a -> Bool
>= Int
len = (Text
t, Text
empty)
| Bool
otherwise = (Array -> Int -> Int -> Text
Text Array
arr Int
off Int
m, Array -> Int -> Int -> Text
Text Array
arr (Int
offforall a. Num a => a -> a -> a
+Int
m) (Int
lenforall a. Num a => a -> a -> a
-Int
m))
where
m :: Int
m | Word8
w0 forall a. Ord a => a -> a -> Bool
< Word8
0x80 = Int
n
| Word8
w0 forall a. Ord a => a -> a -> Bool
>= Word8
0xF0 = Int
nforall a. Num a => a -> a -> a
+Int
3
| Word8
w0 forall a. Ord a => a -> a -> Bool
>= Word8
0xE0 = Int
nforall a. Num a => a -> a -> a
+Int
2
| Word8
w0 forall a. Ord a => a -> a -> Bool
>= Word8
0xC0 = Int
nforall a. Num a => a -> a -> a
+Int
1
| Word8
w1 forall a. Ord a => a -> a -> Bool
>= Word8
0xF0 = Int
nforall a. Num a => a -> a -> a
+Int
2
| Word8
w1 forall a. Ord a => a -> a -> Bool
>= Word8
0xE0 = Int
nforall a. Num a => a -> a -> a
+Int
1
| Word8
w1 forall a. Ord a => a -> a -> Bool
>= Word8
0xC0 = Int
n
| Word8
w2 forall a. Ord a => a -> a -> Bool
>= Word8
0xF0 = Int
nforall a. Num a => a -> a -> a
+Int
1
| Bool
otherwise = Int
n
w0 :: Word8
w0 = Array -> Int -> Word8
A.unsafeIndex Array
arr (Int
offforall a. Num a => a -> a -> a
+Int
nforall a. Num a => a -> a -> a
-Int
1)
w1 :: Word8
w1 = Array -> Int -> Word8
A.unsafeIndex Array
arr (Int
offforall a. Num a => a -> a -> a
+Int
nforall a. Num a => a -> a -> a
-Int
2)
w2 :: Word8
w2 = Array -> Int -> Word8
A.unsafeIndex Array
arr (Int
offforall a. Num a => a -> a -> a
+Int
nforall a. Num a => a -> a -> a
-Int
3)
unsafeCopyToPtr :: Text -> Ptr Word8 -> IO ()
unsafeCopyToPtr :: Text -> Ptr Word8 -> IO ()
unsafeCopyToPtr (Text Array
arr Int
off Int
len) Ptr Word8
ptr = forall s a. ST s a -> IO a
unsafeSTToIO forall a b. (a -> b) -> a -> b
$ forall s. Array -> Int -> Ptr Word8 -> Int -> ST s ()
A.copyToPointer Array
arr Int
off Ptr Word8
ptr Int
len
useAsPtr :: Text -> (Ptr Word8 -> I8 -> IO a) -> IO a
useAsPtr :: forall a. Text -> (Ptr Word8 -> I8 -> IO a) -> IO a
useAsPtr t :: Text
t@(Text Array
_arr Int
_off Int
len) Ptr Word8 -> I8 -> IO a
action =
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
len forall a b. (a -> b) -> a -> b
$ \Ptr Word8
buf -> do
Text -> Ptr Word8 -> IO ()
unsafeCopyToPtr Text
t Ptr Word8
buf
Ptr Word8 -> I8 -> IO a
action (forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
buf) (Int -> I8
I8 Int
len)
asForeignPtr :: Text -> IO (ForeignPtr Word8, I8)
asForeignPtr :: Text -> IO (ForeignPtr Word8, I8)
asForeignPtr t :: Text
t@(Text Array
_arr Int
_off Int
len) = do
ForeignPtr Word8
fp <- forall a. Storable a => Int -> IO (ForeignPtr a)
mallocForeignPtrArray Int
len
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
unsafeWithForeignPtr ForeignPtr Word8
fp forall a b. (a -> b) -> a -> b
$ Text -> Ptr Word8 -> IO ()
unsafeCopyToPtr Text
t
forall (m :: * -> *) a. Monad m => a -> m a
return (ForeignPtr Word8
fp, Int -> I8
I8 Int
len)
withCString :: Text -> (CString -> IO a) -> IO a
withCString :: forall a. Text -> (CString -> IO a) -> IO a
withCString t :: Text
t@(Text Array
_arr Int
_off Int
len) CString -> IO a
action =
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes (Int
len forall a. Num a => a -> a -> a
+ Int
1) forall a b. (a -> b) -> a -> b
$ \Ptr Word8
buf -> do
Text -> Ptr Word8 -> IO ()
unsafeCopyToPtr Text
t Ptr Word8
buf
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
pokeByteOff Ptr Word8
buf Int
len (Word8
0 :: Word8)
CString -> IO a
action (forall a b. Ptr a -> Ptr b
castPtr Ptr Word8
buf)
peekCStringLen :: CStringLen -> IO Text
peekCStringLen :: CStringLen -> IO Text
peekCStringLen CStringLen
cs = do
ByteString
bs <- CStringLen -> IO ByteString
unsafePackCStringLen CStringLen
cs
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$! ByteString -> Text
decodeUtf8 ByteString
bs
withCStringLen :: Text -> (CStringLen -> IO a) -> IO a
withCStringLen :: forall a. Text -> (CStringLen -> IO a) -> IO a
withCStringLen Text
t CStringLen -> IO a
act = forall a. ByteString -> (CStringLen -> IO a) -> IO a
unsafeUseAsCStringLen (Text -> ByteString
encodeUtf8 Text
t) CStringLen -> IO a
act