1(*
2    Title:      Standard Basis Library: Internet Sockets
3    Author:     David Matthews
4    Copyright   David Matthews 2000, 2016
5
6    This library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License version 2.1 as published by the Free Software Foundation.
9    
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14    
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18*)
19
20signature INET_SOCK =
21sig
22    type inet
23
24    type 'sock_type sock = (inet, 'sock_type) Socket.sock
25    type 'mode stream_sock = 'mode Socket.stream sock
26
27    type dgram_sock = Socket.dgram sock
28    type sock_addr = inet Socket.sock_addr
29
30    val inetAF : Socket.AF.addr_family
31    val toAddr : NetHostDB.in_addr * int -> sock_addr
32    val fromAddr : sock_addr -> NetHostDB.in_addr * int
33    val any : int -> sock_addr
34    structure UDP :
35    sig
36        val socket : unit -> dgram_sock
37        val socket' : int -> dgram_sock
38    end
39    structure TCP :
40    sig
41        val socket : unit -> 'mode stream_sock
42        val socket' : int -> 'mode stream_sock
43        val getNODELAY : 'mode stream_sock -> bool
44        val setNODELAY : 'mode stream_sock * bool -> unit
45    end
46end;
47
48structure INetSock :> INET_SOCK =
49struct
50    abstype inet = ABSTRACT with end;
51
52    type 'sock_type sock = (inet, 'sock_type) Socket.sock
53    type 'mode stream_sock = 'mode Socket.stream sock
54
55    type dgram_sock = Socket.dgram sock
56    type sock_addr = inet Socket.sock_addr
57
58    val inetAF : Socket.AF.addr_family =
59        case Socket.AF.fromString "INET" of
60            NONE => raise OS.SysErr("Missing address family", NONE)
61        |   SOME s => s
62
63    local
64        val doCall = RunCall.rtsCallFull2 "PolyNetworkGeneral"
65    in
66        fun toAddr(iaddr: NetHostDB.in_addr, port: int) : sock_addr =
67            doCall(40, (port, iaddr))
68    end
69
70    local
71        val doCall1 = RunCall.rtsCallFull2 "PolyNetworkGeneral"
72        and doCall2 = RunCall.rtsCallFull2 "PolyNetworkGeneral"
73    in
74        fun fromAddr (s: sock_addr) : NetHostDB.in_addr * int =
75            if Socket.familyOfAddr s <> inetAF
76            then raise Match
77            else (doCall1(42, s), doCall2(41, s))
78    end
79
80    local
81        val doCall = RunCall.rtsCallFull2 "PolyNetworkGeneral"
82        val iAddrAny: NetHostDB.in_addr = doCall(13, ())
83    in
84    fun any (p: int) : sock_addr = toAddr(iAddrAny, p)
85    end
86    
87    local
88        val doCall1 = RunCall.rtsCallFull2 "PolyNetworkGeneral"
89        val doCall2 = RunCall.rtsCallFull2 "PolyNetworkGeneral"
90    in
91        structure UDP =
92        struct
93            fun socket () = GenericSock.socket(inetAF, Socket.SOCK.dgram)
94            fun socket' p = GenericSock.socket'(inetAF, Socket.SOCK.dgram, p)
95        end
96
97        structure TCP =
98        struct
99            fun socket () = GenericSock.socket(inetAF, Socket.SOCK.stream)
100            fun socket' p = GenericSock.socket'(inetAF, Socket.SOCK.stream, p)
101
102            fun getNODELAY(s: 'mode stream_sock): bool =
103                doCall1(16, RunCall.unsafeCast s)
104
105            fun setNODELAY (s: 'mode stream_sock, b: bool): unit =
106                doCall2(15, (RunCall.unsafeCast  s, b))
107        end
108    end 
109
110end;
111