spread-client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Tim Lossen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # spread_client
2
+
3
+ portable ruby bindings for the [spread toolkit](http://www.spread.org), version 3.17.x
4
+
5
+ ## usage
6
+
7
+ sudo gem install spread-client -s http://gemcutter.org
8
+
9
+ then
10
+
11
+ require 'rubygems'
12
+ require 'spread_client'
13
+
14
+ c = SpreadClient::connect('bob')
15
+ c.join('chat')
16
+ c.multicast('chat', 'hello folks!')
17
+ c.leave('chat')
18
+ c.disconnect
19
+
20
+ ## setup instructions
21
+
22
+ 1. install the spread toolkit:
23
+
24
+ $ sudo port install spread
25
+
26
+ or
27
+
28
+ $ sudo apt-get install spread
29
+
30
+ or see <http://www.spread.org> for instructions on how to install from source.
31
+
32
+ 2. create a simple `spread.conf`:
33
+
34
+ # one spread daemon running on port 4803 on localhost
35
+ Spread_Segment 127.0.0.255:4803 {
36
+ localhost 127.0.0.1
37
+ }
38
+
39
+ 3. start the spread daemon:
40
+
41
+ $ spread -n localhost -c spread.conf
42
+
43
+ ## Copyright
44
+
45
+ Copyright (c) 2009 Tim Lossen. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "spread-client"
8
+ gem.summary = "ruby bindings for libspread (built with ffi)"
9
+ gem.description = "portable ruby bindings for libspread (built with ffi)."
10
+ gem.email = "tim@lossen.de"
11
+ gem.homepage = "http://github.com/tlossen/spread_client"
12
+ gem.authors = ["Tim Lossen"]
13
+ gem.files.include('lib/**/*.rb')
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ require 'rake/rdoctask'
29
+ Rake::RDocTask.new do |rdoc|
30
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
31
+
32
+ rdoc.rdoc_dir = 'rdoc'
33
+ rdoc.title = "spread_client #{version}"
34
+ rdoc.rdoc_files.include('README*')
35
+ rdoc.rdoc_files.include('lib/**/*.rb')
36
+ end
37
+
38
+ task :test => :check_dependencies
39
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/example/demo.rb ADDED
@@ -0,0 +1,10 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'spread_client')
2
+
3
+ c = SpreadClient::connect('bob')
4
+ c.join('chat')
5
+ puts c.receive().inspect
6
+ c.multicast('chat', 'hello folks!')
7
+ puts c.receive().inspect
8
+ c.leave('chat')
9
+ puts c.receive().inspect
10
+ c.disconnect
@@ -0,0 +1,4 @@
1
+ # one spread daemon running on localhost:4803
2
+ Spread_Segment 127.0.0.255:4803 {
3
+ localhost 127.0.0.1
4
+ }
data/example/start.sh ADDED
@@ -0,0 +1 @@
1
+ spread -n localhost -c spread.conf
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'ffi'
3
+
4
+ require File.join(File.dirname(__FILE__), 'spread_client', 'ffi')
5
+ require File.join(File.dirname(__FILE__), 'spread_client', 'connection')
6
+ require File.join(File.dirname(__FILE__), 'spread_client', 'errors')
7
+ require File.join(File.dirname(__FILE__), 'spread_client', 'messages')
8
+
9
+
10
+
@@ -0,0 +1,163 @@
1
+ module SpreadClient
2
+
3
+ class Connection
4
+
5
+ UNRELIABLE_MESS = 0x00000001
6
+ RELIABLE_MESS = 0x00000002
7
+ FIFO_MESS = 0x00000004
8
+ CAUSAL_MESS = 0x00000008
9
+ AGREED_MESS = 0x00000010
10
+ SAFE_MESS = 0x00000020
11
+ REGULAR_MESS = 0x0000003f
12
+
13
+ SELF_DISCARD = 0x00000040
14
+ DROP_RECV = 0x01000000
15
+
16
+ REG_MEMB_MESS = 0x00001000
17
+ TRANSITION_MESS = 0x00002000
18
+ CAUSED_BY_JOIN = 0x00000100
19
+ CAUSED_BY_LEAVE = 0x00000200
20
+ CAUSED_BY_DISCONNECT = 0x00000400
21
+ CAUSED_BY_NETWORK = 0x00000800
22
+ MEMBERSHIP_MESS = 0x00003f00
23
+
24
+ ENDIAN_RESERVED = 0x80000080
25
+ RESERVED = 0x003fc000
26
+ REJECT_MESS = 0x00400000
27
+
28
+ SERVICE_TYPE = {
29
+ :unreliable => UNRELIABLE_MESS,
30
+ :reliable => RELIABLE_MESS,
31
+ :fifo => FIFO_MESS,
32
+ :causal => CAUSAL_MESS,
33
+ :agreed => AGREED_MESS,
34
+ :safe => SAFE_MESS
35
+ }
36
+
37
+ DEFAULT_SERVER = 'localhost'
38
+ DEFAULT_PORT = 4803
39
+ DEFAULT_NOTIFY = true
40
+ DEFAULT_PRIORITY = 0
41
+ DEFAULT_SERVICE_TYPE = :safe
42
+ DEFAULT_SELF_DISCARD = false
43
+ DEFAULT_MESSAGE_TYPE = 0
44
+
45
+ MAX_GROUPS = 16
46
+ MAX_GROUP_LENGTH = 32
47
+ MAX_MESSAGE_LENGTH = 512
48
+
49
+ def initialize(name, options = {}) #:nodoc:
50
+ @mbox, @name = *connect(name, options)
51
+ end
52
+
53
+ # the private group name of this connection.
54
+ def name
55
+ @name
56
+ end
57
+
58
+ # disconnect from the spread server.
59
+ def disconnect
60
+ result = SpreadClient.SP_disconnect(@mbox)
61
+ raise SpreadClient.error_for(result) unless result == 0
62
+ end
63
+
64
+ # join the given group.
65
+ def join(group)
66
+ result = SpreadClient.SP_join(@mbox, group)
67
+ raise SpreadClient.error_for(result) unless result == 0
68
+ end
69
+
70
+ # leave the given group.
71
+ def leave(group)
72
+ result = SpreadClient.SP_leave(@mbox, group)
73
+ raise SpreadClient.error_for(result) unless result == 0
74
+ end
75
+
76
+ # send a message to a group.
77
+ #
78
+ # options:
79
+ # * :service_type -- can be one of
80
+ # * :unreliable
81
+ # * :reliable
82
+ # * :fifo
83
+ # * :causal
84
+ # * :agreed
85
+ # * :safe (default)
86
+ # * :self_discard -- set this to true if you do not want to receive your own message (default is false)
87
+ def multicast(group, message, options = {})
88
+ options = { :service_type => DEFAULT_SERVICE_TYPE, :self_discard => DEFAULT_SELF_DISCARD }.merge(options)
89
+ service_type = SERVICE_TYPE[options[:service_type]] | (options[:self_discard] ? SELF_DISCARD : 0)
90
+ result = SpreadClient.SP_multicast(@mbox, service_type, group, DEFAULT_MESSAGE_TYPE,
91
+ message.length, message)
92
+ raise SpreadClient.error_for(result) if result < 0
93
+ end
94
+
95
+ # receive the next message or notification.
96
+ #
97
+ # this method blocks until a message is available.
98
+ def receive
99
+ service_type = FFI::MemoryPointer.new(:int)
100
+ sender = FFI::MemoryPointer.new(:char, MAX_GROUP_LENGTH)
101
+ num_groups = FFI::MemoryPointer.new(:int)
102
+ groups = FFI::MemoryPointer.new(:char, MAX_GROUPS * MAX_GROUP_LENGTH)
103
+ message_type = FFI::MemoryPointer.new(:int)
104
+ endian_mismatch = FFI::MemoryPointer.new(:int)
105
+ message = FFI::MemoryPointer.new(:char, MAX_MESSAGE_LENGTH)
106
+ result = SpreadClient.SP_receive(@mbox, service_type, sender, MAX_GROUPS, num_groups, groups,
107
+ message_type, endian_mismatch, MAX_MESSAGE_LENGTH, message)
108
+ raise SpreadClient.error_for(result) if result < 0
109
+ service_type = service_type.read_int
110
+ sender = sender.read_string
111
+ num_groups = num_groups.read_int
112
+ groups = read_groups(groups, num_groups)
113
+ message = message.read_string
114
+ case
115
+ when regularMessage?(service_type)
116
+ Message.new(sender, message)
117
+ when membershipMessage?(service_type)
118
+ Notification.new(sender, groups, causedBy(service_type))
119
+ end
120
+ end
121
+
122
+ private
123
+
124
+ def regularMessage?(type)
125
+ (type & REGULAR_MESS > 0) && !(type & REJECT_MESS > 0)
126
+ end
127
+
128
+ def membershipMessage?(type)
129
+ (type & MEMBERSHIP_MESS > 0) && !(type & REJECT_MESS > 0)
130
+ end
131
+
132
+ def causedBy(type)
133
+ case
134
+ when type & CAUSED_BY_JOIN > 0 then :join
135
+ when type & CAUSED_BY_LEAVE > 0 && type & REG_MEMB_MESS == 0 then :self_leave
136
+ when type & CAUSED_BY_LEAVE > 0 then :leave
137
+ when type & CAUSED_BY_DISCONNECT > 0 then :disconnect
138
+ when type & CAUSED_BY_NETWORK > 0 then :network
139
+ end
140
+ end
141
+
142
+ def connect(name, options = {})
143
+ options = { :server => DEFAULT_SERVER, :port => DEFAULT_PORT, :notify => DEFAULT_NOTIFY }.merge(options)
144
+ spread_server = "#{options[:port]}@#{options[:server]}"
145
+ notify = options[:notify] ? 1 : 0
146
+ mbox = FFI::MemoryPointer.new(:int)
147
+ private_group = FFI::MemoryPointer.new(:char, MAX_GROUP_LENGTH)
148
+ result = SpreadClient.SP_connect(spread_server, name, DEFAULT_PRIORITY, notify, mbox, private_group)
149
+ raise SpreadClient.error_for(result) unless result == 1
150
+ [mbox.read_int, private_group.read_string]
151
+ end
152
+
153
+ def read_groups(pointer, number)
154
+ groups = []
155
+ number.times do |i|
156
+ groups << pointer[i * MAX_GROUP_LENGTH].read_string
157
+ end
158
+ groups
159
+ end
160
+
161
+ end
162
+
163
+ end
@@ -0,0 +1,35 @@
1
+ module SpreadClient
2
+
3
+ class Error < ::RuntimeError; end
4
+
5
+ class IllegalSpread < Error; end
6
+ class CouldNotConnect < Error; end
7
+ class RejectQuota < Error; end
8
+ class RejectNoName < Error; end
9
+ class RejectIllegalName < Error; end
10
+ class RejectNotUnique < Error; end
11
+ class RejectVersion < Error; end
12
+ class ConnectionClosed < Error; end
13
+ class RejectAuth < Error; end
14
+
15
+ class IllegalSession < Error; end
16
+ class IllegalService < Error; end
17
+ class IllegalMessage < Error; end
18
+ class IllegalGroup < Error; end
19
+ class BufferTooShort < Error; end
20
+ class GroupsTooShort < Error; end
21
+ class MessageTooLong < Error; end
22
+
23
+ private
24
+
25
+ def self.error_for(code)
26
+ errors = [nil,
27
+ IllegalSpread, CouldNotConnect, RejectQuota, RejectNoName, RejectIllegalName,
28
+ RejectNotUnique, RejectVersion, ConnectionClosed, RejectAuth,
29
+ nil,
30
+ IllegalSession, IllegalService, IllegalMessage, IllegalGroup, BufferTooShort,
31
+ GroupsTooShort, MessageTooLong]
32
+ errors.at(code.abs) || Error
33
+ end
34
+
35
+ end
@@ -0,0 +1,41 @@
1
+ module SpreadClient
2
+ extend FFI::Library
3
+ ffi_lib "libspread"
4
+
5
+ # open a connection to the given spread server.
6
+ #
7
+ # options:
8
+ # * :server (default is 'localhost')
9
+ # * :port (default is 4803)
10
+ # * :notify -- set this to false if you do not want to receive any group
11
+ # membership notifications (default is true)
12
+ def self.connect(name, options = {})
13
+ Connection.new(name, options)
14
+ end
15
+
16
+ private
17
+
18
+ # int SP_connect(const char* spread name, const char* private name, int priority, int group_membership,
19
+ # mailbox* mbox, char* private group);
20
+ attach_function :SP_connect, [:string, :string, :int, :int, :pointer, :pointer], :int
21
+
22
+ # int SP_disconnect(mailbox mbox);
23
+ attach_function :SP_disconnect, [:int], :int
24
+
25
+ # int SP_join(mailbox mbox, const char* group);
26
+ attach_function :SP_join, [:int, :string], :int
27
+
28
+ # int SP_leave(mailbox mbox, const char* group);
29
+ attach_function :SP_leave, [:int, :string], :int
30
+
31
+ # int SP_multicast(mailbox mbox, service service_type, const char* group, int16 mess_type,
32
+ # int mess_len, const char* mess);
33
+ attach_function :SP_multicast, [:int, :int, :string, :int16, :int, :string], :int
34
+
35
+ # int SP_receive(mailbox mbox, service* service_type, char sender[MAX_GROUP_NAME], int max_groups,
36
+ # int* num groups, char groups[][MAX_GROUP_NAME], int16* mess_type, int* endian_mismatch,
37
+ # int max_mess_len, char* mess);
38
+ attach_function :SP_receive, [:int, :pointer, :pointer, :int, :pointer, :pointer, :pointer, :pointer,
39
+ :int, :pointer], :int
40
+
41
+ end
@@ -0,0 +1,22 @@
1
+ module SpreadClient
2
+
3
+ class Message
4
+ attr_reader :sender, :text
5
+
6
+ def initialize(sender, text) #:nodoc:
7
+ @sender = sender
8
+ @text = text
9
+ end
10
+ end
11
+
12
+ class Notification
13
+ attr_reader :group, :members, :cause
14
+
15
+ def initialize(group, members, cause) #:nodoc:
16
+ @group = group
17
+ @members = members
18
+ @cause = cause
19
+ end
20
+ end
21
+
22
+ end
@@ -0,0 +1,62 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{spread-client}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tim Lossen"]
12
+ s.date = %q{2009-12-11}
13
+ s.description = %q{portable ruby bindings for libspread (built with ffi).}
14
+ s.email = %q{tim@lossen.de}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "example/demo.rb",
27
+ "example/spread.conf",
28
+ "example/start.sh",
29
+ "lib/spread_client.rb",
30
+ "lib/spread_client/connection.rb",
31
+ "lib/spread_client/errors.rb",
32
+ "lib/spread_client/ffi.rb",
33
+ "lib/spread_client/messages.rb",
34
+ "spread-client.gemspec",
35
+ "test/helper.rb",
36
+ "test/test_connection.rb",
37
+ "test/test_connection_no_notify.rb",
38
+ "test/test_errors.rb"
39
+ ]
40
+ s.homepage = %q{http://github.com/tlossen/spread_client}
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.5}
44
+ s.summary = %q{ruby bindings for libspread (built with ffi)}
45
+ s.test_files = [
46
+ "test/helper.rb",
47
+ "test/test_connection.rb",
48
+ "test/test_connection_no_notify.rb",
49
+ "test/test_errors.rb"
50
+ ]
51
+
52
+ if s.respond_to? :specification_version then
53
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
54
+ s.specification_version = 3
55
+
56
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
57
+ else
58
+ end
59
+ else
60
+ end
61
+ end
62
+
data/test/helper.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'spread_client')
5
+
6
+ class Test::Unit::TestCase
7
+ end
@@ -0,0 +1,51 @@
1
+ require 'helper'
2
+
3
+ class TestConnection < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @c = SpreadClient::connect('bob')
7
+ rescue
8
+ raise "this test expects a spread server running at localhost:4803"
9
+ end
10
+
11
+ def teardown
12
+ @c.disconnect if @c
13
+ end
14
+
15
+ def test_self_join_message
16
+ @c.join('chat')
17
+ message = @c.receive
18
+ assert_equal SpreadClient::Notification, message.class
19
+ assert_equal :join, message.cause
20
+ end
21
+
22
+ def test_self_leave_message
23
+ @c.join('chat')
24
+ @c.receive
25
+ @c.leave('chat')
26
+ message = @c.receive
27
+ assert_equal SpreadClient::Notification, message.class
28
+ assert_equal :self_leave, message.cause
29
+ end
30
+
31
+ def test_multicast
32
+ @c.join('chat')
33
+ @c.receive
34
+ @c.multicast('chat', 'hello folks!')
35
+ message = @c.receive
36
+ assert_equal SpreadClient::Message, message.class
37
+ assert_equal @c.name, message.sender
38
+ assert_equal 'hello folks!', message.text
39
+ end
40
+
41
+ def test_multicast_with_self_discard
42
+ @c.join('chat')
43
+ @c.receive
44
+ @c.multicast('chat', 'one', :self_discard => true)
45
+ @c.multicast('chat', 'two')
46
+ message = @c.receive
47
+ assert_equal 'two', message.text
48
+ end
49
+
50
+
51
+ end
@@ -0,0 +1,22 @@
1
+ require 'helper'
2
+
3
+ class TestConnectionNoNotify < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @c = SpreadClient::connect('bob', :notify => false)
7
+ rescue
8
+ raise "this test expects a spread server running at localhost:4803"
9
+ end
10
+
11
+ def teardown
12
+ @c.disconnect if @c
13
+ end
14
+
15
+ def test_regular_message
16
+ @c.join('chat')
17
+ @c.multicast('chat', 'hello folks!')
18
+ message = @c.receive
19
+ assert_equal SpreadClient::Message, message.class
20
+ end
21
+
22
+ end
@@ -0,0 +1,31 @@
1
+ require 'helper'
2
+
3
+ class TestErrors < Test::Unit::TestCase
4
+
5
+ def test_error_for
6
+ assert_equal SpreadClient::IllegalSpread, SpreadClient.error_for(-1)
7
+ assert_equal SpreadClient::CouldNotConnect, SpreadClient.error_for(-2)
8
+ assert_equal SpreadClient::RejectQuota, SpreadClient.error_for(-3)
9
+ assert_equal SpreadClient::RejectNoName, SpreadClient.error_for(-4)
10
+ assert_equal SpreadClient::RejectIllegalName, SpreadClient.error_for(-5)
11
+ assert_equal SpreadClient::RejectNotUnique, SpreadClient.error_for(-6)
12
+ assert_equal SpreadClient::RejectVersion, SpreadClient.error_for(-7)
13
+ assert_equal SpreadClient::ConnectionClosed, SpreadClient.error_for(-8)
14
+ assert_equal SpreadClient::RejectAuth, SpreadClient.error_for(-9)
15
+
16
+ assert_equal SpreadClient::IllegalSession, SpreadClient.error_for(-11)
17
+ assert_equal SpreadClient::IllegalService, SpreadClient.error_for(-12)
18
+ assert_equal SpreadClient::IllegalMessage, SpreadClient.error_for(-13)
19
+ assert_equal SpreadClient::IllegalGroup, SpreadClient.error_for(-14)
20
+ assert_equal SpreadClient::BufferTooShort, SpreadClient.error_for(-15)
21
+ assert_equal SpreadClient::GroupsTooShort, SpreadClient.error_for(-16)
22
+ assert_equal SpreadClient::MessageTooLong, SpreadClient.error_for(-17)
23
+ end
24
+
25
+ def test_error_for_fallback
26
+ assert_equal SpreadClient::Error, SpreadClient.error_for(0)
27
+ assert_equal SpreadClient::Error, SpreadClient.error_for(-10)
28
+ assert_equal SpreadClient::Error, SpreadClient.error_for(-100)
29
+ end
30
+
31
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spread-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Lossen
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-11 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: portable ruby bindings for libspread (built with ffi).
17
+ email: tim@lossen.de
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README.md
25
+ files:
26
+ - .document
27
+ - .gitignore
28
+ - LICENSE
29
+ - README.md
30
+ - Rakefile
31
+ - VERSION
32
+ - example/demo.rb
33
+ - example/spread.conf
34
+ - example/start.sh
35
+ - lib/spread_client.rb
36
+ - lib/spread_client/connection.rb
37
+ - lib/spread_client/errors.rb
38
+ - lib/spread_client/ffi.rb
39
+ - lib/spread_client/messages.rb
40
+ - spread-client.gemspec
41
+ - test/helper.rb
42
+ - test/test_connection.rb
43
+ - test/test_connection_no_notify.rb
44
+ - test/test_errors.rb
45
+ has_rdoc: true
46
+ homepage: http://github.com/tlossen/spread_client
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.5
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: ruby bindings for libspread (built with ffi)
73
+ test_files:
74
+ - test/helper.rb
75
+ - test/test_connection.rb
76
+ - test/test_connection_no_notify.rb
77
+ - test/test_errors.rb