fotonauts-bunny 0.4.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.
@@ -0,0 +1,135 @@
1
+ module Qrack
2
+ module Protocol
3
+ #:stopdoc:
4
+ class Class::Method
5
+ def initialize *args
6
+ opts = args.pop if args.last.is_a? Hash
7
+ opts ||= {}
8
+
9
+ @debug = 1 # XXX hack, p(obj) == '' if no instance vars are set
10
+
11
+ if args.size == 1 and args.first.is_a? Transport::Buffer
12
+ buf = args.shift
13
+ else
14
+ buf = nil
15
+ end
16
+
17
+ self.class.arguments.each do |type, name|
18
+ val = buf ? buf.read(type) :
19
+ args.shift || opts[name] || opts[name.to_s]
20
+ instance_variable_set("@#{name}", val)
21
+ end
22
+ end
23
+
24
+ def arguments
25
+ self.class.arguments.inject({}) do |hash, (type, name)|
26
+ hash.update name => instance_variable_get("@#{name}")
27
+ end
28
+ end
29
+
30
+ def to_binary
31
+ buf = Transport::Buffer.new
32
+ buf.write :short, self.class.parent.id
33
+ buf.write :short, self.class.id
34
+
35
+ bits = []
36
+
37
+ self.class.arguments.each do |type, name|
38
+ val = instance_variable_get("@#{name}")
39
+ if type == :bit
40
+ bits << (val || false)
41
+ else
42
+ unless bits.empty?
43
+ buf.write :bit, bits
44
+ bits = []
45
+ end
46
+ buf.write type, val
47
+ end
48
+ end
49
+
50
+ buf.write :bit, bits unless bits.empty?
51
+ buf.rewind
52
+
53
+ buf
54
+ end
55
+
56
+ def to_s
57
+ to_binary.to_s
58
+ end
59
+
60
+ def to_frame channel = 0
61
+ Transport::Frame::Method.new(self, channel)
62
+ end
63
+ end
64
+
65
+ class Header
66
+ def initialize *args
67
+ opts = args.pop if args.last.is_a? Hash
68
+ opts ||= {}
69
+
70
+ first = args.shift
71
+
72
+ if first.is_a? ::Class and first.ancestors.include? Protocol::Class
73
+ @klass = first
74
+ @size = args.shift || 0
75
+ @weight = args.shift || 0
76
+ @properties = opts
77
+
78
+ elsif first.is_a? Transport::Buffer or first.is_a? String
79
+ buf = first
80
+ buf = Transport::Buffer.new(buf) unless buf.is_a? Transport::Buffer
81
+
82
+ @klass = Protocol.classes[buf.read(:short)]
83
+ @weight = buf.read(:short)
84
+ @size = buf.read(:longlong)
85
+
86
+ props = buf.read(:properties, *klass.properties.map{|type,_| type })
87
+ @properties = Hash[*klass.properties.map{|_,name| name }.zip(props).reject{|k,v| v.nil? }.flatten]
88
+
89
+ else
90
+ raise ArgumentError, 'Invalid argument'
91
+ end
92
+
93
+ end
94
+ attr_accessor :klass, :size, :weight, :properties
95
+
96
+ def to_binary
97
+ buf = Transport::Buffer.new
98
+ buf.write :short, klass.id
99
+ buf.write :short, weight # XXX rabbitmq only supports weight == 0
100
+ buf.write :longlong, size
101
+ buf.write :properties, (klass.properties.map do |type, name|
102
+ [ type, properties[name] || properties[name.to_s] ]
103
+ end)
104
+ buf.rewind
105
+ buf
106
+ end
107
+
108
+ def to_s
109
+ to_binary.to_s
110
+ end
111
+
112
+ def to_frame channel = 0
113
+ Transport::Frame::Header.new(self, channel)
114
+ end
115
+
116
+ def == header
117
+ [ :klass, :size, :weight, :properties ].inject(true) do |eql, field|
118
+ eql and __send__(field) == header.__send__(field)
119
+ end
120
+ end
121
+
122
+ def method_missing meth, *args, &blk
123
+ @properties.has_key?(meth) || @klass.properties.find{|_,name| name == meth } ? @properties[meth] :
124
+ super
125
+ end
126
+ end
127
+
128
+ def self.parse buf
129
+ buf = Transport::Buffer.new(buf) unless buf.is_a? Transport::Buffer
130
+ class_id, method_id = buf.read(:short, :short)
131
+ classes[class_id].methods[method_id].new(buf)
132
+ end
133
+
134
+ end
135
+ end