nn-core 0.1.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.
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==