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