Home My Page Projects Code Snippets Project Openings 3D graphics for Standard ML
Summary Activity SCM

SCM Repository

[sml3d] Annotation of /trunk/sml3d/src/raw-data/c-string.sml
ViewVC logotype

Annotation of /trunk/sml3d/src/raw-data/c-string.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1467 - (view) (download)

1 : jhr 659 (* c-string.sml
2 :     *
3 :     * COPYRIGHT (c) 2006 John Reppy (http://www.cs.uchicago.edu/~jhr)
4 :     * All rights reserved.
5 :     *
6 :     * Utility code for manipulating C strings. Use these operations
7 :     * with care, since ill-formed C strings can cause bad things (TM)
8 :     * to happen.
9 :     *)
10 :    
11 :     signature C_STRING =
12 :     sig
13 : jhr 733 type c_string = CPtr.t
14 : jhr 659
15 : jhr 1467 val sub : c_string * int -> char
16 :    
17 : jhr 659 (* the length of a null-terminated C string *)
18 :     val strlen : c_string -> int
19 :    
20 : jhr 1467 (* extract an SML string of the given length from a C string. Note that this function
21 :     * does _not_ check for overruns, so use with care!!
22 :     *)
23 :     val extract : c_string * int -> string
24 :    
25 : jhr 733 (* convert a C string to an ML string; null pointers map to "" *)
26 :     val toString : c_string -> string
27 : jhr 659
28 : jhr 662 (* given a contiguous sequence of C strings terminated by an empty string,
29 : jhr 659 * convert them to a list of SML strings.
30 :     *)
31 :     val cstringsToML : c_string -> string list
32 :    
33 : jhr 1467 (* reader for C strings; returns NONE when the terminating nul is encountered *)
34 :     val getc : c_string -> (char * c_string) option
35 :    
36 : jhr 893 (* allocate and initialize a string in the C heap from an ML string *)
37 : jhr 662 val fromString : string -> c_string
38 : jhr 659
39 : jhr 893 (* allocate and initialize a string in the C heap from a list of ML strings *)
40 : jhr 662 val fromStringList : string list -> c_string
41 :    
42 : jhr 659 end
43 :    
44 : jhr 662 structure CString :> C_STRING =
45 : jhr 659 struct
46 :    
47 : jhr 733 type c_string = CPtr.t
48 : jhr 659
49 : jhr 733 fun getChar (s, i) = Byte.byteToChar (CPtr.getWord8 (s, CPtrDiff.fromInt i))
50 :     fun setChar (s, i, c) = CPtr.setWord8(s, CPtrDiff.fromInt i, Byte.charToByte c)
51 : jhr 659
52 : jhr 1467 val sub = getChar
53 :    
54 : jhr 733 (* compute the length of a nul-terminated C string *)
55 : jhr 659 fun strlen s = let
56 :     fun lp n = if getChar(s, n) = #"\000" then n else lp(n+1)
57 :     in
58 :     lp 0
59 :     end
60 :    
61 : jhr 1467 fun extract (s, n) = CharVector.tabulate (n, fn i => getChar (s, i))
62 :    
63 : jhr 659 (* convert an C pointer to an SML string value *)
64 : jhr 733 fun toString (s : c_string) = if (s = CPtr.null)
65 :     then ""
66 : jhr 1467 else extract (s, strlen s)
67 : jhr 659
68 : jhr 1467 (* given a contiguous sequence of C strings terminated by an empty string,
69 : jhr 659 * convert them to a list of SML strings.
70 :     *)
71 :     fun cstringsToML (s : c_string) = let
72 :     fun lp p = let
73 :     val n = strlen p
74 :     in
75 :     if (n = 0) then []
76 : jhr 1467 else extract(p, n) :: lp(CPtr.add(p, CPtrDiff.fromInt(n+1)))
77 : jhr 659 end
78 :     in
79 :     lp s
80 :     end
81 :    
82 : jhr 1467 (* reader for C strings; returns NONE when the terminating nul is encountered *)
83 :     fun getc (s : c_string) = (case getChar(s, 0)
84 :     of #"\000" => NONE
85 :     | c => SOME(c, CPtr.add(s, 1))
86 :     (* end case *))
87 :    
88 : jhr 659 (* allocate an initialize a string in the C heap *)
89 : jhr 662 fun fromString s = let
90 : jhr 733 val ptr = CAlloc.malloc(CSize.fromInt(size s + 1))
91 : jhr 659 in
92 : jhr 733 CharVector.appi (fn (i, c) => setChar (ptr, i, c)) s;
93 :     CPtr.setWord8 (ptr, CPtrDiff.fromInt(size s), 0w0);
94 : jhr 659 ptr
95 :     end
96 :    
97 : jhr 662 (* allocate an initialize a string in the C heap from a list of ML strings *)
98 :     fun fromStringList l = let
99 : jhr 733 val len = List.foldl (fn (s, n) => size s + 1) 1 l (* length + 1 for \0 *)
100 :     val ptr = CAlloc.malloc(CSize.fromInt len)
101 : jhr 662 fun lp ([], _) = ()
102 :     | lp (s::r, i) = (
103 : jhr 733 CharVector.appi (fn (j, c) => setChar(ptr, i+j, c)) s;
104 : jhr 811 lp (r, i + size s))
105 : jhr 662 in
106 :     lp (l, 0);
107 : jhr 733 CPtr.setWord8 (ptr, CPtrDiff.fromInt len, 0w0);
108 : jhr 662 ptr
109 :     end
110 :    
111 : jhr 659 end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0