File: zstring.sml

package info (click to toggle)
mlton 20100608-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 34,980 kB
  • ctags: 69,089
  • sloc: ansic: 18,421; lisp: 2,879; makefile: 1,570; sh: 1,325; pascal: 256; asm: 97
file content (66 lines) | stat: -rw-r--r-- 1,839 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
(* zstring.sml
 * 2005 Matthew Fluet (mfluet@acm.org)
 *  Adapted for MLton.
 *)

(*
 * Functions for translating between 0-terminated C strings and native
 * ML strings.
 *
 *  (C) 2001, Lucent Technologies, Bell Laboratories
 *
 * author: Matthias Blume (blume@research.bell-labs.com)
 *)
structure ZString : ZSTRING = struct
    local
        open C
        fun get' p = Get.uchar' (Ptr.|*! p)
        fun set' (p, w) = Set.uchar' (Ptr.|*! p, w)
        fun nxt' p = Ptr.|+! S.uchar (p, 1)
    in
        type 'c zstring = (uchar, 'c) obj ptr
        type 'c zstring' = (uchar, 'c) obj ptr'

        fun length' p = let
            fun loop (n, p) = if get' p = 0w0 then n else loop (n + 1, nxt' p)
        in
            loop (0, p)
        end
        fun length p = length' (Light.ptr p)

        fun toML' p = let
            fun loop (l, p) =
                case get' p of
                    0w0 => String.implode (rev l)
                  | c => loop ((Byte.byteToChar c) :: l, nxt' p)
        in
            loop ([], p)
        end
        fun toML p = toML' (Light.ptr p)

        fun cpML' { from, to } = let
            val n = String.size from
            fun loop (i, p) =
                if i >= n then set' (p, 0w0)
                else (set' (p, Byte.charToByte (String.sub (from, i)));
                      loop (i+1, nxt' p))
        in
            loop (0, to)
        end
        fun cpML { from, to } = cpML' { from = from, to = Light.ptr to }

        fun dupML' s = let
            val z = C.alloc' C.S.uchar (Word.fromInt (size s + 1))
        in
            cpML' { from = s, to = z };
            Ptr.rw' z
        end

        fun dupML s = let
            val z = C.alloc C.T.uchar (Word.fromInt (size s + 1))
        in
            cpML { from = s, to = z };
            Ptr.rw z
        end
    end
end