[project @ 2001-11-27 14:49:10 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / PrelCString.lhs
1 % -----------------------------------------------------------------------------
2 % $Id: PrelCString.lhs,v 1.6 2001/11/27 14:49:10 simonmar Exp $
3 %
4 % (c) The FFI task force, 2000
5 %
6
7 Utilities for primitive marshaling
8
9 \begin{code}
10 {-# OPTIONS -fno-implicit-prelude #-}
11
12 module PrelCString where
13
14 #ifdef __GLASGOW_HASKELL__
15 import PrelMarshalArray
16 import PrelPtr
17 import PrelStorable
18 import PrelCTypes
19 import PrelWord
20 import PrelList
21 import PrelReal
22 import PrelNum
23 import PrelIOBase
24 import PrelBase
25 #endif
26
27 -----------------------------------------------------------------------------
28 -- Strings
29
30 -- representation of strings in C
31 -- ------------------------------
32
33 type CString    = Ptr CChar             -- conventional NUL terminates strings
34 type CStringLen = (CString, Int)        -- strings with explicit length
35
36
37 -- exported functions
38 -- ------------------
39 --
40 -- * the following routines apply the default conversion when converting the
41 --   C-land character encoding into the Haskell-land character encoding
42 --
43 --   ** NOTE: The current implementation doesn't handle conversions yet! **
44 --
45 -- * the routines using an explicit length tolerate NUL characters in the
46 --   middle of a string
47 --
48
49 -- marshal a NUL terminated C string into a Haskell string 
50 --
51 peekCString    :: CString -> IO String
52 peekCString cp  = do cs <- peekArray0 nUL cp; return (cCharsToChars cs)
53
54 -- marshal a C string with explicit length into a Haskell string 
55 --
56 peekCStringLen           :: CStringLen -> IO String
57 peekCStringLen (cp, len)  = do cs <- peekArray len cp; return (cCharsToChars cs)
58
59 -- marshal a Haskell string into a NUL terminated C strings
60 --
61 -- * the Haskell string may *not* contain any NUL characters
62 --
63 -- * new storage is allocated for the C string and must be explicitly freed
64 --
65 newCString :: String -> IO CString
66 newCString  = newArray0 nUL . charsToCChars
67
68 -- marshal a Haskell string into a C string (ie, character array) with
69 -- explicit length information
70 --
71 -- * new storage is allocated for the C string and must be explicitly freed
72 --
73 newCStringLen     :: String -> IO CStringLen
74 newCStringLen str  = do a <- newArray (charsToCChars str)
75                         return (pairLength str a)
76
77 -- marshal a Haskell string into a NUL terminated C strings using temporary
78 -- storage
79 --
80 -- * the Haskell string may *not* contain any NUL characters
81 --
82 -- * see the lifetime constraints of `MarshalAlloc.alloca'
83 --
84 withCString :: String -> (CString -> IO a) -> IO a
85 withCString  = withArray0 nUL . charsToCChars
86
87 -- marshal a Haskell string into a NUL terminated C strings using temporary
88 -- storage
89 --
90 -- * the Haskell string may *not* contain any NUL characters
91 --
92 -- * see the lifetime constraints of `MarshalAlloc.alloca'
93 --
94 withCStringLen         :: String -> (CStringLen -> IO a) -> IO a
95 withCStringLen str act  = withArray (charsToCChars str) $ act . pairLength str
96
97 -- auxilliary definitions
98 -- ----------------------
99
100 -- C's end of string character
101 --
102 nUL :: CChar
103 nUL  = 0
104
105 -- pair a C string with the length of the given Haskell string
106 --
107 pairLength :: String -> CString -> CStringLen
108 pairLength  = flip (,) . length
109
110 -- cast [CChar] to [Char]
111 --
112 cCharsToChars :: [CChar] -> [Char]
113 cCharsToChars  = map castCCharToChar
114
115 -- cast [Char] to [CChar]
116 --
117 charsToCChars :: [Char] -> [CChar]
118 charsToCChars  = map castCharToCChar
119
120 castCCharToChar :: CChar -> Char
121 castCCharToChar ch = unsafeChr (fromIntegral (fromIntegral ch :: Word8))
122
123 castCharToCChar :: Char -> CChar
124 castCharToCChar ch = fromIntegral (ord ch)
125 \end{code}