ruby-osc 0.3.4 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c7a3ed90d79d95eb44be4341b5e0e3cd13b19826
4
+ data.tar.gz: 860511677129f64f5de77c761c6adce36accad05
5
+ SHA512:
6
+ metadata.gz: 5508fc05070baa6616cf7494e7a020c313dbfdf5e870e7db58c45e0d7c80cd3f89b054cec32f5bee0bb78615c232c39e7c38bcd8b2f5a53a09471178a8a1efc6
7
+ data.tar.gz: 3373a2777db15a1c6e4fe73ca7bacc0808ba8fba2ad66653bcd2c46b7e0e687a7f4a4146a9129ffc7c28b493bbe28701b7fe1dea054bf6230e67e0afd904e921
@@ -13,32 +13,32 @@ Concise OSC implementation for Ruby
13
13
  require 'rubygems'
14
14
  require 'ruby-osc'
15
15
 
16
- include OSC
17
-
18
- server = Server.new 9090
19
- client = Client.new 9090
20
-
21
- server.add_pattern /.*/ do |*args| # this will match any address
22
- p "/.*/: #{ args.join(', ') }"
23
- end
24
-
25
- server.add_pattern %r{foo/.*} do |*args| # this will match any /foo node
26
- p "%r{foo/.*}: #{ args.join(', ') }"
27
- end
28
-
29
- server.add_pattern "/foo/bar" do |*args| # this will just match /foo/bar address
30
- p "'/foo/bar': #{ args.join(', ') }"
31
- end
32
-
33
- server.add_pattern "/exit" do |*args| # this will just match /exit address
34
- exit
16
+ include OSC
17
+
18
+ OSC.run do
19
+ server = Server.new 9090
20
+ client = Client.new 9090
21
+
22
+ server.add_pattern /.*/ do |*args| # this will match any address
23
+ p "/.*/: #{ args.join(', ') }"
24
+ end
25
+
26
+ server.add_pattern %r{foo/.*} do |*args| # this will match any /foo node
27
+ p "%r{foo/.*}: #{ args.join(', ') }"
28
+ end
29
+
30
+ server.add_pattern "/foo/bar" do |*args| # this will just match /foo/bar address
31
+ p "'/foo/bar': #{ args.join(', ') }"
32
+ end
33
+
34
+ server.add_pattern "/exit" do |*args| # this will just match /exit address
35
+ exit
36
+ end
37
+
38
+ client.send Message.new('/foo/bar', 1, 1.2, 'a string')
39
+ client.send Message.new('/foo/bar/zar', 1, 1.2, 'a string')
40
+ client.send Bundle.new(Time.now + 2, Message.new('/exit'))
35
41
  end
36
-
37
- client.send Message.new('/foo/bar', 1, 1.2, 'a string')
38
- client.send Message.new('/foo/bar/zar', 1, 1.2, 'a string')
39
- client.send Bundle.new(Time.now + 2, Message.new('/exit'))
40
-
41
- OSC::Thread.join
42
42
 
43
43
  == REQUIREMENTS:
44
44
 
@@ -1,30 +1,30 @@
1
1
  require 'rubygems'
2
- # require "#{ File.dirname __FILE__ }/../lib/ruby-osc"
3
2
  require 'ruby-osc'
4
3
 
5
- include OSC
4
+ include OSC
6
5
 
7
- server = Server.new 9090
8
- client = Client.new 9090
6
+ OSC.run do
7
+ server = Server.new 9090
8
+ client = Client.new 9090
9
9
 
10
- server.add_pattern /.*/ do |*args| # this will match any address
11
- p "/.*/: #{ args.join(', ') }"
12
- end
10
+ server.add_pattern /.*/ do |*args| # this will match any address
11
+ p "/.*/: #{ args.join(', ') }"
12
+ end
13
13
 
14
- server.add_pattern %r{foo/.*} do |*args| # this will match any /foo node
15
- p "%r{foo/.*}: #{ args.join(', ') }"
16
- end
14
+ server.add_pattern %r{foo/.*} do |*args| # this will match any /foo node
15
+ p "%r{foo/.*}: #{ args.join(', ') }"
16
+ end
17
17
 
18
- server.add_pattern "/foo/bar" do |*args| # this will just match /foo/bar address
19
- p "'/foo/bar': #{ args.join(', ') }"
20
- end
18
+ server.add_pattern "/foo/bar" do |*args| # this will just match /foo/bar address
19
+ p "'/foo/bar': #{ args.join(', ') }"
20
+ end
21
21
 
