factor/extra/io/windows/nt/sockets/sockets.factor

266 lines
8.6 KiB
Factor
Raw Normal View History

2007-09-20 18:09:08 -04:00
USING: alien alien.c-types byte-arrays continuations destructors
2007-11-09 10:33:25 -05:00
io.nonblocking io io.sockets io.sockets.impl namespaces
2008-01-05 19:37:13 -05:00
io.streams.duplex io.windows io.windows.nt.backend
2007-09-20 18:09:08 -04:00
windows.winsock kernel libc math sequences threads tuples.lib ;
IN: io.windows.nt.sockets
: malloc-int ( object -- object )
"int" heap-size malloc tuck 0 set-alien-signed-4 ; inline
M: windows-nt-io WSASocket-flags ( -- DWORD )
WSA_FLAG_OVERLAPPED ;
: get-ConnectEx-ptr ( socket -- void* )
SIO_GET_EXTENSION_FUNCTION_POINTER
WSAID_CONNECTEX
"GUID" heap-size
"void*" <c-object>
[
"void*" heap-size
"DWORD" <c-object>
f
f
WSAIoctl SOCKET_ERROR = [
winsock-error-string throw
] when
] keep *void* ;
TUPLE: ConnectEx-args port
s* name* namelen* lpSendBuffer* dwSendDataLength*
lpdwBytesSent* lpOverlapped* ptr* ;
: init-connect ( sockaddr size ConnectEx -- )
2007-09-20 18:09:08 -04:00
[ set-ConnectEx-args-namelen* ] keep
[ set-ConnectEx-args-name* ] keep
f over set-ConnectEx-args-lpSendBuffer*
0 over set-ConnectEx-args-dwSendDataLength*
f over set-ConnectEx-args-lpdwBytesSent*
(make-overlapped) swap set-ConnectEx-args-lpOverlapped* ;
: (ConnectEx) ( ConnectEx -- )
\ ConnectEx-args >tuple*<
"int"
{ "SOCKET" "sockaddr_in*" "int" "PVOID" "DWORD" "LPDWORD" "void*" }
"stdcall" alien-indirect drop
winsock-error-string [ throw ] when* ;
: connect-continuation ( ConnectEx -- )
2008-01-28 00:59:36 -05:00
dup ConnectEx-args-lpOverlapped*
swap ConnectEx-args-port duplex-stream-in
[ save-callback ] 2keep
get-overlapped-result drop ;
2007-09-20 18:09:08 -04:00
M: windows-nt-io (client) ( addrspec -- duplex-stream )
[
\ ConnectEx-args construct-empty
over make-sockaddr/size pick init-connect
2007-09-20 18:09:08 -04:00
over tcp-socket over set-ConnectEx-args-s*
dup ConnectEx-args-s* add-completion
dup ConnectEx-args-s* get-ConnectEx-ptr over set-ConnectEx-args-ptr*
dup ConnectEx-args-s* INADDR_ANY roll bind-socket
dup (ConnectEx)
dup ConnectEx-args-s* <win32-socket> dup handle>duplex-stream
over set-ConnectEx-args-port
dup connect-continuation
ConnectEx-args-port
[ duplex-stream-in pending-error ] keep
[ duplex-stream-out pending-error ] keep
] with-destructors ;
TUPLE: AcceptEx-args port
sListenSocket* sAcceptSocket* lpOutputBuffer* dwReceiveDataLength*
dwLocalAddressLength* dwRemoteAddressLength* lpdwBytesReceived* lpOverlapped* ;
: init-accept-buffer ( server-port AcceptEx -- )
>r server-port-addr sockaddr-type heap-size 16 +
dup dup 2 * malloc dup free-always r>
2007-09-20 18:09:08 -04:00
[ set-AcceptEx-args-lpOutputBuffer* ] keep
[ set-AcceptEx-args-dwLocalAddressLength* ] keep
set-AcceptEx-args-dwRemoteAddressLength* ;
: init-accept ( server-port AcceptEx -- )
[ init-accept-buffer ] 2keep
[ set-AcceptEx-args-port ] 2keep
>r port-handle win32-file-handle r> [ set-AcceptEx-args-sListenSocket* ] keep
dup AcceptEx-args-port server-port-addr tcp-socket
over set-AcceptEx-args-sAcceptSocket*
0 over set-AcceptEx-args-dwReceiveDataLength*
f over set-AcceptEx-args-lpdwBytesReceived*
2008-01-28 00:59:36 -05:00
(make-overlapped) swap set-AcceptEx-args-lpOverlapped* ;
2007-09-20 18:09:08 -04:00
: (accept) ( AcceptEx -- )
\ AcceptEx-args >tuple*<
AcceptEx drop
winsock-error-string [ throw ] when* ;
: make-accept-continuation ( AcceptEx -- )
2008-01-28 00:59:36 -05:00
dup AcceptEx-args-lpOverlapped*
swap AcceptEx-args-port save-callback ;
2007-09-20 18:09:08 -04:00
: check-accept-error ( AcceptEx -- )
2008-01-28 00:59:36 -05:00
dup AcceptEx-args-lpOverlapped*
swap AcceptEx-args-port get-overlapped-result drop ;
2007-09-20 18:09:08 -04:00
: extract-remote-host ( AcceptEx -- addrspec )
[
[ AcceptEx-args-lpOutputBuffer* ] keep
[ AcceptEx-args-dwReceiveDataLength* ] keep
[ AcceptEx-args-dwLocalAddressLength* ] keep
AcceptEx-args-dwRemoteAddressLength*
f <void*>
0 <int>
f <void*> [
0 <int> GetAcceptExSockaddrs
] keep *void*
] keep AcceptEx-args-port server-port-addr parse-sockaddr ;
: accept-continuation ( AcceptEx -- client )
[ make-accept-continuation ] keep
[ check-accept-error ] keep
[ extract-remote-host ] keep
! addrspec AcceptEx
[
AcceptEx-args-sAcceptSocket* add-completion
] keep
AcceptEx-args-sAcceptSocket* <win32-socket> dup handle>duplex-stream
<client-stream> ;
M: windows-nt-io accept ( server -- client )
[
dup check-server-port
dup touch-port
\ AcceptEx-args construct-empty
[ init-accept ] keep
[ (accept) ] keep
[ accept-continuation ] keep
AcceptEx-args-port pending-error
dup duplex-stream-in pending-error
dup duplex-stream-out pending-error
] with-destructors ;
M: windows-nt-io <server> ( addrspec -- server )
[
[
SOCK_STREAM server-fd dup listen-on-socket
dup add-completion
2008-01-21 15:33:43 -05:00
<win32-socket>
2007-09-20 18:09:08 -04:00
] keep <server-port>
] with-destructors ;
M: windows-nt-io <datagram> ( addrspec -- datagram )
[
[
SOCK_DGRAM server-fd
dup add-completion
2008-01-21 15:33:43 -05:00
<win32-socket>
2007-09-20 18:09:08 -04:00
] keep <datagram-port>
] with-destructors ;
TUPLE: WSARecvFrom-args port
s* lpBuffers* dwBufferCount* lpNumberOfBytesRecvd*
lpFlags* lpFrom* lpFromLen* lpOverlapped* lpCompletionRoutine* ;
2008-01-28 02:06:27 -05:00
: make-receive-buffer ( -- WSABUF )
"WSABUF" malloc-object dup free-always
default-buffer-size get over set-WSABUF-len
default-buffer-size get malloc dup free-always over set-WSABUF-buf ;
2007-09-20 18:09:08 -04:00
: init-WSARecvFrom ( datagram WSARecvFrom -- )
[ set-WSARecvFrom-args-port ] 2keep
[
>r delegate port-handle delegate win32-file-handle r>
set-WSARecvFrom-args-s*
] 2keep [
>r datagram-port-addr sockaddr-type heap-size r>
2dup >r malloc dup free-always r> set-WSARecvFrom-args-lpFrom*
>r malloc-int dup free-always r> set-WSARecvFrom-args-lpFromLen*
2007-09-20 18:09:08 -04:00
] keep
2008-01-28 02:06:27 -05:00
make-receive-buffer over set-WSARecvFrom-args-lpBuffers*
2007-09-20 18:09:08 -04:00
1 over set-WSARecvFrom-args-dwBufferCount*
0 malloc-int dup free-always over set-WSARecvFrom-args-lpFlags*
0 malloc-int dup free-always over set-WSARecvFrom-args-lpNumberOfBytesRecvd*
2008-01-28 00:59:36 -05:00
(make-overlapped) swap set-WSARecvFrom-args-lpOverlapped* ;
2007-09-20 18:09:08 -04:00
2008-01-28 00:59:36 -05:00
: WSARecvFrom-continuation ( WSARecvFrom -- n )
dup WSARecvFrom-args-lpOverlapped*
swap WSARecvFrom-args-port [ save-callback ] 2keep
get-overlapped-result ;
2007-09-20 18:09:08 -04:00
: call-WSARecvFrom ( WSARecvFrom -- )
\ WSARecvFrom-args >tuple*<
WSARecvFrom
socket-error* ;
: parse-WSARecvFrom ( n WSARecvFrom -- packet addrspec )
[
WSARecvFrom-args-lpBuffers* WSABUF-buf
swap memory>byte-array
2007-09-20 18:09:08 -04:00
] keep
[ WSARecvFrom-args-lpFrom* ] keep
WSARecvFrom-args-port datagram-port-addr parse-sockaddr ;
M: windows-nt-io receive ( datagram -- packet addrspec )
[
dup check-datagram-port
\ WSARecvFrom-args construct-empty
[ init-WSARecvFrom ] keep
[ call-WSARecvFrom ] keep
[ WSARecvFrom-continuation ] keep
[ WSARecvFrom-args-port pending-error ] keep
parse-WSARecvFrom
] with-destructors ;
TUPLE: WSASendTo-args port
s* lpBuffers* dwBufferCount* lpNumberOfBytesSent*
dwFlags* lpTo* iToLen* lpOverlapped* lpCompletionRoutine* ;
2008-01-28 02:06:27 -05:00
: make-send-buffer ( packet -- WSABUF )
"WSABUF" malloc-object dup free-always
over malloc-byte-array dup free-always over set-WSABUF-buf
swap length over set-WSABUF-len ;
2007-09-20 18:09:08 -04:00
: init-WSASendTo ( packet addrspec datagram WSASendTo -- )
[ set-WSASendTo-args-port ] 2keep
[
2008-01-28 02:06:27 -05:00
>r port-handle win32-file-handle r> set-WSASendTo-args-s*
] keep
[
>r make-sockaddr/size >r
malloc-byte-array dup free-always
r> r>
2007-09-20 18:09:08 -04:00
[ set-WSASendTo-args-iToLen* ] keep
set-WSASendTo-args-lpTo*
2008-01-28 02:06:27 -05:00
] keep
[
>r make-send-buffer r> set-WSASendTo-args-lpBuffers*
2007-09-20 18:09:08 -04:00
] keep
1 over set-WSASendTo-args-dwBufferCount*
0 over set-WSASendTo-args-dwFlags*
2008-01-28 02:06:27 -05:00
0 <uint> over set-WSASendTo-args-lpNumberOfBytesSent*
2008-01-28 00:59:36 -05:00
(make-overlapped) swap set-WSASendTo-args-lpOverlapped* ;
2007-09-20 18:09:08 -04:00
: WSASendTo-continuation ( WSASendTo -- )
2008-01-28 00:59:36 -05:00
dup WSASendTo-args-lpOverlapped*
swap WSASendTo-args-port
[ save-callback ] 2keep
get-overlapped-result drop ;
2007-09-20 18:09:08 -04:00
: call-WSASendTo ( WSASendTo -- )
\ WSASendTo-args >tuple*<
WSASendTo socket-error* ;
2007-11-07 14:01:45 -05:00
USE: io.sockets
2007-09-20 18:09:08 -04:00
M: windows-nt-io send ( packet addrspec datagram -- )
[
3dup check-datagram-send
\ WSASendTo-args construct-empty
[ init-WSASendTo ] keep
[ call-WSASendTo ] keep
[ WSASendTo-continuation ] keep
WSASendTo-args-port pending-error
] with-destructors ;