ffi-rzmq-core 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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