22
- server.add_pattern "/exit" do |*args| # this will just match /exit address
23
- exit
24
- end
22
+ server.add_pattern "/exit" do |*args| # this will just match /exit address
23
+ exit
24
+ end
25
25
 
26
- client.send Message.new('/foo/bar', 1, 1.2, 'a string')
27
- client.send Message.new('/foo/bar/zar', 1, 1.2, 'a string')
28
- client.send Bundle.new(Time.now + 2, Message.new('/exit'))
29
26
 
30
- OSC::Thread.join
27
+ client.send Message.new('/foo/bar', 1, 1.2, 'a string')
28
+ client.send Message.new('/foo/bar/zar', 1, 1.2, 'a string')
29
+ client.send Bundle.new(Time.now + 2, Message.new('/exit'))
30
+ end
@@ -4,6 +4,9 @@ require 'socket' # Strange side effects with eventmachine udp client and SuperCo
4
4
  require 'strscan'
5
5
  require 'thread'
6
6
 
7
+ $:.unshift( File.join( File.dirname( __FILE__), '..', 'lib' ) )
8
+
9
+ # encoding: UTF-8
7
10
  require 'ruby-osc/message'
8
11
  require 'ruby-osc/bundle'
9
12
  require 'ruby-osc/server'
@@ -11,24 +14,16 @@ require 'ruby-osc/client'
11
14
  require "ruby-osc/version"
12
15
 
13
16
  module OSC
14
- Thread = EM.reactor_running? ? nil : Thread.new {
15
- EM.run do
16
- EM.error_handler { |e| puts e }
17
- EM.set_quantum 5
18
- end
19
- }
20
- Thread.run if RUBY_VERSION.to_f >= 1.9
21
-
22
17
  class DecodeError < StandardError; end
23
-
18
+
24
19
  class Blob < String; end
25
-
20
+
26
21
  module OSCArgument
27
22
  def to_osc_type
28
23
  raise NotImplementedError, "#to_osc_type method should be implemented for #{ self.class }"
29
24
  end
30
25
  end
31
-
26
+
32
27
  def self.coerce_argument arg
33
28
  case arg
34
29
  when OSCArgument then arg.to_osc_type
@@ -36,21 +31,29 @@ module OSC
36
31
  when String, Float, Fixnum, Blob, String then arg # Pure osc 1.0 specification
37
32
  else raise(TypeError, "#{ arg.inspect } is not a valid Message argument") end
38
33
  end
39
-
34
+
40
35
  def self.decode str #:nodoc:
