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