bunny 0.2.0 → 0.3.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/LICENSE +20 -0
 - data/README +49 -0
 - data/Rakefile +3 -4
 - data/bunny.gemspec +37 -0
 - data/examples/simple.rb +1 -1
 - data/examples/simple_ack.rb +1 -1
 - data/examples/simple_consumer.rb +1 -1
 - data/examples/simple_fanout.rb +1 -1
 - data/examples/simple_publisher.rb +1 -1
 - data/examples/simple_topic.rb +3 -3
 - data/{protocol → ext}/amqp-0.8.json +0 -0
 - data/ext/codegen.rb +177 -0
 - data/lib/bunny.rb +20 -62
 - data/lib/bunny/client.rb +161 -14
 - data/lib/bunny/exchange.rb +155 -80
 - data/lib/bunny/protocol/protocol.rb +135 -0
 - data/lib/bunny/protocol/spec.rb +836 -0
 - data/lib/bunny/queue.rb +223 -23
 - data/lib/bunny/transport/buffer.rb +266 -0
 - data/lib/bunny/transport/frame.rb +62 -0
 - data/spec/bunny_spec.rb +2 -2
 - data/spec/exchange_spec.rb +3 -3
 - data/spec/queue_spec.rb +10 -9
 - metadata +22 -22
 - data/README.markdown +0 -126
 - data/lib/api_messages.rb +0 -18
 - data/lib/bunny/header.rb +0 -30
 - data/lib/engineroom/buffer.rb +0 -274
 - data/lib/engineroom/frame.rb +0 -61
 - data/lib/engineroom/protocol.rb +0 -156
 - data/lib/engineroom/spec.rb +0 -830
 - data/protocol/codegen.rb +0 -171
 
| 
         @@ -0,0 +1,62 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Bunny
         
     | 
| 
      
 2 
     | 
    
         
            +
            	module Transport #:nodoc: all
         
     | 
| 
      
 3 
     | 
    
         
            +
            	  class Frame
         
     | 
| 
      
 4 
     | 
    
         
            +
            	    def initialize payload = nil, channel = 0
         
     | 
| 
      
 5 
     | 
    
         
            +
            	      @channel, @payload = channel, payload
         
     | 
| 
      
 6 
     | 
    
         
            +
            	    end
         
     | 
| 
      
 7 
     | 
    
         
            +
            	    attr_accessor :channel, :payload
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            	    def id
         
     | 
| 
      
 10 
     | 
    
         
            +
            	      self.class::ID
         
     | 
| 
      
 11 
     | 
    
         
            +
            	    end
         
     | 
| 
      
 12 
     | 
    
         
            +
                
         
     | 
| 
      
 13 
     | 
    
         
            +
            	    def to_binary
         
     | 
| 
      
 14 
     | 
    
         
            +
            	      buf = Transport::Buffer.new
         
     | 
| 
      
 15 
     | 
    
         
            +
            	      buf.write :octet, id
         
     | 
| 
      
 16 
     | 
    
         
            +
            	      buf.write :short, channel
         
     | 
| 
      
 17 
     | 
    
         
            +
            	      buf.write :longstr, payload
         
     | 
| 
      
 18 
     | 
    
         
            +
            	      buf.write :octet, Transport::Frame::FOOTER
         
     | 
| 
      
 19 
     | 
    
         
            +
            	      buf.rewind
         
     | 
| 
      
 20 
     | 
    
         
            +
            	      buf
         
     | 
| 
      
 21 
     | 
    
         
            +
            	    end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            	    def to_s
         
     | 
| 
      
 24 
     | 
    
         
            +
            	      to_binary.to_s
         
     | 
| 
      
 25 
     | 
    
         
            +
            	    end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            	    def == frame
         
     | 
| 
      
 28 
     | 
    
         
            +
            	      [ :id, :channel, :payload ].inject(true) do |eql, field|
         
     | 
| 
      
 29 
     | 
    
         
            +
            	        eql and __send__(field) == frame.__send__(field)
         
     | 
| 
      
 30 
     | 
    
         
            +
            	      end
         
     | 
| 
      
 31 
     | 
    
         
            +
            	    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                
         
     | 
| 
      
 33 
     | 
    
         
            +
            	    class Method
         
     | 
| 
      
 34 
     | 
    
         
            +
            	      def initialize payload = nil, channel = 0
         
     | 
| 
      
 35 
     | 
    
         
            +
            	        super
         
     | 
| 
      
 36 
     | 
    
         
            +
            	        unless @payload.is_a? Protocol::Class::Method or @payload.nil?
         
     | 
| 
      
 37 
     | 
    
         
            +
            	          @payload = Protocol.parse(@payload)
         
     | 
| 
      
 38 
     | 
    
         
            +
            	        end
         
     | 
| 
      
 39 
     | 
    
         
            +
            	      end
         
     | 
| 
      
 40 
     | 
    
         
            +
            	    end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            	    class Header
         
     | 
| 
      
 43 
     | 
    
         
            +
            	      def initialize payload = nil, channel = 0
         
     | 
| 
      
 44 
     | 
    
         
            +
            	        super
         
     | 
| 
      
 45 
     | 
    
         
            +
            	        unless @payload.is_a? Protocol::Header or @payload.nil?
         
     | 
| 
      
 46 
     | 
    
         
            +
            	          @payload = Protocol::Header.new(@payload)
         
     | 
| 
      
 47 
     | 
    
         
            +
            	        end
         
     | 
| 
      
 48 
     | 
    
         
            +
            	      end
         
     | 
| 
      
 49 
     | 
    
         
            +
            	    end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            	    class Body; end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            	    def self.parse buf
         
     | 
| 
      
 54 
     | 
    
         
            +
            	      buf = Transport::Buffer.new(buf) unless buf.is_a? Transport::Buffer
         
     | 
| 
      
 55 
     | 
    
         
            +
            	      buf.extract do
         
     | 
| 
      
 56 
     | 
    
         
            +
            	        id, channel, payload, footer = buf.read(:octet, :short, :longstr, :octet)
         
     | 
| 
      
 57 
     | 
    
         
            +
            	        Transport::Frame.types[id].new(payload, channel) if footer == Transport::Frame::FOOTER
         
     | 
| 
      
 58 
     | 
    
         
            +
            	      end
         
     | 
| 
      
 59 
     | 
    
         
            +
            	    end
         
     | 
| 
      
 60 
     | 
    
         
            +
            	  end
         
     | 
| 
      
 61 
     | 
    
         
            +
            	end
         
     | 
| 
      
 62 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/bunny_spec.rb
    CHANGED
    
    | 
         @@ -11,12 +11,12 @@ require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib bunny])) 
     | 
|
| 
       11 