41
36
  str.match(/^#bundle/) ? Bundle.decode(str) : Message.decode(str)
42
37
  end
43
-
38
+
44
39
  def self.padding_size size
45
- (4 - (size) % 4) % 4
40
+ (4 - (size) % 4) % 4
41
+ end
42
+
43
+ def self.run
44
+ EM.run do
45
+ EM.error_handler { |e| puts e }
46
+ EM.set_quantum 5
47
+ yield
48
+ end
46
49
  end
47
-
50
+
48
51
  def self.encoding_directive obj #:nodoc:
49
52
  case obj
50
53
  when Float then [obj, 'f', 'g']
51
54
  when Fixnum then [obj, 'i', 'N']
52
- when Blob then [[obj.size, obj], 'b', "Na*x#{ padding_size obj.size + 4 }"]
53
- when String then [obj, 's', "Z*x#{ padding_size obj.size + 1 }"]
55
+ when Blob then [[obj.bytesize, obj], 'b', "Na*x#{ padding_size obj.bytesize + 4 }"]
56
+ when String then [obj, 's', "Z*x#{ padding_size obj.bytesize + 1 }"]
54
57
  when Time
55
58
  t1, fr = (obj.to_f + 2208988800).divmod(1)
56
59
  t2 = (fr * (2**32)).to_i
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module OSC
2
3
  class Bundle < Array
3
4
  attr_accessor :timetag
@@ -15,7 +16,7 @@ module OSC
15
16
  time, tag, dir = OSC.encoding_directive @timetag
16
17
  time.pack dir
17
18
  else "\000\000\000\000\000\000\000\001" end
18
-
19
+
19
20
  "#bundle\000#{ timetag }" + collect do |x|
20
21
  x = x.encode
21
22
  [x.size].pack('N') + x
@@ -25,26 +26,26 @@ module OSC
25
26
  def self.decode string
26
27
  string.sub! /^#bundle\000/, ''
27
28
  t1, t2, content_str = string.unpack('N2a*')
28
-
29
+
29
30
  timetag = t1 == 0 && t2 == 1 ? nil : Time.at(t1 + t2 / (2**32.0) - 2_208_988_800)
30
31
  scanner = StringScanner.new content_str
31
32
  args = []
32
-
33
+
33
34
  until scanner.eos?
34
35
  size = scanner.scan(/.{4}/).unpack('N').first
35
36
  arg_str = scanner.scan(/.{#{ size }}/nm) rescue raise(DecodeError, "An error occured while trying to decode bad formatted osc bundle")
36
37
  args << OSC.decode(arg_str)
37
38
  end
38
-
39
+
39
40
  new timetag, *args
40
41
  end
41
-
42
+
42
43
  def == other
43
44
  self.class == other.class and self.timetag == other.timetag and self.to_a == other.to_a
44
45
  end
45
46
 
46
47
  def to_a; Array.new self; end
47
-
48
+
48
49
  def to_s
49
50
  "OSC::Bundle(#{ self.join(', ') })"
50
51
  end
@@ -1,12 +1,17 @@
1
+ # encoding: UTF-8
2
+ require 'socket' # Strange side effects with eventmachine udp client and SuperCollider
3
+
1
4
  # From the Funaba osc gem:
2
5
  module OSC
3
6
  class Client
4
-
5
- def initialize port, host = 'localhost'
7
+
8
+ def initialize port, host = '127.0.0.1'
6
9
  @socket = UDPSocket.new
10
+ @socket = UDPSocket.open
11
+ @socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
7
12
  @socket.connect host, port
8
13
  end
9
-
14
+
10
15
  def send mesg, *args
11
16
  @socket.send mesg.encode, 0
12
17
  end
@@ -15,25 +20,25 @@ end
15
20
 
16
21
  # module OSC
17
22
  # class Client
18
- #
23
+ #
19
24
  # def initialize port, address = 'localhost'
20
25
  # @address, @port = address, port
21
26
  # run
22
27
  # end
23
- #
28
+ #
24
29
  # def run
25
30
  # @connection = EventMachine.open_datagram_socket 'localhost', 0, Connection
26
31
  # end
27
- #
32
+ #
28
33
  # def stop
29
34
  # @connection.close_connection if @connection
30
35
  # end
31
- #
36
+ #
32
37
  # def send item
33
- # @connection.send_datagram item.encode, @address, @port
38
+ # @connection.send_datagram item.encode, @address, @port
34
39
  # end
35
- #
40
+ #
36
41
  # class Connection < EventMachine::Connection #:nodoc:
37
42
  # end
38
43
  # end
39
- # end
44
+ # end
@@ -31,36 +31,51 @@ module OSC
31
31
 
32
32
  def self.decode string
33
33
  scanner = StringScanner.new string
34
- address, tags = (1..2).map do
35
- string = scanner.scan(/[^\000]+\000/)
36
- scanner.pos += OSC.padding_size(string.size)
37
- string.chomp("\000")
38
- end
34
+ msg = self.decode_message scanner
35
+ raise DecodeError if not scanner.eos?
36
+ return msg
37
+ end
39
38
 
40
- args = []
41
- tags.scan(/\w/) do |tag|
42
- case tag
43
- when 'i'
44
- int = scanner.scan(/.{4}/nm).unpack('N').first
45
- args.push( int > (2**31-1) ? int - 2**32 : int )
46
- when 'f'
47
- args.push scanner.scan(/.{4}/nm).unpack('g').first
48
- when 's'
49
- str = scanner.scan(/[^\000]+\000/)
50
- scanner.pos += OSC.padding_size(str.size)
51
- args.push str.chomp("\000")
52
- when 'b'
53
- size = scanner.scan(/.{4}/).unpack('N').first
54
- str = scanner.scan(/.{#{ size }}/nm)
55
- scanner.pos += OSC.padding_size(size + 4)
56
- args.push Blob.new(str)
57
- else
58
- raise DecodeError, "#{ t } is not a known tag"
39
+ def self.decode_message scanner
40
+ pos = scanner.pos
41
+ begin
42
+ address, tags = (1..2).map do
43
+ string = scanner.scan(/[^\000]+\000/)
44
+ raise DecodeError, "no address or tags" if string.nil?
45
+ scanner.pos += OSC.padding_size(string.bytesize)
46
+ string.chomp("\000")
59
47
  end
60
- end
61
48
 
62
- new address, *args
49
+ args = []
50
+ tags.scan(/\w/) do |tag|
51
+ case tag
52
+ when 'i'
53
+ int = scanner.scan(/.{4}/nm).unpack('N').first
54
+ args.push( int > (2**31-1) ? int - 2**32 : int )
55
+ when 'f'
56
+ args.push scanner.scan(/.{4}/nm).unpack('g').first
57
+ when 's'
58
+ str = scanner.scan(/[^\000]+\000/)
59
+ scanner.pos += OSC.padding_size(str.size)
60
+ str = str.respond_to?(:force_encoding) ? str.force_encoding('UTF-8') : str
61
+ args.push str.chomp("\000")
62
+ when 'b'
63
+ size = scanner.scan(/.{4}/).unpack('N').first
64
+ str = scanner.scan(/.{#{ size }}/nm)
65
+ scanner.pos += OSC.padding_size(size + 4)
66
+ args.push Blob.new(str)
67
+ else
68
+ raise DecodeError, "#{ tag } is not a known tag"
69
+ end
70
+ end
71
+ new address, *args
72
+ end
73
+ rescue DecodeError => e
74
+ scanner.pos = pos
75
+ raise e
76
+ rescue => e
77
+ scanner.pos = pos
78
+ raise DecodeError, e
63
79
  end
64
-
65
80
  end
66
81
  end
@@ -1,9 +1,8 @@
1
-
2
1
  module OSC
3
2
  class Server
4
3
  attr_accessor :port, :address
5
4
 
6
- def initialize port, address = 'localhost'
5
+ def initialize port, address = '127.0.0.1'
7
6
  @port, @address = port, address
8
7
  @queue, @patterns = [], []
9
8
  @mutex = Mutex.new
@@ -37,7 +36,7 @@ module OSC
37
36
  when Message
38
37
  dispatch decoded
39
38
  end
40
- rescue => e
39
+ rescue => e
41
40
  warn "Bad data received: #{ e }"
42
41
  end
43
42
 
@@ -55,7 +54,7 @@ module OSC
55
54
  end
56
55
 
57
56
  def dispatch message
58
- @patterns.each do |pat, block|
57
+ @patterns.each do |pat, block|
59
58
  block.call(*message.to_a) if pat === message.address
60
59
  end
61
60
  end
@@ -66,7 +65,7 @@ module OSC
66
65
  end
67
66
 
68
67
  def receive_data data
69
- @server.receive(data)
68
+ @server.receive(data)
70
69
  end
71
70
  end
72
71
  end
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  module Osc
2
- VERSION = "0.3.4"
3
+ VERSION = "0.4.1"
3
4
  end
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  require "#{ File.dirname __FILE__ }/spec_helper"
2
3
 
3
4
  describe Bundle do
@@ -12,11 +13,11 @@ describe Bundle do
12
13
  it "should rise TypeError if passing passing incorrect type" do
13
14
  lambda { Bundle.new Time.now, 1 }.should raise_error(TypeError)
14
15
  end
15
-
16
+
16
17
  it "should raise TypeError if timetag is not Time" do
17
18
  lambda { Bundle.new 1 }.should raise_error(TypeError)
18
19
  end
19
-
20
+
20
21
  it "should accept nil for timetag" do
21
22
  Bundle.new nil
22
23
  end
@@ -38,15 +39,15 @@ describe Bundle do
38
39
  Bundle.decode(@expected).should == @bundle
39
40
  end
40
41
  end
41
-
42
+
42
43
  describe 'Empty bundle nil timetag' do
43
44
  before do
44
45
  @bundle = Bundle.new
45
- @expected = "#bundle\000\000\000\000\000\000\000\000\001"
46
+ @expected = "#bundle\000\000\000\000\000\000\000\000\001".force_encoding("binary")
46
47
  end
47
48
  it_should_behave_like 'Encodable Bundle'
48
49
  end
49
-
50
+
50
51
  describe 'Empty bundle with timetag' do
51
52
  before do
52
53
  @bundle = Bundle.new Time.at(1251420949.16959)
@@ -54,7 +55,7 @@ describe Bundle do
54
55
  end
55
56
  it_should_behave_like 'Encodable Bundle'
56
57
  end
57
-
58
+
58
59
  describe 'Bundle with timetag and messages' do
59
60
  before do
60
61
  @bundle = Bundle.new Time.at(946702800), Message.new('/bar/foo', 4, 3, 2, 1), Message.new('/foo/bar', 1, 2, 3, 4)
@@ -62,15 +63,15 @@ describe Bundle do
62
63
  end
63
64
  it_should_behave_like 'Encodable Bundle'
64
65
  end
65
-
66
+
66
67
  describe 'Nested bundles' do
67
68
  before do
68
69
  @bundle = Bundle.new( nil, Bundle.new(nil, Message.new('/a')), Message.new('/b') )
69
- @expected = "#bundle\000\000\000\000\000\000\000\000\001\000\000\000\034#bundle\000\000\000\000\000\000\000\000\001\000\000\000\b/a\000\000,\000\000\000\000\000\000\b/b\000\000,\000\000\000"
70
+ @expected = "#bundle\000\000\000\000\000\000\000\000\001\000\000\000\034#bundle\000\000\000\000\000\000\000\000\001\000\000\000\b/a\000\000,\000\000\000\000\000\000\b/b\000\000,\000\000\000".force_encoding("binary")
70
71
  end
71
72
  it_should_behave_like 'Encodable Bundle'
72
73
  end
73
-
74
+
74
75
  describe 'Complex blob' do
75
76
  before do
76
77
  data = [ 83, 67, 103, 102, 0, 0, 0, 1, 0, 1, 4, 104, 111, 108, 97, 0, 2, 67, -36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 1, 2, 0, 0 ].pack('C*')
@@ -79,7 +80,7 @@ describe Bundle do
79
80
  end
80
81
  it_should_behave_like 'Encodable Bundle'
81
82
  end
82
-
83
+
83
84
  describe 'Complex blob 2' do
84
85
  before do
85
86
  data = [ 83, 67, 103, 102, 0, 0, 0, 1, 0, 1, 2, 97, 109, 0, 7, 0, 0, 0, 0, 63, 0, 0, 0, 63, -128, 0, 0, 64, 0, 0, 0, -62, -58, 0, 0, 64, -96, 0, 0, -64, -128, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 103, 97, 116, 101, 0, 0, 9, 112, 111, 114, 116, 97, 100, 111, 114, 97, 0, 1, 10, 109, 111, 100, 117, 108, 97, 100, 111, 114, 97, 0, 2, 3, 97, 109, 112, 0, 3, 0, 8, 7, 67, 111, 110, 116, 114, 111, 108, 1, 0, 0, 0, 4, 0, 0, 1, 1, 1, 1, 6, 83, 105, 110, 79, 115, 99, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 2, -1, -1, 0, 0, 1, 6, 77, 117, 108, 65, 100, 100, 1, 0, 3, 0, 1, 0, 0, 0, 1, 0, 0, -1, -1, 0, 1, -1, -1, 0, 1, 1, 6, 83, 105, 110, 79, 115, 99, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, -1, -1, 0, 0, 2, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 2, 0, 3, 0, 0, 0, 2, 0, 0, 2, 6, 69, 110, 118, 71, 101, 110, 1, 0, 17, 0, 1, 0, 0, 0, 0, 0, 0, -1, -1, 0, 2, -1, -1, 0, 0, -1, -1, 0, 2, -1, -1, 0, 3, -1, -1, 0, 0, -1, -1, 0, 3, -1, -1, 0, 2, -1, -1, 0, 4, -1, -1, 0, 2, -1, -1, 0, 3, -1, -1, 0, 5, -1, -1, 0, 6, -1, -1, 0, 0, -1, -1, 0, 3, -1, -1, 0, 5, -1, -1, 0, 6, 1, 12, 66, 105, 110, 97, 114, 121, 79, 112, 85, 71, 101, 110, 2, 0, 2, 0, 1, 0, 2, 0, 4, 0, 0, 0, 5, 0, 0, 2, 3, 79, 117, 116, 2, 0, 2, 0, 0, 0, 0, -1, -1, 0, 0, 0, 6, 0, 0, 0, 0 ].pack('C*')
@@ -88,9 +89,9 @@ describe Bundle do
88
89
  end
89
90
  it_should_behave_like 'Encodable Bundle'
90
91
  end
91
-
92
+
92
93
  it 'Should raise OSC::DecodeError with bad encoded bundle' do
93
- bad_data = "#bundle\000\000\000\000\000\000\000\000\001\000\000\000\034#bundle\000\000\000\000\000\001\000\000\000\b/a\000\000,\000\000\000\000\000\000\b/b\000\000,\000\000\000"
94
+ bad_data = "#bundle\000\000\000\000\000\000\000\000\001\000\000\000\034#bundle\000\000\000\000\000\001\000\000\000\b/a\000\000,\000\000\000\000\000\000\b/b\000\000,\000\000\000".force_encoding("binary")
94
95
  lambda { Bundle.decode bad_data }.should raise_error(DecodeError)
95
96
  end
96
97
  end
@@ -1,56 +1,59 @@
1
+ # encoding: UTF-8
1
2
  require "#{ File.dirname __FILE__ }/spec_helper"
2
3
 
3
4
  describe Message do
4
-
5
5
  it "should raise TypeError if passing wrong type" do
6
- lambda { Message.new('address', Class) }.should raise_error(TypeError)
6
+ expect { Message.new('address', Class) }.to raise_error(TypeError)
7
7
  end
8
-
8
+
9
9
  it "should raise TypeError if not passing a string for address" do
10
- lambda { Message.new(OSC) }.should raise_error(TypeError)
10
+ expect { Message.new(OSC) }.to raise_error(TypeError)
11
11
  end
12
-
12
+
13
13
  it "should have address" do
14
14
  Message.new('/foo/bar').address.should == '/foo/bar'
15
15
  end
16
+
17
+ it "should accept utf8 address" do
18
+ Message.new('/foo/bär').address.should == '/foo/bär'
19
+ end
16
20
 
17
21
  it "should collect args" do
18
22
  Message.new('/foo/bar', 1, 2, 3, 4).args.size.should == 4
19
23
  end
20
-
24
+
21
25
  it "should accept integer" do
22
26
  Message.new('/foo/bar', 1).args.should == [1]
23
27
  end
24
-
28
+
25
29
  it "should should accept float" do
26
30
  Message.new('/foo/bar', 1.0).args.should == [1.0]
27
31
  end
28
-
32
+
29
33
  it "should accept string" do
30
34
  Message.new('/foo/bar', 'string').args.should == ['string']
31
35
  end
32
-
36
+
33
37
  it "should accept Blob" do
34
38
  Message.new('/foo/bar', Blob.new('blob')).args.should == [Blob.new('blob')]
35
39
  end
36
-
40
+
37
41
  it "should convert to array" do
38
42
  Message.new('/foo/bar', 1, 2, 3, 4).to_a.should == ['/foo/bar', 1, 2, 3, 4]
39
43
  end
40
-
44
+
41
45
  describe 'Custom argument coercion' do
42
-
43
46
  before do
44
47
  TrueClass.send(:include, OSCArgument)
45
48
  TrueClass.send( :define_method, :to_osc_type){ 1 }
46
49
  FalseClass.send(:include, OSCArgument)
47
50
  FalseClass.send( :define_method, :to_osc_type){ 0 }
48
51
  Hash.send(:include, OSCArgument)
49
- Hash.send( :define_method, :to_osc_type) do
52
+ Hash.send( :define_method, :to_osc_type) do
50
53
  self.to_a.collect{ |pair| pair.collect{ |a| OSC.coerce_argument a } }
51
54
  end
52
55
  end
53
-
56
+
54
57
  it "should accept true" do
55
58
  Message.new('/foo/bar', true).args.should == [1]
56
59
  end
@@ -63,50 +66,50 @@ describe Message do
63
66
  Message.new('/foo/bar', {:a => :b}).args.should == ["a", "b"]
64
67
  end
65
68
  end
66
-
69
+
67
70
  describe 'Encode/decode' do
68
71
  shared_examples_for 'Encodable Message' do
69
72
  it "should encode" do
70
73
  @message.encode.should == @expected
71
74
  end
72
-
75
+
73
76
  it "should decode to message" do
74
77
  Message.decode(@expected).should be_a(Message)
75
78
  end
76
-
79
+
77
80
  it "should decode address" do
78
81
  Message.decode(@expected).address.should == @message.address
79
82
  end
80
-
83
+
81
84
  it "should actually decode" do
82
85
  Message.decode(@expected).to_a.inspect.should == @message.to_a.inspect.to_s # Problem with float comparing
83
86
  end
84
87
  end
85
-
88
+
86
89
  describe 'Address' do
87
90
  before do
88
91
  @message = Message.new('/foo/bar/long/very/long/long/long/address')
89
- @expected = "/foo/bar/long/very/long/long/long/address\000\000\000,\000\000\000"
92
+ @expected = "/foo/bar/long/very/long/long/long/address\000\000\000,\000\000\000".force_encoding("binary")
90
93
  end
91
94
  it_should_behave_like 'Encodable Message'
92
95
  end
93
-
96
+
94
97
  describe 'Integer' do
95
98
  before do
96
99
  @message = Message.new('/foo/barz', 2)
97
- @expected = "/foo/barz\000\000\000,i\000\000\000\000\000\002"
100
+ @expected = "/foo/barz\000\000\000,i\000\000\000\000\000\002".force_encoding("binary")
98
101
  end
99
102
  it_should_behave_like 'Encodable Message'
100
103
  end
101
-
104
+
102
105
  describe 'Negative Integer' do
103
106
  before do
104
107
  @message = Message.new('/foo/barz', -2)
105
- @expected = "/foo/barz\000\000\000,i\000\000\377\377\377\376"
108
+ @expected = "/foo/barz\000\000\000,i\000\000\377\377\377\376".force_encoding("binary")
106
109
  end
107
110
  it_should_behave_like 'Encodable Message'
108
111
  end
109
-
112
+
110
113
  describe 'Float' do
111
114
  before do
112
115
  @message = Message.new('/foo/bar', 1.100000023841858)
@@ -114,7 +117,7 @@ describe Message do
114
117
  end
115
118
  it_should_behave_like 'Encodable Message'
116
119
  end
117
-
120
+
118
121
  describe 'Negative Float' do
119
122
  before do
120
123
  @message = Message.new('/foo/bar', -1.100000023841858)
@@ -122,11 +125,19 @@ describe Message do
122
125
  end
123
126
  it_should_behave_like 'Encodable Message'
124
127
  end
125
-
128
+
126
129
  describe 'String' do
127
130
  before do
128
131
  @message = Message.new('/foo/bar', 'a string to encode')
129
- @expected = "/foo/bar\000\000\000\000,s\000\000a string to encode\000\000"
132
+ @expected = "/foo/bar\000\000\000\000,s\000\000a string to encode\000\000".force_encoding("binary")
133
+ end
134
+ it_should_behave_like 'Encodable Message'
135
+ end
136
+
137
+ describe 'UTF8 String' do
138
+ before do
139
+ @message = Message.new('/foo/bar', 'a string to äncode')
140
+ @expected = "/foo/bar\000\000\000\000,s\000\000a string to äncode\000".force_encoding("binary")
130
141
  end
131
142
  it_should_behave_like 'Encodable Message'
132
143
  end
@@ -138,27 +149,35 @@ describe Message do
138
149
  end
139
150
  it_should_behave_like 'Encodable Message'
140
151
  end
141
-
152
+
142
153
  describe 'Blob' do
143
154
  before do
144
155
  @message = Message.new('/foo/bar', Blob.new('test blob'))
145
- @expected = "/foo/bar\000\000\000\000,b\000\000\000\000\000\ttest blob\000\000\000"
156
+ @expected = "/foo/bar\000\000\000\000,b\000\000\000\000\000\ttest blob\000\000\000".force_encoding("binary")
146
157
  end
147
158
  it_should_behave_like 'Encodable Message'
148
-
159
+
149
160
  it "should raise if size doesn't correspond and return empty message" do
150
161
  lambda do
151
- Message.decode("/foo/bar\000\000\000\000,b\000\000\000\000\000\020test blob\000\000\000")
162
+ Message.decode("/foo/bar\000\000\000\000,b\000\000\000\000\000\020test blob\000\000\000".force_encoding("binary"))
152
163
  end.should raise_error
153
164
  end
154
165
  end
155
-
166
+
156
167
  describe 'Lots of ints' do
157
168
  before do
158
169
  @message = Message.new('/bar/foo', 4, 3, 2, 1)
159
- @expected = "/bar/foo\000\000\000\000,iiii\000\000\000\000\000\000\004\000\000\000\003\000\000\000\002\000\000\000\001"
170
+ @expected = "/bar/foo\000\000\000\000,iiii\000\000\000\000\000\000\004\000\000\000\003\000\000\000\002\000\000\000\001".force_encoding("binary")
160
171
  end
161
172
  it_should_behave_like 'Encodable Message'
162
173
  end
163
- end
174
+
175
+ describe 'Invalid message' do
176
+ it "should raise if invalid tag is used" do
177
+ lambda do
178
+ Message.decode("/foo/bar\000\000\000\000,k\000\000\000\000\000\020test blob\000\000\000".force_encoding("binary"))
179
+ end.should raise_exception(DecodeError)
180
+ end
181
+ end
182
+ end
164
183
  end
@@ -1,3 +1,4 @@
1
+ # encoding: UTF-8
1
2
  require "#{ File.dirname __FILE__ }/spec_helper"
2
3
 
3
4
  describe Server do
@@ -1,7 +1,7 @@
1
- require 'rubygems'
1
+ # encoding: UTF-8
2
2
  require 'rspec'
3
3
 
4
- $:.unshift( File.join( File.dirname( __FILE__), '..', 'lib' ) )
4
+ $:.unshift( File.join( File.dirname( __FILE__), '..', 'lib' ) )
5
5
 
6
6
  require 'ruby-osc'
7
7
  include OSC
@@ -0,0 +1,37 @@
1
+ require 'benchmark'
2
+
3
+ $:.unshift( File.join( File.dirname( __FILE__), 'lib' ) )
4
+
5
+ require 'ruby-osc/streamscanner'
6
+
7
+ @ss = OSC::StreamScanner.new
8
+
9
+ count = 10_000
10
+
11
+ Benchmark.bm(23) do |x|
12
+ x.report("add new string") do
13
+ count.times do
14
+ @ss << "/bar/foo\000\000\000\000,iiii\000\000\000\000\000\000\004\000\000\000\003\000\000\000\002\000\000\000\001".force_encoding("binary")
15
+ end
16
+ end
17
+
18
+ x.report("parse string") do
19
+ count.times do
20
+ @ss.tryparse
21
+ end
22
+ end
23
+
24
+
25
+ x.report("try parse each message") do
26
+ count.times do
27
+ OSC::Message.decode("/bar/foo\000\000\000\000,iiii\000\000\000\000\000\000\004\000\000\000\003\000\000\000\002\000\000\000\001".force_encoding("binary"))
28
+ end
29
+ end
30
+
31
+ x.report("parse failure") do
32
+ count.times do
33
+ @ss.tryparse rescue nil
34
+ end
35
+ end
36
+ end
37
+
metadata CHANGED
@@ -1,50 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-osc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
5
- prerelease:
4
+ version: 0.4.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Macario
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2011-08-03 00:00:00.000000000 -05:00
13
- default_executable:
11
+ date: 2013-07-06 00:00:00.000000000 Z
14
12
  dependencies:
15
13
  - !ruby/object:Gem::Dependency
16
14
  name: rspec
17
- requirement: &2161094580 !ruby/object:Gem::Requirement
18
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
19
16
  requirements:
20
- - - ! '>='
17
+ - - '>='
21
18
  - !ruby/object:Gem::Version
22
19
  version: 2.6.0
23
20
  type: :development
24
21
  prerelease: false
25
- version_requirements: *2161094580
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.6.0
26
27
  - !ruby/object:Gem::Dependency
27
28
  name: bundler
28
- requirement: &2161093920 !ruby/object:Gem::Requirement
29
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '1.0'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *2161093920
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
37
41
  - !ruby/object:Gem::Dependency
38
42
  name: eventmachine
39
- requirement: &2161093260 !ruby/object:Gem::Requirement
40
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
41
44
  requirements:
42
- - - ! '>='
45
+ - - '>='
43
46
  - !ruby/object:Gem::Version
44
47
  version: 0.12.8
45
48
  type: :runtime
46
49
  prerelease: false
47
- version_requirements: *2161093260
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.12.8
48
55
  description: Concise OSC Ruby implementation
49
56
  email:
50
57
  - macarui@gmail.com
@@ -69,30 +76,29 @@ files:
69
76
  - spec/message_spec.rb
70
77
  - spec/server_spec.rb
71
78
  - spec/spec_helper.rb
72
- has_rdoc: true
79
+ - streamscanner_benchmark.rb
73
80
  homepage: http://makarius.me
74
81
  licenses: []
82
+ metadata: {}
75
83
  post_install_message:
76
84
  rdoc_options: []
77
85
  require_paths:
78
86
  - lib
79
87
  required_ruby_version: !ruby/object:Gem::Requirement
80
- none: false
81
88
  requirements:
82
- - - ! '>='
89
+ - - '>='
83
90
  - !ruby/object:Gem::Version
84
91
  version: '0'
85
92
  required_rubygems_version: !ruby/object:Gem::Requirement
86
- none: false
87
93
  requirements:
88
- - - ! '>='
94
+ - - '>='
89
95
  - !ruby/object:Gem::Version
90
96
  version: '0'
91
97
  requirements: []
92
98
  rubyforge_project: ruby-osc
93
- rubygems_version: 1.6.2
99
+ rubygems_version: 2.0.0
94
100
  signing_key:
95
- specification_version: 3
101
+ specification_version: 4
96
102
  summary: Concise OSC Ruby implementation
97
103
  test_files:
98
104
  - spec/bundle_spec.rb