Skip to content

Commit 3517e18

Browse files
dpwizBodigrim
authored andcommitted
Add withCString
1 parent 3649ea9 commit 3517e18

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

src/Data/Text/Foreign.hs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module Data.Text.Foreign
2121
, useAsPtr
2222
, asForeignPtr
2323
-- ** Encoding as UTF-8
24+
, withCString
2425
, peekCStringLen
2526
, withCStringLen
2627
-- * Unsafe conversion code
@@ -40,10 +41,11 @@ import Data.Text.Internal.Unsafe (unsafeWithForeignPtr)
4041
import Data.Text.Show (addrLen)
4142
import Data.Text.Unsafe (lengthWord8)
4243
import Data.Word (Word8)
43-
import Foreign.C.String (CStringLen)
44+
import Foreign.C.String (CString, CStringLen)
4445
import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtrArray)
4546
import Foreign.Marshal.Alloc (allocaBytes)
4647
import Foreign.Ptr (Ptr, castPtr)
48+
import Foreign.Storable (pokeByteOff)
4749
import GHC.Exts (Ptr(..))
4850
import qualified Data.Text.Array as A
4951

@@ -149,6 +151,21 @@ asForeignPtr t@(Text _arr _off len) = do
149151
unsafeWithForeignPtr fp $ unsafeCopyToPtr t
150152
return (fp, I8 len)
151153

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+
152169
-- | /O(n)/ Decode a C string with explicit length, which is assumed
153170
-- to have been encoded as UTF-8. If decoding fails, a
154171
-- 'UnicodeException' is thrown.

0 commit comments

Comments
 (0)