11 
     | 
    
         
             
            describe Bunny do
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            	before(:each) do
         
     | 
| 
       14 
     | 
    
         
            -
                @b = Bunny.new
         
     | 
| 
      
 14 
     | 
    
         
            +
                @b = Bunny::Client.new
         
     | 
| 
       15 
15 
     | 
    
         
             
            		@b.start
         
     | 
| 
       16 
16 
     | 
    
         
             
            	end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
              it "should connect to an AMQP server" do
         
     | 
| 
       19 
     | 
    
         
            -
                @b.status.should ==  
     | 
| 
      
 19 
     | 
    
         
            +
                @b.status.should == :connected
         
     | 
| 
       20 
20 
     | 
    
         
             
              end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            	it "should be able to create an exchange" do
         
     | 
    
        data/spec/exchange_spec.rb
    CHANGED
    
    | 
         @@ -11,12 +11,12 @@ require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib bunny])) 
     | 
|
| 
       11 
11 
     | 
    
         
             
            describe Bunny::Exchange do
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            	before(:each) do
         
     | 
| 
       14 
     | 
    
         
            -
                @b = Bunny.new
         
     | 
| 
      
 14 
     | 
    
         
            +
                @b = Bunny::Client.new
         
     | 
| 
       15 
15 
     | 
    
         
             
            		@b.start
         
     | 
| 
       16 
16 
     | 
    
         
             
            	end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
18 
     | 
    
         
             
            	it "should raise an error if instantiated as non-existent type" do
         
     | 
| 
       19 
     | 
    
         
            -
            		lambda { @b.exchange('bogus_ex', :type => :bogus) }.should raise_error( 
     | 
| 
      
 19 
     | 
    
         
            +
            		lambda { @b.exchange('bogus_ex', :type => :bogus) }.should raise_error(Bunny::ProtocolError)
         
     | 
| 
       20 
20 
     | 
    
         
             
            	end
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
22 
     | 
    
         
             
            	it "should allow a default direct exchange to be instantiated by specifying :type" do
         
     | 
| 
         @@ -105,7 +105,7 @@ describe Bunny::Exchange do 
     | 
|
| 
       105 
105 
     | 
    
         
             
            	it "should be able to be deleted" do
         
     | 
| 
       106 
106 
     | 
    
         
             
            		exch = @b.exchange('direct_exchange')
         
     | 
| 
       107 
107 
     | 
    
         
             
            		res = exch.delete
         
     | 
| 
       108 
     | 
    
         
            -
            		res.should ==  
     | 
| 
      
 108 
     | 
    
         
            +
            		res.should == :delete_ok
         
     | 
| 
       109 
109 
     | 
    
         
             
            		@b.exchanges.has_key?('direct_exchange').should be false
         
     | 
| 
       110 
110 
     | 
    
         
             
            	end
         
     | 
| 
       111 
111 
     | 
    
         | 
    
        data/spec/queue_spec.rb
    CHANGED
    
    | 
         @@ -11,7 +11,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib bunny])) 
     | 
|
| 
       11 
11 
     | 
    
         
             
            describe Bunny::Queue do
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            	before(:each) do
         
     | 
| 
       14 
     | 
    
         
            -
                @b = Bunny.new
         
     | 
| 
      
 14 
     | 
    
         
            +
                @b = Bunny::Client.new
         
     | 
| 
       15 
15 
     | 
    
         
             
            		@b.start
         
     | 
| 
       16 
16 
     | 
    
         
             
            	end
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
         @@ -22,25 +22,25 @@ describe Bunny::Queue do 
     | 
|
| 
       22 
22 
     | 
    
         
             
            	it "should ignore the :nowait option when binding to an exchange" do
         
     | 
| 
       23 
23 
     | 
    
         
             
            		exch = @b.exchange('direct_exch')
         
     | 
| 
       24 
24 
     | 
    
         
             
            		q = @b.queue('test0')
         
     | 
| 
       25 
     | 
    
         
            -
            		q.bind(exch, :nowait => true).should ==  
     | 
| 
      
 25 
     | 
    
         
            +
            		q.bind(exch, :nowait => true).should == :bind_ok
         
     | 
| 
       26 
26 
     | 
    
         
             
            	end
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
28 
     | 
    
         
             
            	it "should be able to bind to an exchange" do
         
     | 
| 
       29 
29 
     | 
    
         
             
            		exch = @b.exchange('direct_exch')
         
     | 
| 
       30 
30 
     | 
    
         
             
            		q = @b.queue('test1')
         
     | 
| 
       31 
     | 
    
         
            -
            		q.bind(exch).should ==  
     | 
| 
      
 31 
     | 
    
         
            +
            		q.bind(exch).should == :bind_ok
         
     | 
| 
       32 
32 
     | 
    
         
             
            	end
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
            	it "should ignore the :nowait option when unbinding from an exchange" do
         
     | 
| 
       35 
35 
     | 
    
         
             
            		exch = @b.exchange('direct_exch')
         
     | 
| 
       36 
36 
     | 
    
         
             
            		q = @b.queue('test0')
         
     | 
| 
       37 
     | 
    
         
            -
            		q.unbind(exch, :nowait => true).should ==  
     | 
| 
      
 37 
     | 
    
         
            +
            		q.unbind(exch, :nowait => true).should == :unbind_ok
         
     | 
| 
       38 
38 
     | 
    
         
             
            	end
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
            	it "should be able to unbind from an exchange" do
         
     | 
| 
       41 
41 
     | 
    
         
             
            		exch = @b.exchange('direct_exch')
         
     | 
| 
       42 
42 
     | 
    
         
             
            		q = @b.queue('test1')
         
     | 
| 
       43 
     | 
    
         
            -
            		q.unbind(exch).should ==  
     | 
| 
      
 43 
     | 
    
         
            +
            		q.unbind(exch).should == :unbind_ok
         
     | 
| 
       44 
44 
     | 
    
         
             
            	end
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
            	it "should be able to publish a message" do
         
     | 
| 
         @@ -49,12 +49,13 @@ describe Bunny::Queue do 
     | 
|
| 
       49 
49 
     | 
    
         
             
            		q.message_count.should == 1
         
     | 
| 
       50 
50 
     | 
    
         
             
            	end
         
     | 
| 
       51 
51 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
            	it "should be able to pop a message complete with header" do
         
     | 
| 
      
 52 
     | 
    
         
            +
            	it "should be able to pop a message complete with header and delivery details" do
         
     | 
| 
       53 
53 
     | 
    
         
             
            		q = @b.queue('test1')
         
     | 
| 
       54 
54 
     | 
    
         
             
            		msg = q.pop(:header => true)
         
     | 
| 
       55 
55 
     | 
    
         
             
            		msg.should be_an_instance_of Hash
         
     | 
