Analogous to read-unsafe/read-into for streams (and thereby TCP sockets), provide receive-unsafe and receive-into words for datagram sockets that receive into a caller-supplied buffer.
USING: accessors alien.c-types alien.data alien.strings arrays
assocs byte-arrays classes classes.struct combinators
combinators.short-circuit continuations destructors fry generic
-grouping init io.backend io.pathnames io.binary io.encodings
-io.encodings.ascii io.encodings.binary io.ports
-io.streams.duplex kernel math math.parser memoize namespaces
-parser present sequences splitting strings summary system
-vocabs.loader vocabs.parser ;
+grouping init io.backend io.binary io.encodings
+io.encodings.ascii io.encodings.binary io.pathnames io.ports
+io.streams.duplex kernel libc locals math math.parser memoize
+namespaces parser present sequences splitting strings summary
+system unix.ffi values vocabs.loader vocabs.parser ;
IN: io.sockets
<< {
HOOK: (raw) io-backend ( addr -- raw )
-HOOK: (receive) io-backend ( datagram -- packet addrspec )
+HOOK: (receive) io-backend ( n buf datagram -- size addrspec )
ERROR: invalid-port object ;
>>addr
] with-destructors ;
-: receive ( datagram -- packet addrspec )
+: receive-unsafe ( n buf datagram -- count addrspec )
check-receive
- [ (receive) ] [ addr>> ] bi parse-sockaddr ;
+ [ (receive) ] [ addr>> ] bi parse-sockaddr ; inline
+
+CONSTANT: datagram-size 65536
+STRUCT: datagram-buf { buf uchar[datagram-size] } ;
+
+:: receive ( datagram -- packet addrspec )
+ { datagram-buf } [| buf |
+ datagram-size buf datagram
+ receive-unsafe :> ( count addrspec )
+ count [ f f ] [
+ buf swap memory>byte-array addrspec
+ ] if-zero
+ ] with-scoped-allocation ; inline
+
+:: receive-into ( buf datagram -- buf-slice addrspec )
+ buf length :> n
+ n buf datagram receive-unsafe :> ( count addrspec )
+ count [ f f ] [ drop
+ buf count head-slice addrspec
+ ] if-zero ; inline
: send ( packet addrspec datagram -- )
- check-send (send) ;
+ check-send (send) ; inline
MEMO: ipv6-supported? ( -- ? )
[ "::1" 0 <inet6> binary <server> dispose t ] [ drop f ] recover ;
-[ \ ipv6-supported? reset-memoized ] "io.sockets" add-startup-hook
+[ \ ipv6-supported? reset-memoized ]
+"io.sockets:ipv6-supported?" add-startup-hook
GENERIC: resolve-host ( addrspec -- seq )
M: unix (raw)
[ SOCK_RAW server-socket-fd ] with-destructors ;
-SYMBOL: receive-buffer
-
-CONSTANT: packet-size 65536
-
-[ packet-size malloc &free receive-buffer set-global ] "io.sockets.unix" add-startup-hook
-
-:: do-receive ( port -- packet sockaddr )
+:: do-receive ( n buf port -- count sockaddr )
port addr>> empty-sockaddr/size :> ( sockaddr len )
port handle>> handle-fd ! s
- receive-buffer get-global ! buf
- packet-size ! nbytes
+ buf ! buf
+ n ! nbytes
0 ! flags
sockaddr ! from
len int <ref> ! fromlen
- recvfrom dup 0 >=
- [ receive-buffer get-global swap memory>byte-array sockaddr ]
- [ drop f f ]
- if ;
+ recvfrom sockaddr ; inline
+
+: (receive-loop) ( n buf datagram -- count sockaddr )
+ 3dup do-receive over 0 > [ [ 3drop ] 2dip ] [
+ 2drop [ +input+ wait-for-port ] [ (receive-loop) ] bi
+ ] if ; inline recursive
-M: unix (receive) ( datagram -- packet sockaddr )
- dup do-receive dup [ [ drop ] 2dip ] [
- 2drop [ +input+ wait-for-port ] [ (receive) ] bi
- ] if ;
+M: unix (receive) ( n buf datagram -- count sockaddr )
+ (receive-loop) ;
:: do-send ( packet sockaddr len socket datagram -- )
socket handle-fd packet dup length 0 sockaddr len sendto
(io-error)
] if
] if
- ] when ;
+ ] when ; inline recursive
M: unix (send) ( packet addrspec datagram -- )
[ make-sockaddr/size ] [ [ handle>> ] keep ] bi* do-send ;
s lpBuffers dwBufferCount lpNumberOfBytesRecvd\r
lpFlags lpFrom lpFromLen lpOverlapped lpCompletionRoutine ;\r
\r
-: make-receive-buffer ( -- WSABUF )\r
+: make-receive-buffer ( n buf -- WSABUF )\r
WSABUF malloc-struct &free\r
- default-buffer-size get\r
- [ >>len ] [ malloc &free >>buf ] bi ; inline\r
+ n >>len\r
+ buf >>buf ; inline\r
\r
-: <WSARecvFrom-args> ( datagram -- WSARecvFrom )\r
+:: <WSARecvFrom-args> ( n buf datagram -- WSARecvFrom )\r
WSARecvFrom-args new\r
- swap >>port\r
- dup port>> handle>> handle>> >>s\r
- dup port>> addr>> sockaddr-size\r
+ datagram >>port\r
+ datagram handle>> handle>> >>s\r
+ datagram addr>> sockaddr-size\r
[ malloc &free >>lpFrom ]\r
[ malloc-int &free >>lpFromLen ] bi\r
- make-receive-buffer >>lpBuffers\r
+ n buf make-receive-buffer >>lpBuffers\r
1 >>dwBufferCount\r
0 malloc-int &free >>lpFlags\r
0 malloc-int &free >>lpNumberOfBytesRecvd\r
tri memcpy\r
] bi ; inline\r
\r
-M: windows (receive) ( datagram -- packet addrspec )\r
+M: windows (receive) ( n buf datagram -- packet addrspec )\r
[\r
<WSARecvFrom-args>\r
[ call-WSARecvFrom ]\r