656b18f5c33de5f9b21db7c3a9d0dab8bbde2ae6
[ghc-base.git] / Foreign / C / String.hs
1 {-# OPTIONS -fno-implicit-prelude #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module      :  Foreign.C.String
5 -- Copyright   :  (c) The FFI task force 2001
6 -- License     :  BSD-style (see the file libraries/base/LICENSE)
7 -- 
8 -- Maintainer  :  ffi@haskell.org
9 -- Stability   :  provisional
10 -- Portability :  portable
11 --
12 -- Utilities for primitive marshaling
13 --
14 -----------------------------------------------------------------------------
15
16 module Foreign.C.String (   -- representation of strings in C
17
18   CString,           -- = Ptr CChar
19   CStringLen,        -- = (CString, Int)
20
21   -- conversion of C strings into Haskell strings
22   --
23   peekCString,       -- :: CString    -> IO String
24   peekCStringLen,    -- :: CStringLen -> IO String
25
26   -- conversion of Haskell strings into C strings
27   --
28   newCString,        -- :: String -> IO CString
29   newCStringLen,     -- :: String -> IO CStringLen
30
31   -- conversion of Haskell strings into C strings using temporary storage
32   --
33   withCString,       -- :: String -> (CString    -> IO a) -> IO a
34   withCStringLen,    -- :: String -> (CStringLen -> IO a) -> IO a
35
36   -- conversion between Haskell and C characters *ignoring* the encoding
37   --
38   castCharToCChar,   -- :: Char -> CChar
39   castCCharToChar,   -- :: CChar -> Char
40
41   ) where
42
43 import Foreign.Marshal.Array
44 import Foreign.C.Types
45 import Foreign.Ptr
46
47 import Data.Word
48
49 #ifdef __GLASGOW_HASKELL__
50 import GHC.List
51 import GHC.Real
52 import GHC.Num
53 import GHC.IOBase
54 import GHC.Base
55 #else
56 import Char ( chr, ord )
57 #define unsafeChr chr
58 #endif
59
60 -----------------------------------------------------------------------------
61 -- Strings
62
63 -- representation of strings in C
64 -- ------------------------------
65
66 type CString    = Ptr CChar             -- conventional NUL terminates strings
67 type CStringLen = (CString, Int)        -- strings with explicit length
68
69
70 -- exported functions
71 -- ------------------
72 --
73 -- * the following routines apply the default conversion when converting the
74 --   C-land character encoding into the Haskell-land character encoding
75 --
76 --   ** NOTE: The current implementation doesn't handle conversions yet! **
77 --
78 -- * the routines using an explicit length tolerate NUL characters in the
79 --   middle of a string
80 --
81
82 -- marshal a NUL terminated C string into a Haskell string 
83 --
84 peekCString    :: CString -> IO String
85 peekCString cp  = do cs <- peekArray0 nUL cp; return (cCharsToChars cs)
86
87 -- marshal a C string with explicit length into a Haskell string 
88 --
89 peekCStringLen           :: CStringLen -> IO String
90 peekCStringLen (cp, len)  = do cs <- peekArray len cp; return (cCharsToChars cs)
91
92 -- marshal a Haskell string into a NUL terminated C strings
93 --
94 -- * the Haskell string may *not* contain any NUL characters
95 --
96 -- * new storage is allocated for the C string and must be explicitly freed
97 --
98 newCString :: String -> IO CString
99 newCString  = newArray0 nUL . charsToCChars
100
101 -- marshal a Haskell string into a C string (ie, character array) with
102 -- explicit length information
103 --
104 -- * new storage is allocated for the C string and must be explicitly freed
105 --
106 newCStringLen     :: String -> IO CStringLen
107 newCStringLen str  = do a <- newArray (charsToCChars str)
108                         return (pairLength str a)
109
110 -- marshal a Haskell string into a NUL terminated C strings using temporary
111 -- storage
112 --
113 -- * the Haskell string may *not* contain any NUL characters
114 --
115 -- * see the lifetime constraints of `MarshalAlloc.alloca'
116 --
117 withCString :: String -> (CString -> IO a) -> IO a
118 withCString  = withArray0 nUL . charsToCChars
119
120 -- marshal a Haskell string into a NUL terminated C strings using temporary
121 -- storage
122 --
123 -- * the Haskell string may *not* contain any NUL characters
124 --
125 -- * see the lifetime constraints of `MarshalAlloc.alloca'
126 --
127 withCStringLen         :: String -> (CStringLen -> IO a) -> IO a
128 withCStringLen str act  = withArray (charsToCChars str) $ act . pairLength str
129
130 -- auxilliary definitions
131 -- ----------------------
132
133 -- C's end of string character
134 --
135 nUL :: CChar
136 nUL  = 0
137
138 -- pair a C string with the length of the given Haskell string
139 --
140 pairLength :: String -> CString -> CStringLen
141 pairLength  = flip (,) . length
142
143 -- cast [CChar] to [Char]
144 --
145 cCharsToChars :: [CChar] -> [Char]
146 cCharsToChars  = map castCCharToChar
147
148 -- cast [Char] to [CChar]
149 --
150 charsToCChars :: [Char] -> [CChar]
151 charsToCChars  = map castCharToCChar
152
153 castCCharToChar :: CChar -> Char
154 castCCharToChar ch = unsafeChr (fromIntegral (fromIntegral ch :: Word8))
155
156 castCharToCChar :: Char -> CChar
157 castCharToCChar ch = fromIntegral (ord ch)