| 
       56 
     | 
    
         
            -
            		msg[:header].should be_an_instance_of Protocol::Header
         
     | 
| 
      
 56 
     | 
    
         
            +
            		msg[:header].should be_an_instance_of Bunny::Protocol::Header
         
     | 
| 
       57 
57 
     | 
    
         
             
            		msg[:payload].should == 'This is a test message'
         
     | 
| 
      
 58 
     | 
    
         
            +
            		msg[:delivery_details].should be_an_instance_of Hash
         
     | 
| 
       58 
59 
     | 
    
         
             
            		q.message_count.should == 0
         
     | 
| 
       59 
60 
     | 
    
         
             
            	end
         
     | 
| 
       60 
61 
     | 
    
         | 
| 
         @@ -71,13 +72,13 @@ describe Bunny::Queue do 
     | 
|
| 
       71 
72 
     | 
    
         
             
            		q.publish('This is another test message')
         
     | 
| 
       72 
73 
     | 
    
         
             
            		q.pop
         
     | 
| 
       73 
74 
     | 
    
         
             
            		msg = q.pop
         
     | 
| 
       74 
     | 
    
         
            -
            		msg.should ==  
     | 
| 
      
 75 
     | 
    
         
            +
            		msg.should == :queue_empty
         
     | 
| 
       75 
76 
     | 
    
         
             
            	end
         
     | 
| 
       76 
77 
     | 
    
         | 
| 
       77 
78 
     | 
    
         
             
            	it "should be able to be deleted" do
         
     | 
| 
       78 
79 
     | 
    
         
             
            		q = @b.queue('test1')
         
     | 
| 
       79 
80 
     | 
    
         
             
            		res = q.delete
         
     | 
| 
       80 
     | 
    
         
            -
            		res.should ==  
     | 
| 
      
 81 
     | 
    
         
            +
            		res.should == :delete_ok
         
     | 
| 
       81 
82 
     | 
    
         
             
            		@b.queues.has_key?('test1').should be false
         
     | 
| 
       82 
83 
     | 
    
         
             
            	end
         
     | 
| 
       83 
84 
     | 
    
         | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: bunny
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.3.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors: 
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Chris Duncan
         
     | 
| 
         @@ -9,7 +9,7 @@ autorequire: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            date: 2009-05- 
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2009-05-10 00:00:00 +01:00
         
     | 
| 
       13 
13 
     | 
    
         
             
            default_executable: 
         
     | 
| 
       14 
14 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
         @@ -19,38 +19,38 @@ executables: [] 
     | 
|
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
            extensions: []
         
     | 
| 
       21 
21 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
            extra_rdoc_files:  
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
            extra_rdoc_files: 
         
     | 
| 
      
 23 
     | 
    
         
            +
            - README
         
     | 
| 
       24 
24 
     | 
    
         
             
            files: 
         
     | 
| 
      
 25 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
      
 26 
     | 
    
         
            +
            - README
         
     | 
| 
       25 
27 
     | 
    
         
             
            - Rakefile
         
     | 
| 
       26 
     | 
    
         
            -
            -  
     | 
| 
       27 
     | 
    
         
            -
            - lib/api_messages.rb
         
     | 
| 
       28 
     | 
    
         
            -
            - lib/bunny.rb
         
     | 
| 
       29 
     | 
    
         
            -
            - lib/engineroom/buffer.rb
         
     | 
| 
       30 
     | 
    
         
            -
            - lib/engineroom/frame.rb
         
     | 
| 
       31 
     | 
    
         
            -
            - lib/engineroom/protocol.rb
         
     | 
| 
       32 
     | 
    
         
            -
            - lib/engineroom/spec.rb
         
     | 
| 
       33 
     | 
    
         
            -
            - lib/bunny/exchange.rb
         
     | 
| 
       34 
     | 
    
         
            -
            - lib/bunny/header.rb
         
     | 
| 
       35 
     | 
    
         
            -
            - lib/bunny/queue.rb
         
     | 
| 
       36 
     | 
    
         
            -
            - lib/bunny/client.rb
         
     | 
| 
      
 28 
     | 
    
         
            +
            - bunny.gemspec
         
     | 
| 
       37 
29 
     | 
    
         
             
            - examples/simple.rb
         
     | 
| 
       38 
     | 
    
         
            -
            - examples/ 
     | 
| 
      
 30 
     | 
    
         
            +
            - examples/simple_ack.rb
         
     | 
| 
       39 
31 
     | 
    
         
             
            - examples/simple_consumer.rb
         
     | 
| 
      
 32 
     | 
    
         
            +
            - examples/simple_fanout.rb
         
     | 
| 
       40 
33 
     | 
    
         
             
            - examples/simple_publisher.rb
         
     | 
| 
       41 
     | 
    
         
            -
            - examples/simple_ack.rb
         
     | 
| 
       42 
34 
     | 
    
         
             
            - examples/simple_topic.rb
         
     | 
| 
      
 35 
     | 
    
         
            +
            - ext/amqp-0.8.json
         
     | 
| 
      
 36 
     | 
    
         
            +
            - ext/codegen.rb
         
     | 
| 
      
 37 
     | 
    
         
            +
            - lib/bunny.rb
         
     | 
| 
      
 38 
     | 
    
         
            +
            - lib/bunny/client.rb
         
     | 
| 
      
 39 
     | 
    
         
            +
            - lib/bunny/exchange.rb
         
     | 
| 
      
 40 
     | 
    
         
            +
            - lib/bunny/protocol/protocol.rb
         
     | 
| 
      
 41 
     | 
    
         
            +
            - lib/bunny/protocol/spec.rb
         
     | 
| 
      
 42 
     | 
    
         
            +
            - lib/bunny/queue.rb
         
     | 
| 
      
 43 
     | 
    
         
            +
            - lib/bunny/transport/buffer.rb
         
     | 
| 
      
 44 
     | 
    
         
            +
            - lib/bunny/transport/frame.rb
         
     | 
| 
       43 
45 
     | 
    
         
             
            - spec/bunny_spec.rb
         
     | 
| 
       44 
46 
     | 
    
         
             
            - spec/exchange_spec.rb
         
     | 
| 
       45 
47 
     | 
    
         
             
            - spec/queue_spec.rb
         
     | 
| 
       46 
     | 
    
         
            -
            - protocol/amqp-0.8.json
         
     | 
| 
       47 
     | 
    
         
            -
            - protocol/codegen.rb
         
     | 
| 
       48 
48 
     | 
    
         
             
            has_rdoc: true
         
     | 
| 
       49 
49 
     | 
    
         
             
            homepage: http://github.com/celldee/bunny
         
     | 
| 
       50 
