1 ! Copyright (C) 2011-2013 Eungju PARK, John Benediktsson.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.c-types alien.data arrays byte-arrays
4 classes.struct combinators destructors fry kernel libc math math.order
5 memoize sequences zeromq.ffi ;
9 TUPLE: zmq-error n string ;
11 : throw-zmq-error ( -- )
12 zmq_errno dup zmq_strerror zmq-error boa throw ; inline
14 : check-zmq-error ( retval -- )
15 [ throw-zmq-error ] unless-zero ; inline
17 : zmq-version ( -- version )
18 { int int int } [ zmq_version ] with-out-parameters 3array ;
20 : zmq-version-numeric ( -- n )
21 zmq-version first3 [ 100 * ] [ 10 * ] [ 1 * ] tri* + + ;
24 ! https://github.com/chuckremes/ffi-rzmq-core/blob/master/lib/ffi-rzmq-core/structures.rb
25 MEMO: zmq-msg-size ( -- x )
26 zmq-version-numeric 410 <=> {
32 ! This word should be used to allocate the zmq_msg_t struct because
33 ! the size of it varies between versions.
34 : <zmq_msg_t> ( -- byte-array )
35 zmq-msg-size (byte-array) ;
37 GENERIC#: zmq-setopt 2 ( obj name value -- )
38 GENERIC#: zmq-getopt 1 ( obj name -- value )
40 TUPLE: zmq-message underlying ;
42 : <zmq-message> ( -- msg )
44 [ zmq_msg_init check-zmq-error ]
45 [ zmq-message boa ] bi ;
47 M: zmq-message dispose
48 underlying>> zmq_msg_close check-zmq-error ;
50 : byte-array>zmq-message ( byte-array -- msg )
52 [ over length zmq_msg_init_size check-zmq-error ]
53 [ zmq_msg_data swap dup length memcpy ]
54 [ zmq-message boa ] tri ;
56 : zmq-message>byte-array ( msg -- byte-array )
57 underlying>> [ zmq_msg_data ] [ zmq_msg_size ] bi
58 [ drop B{ } ] [ memory>byte-array ] if-zero ;
60 TUPLE: zmq-context underlying ;
62 ! this uses the "New API" with version 3
63 ! previous versions should use zmq_init and zmq_term
65 : <zmq-context> ( -- context )
66 zmq_ctx_new zmq-context boa ;
68 M: zmq-context dispose
69 underlying>> zmq_ctx_destroy check-zmq-error ;
71 M: zmq-context zmq-setopt
72 [ underlying>> ] 2dip zmq_ctx_set check-zmq-error ;
74 M: zmq-context zmq-getopt
75 [ underlying>> ] dip zmq_ctx_get ;
77 TUPLE: zmq-socket underlying ;
79 : <zmq-socket> ( context type -- socket )
80 [ underlying>> ] dip zmq_socket
81 dup [ throw-zmq-error ] unless
85 underlying>> zmq_close check-zmq-error ;
87 M: zmq-socket zmq-setopt
88 [ underlying>> ] 2dip over {
89 { ZMQ_SUBSCRIBE [ dup length ] }
90 { ZMQ_UNSUBSCRIBE [ dup length ] }
91 { ZMQ_RCVTIMEO [ 4 ] }
92 { ZMQ_SNDTIMEO [ 4 ] }
93 } case zmq_setsockopt check-zmq-error ;
95 : zmq-bind ( socket addr -- )
96 [ underlying>> ] dip zmq_bind check-zmq-error ;
98 : zmq-unbind ( socket addr -- )
99 [ underlying>> ] dip zmq_unbind check-zmq-error ;
101 : zmq-connect ( socket addr -- )
102 [ underlying>> ] dip zmq_connect check-zmq-error ;
104 : zmq-disconnect ( socket addr -- )
105 [ underlying>> ] dip zmq_disconnect check-zmq-error ;
107 : zmq-sendmsg ( socket msg flags -- )
108 [ [ underlying>> ] bi@ ] dip zmq_sendmsg
109 0 < [ throw-zmq-error ] when ;
111 : zmq-recvmsg ( socket msg flags -- )
112 [ [ underlying>> ] bi@ ] dip zmq_recvmsg
113 0 < [ throw-zmq-error ] when ;
115 : zmq-send ( socket byte-array flags -- )
116 [ byte-array>zmq-message ] dip
117 '[ _ zmq-sendmsg ] with-disposal ;
119 : zmq-recv ( socket flags -- byte-array )
121 [ swap zmq-recvmsg ] [ zmq-message>byte-array ] bi