blob: 662d2eddd18d2982b45fea50863adc45f998793d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE UnliftedFFITypes #-}
module EscapeXML (escapeXML) where
import Data.Array.Byte
import Data.Text.Internal
import Foreign.C.Types
import GHC.Exts
import GHC.IO (IO(IO))
import System.IO.Unsafe (unsafePerformIO)
foreign import ccall unsafe "tirclogv_escapexml_len"
c_escapexml_len :: ByteArray# -> CSize -> CSize -> IO CSize
foreign import ccall unsafe "tirclogv_escapexml"
c_escapexml :: MutableByteArray# RealWorld -> ByteArray# -> CSize -> CSize -> IO ()
{-# NOINLINE escapeXML #-}
escapeXML :: Text -> Text
escapeXML (Text (ByteArray src#) off len) = unsafePerformIO $ do
let offCS = fromIntegral @Int @CSize off
lenCS = fromIntegral @Int @CSize len
reslen <- c_escapexml_len src# offCS lenCS
let !reslenI@(I# reslen#) = fromIntegral @CSize @Int reslen
MutableByteArray dst# <-
IO $ \s -> case newByteArray# reslen# s of
(# s', mba# #) -> (# s', MutableByteArray mba# #)
c_escapexml dst# src# offCS lenCS
ba <- IO $ \s -> case unsafeFreezeByteArray# dst# s of
(# s', ba# #) -> (# s', ByteArray ba# #)
return (Text ba 0 reslenI)
|