50 
     | 
    
         
             
            post_install_message: 
         
     | 
| 
       51 
51 
     | 
    
         
             
            rdoc_options: 
         
     | 
| 
       52 
     | 
    
         
            -
            - -- 
     | 
| 
       53 
     | 
    
         
            -
            -  
     | 
| 
      
 52 
     | 
    
         
            +
            - --main
         
     | 
| 
      
 53 
     | 
    
         
            +
            - README
         
     | 
| 
       54 
54 
     | 
    
         
             
            require_paths: 
         
     | 
| 
       55 
55 
     | 
    
         
             
            - lib
         
     | 
| 
       56 
56 
     | 
    
         
             
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
         @@ -71,6 +71,6 @@ rubyforge_project: bunny-amqp 
     | 
|
| 
       71 
71 
     | 
    
         
             
            rubygems_version: 1.3.1
         
     | 
| 
       72 
72 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       73 
73 
     | 
    
         
             
            specification_version: 2
         
     | 
| 
       74 
     | 
    
         
            -
            summary:  
     | 
| 
      
 74 
     | 
    
         
            +
            summary: A synchronous Ruby AMQP client that enables interaction with AMQP-compliant brokers/servers.
         
     | 
| 
       75 
75 
     | 
    
         
             
            test_files: []
         
     | 
| 
       76 
