Import Upstream version 20180207
[hcoop/debian/mlton.git] / basis-library / util / CUtil.sml
CommitLineData
7f918cf1
CE
1(* Copyright (C) 1999-2008 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 * Copyright (C) 1997-2000 NEC Research Institute.
4 *
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
7 *)
8
9structure CUtil: C_UTIL =
10 struct
11 open Int
12
13 structure Pointer = Primitive.MLton.Pointer
14
15 fun makeLength (sub, term) p =
16 let
17 fun loop i =
18 if term (sub (p, i))
19 then i
20 else loop (i +? 1)
21 in loop 0
22 end
23
24 fun toArrayOfLength (s: 'a,
25 sub: 'a * int -> 'b,
26 n: int) : 'b array =
27 let
28 val (a, _) =
29 Array.unfoldi
30 (n, (), fn (i, ()) =>
31 (sub (s, i), ()))
32 in
33 a
34 end
35
36 structure C_Pointer =
37 struct
38 type t = C_Pointer.t
39 val null = Pointer.toWord Pointer.null
40 fun isNull p = p = null
41 end
42
43 structure C_String =
44 struct
45 type t = C_String.t
46
47 fun sub (cs, i) =
48 Primitive.Char8.idFromWord8
49 (Pointer.getWord8
50 (Pointer.fromWord cs,
51 C_Ptrdiff.fromInt i))
52
53 fun update (cs, i, c) =
54 Pointer.setWord8
55 (Pointer.fromWord cs,
56 C_Ptrdiff.fromInt i,
57 Primitive.Char8.idToWord8 c)
58
59 val length = makeLength (sub, fn #"\000" => true | _ => false)
60
61 fun toCharArrayOfLength (cs, n) =
62 toArrayOfLength (cs, sub, n)
63
64 fun toStringOfLength (cs, n) =
65 String.unsafeFromArray
66 (CharArray.fromPoly (toCharArrayOfLength (cs, n)))
67
68 fun toString cs = toStringOfLength (cs, length cs)
69 end
70
71 structure C_StringArray =
72 struct
73 type t = C_StringArray.t
74
75 fun sub (css: t, i) =
76 (Pointer.toWord o Pointer.getCPointer)
77 (Pointer.fromWord css,
78 C_Ptrdiff.fromInt i)
79
80 val length = makeLength (sub, C_Pointer.isNull)
81
82 val toArrayOfLength =
83 fn (css, n) =>
84 toArrayOfLength (css, C_String.toString o sub, n)
85
86 fun toArray css = toArrayOfLength (css, length css)
87
88 val toList = Array.toList o toArray
89
90 (* The C side converts the last element of the array, "",
91 * to the null terminator that C primitives expect.
92 * As far as C can tell, the other elements of the array
93 * are just char*'s.
94 *)
95 fun fromList l =
96 let
97 val (a, _) =
98 Array.unfoldi
99 (1 +? List.length l, l, fn (_, l) =>
100 case l of
101 [] => (NullString.empty, l)
102 | s::l => (NullString.nullTerm s, l))
103 in
104 a
105 end
106 end
107 end