ruby-osc 0.3.4 → 0.4.1

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.
@@ -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