1 {-# OPTIONS -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
4 -- Module : Foreign.C.String
5 -- Copyright : (c) The FFI task force 2001
6 -- License : BSD-style (see the file libraries/core/LICENSE)
8 -- Maintainer : ffi@haskell.org
9 -- Stability : provisional
10 -- Portability : portable
12 -- $Id: String.hs,v 1.3 2001/08/17 12:50:34 simonmar Exp $
14 -- Utilities for primitive marshaling
16 -----------------------------------------------------------------------------
18 module Foreign.C.String ( -- representation of strings in C
20 CString, -- = Ptr CChar
21 CStringLen, -- = (CString, Int)
23 -- conversion of C strings into Haskell strings
25 peekCString, -- :: CString -> IO String
26 peekCStringLen, -- :: CStringLen -> IO String
28 -- conversion of Haskell strings into C strings
30 newCString, -- :: String -> IO CString
31 newCStringLen, -- :: String -> IO CStringLen
33 -- conversion of Haskell strings into C strings using temporary storage
35 withCString, -- :: String -> (CString -> IO a) -> IO a
36 withCStringLen, -- :: String -> (CStringLen -> IO a) -> IO a
38 -- conversion between Haskell and C characters *ignoring* the encoding
40 castCharToCChar, -- :: Char -> CChar
41 castCCharToChar, -- :: CChar -> Char
45 import Foreign.Marshal.Array
46 import Foreign.C.Types
51 #ifdef __GLASGOW_HASKELL__
61 -----------------------------------------------------------------------------
64 -- representation of strings in C
65 -- ------------------------------
67 type CString = Ptr CChar -- conventional NUL terminates strings
68 type CStringLen = (CString, Int) -- strings with explicit length
74 -- * the following routines apply the default conversion when converting the
75 -- C-land character encoding into the Haskell-land character encoding
77 -- ** NOTE: The current implementation doesn't handle conversions yet! **
79 -- * the routines using an explicit length tolerate NUL characters in the
83 -- marshal a NUL terminated C string into a Haskell string
85 peekCString :: CString -> IO String
86 peekCString cp = do cs <- peekArray0 nUL cp; return (cCharsToChars cs)
88 -- marshal a C string with explicit length into a Haskell string
90 peekCStringLen :: CStringLen -> IO String
91 peekCStringLen (cp, len) = do cs <- peekArray len cp; return (cCharsToChars cs)
93 -- marshal a Haskell string into a NUL terminated C strings
95 -- * the Haskell string may *not* contain any NUL characters
97 -- * new storage is allocated for the C string and must be explicitly freed
99 newCString :: String -> IO CString
100 newCString = newArray0 nUL . charsToCChars
102 -- marshal a Haskell string into a C string (ie, character array) with
103 -- explicit length information
105 -- * new storage is allocated for the C string and must be explicitly freed
107 newCStringLen :: String -> IO CStringLen
108 newCStringLen str = do a <- newArray (charsToCChars str)
109 return (pairLength str a)
111 -- marshal a Haskell string into a NUL terminated C strings using temporary
114 -- * the Haskell string may *not* contain any NUL characters
116 -- * see the lifetime constraints of `MarshalAlloc.alloca'
118 withCString :: String -> (CString -> IO a) -> IO a
119 withCString = withArray0 nUL . charsToCChars
121 -- marshal a Haskell string into a NUL terminated C strings using temporary
124 -- * the Haskell string may *not* contain any NUL characters
126 -- * see the lifetime constraints of `MarshalAlloc.alloca'
128 withCStringLen :: String -> (CStringLen -> IO a) -> IO a
129 withCStringLen str act = withArray (charsToCChars str) $ act . pairLength str
131 -- auxilliary definitions
132 -- ----------------------
134 -- C's end of string character
139 -- pair a C string with the length of the given Haskell string
141 pairLength :: String -> CString -> CStringLen
142 pairLength = flip (,) . length
144 -- cast [CChar] to [Char]
146 cCharsToChars :: [CChar] -> [Char]
147 cCharsToChars = map castCCharToChar
149 -- cast [Char] to [CChar]
151 charsToCChars :: [Char] -> [CChar]
152 charsToCChars = map castCharToCChar
154 castCCharToChar :: CChar -> Char
155 castCCharToChar ch = unsafeChr (fromIntegral (fromIntegral ch :: Word8))
157 castCharToCChar :: Char -> CChar
158 castCharToCChar ch = fromIntegral (ord ch)