@@ -21,6 +21,7 @@ module Data.Text.Foreign
21
21
, useAsPtr
22
22
, asForeignPtr
23
23
-- ** Encoding as UTF-8
24
+ , withCString
24
25
, peekCStringLen
25
26
, withCStringLen
26
27
-- * Unsafe conversion code
@@ -40,10 +41,11 @@ import Data.Text.Internal.Unsafe (unsafeWithForeignPtr)
40
41
import Data.Text.Show (addrLen )
41
42
import Data.Text.Unsafe (lengthWord8 )
42
43
import Data.Word (Word8 )
43
- import Foreign.C.String (CStringLen )
44
+ import Foreign.C.String (CString , CStringLen )
44
45
import Foreign.ForeignPtr (ForeignPtr , mallocForeignPtrArray )
45
46
import Foreign.Marshal.Alloc (allocaBytes )
46
47
import Foreign.Ptr (Ptr , castPtr )
48
+ import Foreign.Storable (pokeByteOff )
47
49
import GHC.Exts (Ptr (.. ))
48
50
import qualified Data.Text.Array as A
49
51
@@ -149,6 +151,21 @@ asForeignPtr t@(Text _arr _off len) = do
149
151
unsafeWithForeignPtr fp $ unsafeCopyToPtr t
150
152
return (fp, I8 len)
151
153
154
+ -- | Marshal a 'Text' into a C string with a trailing NUL byte,
155
+ -- encoded as UTF-8 in temporary storage.
156
+ --
157
+ -- The temporary storage is freed when the subcomputation terminates
158
+ -- (either normally or via an exception), so the pointer to the
159
+ -- temporary storage must /not/ be used after this function returns.
160
+ --
161
+ -- @since 2.0.1
162
+ withCString :: Text -> (CString -> IO a ) -> IO a
163
+ withCString t@ (Text _arr _off len) action =
164
+ allocaBytes (len + 1 ) $ \ buf -> do
165
+ unsafeCopyToPtr t buf
166
+ pokeByteOff buf len (0 :: Word8 )
167
+ action (castPtr buf)
168
+
152
169
-- | /O(n)/ Decode a C string with explicit length, which is assumed
153
170
-- to have been encoded as UTF-8. If decoding fails, a
154
171
-- 'UnicodeException' is thrown.
0 commit comments