ffi-rzmq-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d251cf90787964d1767307c511f830c983dd47c0
4
+ data.tar.gz: dbc73d731823c0f445d56b3a06250e4bdea8d2cc
5
+ SHA512:
6
+ metadata.gz: 4a0b12abbb518be94ce38b80a65c3c494f76d7e527cbcb4e93ad801e066ef2d6553c5a0ed44c73aed998626d497e5d9e96f01fd0399407f5186bc100604f58d9
7
+ data.tar.gz: da40bae1ff70d829ec8b4f8bea9628417e3210138e83aa89f6e4d58fe5209103af8126ab48a2718f9b01416dc0fdcc268718e0c9e323bfd8a6213edc752739b9
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+
6
+ *.rbc
7
+ .redcar/
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ before_install: sudo apt-get install libzmq3-dev
2
+ script: bundle exec rspec
3
+ language: ruby
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - ruby-head
8
+ - jruby-19mode
9
+ - jruby-head
10
+ - rbx-2.1.1
11
+
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: ruby-head
15
+ - rvm: jruby-head
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 Chuck Remes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,13 @@
1
+ ffi-rzmq-core
2
+ =============
3
+
4
+ The intention of this gem is to provide a very basic FFI wrapper around the Zeromq libzmq C API.
5
+ This gem isn't intended to be used directly by any Ruby programmer looking to write Zeromq code.
6
+ They should use a higher-level gem like ffi-rzmq which pulls in this gem for its FFI definitions.
7
+
8
+ There have been complaints that the ffi-rzmq gem doesn't provide the correct or best Ruby idioms, so I am
9
+ hoping this encourages other library writers to create their own. Rather than duplicate the FFI
10
+ wrapping code, they can just pull in this gem and build a more idiomatic library around the
11
+ basic definitions.
12
+
13
+ See [ffi-rzmq]
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ffi-rzmq-core/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ffi-rzmq-core"
7
+ s.version = LibZMQ::VERSION
8
+ s.authors = ["Chuck Remes"]
9
+ s.email = ["git@chuckremes.com"]
10
+ s.homepage = "http://github.com/chuckremes/ffi-rzmq-core"
11
+ s.summary = %q{This gem provides only the FFI wrapper for the ZeroMQ (0mq) networking library.}
12
+ s.description = %q{This gem provides only the FFI wrapper for the ZeroMQ (0mq) networking library.
13
+ Project can be used by any other zeromq gems that want to provide their own high-level Ruby API.}
14
+
15
+ s.license = 'MIT'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_runtime_dependency "ffi", ["~> 1.9"]
23
+ s.add_development_dependency "rspec", ["~> 2.14"]
24
+ s.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,6 @@
1
+ require 'ffi'
2
+ require 'ffi-rzmq-core/libc'
3
+ require 'ffi-rzmq-core/libzmq'
4
+ require 'ffi-rzmq-core/structures'
5
+ require 'ffi-rzmq-core/utilities'
6
+ require 'ffi-rzmq-core/constants'
@@ -0,0 +1,213 @@
1
+
2
+ module ZMQ
3
+ # Set up all of the constants that are *common* to all API
4
+ # versions
5
+
6
+ # Socket types
7
+ PAIR = 0
8
+ PUB = 1
9
+ SUB = 2
10
+ REQ = 3
11
+ REP = 4
12
+ XREQ = 5
13
+ XREP = 6
14
+ PULL = 7
15
+ PUSH = 8
16
+ XPUB = 9
17
+ XSUB = 10
18
+ DEALER = XREQ
19
+ ROUTER = XREP
20
+ STREAM = 11
21
+
22
+ SocketTypeNameMap = {
23
+ PAIR => "PAIR",
24
+ PUB => "PUB",
25
+ SUB => "SUB",
26
+ REQ => "REQ",
27
+ REP => "REP",
28
+ PULL => "PULL",
29
+ PUSH => "PUSH",
30
+ XREQ => "XREQ",
31
+ XREP => "XREP",
32
+ ROUTER => "ROUTER",
33
+ DEALER => "DEALER",
34
+ XPUB => "XPUB",
35
+ XSUB => "XSUB",
36
+ STREAM => "STREAM",
37
+ }
38
+
39
+ # Socket options
40
+ AFFINITY = 4
41
+ IDENTITY = 5
42
+ SUBSCRIBE = 6
43
+ UNSUBSCRIBE = 7
44
+ RATE = 8
45
+ RECOVERY_IVL = 9
46
+ SNDBUF = 11
47
+ RCVBUF = 12
48
+ RCVMORE = 13
49
+ FD = 14
50
+ EVENTS = 15
51
+ TYPE = 16
52
+ LINGER = 17
53
+ RECONNECT_IVL = 18
54
+ BACKLOG = 19
55
+ RECONNECT_IVL_MAX = 21
56
+ MAXMSGSIZE = 22
57
+ SNDHWM = 23
58
+ RCVHWM = 24
59
+ MULTICAST_HOPS = 25
60
+ RCVTIMEO = 27
61
+ SNDTIMEO = 28
62
+ IPV4ONLY = 31
63
+ LAST_ENDPOINT = 32
64
+ ROUTER_MANDATORY = 33
65
+ TCP_KEEPALIVE = 34
66
+ TCP_KEEPALIVE_CNT = 35
67
+ TCP_KEEPALIVE_IDLE = 36
68
+ TCP_KEEPALIVE_INTVL = 37
69
+ TCP_ACCEPT_FILTER = 38
70
+ DELAY_ATTACH_ON_CONNECT = 39
71
+ XPUB_VERBOSE = 40
72
+ ROUTER_RAW = 41
73
+ IPV6 = 42
74
+ MECHANISM = 43
75
+ PLAIN_SERVER = 44
76
+ PLAIN_USERNAME = 45
77
+ PLAIN_PASSWORD = 46
78
+ CURVE_SERVER = 47
79
+ CURVE_PUBLICKEY = 48
80
+ CURVE_SECRETKEY = 49
81
+ CURVE_SERVERKEY = 50
82
+ PROBE_ROUTER = 51
83
+ REQ_CORRELATE = 52
84
+ REQ_RELAXED = 53
85
+ CONFLATE = 54
86
+ ZAP_DOMAIN = 55
87
+ ROUTER_HANDOVER = 56
88
+
89
+ IMMEDIATE = DELAY_ATTACH_ON_CONNECT
90
+ FAIL_UNROUTABLE = ROUTER_MANDATORY
91
+ ROUTER_BEHAVIOR = ROUTER_MANDATORY
92
+
93
+ # Socket Security Types
94
+ NULL = 0
95
+ PLAIN = 1
96
+ CURVE = 2
97
+
98
+ # Send/recv options
99
+ DONTWAIT = 1
100
+ SNDMORE = 2
101
+ SNDLABEL = 4
102
+ NOBLOCK = DONTWAIT
103
+
104
+ # Message options
105
+ MORE = 1
106
+
107
+ # Context options
108
+ IO_THREADS = 1
109
+ MAX_SOCKETS = 2
110
+ IO_THREADS_DFLT = 1
111
+ MAX_SOCKETS_DFLT = 1024
112
+
113
+ # I/O multiplexing
114
+ POLL = 1
115
+ POLLIN = 1
116
+ POLLOUT = 2
117
+ POLLERR = 4
118
+
119
+ # Socket errors
120
+ EAGAIN = Errno::EAGAIN::Errno
121
+ EINVAL = Errno::EINVAL::Errno
122
+ ENOMEM = Errno::ENOMEM::Errno
123
+ ENODEV = Errno::ENODEV::Errno
124
+ EFAULT = Errno::EFAULT::Errno
125
+ EINTR = Errno::EINTR::Errno
126
+ EMFILE = Errno::EMFILE::Errno
127
+
128
+ # ZMQ errors
129
+ HAUSNUMERO = 156384712
130
+ EFSM = (HAUSNUMERO + 51)
131
+ ENOCOMPATPROTO = (HAUSNUMERO + 52)
132
+ ETERM = (HAUSNUMERO + 53)
133
+ EMTHREAD = (HAUSNUMERO + 54)
134
+
135
+ # Rescue unknown constants and use the ZeroMQ defined values
136
+ # Usually only happens on Windows though some don't resolve on
137
+ # OSX too (ENOTSUP)
138
+ ENOTSUP = Errno::ENOTSUP::Errno rescue (HAUSNUMERO + 1)
139
+ EPROTONOSUPPORT = Errno::EPROTONOSUPPORT::Errno rescue (HAUSNUMERO + 2)
140
+ ENOBUFS = Errno::ENOBUFS::Errno rescue (HAUSNUMERO + 3)
141
+ ENETDOWN = Errno::ENETDOWN::Errno rescue (HAUSNUMERO + 4)
142
+ EADDRINUSE = Errno::EADDRINUSE::Errno rescue (HAUSNUMERO + 5)
143
+ EADDRNOTAVAIL = Errno::EADDRNOTAVAIL::Errno rescue (HAUSNUMERO + 6)
144
+ ECONNREFUSED = Errno::ECONNREFUSED::Errno rescue (HAUSNUMERO + 7)
145
+ EINPROGRESS = Errno::EINPROGRESS::Errno rescue (HAUSNUMERO + 8)
146
+ ENOTSOCK = Errno::ENOTSOCK::Errno rescue (HAUSNUMERO + 9)
147
+ EMSGSIZE = Errno::EMSGSIZE::Errno rescue (HAUSNUMERO + 10)
148
+ EAFNOSUPPORT = Errno::EAFNOSUPPORT::Errno rescue (HAUSNUMERO + 11)
149
+ ENETUNREACH = Errno::ENETUNREACH::Errno rescue (HAUSNUMERO + 12)
150
+ ECONNABORTED = Errno::ECONNABORTED::Errno rescue (HAUSNUMERO + 13)
151
+ ECONNRESET = Errno::ECONNRESET::Errno rescue (HAUSNUMERO + 14)
152
+ ENOTCONN = Errno::ENOTCONN::Errno rescue (HAUSNUMERO + 15)
153
+ ETIMEDOUT = Errno::ETIMEDOUT::Errno rescue (HAUSNUMERO + 16)
154
+ EHOSTUNREACH = Errno::EHOSTUNREACH::Errno rescue (HAUSNUMERO + 17)
155
+ ENETRESET = Errno::ENETRESET::Errno rescue (HAUSNUMERO + 18)
156
+
157
+ # Device Types
158
+ STREAMER = 1
159
+ FORWARDER = 2
160
+ QUEUE = 3
161
+
162
+ # Socket events and monitoring
163
+ EVENT_CONNECTED = 1
164
+ EVENT_CONNECT_DELAYED = 2
165
+ EVENT_CONNECT_RETRIED = 4
166
+ EVENT_LISTENING = 8
167
+ EVENT_BIND_FAILED = 16
168
+ EVENT_ACCEPTED = 32
169
+ EVENT_ACCEPT_FAILED = 64
170
+ EVENT_CLOSED = 128
171
+ EVENT_CLOSE_FAILED = 256
172
+ EVENT_DISCONNECTED = 512
173
+ EVENT_MONITOR_STOPPED = 1024
174
+ EVENT_ALL = (EVENT_CONNECTED | EVENT_CONNECT_DELAYED | EVENT_CONNECT_RETRIED |
175
+ EVENT_LISTENING | EVENT_BIND_FAILED | EVENT_ACCEPTED |
176
+ EVENT_ACCEPT_FAILED | EVENT_CLOSED | EVENT_CLOSE_FAILED |
177
+ EVENT_DISCONNECTED | EVENT_MONITOR_STOPPED)
178
+
179
+ # version checking
180
+ # This gem supports both libzmq 3.2+ and 4.x. However, not all socket options are visible between versions.
181
+ # To make support easier for consumers of this gem, we do all version checking here and only
182
+ # expose the appropriate socket options. Note that *all* options are defined above even if the library
183
+ # version doesn't support it. Consumers of this gem can enable support at runtime.
184
+ integer_socket_options = [
185
+ EVENTS, LINGER, RCVTIMEO, SNDTIMEO, RECONNECT_IVL, FD, TYPE, BACKLOG, RECONNECT_IVL_MAX, RCVHWM,
186
+ SNDHWM, RATE, RECOVERY_IVL, SNDBUF, RCVBUF, IPV4ONLY, ROUTER_BEHAVIOR, TCP_KEEPALIVE,
187
+ TCP_KEEPALIVE_CNT, TCP_KEEPALIVE_IDLE, TCP_KEEPALIVE_INTVL, TCP_ACCEPT_FILTER, MULTICAST_HOPS,
188
+ IMMEDIATE,
189
+ ]
190
+
191
+ long_long_socket_options = [
192
+ RCVMORE, AFFINITY, MAXMSGSIZE,
193
+ ]
194
+
195
+ string_socket_options = [
196
+ IDENTITY, SUBSCRIBE, UNSUBSCRIBE, LAST_ENDPOINT,
197
+ ]
198
+
199
+ if LibZMQ.version4?
200
+ integer_socket_options += [
201
+ IPV6, MECHANISM, PLAIN_SERVER, CURVE_SERVER, PROBE_ROUTER, REQ_CORRELATE, REQ_RELAXED, CONFLATE,
202
+ ]
203
+
204
+ string_socket_options += [
205
+ ZAP_DOMAIN, PLAIN_USERNAME, PLAIN_PASSWORD, CURVE_PUBLICKEY, CURVE_SERVERKEY, CURVE_SECRETKEY,
206
+ ]
207
+ end
208
+
209
+ IntegerSocketOptions = integer_socket_options.sort
210
+ LongLongSocketOptions = long_long_socket_options.sort
211
+ StringSocketOptions = string_socket_options.sort
212
+ SocketOptions = (IntegerSocketOptions + LongLongSocketOptions + StringSocketOptions).sort
213
+ end
@@ -0,0 +1,19 @@
1
+
2
+ module LibC
3
+ extend FFI::Library
4
+ # figures out the correct libc for each platform including Windows
5
+ library = ffi_lib(FFI::Library::LIBC).first
6
+
7
+ # Size_t not working properly on Windows
8
+ find_type(:size_t) rescue typedef(:ulong, :size_t)
9
+
10
+ # memory allocators
11
+ attach_function :malloc, [:size_t], :pointer
12
+ attach_function :free, [:pointer], :void
13
+
14
+ # get a pointer to the free function; used for ZMQ::Message deallocation
15
+ Free = library.find_symbol('free')
16
+
17
+ # memory movers
18
+ attach_function :memcpy, [:pointer, :pointer, :size_t], :pointer
19
+ end # module LibC
@@ -0,0 +1,100 @@
1
+ # Wraps the libzmq library and attaches to the functions that are
2
+ # common across the 3.2.x+ and 4.x APIs.
3
+ #
4
+ module LibZMQ
5
+ extend FFI::Library
6
+
7
+ begin
8
+ # bias the library discovery to a path inside the gem first, then
9
+ # to the usual system paths
10
+ inside_gem = File.join(File.dirname(__FILE__), '..', '..', 'ext')
11
+ local_path = FFI::Platform::IS_WINDOWS ? ENV['PATH'].split(';') : ENV['PATH'].split(':')
12
+
13
+ # Search for libzmq in the following order...
14
+ ZMQ_LIB_PATHS = ([inside_gem] + local_path + [
15
+ '/usr/local/lib', '/opt/local/lib', '/usr/local/homebrew/lib', '/usr/lib64'
16
+ ]).map{|path| "#{path}/libzmq.#{FFI::Platform::LIBSUFFIX}"}
17
+ ffi_lib(ZMQ_LIB_PATHS + %w{libzmq})
18
+
19
+ rescue LoadError
20
+ if ZMQ_LIB_PATHS.any? {|path|
21
+ File.file? File.join(path, "libzmq.#{FFI::Platform::LIBSUFFIX}")}
22
+ warn "Unable to load this gem. The libzmq library exists, but cannot be loaded."
23
+ warn "If this is Windows:"
24
+ warn "- Check that you have MSVC runtime installed or statically linked"
25
+ warn "- Check that your DLL is compiled for #{FFI::Platform::ADDRESS_SIZE} bit"
26
+ else
27
+ warn "Unable to load this gem. The libzmq library (or DLL) could not be found."
28
+ warn "If this is a Windows platform, make sure libzmq.dll is on the PATH."
29
+ warn "If the DLL was built with mingw, make sure the other two dependent DLLs,"
30
+ warn "libgcc_s_sjlj-1.dll and libstdc++6.dll, are also on the PATH."
31
+ warn "For non-Windows platforms, make sure libzmq is located in this search path:"
32
+ warn ZMQ_LIB_PATHS.inspect
33
+ end
34
+ raise LoadError, "The libzmq library (or DLL) could not be loaded"
35
+ end
36
+
37
+ # Size_t not working properly on Windows
38
+ find_type(:size_t) rescue typedef(:ulong, :size_t)
39
+
40
+ # Context and misc api
41
+ #
42
+ # @blocking = true is a hint to FFI that the following (and only the following)
43
+ # function may block, therefore it should release the GIL before calling it.
44
+ # This can aid in situations where the function call will/may block and another
45
+ # thread within the lib may try to call back into the ruby runtime. Failure to
46
+ # release the GIL will result in a hang; the hint is required for MRI otherwise
47
+ # there are random hangs (which require kill -9 to terminate).
48
+ #
49
+ attach_function :zmq_version, [:pointer, :pointer, :pointer], :void, :blocking => true
50
+ attach_function :zmq_errno, [], :int, :blocking => true
51
+ attach_function :zmq_strerror, [:int], :pointer, :blocking => true
52
+
53
+ # Context initialization and destruction
54
+ attach_function :zmq_init, [:int], :pointer, :blocking => true
55
+ attach_function :zmq_term, [:pointer], :int, :blocking => true
56
+ attach_function :zmq_ctx_new, [], :pointer, :blocking => true
57
+ attach_function :zmq_ctx_destroy, [:pointer], :int, :blocking => true
58
+ attach_function :zmq_ctx_set, [:pointer, :int, :int], :int, :blocking => true
59
+ attach_function :zmq_ctx_get, [:pointer, :int], :int, :blocking => true
60
+
61
+ # Message API
62
+ attach_function :zmq_msg_init, [:pointer], :int, :blocking => true
63
+ attach_function :zmq_msg_init_size, [:pointer, :size_t], :int, :blocking => true
64
+ attach_function :zmq_msg_init_data, [:pointer, :pointer, :size_t, :pointer, :pointer], :int, :blocking => true
65
+ attach_function :zmq_msg_close, [:pointer], :int, :blocking => true
66
+ attach_function :zmq_msg_data, [:pointer], :pointer, :blocking => true
67
+ attach_function :zmq_msg_size, [:pointer], :size_t, :blocking => true
68
+ attach_function :zmq_msg_copy, [:pointer, :pointer], :int, :blocking => true
69
+ attach_function :zmq_msg_move, [:pointer, :pointer], :int, :blocking => true
70
+ attach_function :zmq_msg_send, [:pointer, :pointer, :int], :int, :blocking => true
71
+ attach_function :zmq_msg_recv, [:pointer, :pointer, :int], :int, :blocking => true
72
+ attach_function :zmq_msg_more, [:pointer], :int, :blocking => true
73
+ attach_function :zmq_msg_get, [:pointer, :int], :int, :blocking => true
74
+ attach_function :zmq_msg_set, [:pointer, :int, :int], :int, :blocking => true
75
+
76
+ # Socket API
77
+ attach_function :zmq_socket, [:pointer, :int], :pointer, :blocking => true
78
+ attach_function :zmq_setsockopt, [:pointer, :int, :pointer, :int], :int, :blocking => true
79
+ attach_function :zmq_getsockopt, [:pointer, :int, :pointer, :pointer], :int, :blocking => true
80
+ attach_function :zmq_bind, [:pointer, :string], :int, :blocking => true
81
+ attach_function :zmq_connect, [:pointer, :string], :int, :blocking => true
82
+ attach_function :zmq_close, [:pointer], :int, :blocking => true
83
+
84
+ # Device API
85
+ attach_function :zmq_proxy, [:pointer, :pointer, :pointer], :int, :blocking => true
86
+
87
+ # Poll API
88
+ attach_function :zmq_poll, [:pointer, :int, :long], :int, :blocking => true
89
+
90
+ # Monitoring API
91
+ attach_function :zmq_socket_monitor, [:pointer, :pointer, :int], :int, :blocking => true
92
+
93
+ # Socket API
94
+ attach_function :zmq_unbind, [:pointer, :string], :int, :blocking => true
95
+ attach_function :zmq_disconnect, [:pointer, :string], :int, :blocking => true
96
+ attach_function :zmq_recvmsg, [:pointer, :pointer, :int], :int, :blocking => true
97
+ attach_function :zmq_recv, [:pointer, :pointer, :size_t, :int], :int, :blocking => true
98
+ attach_function :zmq_sendmsg, [:pointer, :pointer, :int], :int, :blocking => true
99
+ attach_function :zmq_send, [:pointer, :pointer, :size_t, :int], :int, :blocking => true
100
+ end
@@ -0,0 +1,96 @@
1
+ module LibZMQ
2
+
3
+ # Used for casting pointers back to the msg_t struct
4
+ #
5
+ class Msg < FFI::Struct
6
+ layout :content, :pointer,
7
+ :flags, :uint8,
8
+ :vsm_size, :uint8,
9
+ :vsm_data, [:uint8, 30]
10
+ end # class Msg
11
+
12
+
13
+ # Create the basic mapping for the poll_item_t structure so we can
14
+ # access those fields via Ruby.
15
+ #
16
+ module PollItemLayout
17
+ def self.included(base)
18
+ fd_type = if FFI::Platform::IS_WINDOWS && FFI::Platform::ADDRESS_SIZE == 64
19
+ # On Windows, zmq.h defines fd as a SOCKET, which is 64 bits on x64.
20
+ :uint64
21
+ else
22
+ :int
23
+ end
24
+
25
+ base.class_eval do
26
+ layout :socket, :pointer,
27
+ :fd, fd_type,
28
+ :events, :short,
29
+ :revents, :short
30
+ end
31
+ end
32
+ end
33
+
34
+
35
+ # PollItem class includes the PollItemLayout module so that we can use the
36
+ # basic FFI accessors to get at the structure's fields. We also want to provide
37
+ # some higher-level Ruby accessors for convenience.
38
+ #
39
+ class PollItem < FFI::Struct
40
+ include PollItemLayout
41
+
42
+ def socket
43
+ self[:socket]
44
+ end
45
+
46
+ def fd
47
+ self[:fd]
48
+ end
49
+
50
+ def readable?
51
+ (self[:revents] & ZMQ::POLLIN) > 0
52
+ end
53
+
54
+ def writable?
55
+ (self[:revents] & ZMQ::POLLOUT) > 0
56
+ end
57
+
58
+ def inspect
59
+ "socket [#{socket}], fd [#{fd}], events [#{self[:events]}], revents [#{self[:revents]}]"
60
+ end
61
+ end
62
+
63
+
64
+ # /* Socket event data */
65
+ # typedef struct {
66
+ # uint16_t event; // id of the event as bitfield
67
+ # int32_t value ; // value is either error code, fd or reconnect interval
68
+ # } zmq_event_t;
69
+ module EventDataLayout
70
+ def self.included(base)
71
+ base.class_eval do
72
+ layout :event, :uint16,
73
+ :value, :int32
74
+ end
75
+ end
76
+ end # module EventDataLayout
77
+
78
+
79
+ # Provide a few convenience methods for accessing the event structure.
80
+ #
81
+ class EventData < FFI::Struct
82
+ include EventDataLayout
83
+
84
+ def event
85
+ self[:event]
86
+ end
87
+
88
+ def value
89
+ self[:value]
90
+ end
91
+
92
+ def inspect
93
+ "event [#{event}], value [#{value}]"
94
+ end
95
+ end # class EventData
96
+ end
@@ -0,0 +1,40 @@
1
+
2
+ module LibZMQ
3
+
4
+ # Returns a hash of the form {:major => X, :minor => Y, :patch => Z} to represent the
5
+ # version of libzmq.
6
+ #
7
+ # Class method.
8
+ #
9
+ # Invoke as: ZMQ::LibZMQ.version
10
+ #
11
+ def self.version
12
+ unless @version
13
+ major = FFI::MemoryPointer.new :int
14
+ minor = FFI::MemoryPointer.new :int
15
+ patch = FFI::MemoryPointer.new :int
16
+ LibZMQ.zmq_version major, minor, patch
17
+ @version = {:major => major.read_int, :minor => minor.read_int, :patch => patch.read_int}
18
+ end
19
+
20
+ @version
21
+ end
22
+
23
+ def self.version3?
24
+ version[:major] == 3 && version[:minor] >= 2
25
+ end
26
+
27
+ def self.version4?
28
+ version[:major] == 4
29
+ end
30
+
31
+ # Sanity check; print an error and exit if we are trying to load an unsupported
32
+ # version of libzmq.
33
+ #
34
+ hash = LibZMQ.version
35
+ major, minor = hash[:major], hash[:minor]
36
+ if major < 3 || (major == 3 && minor < 2)
37
+ version = "#{hash[:major]}.#{hash[:minor]}.#{hash[:patch]}"
38
+ raise LoadError, "The libzmq version #{version} is incompatible with this version of ffi-rzmq-core."
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module LibZMQ
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,8 @@
1
+
2
+ require File.expand_path(
3
+ File.join(File.dirname(__FILE__), %w[.. lib ffi-rzmq-core]))
4
+
5
+ def jruby?
6
+ RUBY_PLATFORM =~ /java/
7
+ end
8
+
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ffi-rzmq-core
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Chuck Remes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '2.14'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '2.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |-
56
+ This gem provides only the FFI wrapper for the ZeroMQ (0mq) networking library.
57
+ Project can be used by any other zeromq gems that want to provide their own high-level Ruby API.
58
+ email:
59
+ - git@chuckremes.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - .gitignore
65
+ - .travis.yml
66
+ - LICENSE
67
+ - README.md
68
+ - ffi-rzmq-core.gemspec
69
+ - lib/ffi-rzmq-core.rb
70
+ - lib/ffi-rzmq-core/constants.rb
71
+ - lib/ffi-rzmq-core/libc.rb
72
+ - lib/ffi-rzmq-core/libzmq.rb
73
+ - lib/ffi-rzmq-core/structures.rb
74
+ - lib/ffi-rzmq-core/utilities.rb
75
+ - lib/ffi-rzmq-core/version.rb
76
+ - spec/spec_helper.rb
77
+ homepage: http://github.com/chuckremes/ffi-rzmq-core
78
+ licenses:
79
+ - MIT
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.0.3
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: This gem provides only the FFI wrapper for the ZeroMQ (0mq) networking library.
101
+ test_files:
102
+ - spec/spec_helper.rb