Import Upstream version 20180207
[hcoop/debian/mlton.git] / lib / mlnlffi-lib / internals / zstring.sml
1 (* zstring.sml
2 * 2005 Matthew Fluet (mfluet@acm.org)
3 * Adapted for MLton.
4 *)
5
6 (*
7 * Functions for translating between 0-terminated C strings and native
8 * ML strings.
9 *
10 * (C) 2001, Lucent Technologies, Bell Laboratories
11 *
12 * author: Matthias Blume (blume@research.bell-labs.com)
13 *)
14 structure ZString : ZSTRING = struct
15 local
16 open C
17 fun get' p = Get.uchar' (Ptr.|*! p)
18 fun set' (p, w) = Set.uchar' (Ptr.|*! p, w)
19 fun nxt' p = Ptr.|+! S.uchar (p, 1)
20 in
21 type 'c zstring = (uchar, 'c) obj ptr
22 type 'c zstring' = (uchar, 'c) obj ptr'
23
24 fun length' p = let
25 fun loop (n, p) = if get' p = 0w0 then n else loop (n + 1, nxt' p)
26 in
27 loop (0, p)
28 end
29 fun length p = length' (Light.ptr p)
30
31 fun toML' p = let
32 fun loop (l, p) =
33 case get' p of
34 0w0 => String.implode (rev l)
35 | c => loop ((Byte.byteToChar c) :: l, nxt' p)
36 in
37 loop ([], p)
38 end
39 fun toML p = toML' (Light.ptr p)
40
41 fun cpML' { from, to } = let
42 val n = String.size from
43 fun loop (i, p) =
44 if i >= n then set' (p, 0w0)
45 else (set' (p, Byte.charToByte (String.sub (from, i)));
46 loop (i+1, nxt' p))
47 in
48 loop (0, to)
49 end
50 fun cpML { from, to } = cpML' { from = from, to = Light.ptr to }
51
52 fun dupML' s = let
53 val z = C.alloc' C.S.uchar (Word.fromInt (size s + 1))
54 in
55 cpML' { from = s, to = z };
56 Ptr.rw' z
57 end
58
59 fun dupML s = let
60 val z = C.alloc C.T.uchar (Word.fromInt (size s + 1))
61 in
62 cpML { from = s, to = z };
63 Ptr.rw z
64 end
65 end
66 end