nn-core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.tmproj
6
+ .rbx
7
+
8
+ *.rbc
9
+ .redcar/
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --format documentation
3
+ --backtrace
4
+ --default_path spec
data/Authors.txt ADDED
@@ -0,0 +1,2 @@
1
+ Chuck Remes, git@chuckremes.com
2
+
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "jruby-openssl", :platform => :jruby
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ 20130204 / 0.1.0
2
+ * Initial release. Wrapped the nanomsg library as of commit
3
+ 5ded934af0.
4
+
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ nn-core
2
+ -------
3
+
4
+ nn-core is a very thin FFI wrapper around the nanomsg library. The intention is to provide a very
5
+ simple wrapper that hews as close to the C API as possible. Other gems that want to offer a more
6
+ idiomatic API for Ruby should require this gem and build a nice Ruby API with it.
7
+
8
+ For more information on nanomsg, please visit its website:
9
+
10
+ http://nanomsg.org
11
+
12
+ Installation
13
+ ------------
14
+
15
+ 1. Make sure to build libnanomsg first by following these instructions:
16
+
17
+ http://github.com/250bpm/nanomsg
18
+
19
+ 2. git clone git://github.com/chuckremes/nn-core.git
20
+
21
+ 3. cd nn-core
22
+
23
+ 4. ruby -S gem build nn-core.gemspec
24
+
25
+ 5. ruby -S gem install nn-core*.gem
26
+
27
+ 6. In your code, do:
28
+
29
+ ```ruby
30
+ require "nn-core"
31
+ ```
32
+
33
+ License
34
+ -------
35
+
36
+ (The MIT License)
37
+
38
+ Copyright (c) 2013 Chuck Remes
39
+
40
+ Permission is hereby granted, free of charge, to any person obtaining
41
+ a copy of this software and associated documentation files (the
42
+ 'Software'), to deal in the Software without restriction, including
43
+ without limitation the rights to use, copy, modify, merge, publish,
44
+ distribute, sublicense, and/or sell copies of the Software, and to
45
+ permit persons to whom the Software is furnished to do so, subject to
46
+ the following conditions:
47
+
48
+ The above copyright notice and this permission notice shall be
49
+ included in all copies or substantial portions of the Software.
50
+
51
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
52
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
53
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
54
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
55
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
56
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
57
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
@@ -0,0 +1,85 @@
1
+ module NNCore
2
+ NN_HAUSNUMERO = 156384712
3
+
4
+ # SP address families
5
+ AF_SP = 1
6
+ AF_SP_RAW = 2
7
+
8
+ # Transport types
9
+ NN_INPROC = -1
10
+ NN_IPC = -2
11
+ NN_TCP = -3
12
+
13
+ # Protocols
14
+ NN_PAIR_ID = 1
15
+ NN_PAIR = (NN_PAIR_ID * 16 + 0)
16
+
17
+ NN_PUBSUB_ID = 2
18
+ NN_PUB = (NN_PUBSUB_ID * 16 + 0)
19
+ NN_SUB = (NN_PUBSUB_ID * 16 + 1)
20
+
21
+ NN_REQREP_ID = 3
22
+ NN_REQ = (NN_REQREP_ID * 16 + 0)
23
+ NN_REP = (NN_REQREP_ID * 16 + 1)
24
+
25
+ NN_FANIN_ID = 4
26
+ NN_SOURCE = (NN_FANIN_ID * 16 + 0)
27
+ NN_SINK = (NN_FANIN_ID * 16 + 1)
28
+ NN_FANOUT_ID = 5
29
+ NN_PUSH = (NN_FANOUT_ID * 16 + 0)
30
+ NN_PULL = (NN_FANOUT_ID * 16 + 1)
31
+
32
+ NN_SURVEY_ID = 6
33
+ NN_SURVEYOR = (NN_SURVEY_ID * 16 + 0)
34
+ NN_RESPONDENT = (NN_SURVEY_ID * 16 + 1)
35
+
36
+ # Socket Option Levels (SOL)
37
+ NN_SOL_SOCKET = 0
38
+
39
+ # Socket options
40
+ NN_LINGER = 1
41
+ NN_SNDBUF = 2
42
+ NN_RCVBUF = 3
43
+ NN_SNDTIMEO = 4
44
+ NN_RCVTIMEO = 5
45
+ NN_RECONNECT_IVL = 6
46
+ NN_RECONNECT_IVL_MAX = 7
47
+ NN_SNDPRIO = 8
48
+ #NN_SNDFD = 10
49
+ #NN_RCVFD = 11
50
+
51
+ # Send/recv options
52
+ NN_DONTWAIT = 1
53
+ NN_MSG = -1
54
+
55
+ # Socket errors
56
+ ENOTSUP = Errno::ENOTSUP::Errno rescue NN_HAUSNUMERO + 1
57
+ EPROTONOSUPPORT = Errno::EPROTONOSUPPORT::Errno rescue NN_HAUSNUMERO + 2
58
+ ENOBUFS = Errno::ENOBUFS::Errno rescue NN_HAUSNUMERO + 3
59
+ ENETDOWN = Errno::ENETDOWN::Errnow rescue NN_HAUSNUMERO + 4
60
+ EADDRINUSE = Errno::EADDRINUSE::Errno rescue NN_HAUSNUMERO + 5
61
+ EADDRNOTAVAIL = Errno::EADDRNOTAVAIL::Errno rescue NN_HAUSNUMERO + 6
62
+ ECONNREFUSED = Errno::ECONNREFUSED::Errno rescue NN_HAUSNUMERO + 7
63
+ EINPROGRESS = Errno::EINPROGRESS::Errno rescue NN_HAUSNUMERO + 8
64
+ ENOTSOCK = Errno::ENOTSOCK::Errno rescue NN_HAUSNUMERO + 9
65
+ EAFNOSUPPORT = Errno::EAFNOSUPPORT::Errno rescue NN_HAUSNUMERO + 10
66
+ EPROTO = Errno::EPROTO::Errno rescue NN_HAUSNUMERO + 11
67
+
68
+ ETIMEDOUT = Errno::ETIMEDOUT::Errno
69
+ EAGAIN = Errno::EAGAIN::Errno
70
+ EINVAL = Errno::EINVAL::Errno
71
+ ENOMEM = Errno::ENOMEM::Errno
72
+ ENODEV = Errno::ENODEV::Errno
73
+ EFAULT = Errno::EFAULT::Errno
74
+ # EINTR = Errno::EINTR::Errno
75
+ EBADF = Errno::EBADF::Errno
76
+ ENOPROTOOPT = Errno::ENOPROTOOPT::Errno
77
+ ENAMETOOLONG = Errno::ENAMETOOLONG::Errno
78
+
79
+ # Library errors
80
+ ETERM = Errno::ETERM::Errno rescue NN_HAUSNUMERO + 53
81
+ EFSM = Errno::EFSM::Errno rescue NN_HAUSNUMERO + 54
82
+
83
+ # Miscellaneous
84
+ NN_INPROCB_NAMELEN_MAX = 64
85
+ end
@@ -0,0 +1,59 @@
1
+
2
+ module NNCore
3
+ module LibNanomsg
4
+ extend FFI::Library
5
+
6
+ begin
7
+ # bias the library discovery to a path inside the gem first, then
8
+ # to the usual system paths
9
+ inside_gem = File.join(File.dirname(__FILE__), '..', '..', 'ext')
10
+ local_path = FFI::Platform::IS_WINDOWS ? ENV['PATH'].split(';') : ENV['PATH'].split(':')
11
+ library_name = "libnanomsg"
12
+ LIB_PATHS = [
13
+ inside_gem, '/usr/local/lib', '/opt/local/lib', '/usr/local/homebrew/lib', '/usr/lib64'
14
+ ].map{|path| "#{path}/#{library_name}.#{FFI::Platform::LIBSUFFIX}"}
15
+ ffi_lib(LIB_PATHS + [library_name])
16
+ rescue LoadError
17
+ if LIB_PATHS.push(*local_path).any? {|path|
18
+ File.file? File.join(path, "#{library_name}.#{FFI::Platform::LIBSUFFIX}")}
19
+ warn "Unable to load this gem. The #{library_name} library exists, but cannot be loaded."
20
+ warn "If this is Windows:"
21
+ warn "- Check that you have MSVC runtime installed or statically linked"
22
+ warn "- Check that your DLL is compiled for #{FFI::Platform::ADDRESS_SIZE} bit"
23
+ else
24
+ warn "Unable to load this gem. The #{library_name} library (or DLL) could not be found."
25
+ warn "If this is a Windows platform, make sure #{library_name}.dll is on the PATH."
26
+ warn "If the DLL was built with mingw, make sure the other two dependent DLLs,"
27
+ warn "libgcc_s_sjlj-1.dll and libstdc++6.dll, are also on the PATH."
28
+ warn "For non-Windows platforms, make sure #{library_name} is located in this search path:"
29
+ warn LIB_PATHS.inspect
30
+ end
31
+ raise LoadError, "The #{library_name} library (or DLL) could not be loaded"
32
+ end
33
+ # Size_t not working properly on Windows
34
+ find_type(:size_t) rescue typedef(:ulong, :size_t)
35
+
36
+ attach_function :nn_version, [:pointer, :pointer, :pointer], :int
37
+
38
+ attach_function :nn_init, [], :int
39
+ attach_function :nn_term, [], :int
40
+ attach_function :nn_errno, [], :int
41
+ attach_function :nn_strerror, [:int], :string
42
+ attach_function :nn_socket, [:int, :int], :int
43
+ attach_function :nn_close, [:int], :int
44
+
45
+ attach_function :nn_getsockopt, [:int, :int, :int, :pointer, :pointer], :int
46
+ attach_function :nn_setsockopt, [:int, :int, :int, :pointer, :size_t], :int
47
+ attach_function :nn_bind, [:int, :string], :int
48
+ attach_function :nn_connect, [:int, :string], :int
49
+ attach_function :nn_shutdown, [:int, :int], :int
50
+ attach_function :nn_send, [:int, :pointer, :size_t, :int], :int
51
+ attach_function :nn_recv, [:int, :pointer, :size_t, :int], :int
52
+
53
+ # functions for working with raw buffers
54
+ attach_function :nn_sendmsg, [:int, :pointer, :int], :int
55
+ attach_function :nn_recvmsg, [:int, :pointer, :int], :int
56
+ attach_function :nn_allocmsg, [:size_t, :int], :pointer
57
+ attach_function :nn_freemsg, [:pointer], :int
58
+ end
59
+ end
@@ -0,0 +1,121 @@
1
+
2
+ module NNCore
3
+ module LibNanomsg
4
+
5
+ # Structs for working with raw buffers (not recommended)
6
+ module NNIOVecLayout
7
+ def self.included(base)
8
+ base.class_eval do
9
+ layout :iov_base, :pointer,
10
+ :iov_len, :size_t
11
+ end
12
+ end
13
+ end
14
+
15
+ class NNIOVec < FFI::Struct
16
+ include NNIOVecLayout
17
+
18
+ def iov_base
19
+ self[:iov_base]
20
+ end
21
+
22
+ def iov_base=(pointer)
23
+ self[:iov_base] = pointer
24
+ end
25
+
26
+ def iov_len
27
+ self[:iov_len]
28
+ end
29
+
30
+ def iov_len=(length)
31
+ self[:iov_len] = length
32
+ end
33
+ end
34
+
35
+ module NNMsgHdrLayout
36
+ def self.included(base)
37
+ base.class_eval do
38
+ layout :msg_iov, NNIOVec.ptr,
39
+ :msg_iovlen, :int,
40
+ :msg_control, :pointer,
41
+ :msg_controllen, :size_t
42
+ end
43
+ end
44
+ end
45
+
46
+ class NNMsgHdr < FFI::Struct
47
+ include NNMsgHdrLayout
48
+
49
+ def msg_iov
50
+ self[:msg_iov]
51
+ end
52
+
53
+ def msg_iov=(structure)
54
+ self[:msg_iov] = structure
55
+ end
56
+
57
+ def msg_iovlen
58
+ self[:msg_iovlen]
59
+ end
60
+
61
+ def msg_iovlen=(length)
62
+ self[:msg_iovlen] = length
63
+ end
64
+
65
+ def msg_control
66
+ self[:msg_control]
67
+ end
68
+
69
+ def msg_control=(pointer)
70
+ self[:msg_control] = pointer
71
+ end
72
+
73
+ def msg_controllen
74
+ self[:msg_controllen]
75
+ end
76
+
77
+ def msg_controllen=(value)
78
+ self[:msg_controllen] = value
79
+ end
80
+ end
81
+
82
+ module NNCMsgHdrLayout
83
+ def self.included(base)
84
+ base.class_eval do
85
+ layout :cmsg_len, :size_t,
86
+ :cmsg_level, :int,
87
+ :cmsg_type, :int
88
+ end
89
+ end
90
+ end
91
+
92
+ class NNCMsgHdr < FFI::Struct
93
+ include NNCMsgHdrLayout
94
+
95
+ def cmsg_len
96
+ self[:cmsg_len]
97
+ end
98
+
99
+ def cmsg_len=(length)
100
+ self[:csmg_len] = length
101
+ end
102
+
103
+ def cmsg_level
104
+ self[:cmsg_level]
105
+ end
106
+
107
+ def cmsg_level=(level)
108
+ self[:cmsg_level] = level
109
+ end
110
+
111
+ def cmsg_type
112
+ self[:cmsg_type]
113
+ end
114
+
115
+ def cmsg_type=(type)
116
+ self[:cmsg_type] = type
117
+ end
118
+ end
119
+
120
+ end
121
+ end
@@ -0,0 +1,3 @@
1
+ module NNCore
2
+ VERSION = "0.1.0"
3
+ end
data/lib/nn-core.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'ffi'
2
+ require 'nn-core/version'
3
+
4
+ require 'nn-core/libnanomsg'
5
+ require 'nn-core/structs'
6
+ require 'nn-core/constants'
data/nn-core.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "nn-core/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "nn-core"
7
+ s.version = NNCore::VERSION
8
+ s.authors = ["Chuck Remes"]
9
+ s.email = ["git@chuckremes.com"]
10
+ s.homepage = "http://github.com/chuckremes/nn-core"
11
+ s.summary = %q{Wraps the nanomsg networking library using Ruby FFI (foreign function interface).}
12
+ s.description = %q{Wraps the nanomsg networking library using the ruby FFI (foreign
13
+ function interface). It only exposes the native C API to Ruby. Other gems should use this gem
14
+ to build an API using Ruby idioms.}
15
+
16
+ s.rubyforge_project = "nn-core"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ s.add_runtime_dependency "ffi"
24
+ s.add_development_dependency "rspec", ["~> 2.6"]
25
+ s.add_development_dependency "rake"
26
+ end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_bind" do
5
+
6
+ context "given an initialized library and" do
7
+ before(:each) { LibNanomsg.nn_init }
8
+ after(:each) { LibNanomsg.nn_term }
9
+
10
+
11
+ context "given a valid socket" do
12
+ before(:each) do
13
+ LibNanomsg.nn_init
14
+ @socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
15
+ end
16
+
17
+ after(:each) do
18
+ LibNanomsg.nn_close(@socket)
19
+ LibNanomsg.nn_term
20
+ end
21
+
22
+ it "returns a non-zero endpoint number for a valid INPROC address" do
23
+ rc = LibNanomsg.nn_bind(@socket, "inproc://some_address")
24
+ rc.should > 0
25
+ end
26
+
27
+ it "returns a non-zero endpoint number for a valid IPC address" do
28
+ rc = LibNanomsg.nn_bind(@socket, "ipc:///tmp/some_address")
29
+ rc.should > 0
30
+ end
31
+
32
+ it "returns a non-zero endpoint number for a valid TCP address" do
33
+ rc = LibNanomsg.nn_bind(@socket, "tcp://127.0.0.1:5555")
34
+ rc.should > 0
35
+ end
36
+
37
+ it "returns -1 for an invalid INPROC address" do
38
+ rc = LibNanomsg.nn_bind(@socket, "inproc:/missing_first_slash")
39
+ rc.should == -1
40
+ LibNanomsg.nn_errno.should == EINVAL
41
+ end
42
+
43
+ it "returns -1 for an invalid INPROC address (too long)" do
44
+ rc = LibNanomsg.nn_bind(@socket, "inproc://#{'a' * (NN_INPROCB_NAMELEN_MAX + 1)}")
45
+ rc.should == -1
46
+ LibNanomsg.nn_errno.should == ENAMETOOLONG
47
+ end
48
+
49
+ it "returns -1 for an invalid IPC address" do
50
+ rc = LibNanomsg.nn_bind(@socket, "ipc:/missing_slashes)")
51
+ rc.should == -1
52
+ LibNanomsg.nn_errno.should == EINVAL
53
+ end
54
+
55
+ it "returns -1 for an invalid TCP address (missing address)" do
56
+ rc = LibNanomsg.nn_bind(@socket, "tcp://")
57
+ rc.should == -1
58
+ LibNanomsg.nn_errno.should == EINVAL
59
+ end
60
+
61
+ it "returns -1 for an invalid TCP address (non-numeric port)" do
62
+ rc = LibNanomsg.nn_bind(@socket, "tcp://192.168.0.1:port")
63
+ rc.should == -1
64
+ LibNanomsg.nn_errno.should == EINVAL
65
+ end
66
+
67
+ it "returns -1 for an invalid TCP address (port number is out of range)" do
68
+ rc = LibNanomsg.nn_bind(@socket, "tcp://192.168.0.1:65536")
69
+ rc.should == -1
70
+ LibNanomsg.nn_errno.should == EINVAL
71
+ end
72
+
73
+ it "returns -1 for an unsupported transport protocol" do
74
+ rc = LibNanomsg.nn_bind(@socket, "zmq://192.168.0.1:65536")
75
+ rc.should == -1
76
+ LibNanomsg.nn_errno.should == EPROTONOSUPPORT
77
+ end
78
+
79
+ it "returns -1 for specifying a non-existent device using TCP transport" do
80
+ rc = LibNanomsg.nn_bind(@socket, "tcp://eth5:5555")
81
+ rc.should == -1
82
+ LibNanomsg.nn_errno.should == ENODEV
83
+ end
84
+
85
+ it "returns -1 when binding to an existing endpoint" do
86
+ rc = LibNanomsg.nn_bind(@socket, "inproc://some_endpoint")
87
+ rc = LibNanomsg.nn_bind(@socket, "inproc://some_endpoint")
88
+ rc.should == -1
89
+ LibNanomsg.nn_errno.should == EADDRINUSE
90
+ end
91
+
92
+ end
93
+
94
+ context "given an invalid file descriptor" do
95
+
96
+ it "returns -1 and sets nn_errno to EBADF" do
97
+ rc = LibNanomsg.nn_bind(0, "inproc://some_endpoint")
98
+ rc.should == -1
99
+ LibNanomsg.nn_errno.should == EBADF
100
+ end
101
+
102
+ end
103
+
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_close" do
5
+
6
+ context "given an unitialized library" do
7
+ before(:each) { LibNanomsg.nn_term }
8
+
9
+ it "returns -1 and sets nn_errno to EFAULT" do
10
+ LibNanomsg.nn_close(0).should == -1
11
+ LibNanomsg.nn_errno.should == EFAULT
12
+ end
13
+
14
+ end
15
+
16
+ context "given an initialized library and" do
17
+ before(:each) { LibNanomsg.nn_init }
18
+ after(:each) { LibNanomsg.nn_term }
19
+
20
+ context "given a valid socket" do
21
+ before(:each) { @socket = LibNanomsg.nn_socket(AF_SP, NN_PUB) }
22
+
23
+ it "returns 0" do
24
+ LibNanomsg.nn_close(@socket).should be_zero
25
+ end
26
+
27
+ end
28
+
29
+ context "given an invalid file descriptor" do
30
+
31
+ it "returns -1 and sets nn_errno to EBADF" do
32
+ LibNanomsg.nn_close(0).should == -1
33
+ LibNanomsg.nn_errno.should == EBADF
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,112 @@
1
+ require 'spec_helper'
2
+
3
+ # NOTE!
4
+ #
5
+ # Any specs added to this file should be mirrored in the nn_bind_spec.rb file too
6
+ # so that coverage remains complete.
7
+ #
8
+
9
+ module NNCore
10
+ describe "nn_connect" do
11
+
12
+ context "given an initialized library and" do
13
+ before(:each) { LibNanomsg.nn_init }
14
+ after(:each) { LibNanomsg.nn_term }
15
+
16
+
17
+ context "given a valid socket" do
18
+ before(:each) do
19
+ LibNanomsg.nn_init
20
+ @socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
21
+ end
22
+
23
+ after(:each) do
24
+ LibNanomsg.nn_close(@socket)
25
+ LibNanomsg.nn_term
26
+ end
27
+
28
+ it "returns a non-zero endpoint number for a valid INPROC address" do
29
+ rc = LibNanomsg.nn_connect(@socket, "inproc://some_address")
30
+ rc.should > 0
31
+ end
32
+
33
+ it "returns a non-zero endpoint number for a valid IPC address" do
34
+ rc = LibNanomsg.nn_connect(@socket, "ipc:///tmp/some_address")
35
+ rc.should > 0
36
+ end
37
+
38
+ it "returns a non-zero endpoint number for a valid TCP address" do
39
+ rc = LibNanomsg.nn_connect(@socket, "tcp://127.0.0.1:5555")
40
+ rc.should > 0
41
+ end
42
+
43
+ it "returns -1 for an invalid INPROC address" do
44
+ rc = LibNanomsg.nn_connect(@socket, "inproc:/missing_first_slash")
45
+ rc.should == -1
46
+ LibNanomsg.nn_errno.should == EINVAL
47
+ end
48
+
49
+ it "returns -1 for an invalid INPROC address (too long)" do
50
+ rc = LibNanomsg.nn_connect(@socket, "inproc://#{'a' * (NN_INPROCB_NAMELEN_MAX + 1)}")
51
+ rc.should == -1
52
+ LibNanomsg.nn_errno.should == ENAMETOOLONG
53
+ end
54
+
55
+ it "returns -1 for an invalid IPC address" do
56
+ rc = LibNanomsg.nn_connect(@socket, "ipc:/missing_slashes)")
57
+ rc.should == -1
58
+ LibNanomsg.nn_errno.should == EINVAL
59
+ end
60
+
61
+ # it "returns -1 for an invalid TCP address (missing port)" do
62
+ # rc = LibNanomsg.nn_connect(@socket, "tcp://*:")
63
+ # rc.should == -1
64
+ # LibNanomsg.nn_errno.should == EINVAL
65
+ # end
66
+ #
67
+ # it "returns -1 for an invalid TCP address (non-numeric port)" do
68
+ # rc = LibNanomsg.nn_connect(@socket, "tcp://192.168.0.1:port")
69
+ # rc.should == -1
70
+ # LibNanomsg.nn_errno.should == EINVAL
71
+ # end
72
+ #
73
+ # it "returns -1 for an invalid TCP address (port number is out of range)" do
74
+ # rc = LibNanomsg.nn_connect(@socket, "tcp://192.168.0.1:65536")
75
+ # rc.should == -1
76
+ # LibNanomsg.nn_errno.should == EINVAL
77
+ # end
78
+
79
+ it "returns -1 for an unsupported transport protocol" do
80
+ rc = LibNanomsg.nn_connect(@socket, "zmq://192.168.0.1:65536")
81
+ rc.should == -1
82
+ LibNanomsg.nn_errno.should == EPROTONOSUPPORT
83
+ end
84
+
85
+ it "returns -1 for specifying a non-existent device using TCP transport" do
86
+ pending # currently fails
87
+ rc = LibNanomsg.nn_connect(@socket, "tcp://doesntexist:5555")
88
+ rc.should == -1
89
+ LibNanomsg.nn_errno.should == ENODEV
90
+ end
91
+
92
+ it "returns 2 when connecting twice to an existing endpoint" do
93
+ rc = LibNanomsg.nn_connect(@socket, "inproc://some_endpoint")
94
+ rc = LibNanomsg.nn_connect(@socket, "inproc://some_endpoint")
95
+ rc.should == 2
96
+ end
97
+
98
+ end
99
+
100
+ context "given an invalid file descriptor" do
101
+
102
+ it "returns -1 and sets nn_errno to EBADF" do
103
+ rc = LibNanomsg.nn_connect(0, "inproc://some_endpoint")
104
+ rc.should == -1
105
+ LibNanomsg.nn_errno.should == EBADF
106
+ end
107
+
108
+ end
109
+
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_getsockopt" do
5
+
6
+ context "given an initialized library and" do
7
+ before(:each) { LibNanomsg.nn_init }
8
+ after(:each) { LibNanomsg.nn_term }
9
+
10
+
11
+ context "given a valid socket" do
12
+ before(:each) do
13
+ LibNanomsg.nn_init
14
+ @socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
15
+ @option = FFI::MemoryPointer.new(:int32)
16
+ @size = FFI::MemoryPointer.new :size_t
17
+ @size.write_int(4)
18
+ end
19
+
20
+ after(:each) do
21
+ LibNanomsg.nn_close(@socket)
22
+ LibNanomsg.nn_term
23
+ end
24
+
25
+ it "NN_LINGER returns a default of 1000" do
26
+ rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_LINGER, @option, @size)
27
+ rc.should == 0
28
+ @option.read_int.should == 1000
29
+ end
30
+
31
+ it "NN_SNDBUF returns a default of 128KB" do
32
+ rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_SNDBUF, @option, @size)
33
+ rc.should == 0
34
+ @option.read_int.should == 131072
35
+ end
36
+
37
+ it "NN_RCVBUF returns a default of 128KB" do
38
+ rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_RCVBUF, @option, @size)
39
+ rc.should == 0
40
+ @option.read_int.should == 131072
41
+ end
42
+
43
+ it "NN_SNDTIMEO returns a default of -1" do
44
+ rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_SNDTIMEO, @option, @size)
45
+ rc.should == 0
46
+ @option.read_int.should == -1
47
+ end
48
+
49
+ it "NN_RCVTIMEO returns a default of -1" do
50
+ rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_RCVTIMEO, @option, @size)
51
+ rc.should == 0
52
+ @option.read_int.should == -1
53
+ end
54
+
55
+ it "NN_RECONNECT_IVL returns a default of 100 (units are milliseconds)" do
56
+ rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_RECONNECT_IVL, @option, @size)
57
+ rc.should == 0
58
+ @option.read_int.should == 100
59
+ end
60
+
61
+ it "NN_RECONNECT_IVL_MAX returns a default of 0 (units are milliseconds)" do
62
+ rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_RECONNECT_IVL_MAX, @option, @size)
63
+ rc.should == 0
64
+ @option.read_int.should == 0
65
+ end
66
+
67
+ it "NN_SNDPRIO returns a default of 8" do
68
+ rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, NN_SNDPRIO, @option, @size)
69
+ rc.should == 0
70
+ @option.read_int.should == 8
71
+ end
72
+
73
+
74
+ context "given an unsupported socket level" do
75
+
76
+ SOCKET_OPTIONS.keys.each do |socket_option|
77
+ it "socket option #{socket_option} returns -1 and set nn_errno to EBADF" do
78
+ option = FFI::MemoryPointer.new(:int32)
79
+ size = FFI::MemoryPointer.new :size_t
80
+ size.write_int(4)
81
+
82
+ rc = LibNanomsg.nn_getsockopt(@socket, 100, SOCKET_OPTIONS[socket_option], option, size)
83
+ rc.should == -1
84
+ LibNanomsg.nn_errno.should == ENOPROTOOPT
85
+ end
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+
92
+ context "given a bad socket file descriptor" do
93
+
94
+ SOCKET_OPTIONS.keys.each do |socket_option|
95
+ it "socket option #{socket_option} returns -1 and set nn_errno to EBADF" do
96
+ option = FFI::MemoryPointer.new(:int32)
97
+ size = FFI::MemoryPointer.new :size_t
98
+ size.write_int(4)
99
+
100
+ rc = LibNanomsg.nn_getsockopt(0, NN_SOL_SOCKET, SOCKET_OPTIONS[socket_option], option, size)
101
+ rc.should == -1
102
+ LibNanomsg.nn_errno.should == EBADF
103
+ end
104
+ end
105
+ end
106
+
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_init" do
5
+
6
+ it "returns 0 for successful library initialization" do
7
+ LibNanomsg.nn_init.should be_zero
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_recv" do
5
+
6
+ context "given an initialized library and" do
7
+ before(:each) { LibNanomsg.nn_init }
8
+ after(:each) { LibNanomsg.nn_term }
9
+
10
+
11
+ context "given a valid connected sender and receiver socket pair" do
12
+ before(:each) do
13
+ LibNanomsg.nn_init
14
+ @socket = LibNanomsg.nn_socket(AF_SP, NN_PAIR)
15
+ @sender = LibNanomsg.nn_socket(AF_SP, NN_PAIR)
16
+ @endpoint = LibNanomsg.nn_bind(@socket, "inproc://some_endpoint")
17
+ LibNanomsg.nn_connect(@sender, "inproc://some_endpoint")
18
+ end
19
+
20
+ after(:each) do
21
+ LibNanomsg.nn_close(@socket)
22
+ LibNanomsg.nn_close(@sender)
23
+ LibNanomsg.nn_term
24
+ end
25
+
26
+ context "given a pre-allocated buffer" do
27
+
28
+ it "returns the number of bytes received" do
29
+ string = "ABC"
30
+ LibNanomsg.nn_send(@sender, string, string.size, 0)
31
+
32
+ buffer = FFI::MemoryPointer.new(5)
33
+ nbytes = LibNanomsg.nn_recv(@socket, buffer, 5, 0)
34
+ nbytes.should == 3
35
+ buffer.read_string.should == string
36
+ end
37
+ end
38
+
39
+ context "given no pre-allocated buffer" do
40
+
41
+
42
+ it "returns the number of bytes received and returns the buffer" do
43
+ string = "ABC"
44
+ LibNanomsg.nn_send(@sender, string, string.size, 0)
45
+
46
+ buffer = FFI::MemoryPointer.new(:pointer)
47
+ nbytes = LibNanomsg.nn_recv(@socket, buffer, NN_MSG, 0)
48
+ nbytes.should == 3
49
+ buffer.get_pointer(0).read_string.should == string
50
+ end
51
+ end
52
+ end
53
+
54
+ context "given an invalid socket" do
55
+
56
+ it "returns -1 and sets nn_errno to EBADF" do
57
+ rc = LibNanomsg.nn_send(0, "ABC", 3, 0)
58
+ rc.should == -1
59
+ LibNanomsg.nn_errno.should == EBADF
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_send" do
5
+
6
+ context "given an initialized library and" do
7
+ before(:each) { LibNanomsg.nn_init }
8
+ after(:each) { LibNanomsg.nn_term }
9
+
10
+
11
+ context "given a valid socket" do
12
+ before(:each) do
13
+ LibNanomsg.nn_init
14
+ @socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
15
+ end
16
+
17
+ after(:each) do
18
+ LibNanomsg.nn_close(@socket)
19
+ LibNanomsg.nn_term
20
+ end
21
+
22
+ context "given a valid endpoint" do
23
+ before(:each) do
24
+ @endpoint = LibNanomsg.nn_bind(@socket, "inproc://some_endpoint")
25
+ end
26
+
27
+ it "returns the number of bytes sent" do
28
+ nbytes = LibNanomsg.nn_send(@socket, "ABC", 3, 0)
29
+ nbytes.should == 3
30
+ end
31
+ end
32
+
33
+ context "disconnected from all endpoints" do
34
+ it "returns the number of bytes queued" do
35
+ nbytes = LibNanomsg.nn_send(@socket, "ABC", 3, 0)
36
+ nbytes.should == 3
37
+ end
38
+ end
39
+ end
40
+
41
+ context "given an invalid socket" do
42
+
43
+ it "returns -1 and sets nn_errno to EBADF" do
44
+ rc = LibNanomsg.nn_send(0, "ABC", 3, 0)
45
+ rc.should == -1
46
+ LibNanomsg.nn_errno.should == EBADF
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_setsockopt" do
5
+
6
+ context "given an initialized library and" do
7
+ before(:each) { LibNanomsg.nn_init }
8
+ after(:each) { LibNanomsg.nn_term }
9
+
10
+
11
+ context "given a valid socket" do
12
+ before(:each) do
13
+ LibNanomsg.nn_init
14
+ @socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
15
+ @option = FFI::MemoryPointer.new(:int32)
16
+ @size = FFI::MemoryPointer.new :size_t
17
+ @size.write_int(4)
18
+ end
19
+
20
+ after(:each) do
21
+ LibNanomsg.nn_close(@socket)
22
+ LibNanomsg.nn_term
23
+ end
24
+
25
+ SOCKET_OPTIONS.keys.each do |socket_option|
26
+
27
+ it "#{socket_option} overrides the default" do
28
+ @option.write_int(10)
29
+ rc = LibNanomsg.nn_setsockopt(@socket, NN_SOL_SOCKET, SOCKET_OPTIONS[socket_option], @option, 4)
30
+ rc.should == 0
31
+ rc = LibNanomsg.nn_getsockopt(@socket, NN_SOL_SOCKET, SOCKET_OPTIONS[socket_option], @option, @size)
32
+ rc.should == 0
33
+
34
+ @option.read_int.should == 10
35
+ end
36
+ end
37
+
38
+
39
+ context "given an unsupported socket level" do
40
+
41
+ SOCKET_OPTIONS.keys.each do |socket_option|
42
+ it "socket option #{socket_option} returns -1 and set nn_errno to EBADF" do
43
+ option = FFI::MemoryPointer.new(:int32)
44
+
45
+ rc = LibNanomsg.nn_setsockopt(@socket, 100, SOCKET_OPTIONS[socket_option], option, 4)
46
+ rc.should == -1
47
+ LibNanomsg.nn_errno.should == ENOPROTOOPT
48
+ end
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+
55
+ context "given a bad socket file descriptor" do
56
+
57
+ SOCKET_OPTIONS.keys.each do |socket_option|
58
+ it "socket option #{socket_option} returns -1 and set nn_errno to EBADF" do
59
+ option = FFI::MemoryPointer.new(:int32)
60
+ size = FFI::MemoryPointer.new :size_t
61
+ size.write_int(4)
62
+
63
+ rc = LibNanomsg.nn_getsockopt(0, NN_SOL_SOCKET, SOCKET_OPTIONS[socket_option], option, size)
64
+ rc.should == -1
65
+ LibNanomsg.nn_errno.should == EBADF
66
+ end
67
+ end
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_shutdown" do
5
+
6
+ context "given an initialized library and" do
7
+ before(:each) { LibNanomsg.nn_init }
8
+ after(:each) { LibNanomsg.nn_term }
9
+
10
+
11
+ context "given a valid socket and" do
12
+ before(:each) do
13
+ LibNanomsg.nn_init
14
+ @socket = LibNanomsg.nn_socket(AF_SP, NN_PUB)
15
+ end
16
+
17
+ after(:each) do
18
+ LibNanomsg.nn_close(@socket)
19
+ LibNanomsg.nn_term
20
+ end
21
+
22
+ context "given a valid endpoint" do
23
+ before(:each) do
24
+ @endpoint = LibNanomsg.nn_bind(@socket, "inproc://some_endpoint")
25
+ end
26
+
27
+ it "returns 0" do
28
+ rc = LibNanomsg.nn_shutdown(@socket, @endpoint)
29
+ rc.should == 0
30
+ end
31
+ end
32
+
33
+ context "given an invalid endpoint" do
34
+ it "returns -1 and set nn_errno to EINVAL" do
35
+ rc = LibNanomsg.nn_shutdown(@socket, 0)
36
+ rc.should == -1
37
+ LibNanomsg.nn_errno.should == EINVAL
38
+ end
39
+ end
40
+ end
41
+
42
+ context "given an invalid socket" do
43
+
44
+ it "returns -1 and sets nn_errno to EBADF" do
45
+ rc = LibNanomsg.nn_shutdown(0, 0)
46
+ rc.should == -1
47
+ LibNanomsg.nn_errno.should == EBADF
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_socket" do
5
+
6
+ context "given an initialized library and" do
7
+ before(:each) { LibNanomsg.nn_init }
8
+ after(:each) { LibNanomsg.nn_term }
9
+
10
+ PROTOCOLS.keys.each do |protocol|
11
+
12
+ context "given a supported protocol #{protocol} and address family AF_SP" do
13
+
14
+ it "returns a non-zero file descriptor for the socket" do
15
+ @socket = LibNanomsg.nn_socket(AF_SP, PROTOCOLS[protocol])
16
+
17
+ @socket.should == 0
18
+
19
+ LibNanomsg.nn_close(@socket)
20
+ end
21
+ end
22
+
23
+ context "given a supported protocol #{protocol} and address family AF_SP_RAW" do
24
+
25
+ it "returns -1 and sets nn_errno to EINVAL" do
26
+ @socket = LibNanomsg.nn_socket(AF_SP_RAW, PROTOCOLS[protocol])
27
+
28
+ @socket.should == -1
29
+ LibNanomsg.nn_errno.should == EINVAL
30
+ end
31
+ end
32
+
33
+ end
34
+
35
+ context "given an unsupported address family" do
36
+
37
+ # it "nn_socket returns -1 and sets nn_errno to EAFNOSUPPORT" do
38
+ # LibNanomsg.nn_socket(0, NN_PUB).should == -1
39
+ # LibNanomsg.nn_errno.should == EAFNOSUPPORT
40
+ # end
41
+ end
42
+
43
+ context "given an unsupported protocol and a supported address family" do
44
+
45
+ it "AF_SP returns -1 and sets nn_errno to EINVAL" do
46
+ LibNanomsg.nn_socket(AF_SP, 0).should == -1
47
+ LibNanomsg.nn_errno.should == EINVAL
48
+ end
49
+
50
+ it "AF_SP_RAW returns -1 and sets nn_errno to EINVAL" do
51
+ LibNanomsg.nn_socket(AF_SP_RAW, 0).should == -1
52
+ LibNanomsg.nn_errno.should == EINVAL
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_term" do
5
+
6
+ context "given an initialized library and" do
7
+ before(:each) { LibNanomsg.nn_init }
8
+ after(:each) { LibNanomsg.nn_term }
9
+
10
+ it "returns 0 for successful library termination" do
11
+ LibNanomsg.nn_term.should be_zero
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ module NNCore
4
+ describe "nn_bind" do
5
+
6
+ context "given an initialized library" do
7
+ before(:each) { LibNanomsg.nn_init }
8
+ after(:each) { LibNanomsg.nn_term }
9
+
10
+ it "returns 0 and populates the pointers with the major, minor and patch version numbers" do
11
+ major = FFI::MemoryPointer.new(:int)
12
+ minor = FFI::MemoryPointer.new(:int)
13
+ patch = FFI::MemoryPointer.new(:int)
14
+
15
+ # there is no return value for this function
16
+ LibNanomsg.nn_version(major, minor, patch)
17
+
18
+ major.read_int.should >= 0
19
+ minor.read_int.should >= 0
20
+ patch.read_int.should >= 0
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require 'bundler/setup'
2
+ require 'nn-core'
3
+
4
+ module NNCore
5
+ SOCKET_OPTIONS = {
6
+ :NN_LINGER => NN_LINGER,
7
+ :NN_SNDBUF => NN_SNDBUF,
8
+ :NN_RCVBUF => NN_RCVBUF,
9
+ :NN_SENDTIMEO => NN_SNDTIMEO,
10
+ :NN_RCVTIMEO => NN_RCVTIMEO,
11
+ :NN_RECONNECT_IVL => NN_RECONNECT_IVL,
12
+ :NN_RECONNECT_IVL_MAX => NN_RECONNECT_IVL_MAX,
13
+ :NN_SNDPRIO => NN_SNDPRIO
14
+ }
15
+
16
+ PROTOCOLS = {
17
+ :NN_PUB => NN_PUB,
18
+ :NN_SUB => NN_SUB
19
+ }
20
+
21
+ ADDRESS_FAMILIES = {
22
+ :AF_SP => AF_SP,
23
+ :AF_SP_RAW => AF_SP_RAW
24
+ }
25
+ end
metadata ADDED
@@ -0,0 +1,176 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nn-core
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Chuck Remes
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ prerelease: false
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ none: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ none: false
28
+ name: ffi
29
+ type: :runtime
30
+ - !ruby/object:Gem::Dependency
31
+ prerelease: false
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ~>
35
+ - !ruby/object:Gem::Version
36
+ version: '2.6'
37
+ none: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ version: '2.6'
43
+ none: false
44
+ name: rspec
45
+ type: :development
46
+ - !ruby/object:Gem::Dependency
47
+ prerelease: false
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ none: false
54
+ version_requirements: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ none: false
60
+ name: rake
61
+ type: :development
62
+ description: ! 'Wraps the nanomsg networking library using the ruby FFI (foreign
63
+
64
+ function interface). It only exposes the native C API to Ruby. Other gems should
65
+ use this gem
66
+
67
+ to build an API using Ruby idioms.'
68
+ email:
69
+ - git@chuckremes.com
70
+ executables: []
71
+ extensions: []
72
+ extra_rdoc_files: []
73
+ files:
74
+ - !binary |-
75
+ LmdpdGlnbm9yZQ==
76
+ - !binary |-
77
+ LnJzcGVj
78
+ - !binary |-
79
+ QXV0aG9ycy50eHQ=
80
+ - !binary |-
81
+ R2VtZmlsZQ==
82
+ - !binary |-
83
+ SGlzdG9yeS50eHQ=
84
+ - !binary |-
85
+ UkVBRE1FLm1k
86
+ - !binary |-
87
+ UmFrZWZpbGU=
88
+ - !binary |-
89
+ bGliL25uLWNvcmUucmI=
90
+ - !binary |-
91
+ bGliL25uLWNvcmUvY29uc3RhbnRzLnJi
92
+ - !binary |-
93
+ bGliL25uLWNvcmUvbGlibmFub21zZy5yYg==
94
+ - !binary |-
95
+ bGliL25uLWNvcmUvc3RydWN0cy5yYg==
96
+ - !binary |-
97
+ bGliL25uLWNvcmUvdmVyc2lvbi5yYg==
98
+ - !binary |-
99
+ bm4tY29yZS5nZW1zcGVj
100
+ - !binary |-
101
+ c3BlYy9ubl9iaW5kX3NwZWMucmI=
102
+ - !binary |-
103
+ c3BlYy9ubl9jbG9zZV9zcGVjLnJi
104
+ - !binary |-
105
+ c3BlYy9ubl9jb25uZWN0X3NwZWMucmI=
106
+ - !binary |-
107
+ c3BlYy9ubl9nZXRzb2Nrb3B0X3NwZWMucmI=
108
+ - !binary |-
109
+ c3BlYy9ubl9pbml0X3NwZWMucmI=
110
+ - !binary |-
111
+ c3BlYy9ubl9yZWN2X3NwZWMucmI=
112
+ - !binary |-
113
+ c3BlYy9ubl9zZW5kX3NwZWMucmI=
114
+ - !binary |-
115
+ c3BlYy9ubl9zZXRzb2Nrb3B0X3NwZWMucmI=
116
+ - !binary |-
117
+ c3BlYy9ubl9zaHV0ZG93bl9zcGVjLnJi
118
+ - !binary |-
119
+ c3BlYy9ubl9zb2NrZXRfc3BlYy5yYg==
120
+ - !binary |-
121
+ c3BlYy9ubl90ZXJtX3NwZWMucmI=
122
+ - !binary |-
123
+ c3BlYy9ubl92ZXJzaW9uX3NwZWMucmI=
124
+ - !binary |-
125
+ c3BlYy9zcGVjX2hlbHBlci5yYg==
126
+ homepage: http://github.com/chuckremes/nn-core
127
+ licenses: []
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ! '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ none: false
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ none: false
144
+ requirements: []
145
+ rubyforge_project: nn-core
146
+ rubygems_version: 1.8.24
147
+ signing_key:
148
+ specification_version: 3
149
+ summary: Wraps the nanomsg networking library using Ruby FFI (foreign function interface).
150
+ test_files:
151
+ - !binary |-
152
+ c3BlYy9ubl9iaW5kX3NwZWMucmI=
153
+ - !binary |-
154
+ c3BlYy9ubl9jbG9zZV9zcGVjLnJi
155
+ - !binary |-
156
+ c3BlYy9ubl9jb25uZWN0X3NwZWMucmI=
157
+ - !binary |-
158
+ c3BlYy9ubl9nZXRzb2Nrb3B0X3NwZWMucmI=
159
+ - !binary |-
160
+ c3BlYy9ubl9pbml0X3NwZWMucmI=
161
+ - !binary |-
162
+ c3BlYy9ubl9yZWN2X3NwZWMucmI=
163
+ - !binary |-
164
+ c3BlYy9ubl9zZW5kX3NwZWMucmI=
165
+ - !binary |-
166
+ c3BlYy9ubl9zZXRzb2Nrb3B0X3NwZWMucmI=
167
+ - !binary |-
168
+ c3BlYy9ubl9zaHV0ZG93bl9zcGVjLnJi
169
+ - !binary |-
170
+ c3BlYy9ubl9zb2NrZXRfc3BlYy5yYg==
171
+ - !binary |-
172
+ c3BlYy9ubl90ZXJtX3NwZWMucmI=
173
+ - !binary |-
174
+ c3BlYy9ubl92ZXJzaW9uX3NwZWMucmI=
175
+ - !binary |-
176
+ c3BlYy9zcGVjX2hlbHBlci5yYg==