76 
     | 
    
         | 
    
        data/README.markdown
    DELETED
    
    | 
         @@ -1,126 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            # Bunny: A synchronous Ruby AMQP client
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            Google Group: [http://groups.google.com/group/bunny-amqp](http://groups.google.com/group/bunny-amqp)
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
            Mailing List: [http://rubyforge.org/mailman/listinfo/bunny-amqp-devel](http://rubyforge.org/mailman/listinfo/bunny-amqp-devel)
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            Rubyforge: [http://rubyforge.org/projects/bunny-amqp](http://rubyforge.org/projects/bunny-amqp)
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            Twitter: [http://twitter.com/bunny_amqp](https://twitter.com/bunny_amqp)
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            ## Announcements
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            Bunny v0.2.0 is now available. The highlights are -
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
            * Code has been re-organised enabling Bunny to play nicely with [amqp](http://github.com/tmm1/amqp) (thanks [Dan](http://github.com/danielsdeleo))
         
     | 
| 
       16 
     | 
    
         
            -
            * When instantiating a default exchange (one beginning with ‘amq.’) the type will be inferred from the name.
         
     | 
| 
       17 
     | 
    
         
            -
            * Fixed Queue#subscribe and included Queue#unsubscribe method. See examples/simple_consumer.rb for details
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
            ## About
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
            *Bunny* is an [AMQP](http://www.amqp.org) (Advanced Message Queuing Protocol) client, written in Ruby, that is intended to allow you to interact with AMQP-compliant message brokers/servers such as [RabbitMQ](http://www.rabbitmq.com) in a synchronous fashion.
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
            It is based on a great deal of fabulous code from [amqp](http://github.com/tmm1/amqp) by Aman Gupta and [Carrot](http://github.com/famoseagle/carrot) by Amos Elliston.
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
            You can use *Bunny* to -
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
            * Create and delete exchanges
         
     | 
| 
       28 
     | 
    
         
            -
            * Create and delete queues
         
     | 
| 
       29 
     | 
    
         
            -
            * Publish and consume messages
         
     | 
| 
       30 
     | 
    
         
            -
             
         
     | 
| 
       31 
     | 
    
         
            -
            *Bunny* is known to work with RabbitMQ version 1.5.4 and version 0-8 of the AMQP specification. If you want to try to use it with other AMQP message brokers/servers please let me know how you get on.
         
     | 
| 
       32 
     | 
    
         
            -
             
         
     | 
| 
       33 
     | 
    
         
            -
            ## Quick Start
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                require 'bunny'
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                b = Bunny.new(:logging => true)
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                # start a communication session with the amqp server
         
     | 
| 
       40 
     | 
    
         
            -
                b.start
         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                # declare a queue
         
     | 
| 
       43 
     | 
    
         
            -
                q = b.queue('test1')
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                # publish a message to the queue
         
     | 
| 
       46 
     | 
    
         
            -
                q.publish('Hello everybody!')
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                # get message from the queue
         
     | 
| 
       49 
     | 
    
         
            -
                msg = q.pop
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                puts 'This is the message: ' + msg + "\n\n"
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
     | 
    
         
            -
                # close the connection
         
     | 
| 
       54 
     | 
    
         
            -
                b.close
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
     | 
    
         
            -
            ## Bunny methods
         
     | 
| 
       57 
     | 
    
         
            -
             
     | 
| 
       58 
     | 
    
         
            -
            These are the Bunny methods that you will probably want to use -
         
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
            ### Create a Bunny instance
         
     | 
| 
       61 
     | 
    
         
            -
            Bunny#new({_options_})
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
       63 
     | 
    
         
            -
            ### Start a communication session with the target server
         
     | 
| 
       64 
     | 
    
         
            -
            Bunny#start
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
            ### Stop a communication session with the target server
         
     | 
| 
       67 
     | 
    
         
            -
            Bunny#stop
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
            ### Create a Queue
         
     | 
| 
       70 
     | 
    
         
            -
            Bunny#queue(_**name**_, {_options_})
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
            ### Create an Exchange
         
     | 
| 
       73 
     | 
    
         
            -
            Bunny#exchange(_**name**_, {_options_})
         
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
            ### Return connection status ('CONNECTED' or 'NOT CONNECTED')
         
     | 
| 
       76 
     | 
    
         
            -
            Bunny#status               
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
            ### Publish a message to an exchange
         
     | 
| 
       79 
     | 
    
         
            -
            Exchange#publish(_**data**_, {_options_})
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
            ### Delete an exchange from the target server
         
     | 
| 
       82 
     | 
    
         
            -
            Exchange#delete({_options_})
         
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
            ### Bind a queue to an exchange
         
     | 
| 
       85 
     | 
    
         
            -
            Queue#bind(_**exchange**_, {_options_})
         
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
            ### Unbind a queue from an exchange
         
     | 
| 
       88 
     | 
    
         
            -
            Queue#unbind(_**exchange**_, {_options_})
         
     | 
| 
       89 
     | 
    
         
            -
             
     | 
| 
       90 
     | 
    
         
            -
            ### Publish a message to a queue
         
     | 
| 
       91 
     | 
    
         
            -
            Queue#publish(_**data**_, {_options_})
         
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
            ### Pop a message off of a queue
         
     | 
| 
       94 
     | 
    
         
            -
            Queue#pop({_options_})
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
            ### Subscribe to a queue
         
     | 
| 
       97 
     | 
    
         
            -
            Queue#subscribe({_options_}, &blk)
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
       99 
     | 
    
         
            -
            ### Unsubscribe from a queue
         
     | 
| 
       100 
     | 
    
         
            -
            Queue#unsubscribe({_options_})
         
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
       102 
     | 
    
         
            -
            ### Return queue message count
         
     | 
| 
       103 
     | 
    
         
            -
            Queue#message_count
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
            ### Return queue consumer count
         
     | 
| 
       106 
     | 
    
         
            -
            Queue#consumer_count
         
     | 
| 
       107 
     | 
    
         
            -
             
     | 
| 
       108 
     | 
    
         
            -
            ### Return queue status (hash {:message count, :consumer_count})
         
     | 
| 
       109 
     | 
    
         
            -
            Queue#status
         
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
     | 
    
         
            -
            ### Delete a queue from the target server
         
     | 
| 
       112 
     | 
    
         
            -
            Queue#delete({_options_})
         
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
            ### Acknowledge receipt of a message
         
     | 
| 
       115 
     | 
    
         
            -
            Queue#ack
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
            ## Acknowledgements
         
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
            This project has borrowed heavily from the following two projects and owes their respective creators and collaborators a whole lot of gratitude:
         
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
       121 
     | 
    
         
            -
            1. **amqp** by *tmm1* [http://github.com/tmm1/amqp/tree/master](http://github.com/tmm1/amqp/tree/master)
         
     | 
| 
       122 
     | 
    
         
            -
            2. **carrot** by *famoseagle* [http://github.com/famoseagle/carrot/tree/master](http://github.com/famoseagle/carrot/tree/master)
         
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
            ## LICENSE
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
            Copyright (c) 2009 Chris Duncan; Published under The MIT License, see License
         
     | 
    
        data/lib/api_messages.rb
    DELETED
    
    | 
         @@ -1,18 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module API
         
     | 
| 
       2 
     | 
    
         
            -
            	# return messages
         
     | 
| 
       3 
     | 
    
         
            -
            	CONNECTED = 'CONNECTED'
         
     | 
| 
       4 
     | 
    
         
            -
            	NOT_CONNECTED = 'NOT CONNECTED'
         
     | 
| 
       5 
     | 
    
         
            -
            	QUEUE_EMPTY = 'QUEUE EMPTY'
         
     | 
| 
       6 
     | 
    
         
            -
            	QUEUE_DELETED = 'QUEUE DELETED'
         
     | 
| 
       7 
     | 
    
         
            -
            	EXCHANGE_DELETED = 'EXCHANGE DELETED'
         
     | 
| 
       8 
     | 
    
         
            -
            	BIND_SUCCEEDED = 'BIND SUCCEEDED'
         
     | 
| 
       9 
     | 
    
         
            -
            	UNBIND_SUCCEEDED = 'UNBIND SUCCEEDED'
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            	# specific error definitions
         
     | 
| 
       12 
     | 
    
         
            -
            	class ProtocolError < StandardError; end
         
     | 
| 
       13 
     | 
    
         
            -
            	class ServerDownError < StandardError; end
         
     | 
| 
       14 
     | 
    
         
            -
            	class BufferOverflowError < StandardError; end
         
     | 
| 
       15 
     | 
    
         
            -
              class InvalidTypeError < StandardError; end
         
     | 
| 
       16 
     | 
    
         
            -
            	class ConnectionError < StandardError; end
         
     | 
| 
       17 
     | 
    
         
            -
            	class MessageError < StandardError; end
         
     | 
| 
       18 
     | 
    
         
            -
            end
         
     | 
    
        data/lib/bunny/header.rb
    DELETED
    
    | 
         @@ -1,30 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            module API
         
     | 
| 
       2 
     | 
    
         
            -
            	class Header
         
     | 
| 
       3 
     | 
    
         
            -
            	
         
     | 
| 
       4 
     | 
    
         
            -
            		attr_reader :client
         
     | 
| 
       5 
     | 
    
         
            -
            	
         
     | 
| 
       6 
     | 
    
         
            -
            	  def initialize(client, header_obj)
         
     | 
| 
       7 
     | 
    
         
            -
            	    @client = client
         
     | 
| 
       8 
     | 
    
         
            -
            	    @header = header_obj
         
     | 
| 
       9 
     | 
    
         
            -
            	  end
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            	  # Acknowledges the receipt of this message with the server.
         
     | 
| 
       12 
     | 
    
         
            -
            	  def ack
         
     | 
| 
       13 
     | 
    
         
            -
            	    client.send(Protocol::Basic::Ack.new(:delivery_tag => properties[:delivery_tag]))
         
     | 
| 
       14 
     | 
    
         
            -
            	  end
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            	  # Reject this message (XXX currently unimplemented in rabbitmq)
         
     | 
| 
       17 
     | 
    
         
            -
            	  # * :requeue => true | false (default false)
         
     | 
| 
       18 
     | 
    
         
            -
            	  def reject(opts = {})
         
     | 
| 
       19 
     | 
    
         
            -
            	    client.send(Protocol::Basic::Reject.new(opts.merge(:delivery_tag => properties[:delivery_tag])))
         
     | 
| 
       20 
     | 
    
         
            -
            	  end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
            	  def method_missing(meth, *args, &blk)
         
     | 
| 
       23 
     | 
    
         
            -
            	    @header.send(meth, *args, &blk)
         
     | 
| 
       24 
     | 
    
         
            -
            	  end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            	  def inspect
         
     | 
| 
       27 
     | 
    
         
            -
            	    @header.inspect
         
     | 
| 
       28 
     | 
    
         
            -
            	  end
         
     | 
| 
       29 
     | 
    
         
            -
            	end
         
     | 
| 
       30 
     | 
    
         
            -
            end
         
     | 
    
        data/lib/engineroom/buffer.rb
    DELETED
    
    | 
         @@ -1,274 +0,0 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            if [].map.respond_to? :with_index
         
     | 
| 
       2 
     | 
    
         
            -
              class Array #:nodoc:
         
     | 
| 
       3 
     | 
    
         
            -
                def enum_with_index
         
     | 
| 
       4 
     | 
    
         
            -
                  each.with_index
         
     | 
| 
       5 
     | 
    
         
            -
                end
         
     | 
| 
       6 
     | 
    
         
            -
              end
         
     | 
| 
       7 
     | 
    
         
            -
            else
         
     | 
| 
       8 
     | 
    
         
            -
              require 'enumerator'
         
     | 
| 
       9 
     | 
    
         
            -
            end
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
            module Transport
         
     | 
| 
       12 
     | 
    
         
            -
              class Buffer #:nodoc: all
         
     | 
| 
       13 
     | 
    
         
            -
                
         
     | 
| 
       14 
     | 
    
         
            -
                def initialize data = ''
         
     | 
| 
       15 
     | 
    
         
            -
                  @data = data
         
     | 
| 
       16 
     | 
    
         
            -
                  @pos = 0
         
     | 
| 
       17 
     | 
    
         
            -
                end
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                attr_reader :pos
         
     | 
| 
       20 
     | 
    
         
            -
                
         
     | 
| 
       21 
     | 
    
         
            -
                def data
         
     | 
| 
       22 
     | 
    
         
            -
                  @data.clone
         
     | 
| 
       23 
     | 
    
         
            -
                end
         
     | 
| 
       24 
     | 
    
         
            -
                alias :contents :data
         
     | 
| 
       25 
     | 
    
         
            -
                alias :to_s :data
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                def << data
         
     | 
| 
       28 
     | 
    
         
            -
                  @data << data.to_s
         
     | 
| 
       29 
     | 
    
         
            -
                  self
         
     | 
| 
       30 
     | 
    
         
            -
                end
         
     | 
| 
       31 
     | 
    
         
            -
                
         
     | 
| 
       32 
     | 
    
         
            -
                def length
         
     | 
| 
       33 
     | 
    
         
            -
                  @data.length
         
     | 
| 
       34 
     | 
    
         
            -
                end
         
     | 
| 
       35 
     | 
    
         
            -
                
         
     | 
| 
       36 
     | 
    
         
            -
                def empty?
         
     | 
| 
       37 
     | 
    
         
            -
                  pos == length
         
     | 
| 
       38 
     | 
    
         
            -
                end
         
     | 
| 
       39 
     | 
    
         
            -
                
         
     | 
| 
       40 
     | 
    
         
            -
                def rewind
         
     | 
| 
       41 
     | 
    
         
            -
                  @pos = 0
         
     | 
| 
       42 
     | 
    
         
            -
                end
         
     | 
| 
       43 
     | 
    
         
            -
                
         
     | 
| 
       44 
     | 
    
         
            -
                def read_properties *types
         
     | 
| 
       45 
     | 
    
         
            -
                  types.shift if types.first == :properties
         
     | 
| 
       46 
     | 
    
         
            -
                  
         
     | 
| 
       47 
     | 
    
         
            -
                  i = 0
         
     | 
| 
       48 
     | 
    
         
            -
                  values = []
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                  while props = read(:short)
         
     | 
| 
       51 
     | 
    
         
            -
                    (0..14).each do |n|
         
     | 
| 
       52 
     | 
    
         
            -
                      # no more property types
         
     | 
| 
       53 
     | 
    
         
            -
                      break unless types[i]
         
     | 
| 
       54 
     | 
    
         
            -
                      
         
     | 
| 
       55 
     | 
    
         
            -
                      # if flag is set
         
     | 
| 
       56 
     | 
    
         
            -
                      if props & (1<<(15-n)) != 0
         
     | 
| 
       57 
     | 
    
         
            -
                        if types[i] == :bit
         
     | 
| 
       58 
     | 
    
         
            -
                          # bit values exist in flags only
         
     | 
| 
       59 
     | 
    
         
            -
                          values << true
         
     | 
| 
       60 
     | 
    
         
            -
                        else
         
     | 
| 
       61 
     | 
    
         
            -
                          # save type name for later reading
         
     | 
| 
       62 
     | 
    
         
            -
                          values << types[i]
         
     | 
| 
       63 
     | 
    
         
            -
                        end
         
     | 
| 
       64 
     | 
    
         
            -
                      else
         
     | 
| 
       65 
     | 
    
         
            -
                        # property not set or is false bit
         
     | 
| 
       66 
     | 
    
         
            -
                        values << (types[i] == :bit ? false : nil)
         
     | 
| 
       67 
     | 
    
         
            -
                      end
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                      i+=1
         
     | 
| 
       70 
     | 
    
         
            -
                    end
         
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
                    # bit(0) == 0 means no more property flags
         
     | 
| 
       73 
     | 
    
         
            -
                    break unless props & 1 == 1
         
     | 
| 
       74 
     | 
    
         
            -
                  end
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                  values.map do |value|
         
     | 
| 
       77 
     | 
    
         
            -
                    value.is_a?(Symbol) ? read(value) : value
         
     | 
| 
       78 
     | 
    
         
            -
                  end
         
     | 
| 
       79 
     | 
    
         
            -
                end
         
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
                def read *types
         
     | 
| 
       82 
     | 
    
         
            -
                  if types.first == :properties
         
     | 
| 
       83 
     | 
    
         
            -
                    return read_properties(*types)
         
     | 
| 
       84 
     | 
    
         
            -
                  end
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
                  values = types.map do |type|
         
     | 
| 
       87 
     | 
    
         
            -
                    case type
         
     | 
| 
       88 
     | 
    
         
            -
                    when :octet
         
     | 
| 
       89 
     | 
    
         
            -
                      _read(1, 'C')
         
     | 
| 
       90 
     | 
    
         
            -
                    when :short
         
     | 
| 
       91 
     | 
    
         
            -
                      _read(2, 'n')
         
     | 
| 
       92 
     | 
    
         
            -
                    when :long
         
     | 
| 
       93 
     | 
    
         
            -
                      _read(4, 'N')
         
     | 
| 
       94 
     | 
    
         
            -
                    when :longlong
         
     | 
| 
       95 
     | 
    
         
            -
                      upper, lower = _read(8, 'NN')
         
     | 
| 
       96 
     | 
    
         
            -
                      upper << 32 | lower
         
     | 
| 
       97 
     | 
    
         
            -
                    when :shortstr
         
     | 
| 
       98 
     | 
    
         
            -
                      _read read(:octet)
         
     | 
| 
       99 
     | 
    
         
            -
                    when :longstr
         
     | 
| 
       100 
     | 
    
         
            -
                      _read read(:long)
         
     | 
| 
       101 
     | 
    
         
            -
                    when :timestamp
         
     | 
| 
       102 
     | 
    
         
            -
                      Time.at read(:longlong)
         
     | 
| 
       103 
     | 
    
         
            -
                    when :table
         
     | 
| 
       104 
     | 
    
         
            -
                      t = Hash.new
         
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
                      table = Buffer.new(read(:longstr))
         
     | 
| 
       107 
     | 
    
         
            -
                      until table.empty?
         
     | 
| 
       108 
     | 
    
         
            -
                        key, type = table.read(:shortstr, :octet)
         
     | 
| 
       109 
     | 
    
         
            -
                        key = key.intern
         
     | 
| 
       110 
     | 
    
         
            -
                        t[key] ||= case type
         
     | 
| 
       111 
     | 
    
         
            -
                                   when 83 # 'S'
         
     | 
| 
       112 
     | 
    
         
            -
                                     table.read(:longstr)
         
     | 
| 
       113 
     | 
    
         
            -
                                   when 73 # 'I'
         
     | 
| 
       114 
     | 
    
         
            -
                                     table.read(:long)
         
     | 
| 
       115 
     | 
    
         
            -
                                   when 68 # 'D'
         
     | 
| 
       116 
     | 
    
         
            -
                                     exp = table.read(:octet)
         
     | 
| 
       117 
     | 
    
         
            -
                                     num = table.read(:long)
         
     | 
| 
       118 
     | 
    
         
            -
                                     num / 10.0**exp
         
     | 
| 
       119 
     | 
    
         
            -
                                   when 84 # 'T'
         
     | 
| 
       120 
     | 
    
         
            -
                                     table.read(:timestamp)
         
     | 
| 
       121 
     | 
    
         
            -
                                   when 70 # 'F'
         
     | 
| 
       122 
     | 
    
         
            -
                                     table.read(:table)
         
     | 
| 
       123 
     | 
    
         
            -
                                   end
         
     | 
| 
       124 
     | 
    
         
            -
                      end
         
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
                      t
         
     | 
| 
       127 
     | 
    
         
            -
                    when :bit
         
     | 
| 
       128 
     | 
    
         
            -
                      if (@bits ||= []).empty?
         
     | 
| 
       129 
     | 
    
         
            -
                        val = read(:octet)
         
     | 
| 
       130 
     | 
    
         
            -
                        @bits = (0..7).map{|i| (val & 1<<i) != 0 }
         
     | 
| 
       131 
     | 
    
         
            -
                      end
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
                      @bits.shift
         
     | 
| 
       134 
     | 
    
         
            -
                    else
         
     | 
| 
       135 
     | 
    
         
            -
                      raise API::InvalidTypeError, "Cannot read data of type #{type}"
         
     | 
| 
       136 
     | 
    
         
            -
                    end
         
     | 
| 
       137 
     | 
    
         
            -
                  end
         
     | 
| 
       138 
     | 
    
         
            -
                  
         
     | 
| 
       139 
     | 
    
         
            -
                  types.size == 1 ? values.first : values
         
     | 
| 
       140 
     | 
    
         
            -
                end
         
     | 
| 
       141 
     | 
    
         
            -
                
         
     | 
| 
       142 
     | 
    
         
            -
                def write type, data
         
     | 
| 
       143 
     | 
    
         
            -
                  case type
         
     | 
| 
       144 
     | 
    
         
            -
                  when :octet
         
     | 
| 
       145 
     | 
    
         
            -
                    _write(data, 'C')
         
     | 
| 
       146 
     | 
    
         
            -
                  when :short
         
     | 
| 
       147 
     | 
    
         
            -
                    _write(data, 'n')
         
     | 
| 
       148 
     | 
    
         
            -
                  when :long
         
     | 
| 
       149 
     | 
    
         
            -
                    _write(data, 'N')
         
     | 
| 
       150 
     | 
    
         
            -
                  when :longlong
         
     | 
| 
       151 
     | 
    
         
            -
                    lower =  data & 0xffffffff
         
     | 
| 
       152 
     | 
    
         
            -
                    upper = (data & ~0xffffffff) >> 32
         
     | 
| 
       153 
     | 
    
         
            -
                    _write([upper, lower], 'NN')
         
     | 
| 
       154 
     | 
    
         
            -
                  when :shortstr
         
     | 
| 
       155 
     | 
    
         
            -
                    data = (data || '').to_s
         
     | 
| 
       156 
     | 
    
         
            -
                    _write([data.length, data], 'Ca*')
         
     | 
| 
       157 
     | 
    
         
            -
                  when :longstr
         
     | 
| 
       158 
     | 
    
         
            -
                    if data.is_a? Hash
         
     | 
| 
       159 
     | 
    
         
            -
                      write(:table, data)
         
     | 
| 
       160 
     | 
    
         
            -
                    else
         
     | 
| 
       161 
     | 
    
         
            -
                      data = (data || '').to_s
         
     | 
| 
       162 
     | 
    
         
            -
                      _write([data.length, data], 'Na*')
         
     | 
| 
       163 
     | 
    
         
            -
                    end
         
     | 
| 
       164 
     | 
    
         
            -
                  when :timestamp
         
     | 
| 
       165 
     | 
    
         
            -
                    write(:longlong, data.to_i)
         
     | 
| 
       166 
     | 
    
         
            -
                  when :table
         
     | 
| 
       167 
     | 
    
         
            -
                    data ||= {}
         
     | 
| 
       168 
     | 
    
         
            -
                    write :longstr, (data.inject(Buffer.new) do |table, (key, value)|
         
     | 
| 
       169 
     | 
    
         
            -
                                      table.write(:shortstr, key.to_s)
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
                                      case value
         
     | 
| 
       172 
     | 
    
         
            -
                                      when String
         
     | 
| 
       173 
     | 
    
         
            -
                                        table.write(:octet, 83) # 'S'
         
     | 
| 
       174 
     | 
    
         
            -
                                        table.write(:longstr, value.to_s)
         
     | 
| 
       175 
     | 
    
         
            -
                                      when Fixnum
         
     | 
| 
       176 
     | 
    
         
            -
                                        table.write(:octet, 73) # 'I'
         
     | 
| 
       177 
     | 
    
         
            -
                                        table.write(:long, value)
         
     | 
| 
       178 
     | 
    
         
            -
                                      when Float
         
     | 
| 
       179 
     | 
    
         
            -
                                        table.write(:octet, 68) # 'D'
         
     | 
| 
       180 
     | 
    
         
            -
                                        # XXX there's gotta be a better way to do this..
         
     | 
| 
       181 
     | 
    
         
            -
                                        exp = value.to_s.split('.').last.length
         
     | 
| 
       182 
     | 
    
         
            -
                                        num = value * 10**exp
         
     | 
| 
       183 
     | 
    
         
            -
                                        table.write(:octet, exp)
         
     | 
| 
       184 
     | 
    
         
            -
                                        table.write(:long, num)
         
     | 
| 
       185 
     | 
    
         
            -
                                      when Time
         
     | 
| 
       186 
     | 
    
         
            -
                                        table.write(:octet, 84) # 'T'
         
     | 
| 
       187 
     | 
    
         
            -
                                        table.write(:timestamp, value)
         
     | 
| 
       188 
     | 
    
         
            -
                                      when Hash
         
     | 
| 
       189 
     | 
    
         
            -
                                        table.write(:octet, 70) # 'F'
         
     | 
| 
       190 
     | 
    
         
            -
                                        table.write(:table, value)
         
     | 
| 
       191 
     | 
    
         
            -
                                      end
         
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
     | 
    
         
            -
                                      table
         
     | 
| 
       194 
     | 
    
         
            -
                                    end)
         
     | 
| 
       195 
     | 
    
         
            -
                  when :bit
         
     | 
| 
       196 
     | 
    
         
            -
                    [*data].to_enum(:each_slice, 8).each{|bits|
         
     | 
| 
       197 
     | 
    
         
            -
                      write(:octet, bits.enum_with_index.inject(0){ |byte, (bit, i)|
         
     | 
| 
       198 
     | 
    
         
            -
                        byte |= 1<<i if bit
         
     | 
| 
       199 
     | 
    
         
            -
                        byte
         
     | 
| 
       200 
     | 
    
         
            -
                       })
         
     | 
| 
       201 
     | 
    
         
            -
                     }
         
     | 
| 
       202 
     | 
    
         
            -
                  when :properties
         
     | 
| 
       203 
     | 
    
         
            -
                    values = []
         
     | 
| 
       204 
     | 
    
         
            -
                    data.enum_with_index.inject(0) do |short, ((type, value), i)|
         
     | 
| 
       205 
     | 
    
         
            -
                      n = i % 15
         
     | 
| 
       206 
     | 
    
         
            -
                      last = i+1 == data.size
         
     | 
| 
       207 
     | 
    
         
            -
             
     | 
| 
       208 
     | 
    
         
            -
                      if (n == 0 and i != 0) or last
         
     | 
| 
       209 
     | 
    
         
            -
                        if data.size > i+1
         
     | 
| 
       210 
     | 
    
         
            -
                          short |= 1<<0
         
     | 
| 
       211 
     | 
    
         
            -
                        elsif last and value
         
     | 
| 
       212 
     | 
    
         
            -
                          values << [type,value]
         
     | 
| 
       213 
     | 
    
         
            -
                          short |= 1<<(15-n)
         
     | 
| 
       214 
     | 
    
         
            -
                        end
         
     | 
| 
       215 
     | 
    
         
            -
             
     | 
| 
       216 
     | 
    
         
            -
                        write(:short, short)
         
     | 
| 
       217 
     | 
    
         
            -
                        short = 0
         
     | 
| 
       218 
     | 
    
         
            -
                      end
         
     | 
| 
       219 
     | 
    
         
            -
             
     | 
| 
       220 
     | 
    
         
            -
                      if value and !last
         
     | 
| 
       221 
     | 
    
         
            -
                        values << [type,value] 
         
     | 
| 
       222 
     | 
    
         
            -
                        short |= 1<<(15-n)
         
     | 
| 
       223 
     | 
    
         
            -
                      end
         
     | 
| 
       224 
     | 
    
         
            -
             
     | 
| 
       225 
     | 
    
         
            -
                      short
         
     | 
| 
       226 
     | 
    
         
            -
                    end
         
     | 
| 
       227 
     | 
    
         
            -
                    
         
     | 
| 
       228 
     | 
    
         
            -
                    values.each do |type, value|
         
     | 
| 
       229 
     | 
    
         
            -
                      write(type, value) unless type == :bit
         
     | 
| 
       230 
     | 
    
         
            -
                    end
         
     | 
| 
       231 
     | 
    
         
            -
                  else
         
     | 
| 
       232 
     | 
    
         
            -
                    raise API::InvalidTypeError, "Cannot write data of type #{type}"
         
     | 
| 
       233 
     | 
    
         
            -
                  end
         
     | 
| 
       234 
     | 
    
         
            -
                  
         
     | 
| 
       235 
     | 
    
         
            -
                  self
         
     | 
| 
       236 
     | 
    
         
            -
                end
         
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
                def extract
         
     | 
| 
       239 
     | 
    
         
            -
                  begin
         
     | 
| 
       240 
     | 
    
         
            -
                    cur_data, cur_pos = @data.clone, @pos
         
     | 
| 
       241 
     | 
    
         
            -
                    yield self
         
     | 
| 
       242 
     | 
    
         
            -
                  rescue API::BufferOverflowError
         
     | 
| 
       243 
     | 
    
         
            -
                    @data, @pos = cur_data, cur_pos
         
     | 
| 
       244 
     | 
    
         
            -
                    nil
         
     | 
| 
       245 
     | 
    
         
            -
                  end
         
     | 
| 
       246 
     | 
    
         
            -
                end
         
     | 
| 
       247 
     | 
    
         
            -
             
     | 
| 
       248 
     | 
    
         
            -
                def _read(size, pack = nil)
         
     | 
| 
       249 
     | 
    
         
            -
                  if @data.is_a?(API::Client)
         
     | 
| 
       250 
     | 
    
         
            -
                    raw = @data.read(size)
         
     | 
| 
       251 
     | 
    
         
            -
                    return raw if raw.nil? or pack.nil? 
         
     | 
| 
       252 
     | 
    
         
            -
                    return raw.unpack(pack).first
         
     | 
| 
       253 
     | 
    
         
            -
                  end
         
     | 
| 
       254 
     | 
    
         
            -
             
     | 
| 
       255 
     | 
    
         
            -
                  if @pos + size > length
         
     | 
| 
       256 
     | 
    
         
            -
                    raise API::BufferOverflowError
         
     | 
| 
       257 
     | 
    
         
            -
                  else
         
     | 
| 
       258 
     | 
    
         
            -
                    data = @data[@pos,size]
         
     | 
| 
       259 
     | 
    
         
            -
                    @data[@pos,size] = ''
         
     | 
| 
       260 
     | 
    
         
            -
                    if pack
         
     | 
| 
       261 
     | 
    
         
            -
                      data = data.unpack(pack)
         
     | 
| 
       262 
     | 
    
         
            -
                      data = data.pop if data.size == 1
         
     | 
| 
       263 
     | 
    
         
            -
                    end
         
     | 
| 
       264 
     | 
    
         
            -
                    data
         
     | 
| 
       265 
     | 
    
         
            -
                  end
         
     | 
| 
       266 
     | 
    
         
            -
                end
         
     | 
| 
       267 
     | 
    
         
            -
                
         
     | 
| 
       268 
     | 
    
         
            -
                def _write data, pack = nil
         
     | 
| 
       269 
     | 
    
         
            -
                  data = [*data].pack(pack) if pack
         
     | 
| 
       270 
     | 
    
         
            -
                  @data[@pos,0] = data
         
     | 
| 
       271 
     | 
    
         
            -
                  @pos += data.length
         
     | 
| 
       272 
     | 
    
         
            -
                end
         
     | 
| 
       273 
     | 
    
         
            -
              end
         
     | 
| 
       274 
     | 
    
         
            -
            end
         
     |