@@ -52,6 +52,7 @@ module Data.Text.Encoding
5252 , encodeUtf8
5353 , encodeUtf8_0
5454 , encodeUtf8_1
55+ , encodeUtf8_2
5556 , encodeUtf16LE
5657 , encodeUtf16BE
5758 , encodeUtf32LE
@@ -101,12 +102,12 @@ import Data.Text.Internal.Unsafe.Shift (shiftL, shiftR)
101102import Data.Text.Internal.Private (runText)
102103import Data.Text.Internal.Unsafe.Char (ord, unsafeWrite)
103104import Data.Word (Word8, Word32)
104−import Foreign.C.Types (CSize)
105+import Foreign.C.Types (CSize(..))
105106import Foreign.ForeignPtr (touchForeignPtr, withForeignPtr)
106107import Foreign.Marshal.Utils (with)
107108import Foreign.Ptr (Ptr, minusPtr, nullPtr, plusPtr)
108109import Foreign.Storable (Storable, peek, poke)
109−import GHC.Base (MutableByteArray#)
110+import GHC.Base (ByteArray#, MutableByteArray#)
110111import qualified Data.Text.Array as A
111112import qualified Data.Text.Internal.Encoding.Fusion as E
112113import qualified Data.Text.Internal.Encoding.Utf16 as U16
@@ -521,6 +522,17 @@ encodeUtf8_1 (Text arr off len)
521522 hot (n+2) (ptr `plusPtr` 4)
522523 hot n0 ptr0
523524
525+encodeUtf8_2 :: Text -> ByteString
526+encodeUtf8_2 (Text arr off len)
527+ | len == 0 = B.empty
528+ | otherwise = unsafeDupablePerformIO $ do
529+ fp <- mallocByteString (len*4)
530+ withForeignPtr fp $ \ptr ->
531+ with ptr $ \destPtr -> do
532+ c_encode_utf8 destPtr (A.aBA arr) (fromIntegral off) (fromIntegral len)
533+ newDest <- peek destPtr
534+ return (PS fp 0 (newDest `minusPtr` ptr))
535+
524536-- | Decode text from little endian UTF-16 encoding.
525537decodeUtf16LEWith :: OnDecodeError -> ByteString -> Text
526538decodeUtf16LEWith onErr bs = F.unstream (E.streamUtf16LE onErr bs)
@@ -608,3 +620,6 @@ foreign import ccall unsafe "_hs_text_decode_utf8_state" c_decode_utf8_with_stat
608620
609621foreign import ccall unsafe "_hs_text_decode_latin1" c_decode_latin1
610622 :: MutableByteArray# s -> Ptr Word8 -> Ptr Word8 -> IO ()
623+
624+foreign import ccall unsafe "_hs_text_encode_utf8" c_encode_utf8
625+ :: Ptr (Ptr Word8) -> ByteArray# -> CSize -> CSize -> IO ()