1 % -----------------------------------------------------------------------------
2 % $Id: PrelCString.lhs,v 1.3 2001/04/14 22:28:46 qrczak Exp $
4 % (c) The FFI task force, 2000
7 Utilities for primitive marshaling
10 module PrelCString where
14 import PrelMarshalArray
23 #ifdef __GLASGOW_HASKELL__
24 import PrelIOBase hiding (malloc, _malloc)
27 -----------------------------------------------------------------------------
30 -- representation of strings in C
31 -- ------------------------------
33 type CString = Ptr CChar -- conventional NUL terminates strings
34 type CStringLen = (CString, Int) -- strings with explicit length
40 -- * the following routines apply the default conversion when converting the
41 -- C-land character encoding into the Haskell-land character encoding
43 -- ** NOTE: The current implementation doesn't handle conversions yet! **
45 -- * the routines using an explicit length tolerate NUL characters in the
49 -- marshal a NUL terminated C string into a Haskell string
51 peekCString :: CString -> IO String
52 peekCString cp = liftM cCharsToChars $ peekArray0 nUL cp
54 -- marshal a C string with explicit length into a Haskell string
56 peekCStringLen :: CStringLen -> IO String
57 peekCStringLen (cp, len) = liftM cCharsToChars $ peekArray len cp
59 -- marshal a Haskell string into a NUL terminated C strings
61 -- * the Haskell string may *not* contain any NUL characters
63 -- * new storage is allocated for the C string and must be explicitly freed
65 newCString :: String -> IO CString
66 newCString = newArray0 nUL . charsToCChars
68 -- marshal a Haskell string into a C string (ie, character array) with
69 -- explicit length information
71 -- * new storage is allocated for the C string and must be explicitly freed
73 newCStringLen :: String -> IO CStringLen
74 newCStringLen str = liftM (pairLength str) $ newArray (charsToCChars str)
76 -- marshal a Haskell string into a NUL terminated C strings using temporary
79 -- * the Haskell string may *not* contain any NUL characters
81 -- * see the lifetime constraints of `MarshalAlloc.alloca'
83 withCString :: String -> (CString -> IO a) -> IO a
84 withCString = withArray0 nUL . charsToCChars
86 -- marshal a Haskell string into a NUL terminated C strings using temporary
89 -- * the Haskell string may *not* contain any NUL characters
91 -- * see the lifetime constraints of `MarshalAlloc.alloca'
93 withCStringLen :: String -> (CStringLen -> IO a) -> IO a
94 withCStringLen str act = withArray (charsToCChars str) $ act . pairLength str
96 -- auxilliary definitions
97 -- ----------------------
99 -- C's end of string character
104 -- pair a C string with the length of the given Haskell string
106 pairLength :: String -> CString -> CStringLen
107 pairLength = flip (,) . length
109 -- cast [CChar] to [Char]
111 cCharsToChars :: [CChar] -> [Char]
112 cCharsToChars = map castCCharToChar
114 -- cast [Char] to [CChar]
116 charsToCChars :: [Char] -> [CChar]
117 charsToCChars = map castCharToCChar
119 castCCharToChar :: CChar -> Char
120 castCCharToChar ch = unsafeChr (fromIntegral (fromIntegral ch :: Word8))
122 castCharToCChar :: Char -> CChar
123 castCharToCChar ch = fromIntegral (ord ch)
129 withUnsafeCString :: String -> (UnsafeCString -> IO a) -> IO a
130 #if __GLASGOW_HASKELL__
131 newtype UnsafeCString = UnsafeCString (ByteArray Int)
132 withUnsafeCString s f = f (UnsafeCString (packString s))
134 newtype UnsafeCString = UnsafeCString (Ptr CChar)
135 withUnsafeCString s f = withCString s (\p -> f (UnsafeCString p))