4 | module Network.Socket
6 | import public Network.Socket.Data
7 | import Network.Socket.Raw
11 | import Data.SnocList
19 | => (fam : SocketFamily)
20 | -> (ty : SocketType)
21 | -> (pnum : ProtocolNumber)
22 | -> io (Either SocketError Socket)
23 | socket sf st pn = do
24 | socket_res <- primIO $
prim__idrnet_socket (toCode sf) (toCode st) pn
27 | then map Left getErrno
28 | else pure $
Right (MkSocket socket_res sf st pn)
32 | close : HasIO io => Socket -> io ()
33 | close sock = do _ <- primIO $
prim__idrnet_close $
descriptor sock
41 | -> (addr : Maybe SocketAddress)
44 | bind sock addr port = do
45 | bind_res <- primIO $
prim__idrnet_bind
47 | (toCode $
family sock)
48 | (toCode $
socketType sock)
56 | saString : Maybe SocketAddress -> String
57 | saString (Just sa) = show sa
58 | saString Nothing = ""
65 | -> (addr : SocketAddress)
68 | connect sock addr port = do
69 | conn_res <- primIO $
prim__idrnet_connect
70 | (descriptor sock) (toCode $
family sock) (toCode $
socketType sock) (show addr) port
80 | listen : HasIO io => (sock : Socket) -> io Int
82 | listen_res <- primIO $
prim__idrnet_listen (descriptor sock) BACKLOG
83 | if listen_res == (-
1)
98 | -> io (Either SocketError (Socket, SocketAddress))
104 | sockaddr_ptr <- primIO prim__idrnet_create_sockaddr
106 | accept_res <- primIO $
prim__idrnet_accept (descriptor sock) sockaddr_ptr
107 | if accept_res == (-
1)
108 | then map Left getErrno
110 | let (MkSocket _ fam ty p_num) = sock
111 | sockaddr <- getSockAddr (SAPtr sockaddr_ptr)
112 | sockaddr_free (SAPtr sockaddr_ptr)
113 | pure $
Right ((MkSocket accept_res fam ty p_num), sockaddr)
126 | -> io (Either SocketError ResultCode)
128 | send_res <- primIO $
prim__idrnet_send (descriptor sock) dat
130 | if send_res == (-
1)
131 | then map Left getErrno
132 | else pure $
Right send_res
146 | -> (len : ByteLength)
147 | -> io (Either SocketError (String, ResultCode))
151 | recv_struct_ptr <- primIO $
prim__idrnet_recv (descriptor sock) len
152 | recv_res <- primIO $
prim__idrnet_get_recv_res recv_struct_ptr
154 | if recv_res == (-
1)
157 | freeRecvStruct (RSPtr recv_struct_ptr)
162 | freeRecvStruct (RSPtr recv_struct_ptr)
165 | payload <- primIO $
prim__idrnet_get_recv_payload recv_struct_ptr
166 | freeRecvStruct (RSPtr recv_struct_ptr)
167 | pure $
Right (payload, recv_res)
169 | recvAllRec : (Monoid a, HasIO io) => io (Either SocketError a) -> SnocList a -> io (Either SocketError a)
170 | recvAllRec recv_from_socket acc = case !recv_from_socket of
171 | Left 0 => pure (Right $
concat acc)
172 | Left c => pure (Left c)
173 | Right str => recvAllRec recv_from_socket (acc :< str)
182 | recvAll : HasIO io => (sock : Socket) -> io (Either SocketError String)
183 | recvAll sock = recvAllRec {a=String} (mapSnd fst <$> recv sock 65536) [<]
197 | -> (addr : SocketAddress)
200 | -> io (Either SocketError ByteLength)
201 | sendTo sock addr p dat = do
202 | sendto_res <- primIO $
prim__idrnet_sendto
203 | (descriptor sock) dat (show addr) p (toCode $
family sock)
205 | if sendto_res == (-
1)
206 | then map Left getErrno
207 | else pure $
Right sendto_res
221 | recvFrom : HasIO io
223 | -> (len : ByteLength)
224 | -> io (Either SocketError (UDPAddrInfo, String, ResultCode))
225 | recvFrom sock bl = do
226 | recv_ptr <- primIO $
prim__idrnet_recvfrom
227 | (descriptor sock) bl
229 | let recv_ptr' = RFPtr recv_ptr
230 | isNull <- (nullPtr recv_ptr)
232 | then map Left getErrno
234 | result <- primIO $
prim__idrnet_get_recvfrom_res recv_ptr
237 | freeRecvfromStruct recv_ptr'
240 | payload <- foreignGetRecvfromPayload recv_ptr'
241 | port <- foreignGetRecvfromPort recv_ptr'
242 | addr <- foreignGetRecvfromAddr recv_ptr'
243 | freeRecvfromStruct recv_ptr'
244 | pure $
Right (MkUDPAddrInfo addr port, payload, result)
254 | sendBytes : HasIO m => Socket -> List Bits8 -> m (Either SocketError Int)
255 | sendBytes sock bytes = do
256 | let len' = cast $
length bytes
257 | Just buffer <- newBuffer len'
258 | | Nothing => assert_total $
idris_crash "INTERNAL ERROR: sendBytes -> somehow newBuffer failed"
259 | traverse_ (uncurry (setBits8 buffer)) (zip [0..len'] bytes)
260 | ret <- primIO $
prim__idrnet_send_bytes sock.descriptor buffer len' 0
262 | True => pure $
Left ret
263 | False => pure $
Right ret
275 | recvBytes : HasIO m => Socket -> (max_size : ByteLength) -> m (Either SocketError (List Bits8))
276 | recvBytes sock max_size = do
277 | Just buffer <- newBuffer max_size
278 | | Nothing => pure $
Left (-
1)
279 | ret <- primIO $
prim__idrnet_recv_bytes sock.descriptor buffer max_size 0
284 | bytes <- traverse (getBits8 buffer) [0..((cast ret)-1)]
285 | pure $
Right $
toList bytes
295 | recvAllBytes : HasIO io => (sock : Socket) -> io (Either SocketError (List Bits8))
296 | recvAllBytes sock = recvAllRec {a=List Bits8} (recvBytes sock 65536) [<]