ruby_protobuf 0.0.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,5 @@
1
+ === 0.0.1 / 2008-07-26
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
5
+
@@ -0,0 +1,32 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/rprotoc
6
+ bin/ruby_protobuf
7
+ lib/protobuf/compiler.rb
8
+ lib/protobuf/decoder.rb
9
+ lib/protobuf/encoder.rb
10
+ lib/protobuf/enum.rb
11
+ lib/protobuf/extend.rb
12
+ lib/protobuf/field.rb
13
+ lib/protobuf/message.rb
14
+ lib/protobuf/parser.y
15
+ lib/protobuf/service.rb
16
+ lib/protobuf/wire_type.rb
17
+ lib/ruby_protobuf.rb
18
+ test/addressbook.proto
19
+ test/addressbook.rb
20
+ test/data/data.bin
21
+ test/data/data_source.py
22
+ test/data/types.bin
23
+ test/data/types_source.py
24
+ test/test_addressbook.rb
25
+ test/test_compiler.rb
26
+ test/test_message.rb
27
+ test/test_parse.rb
28
+ test/test_ruby_protobuf.rb
29
+ test/test_serialize.rb
30
+ test/test_types.rb
31
+ test/types.proto
32
+ test/types.rb
@@ -0,0 +1,50 @@
1
+ = RubyProtobuf
2
+
3
+ * http://code.google.com/p/ruby-protobuf
4
+
5
+ == DESCRIPTION:
6
+
7
+ Protocol Buffers for Ruby.
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * Compile .proto file to ruby script
12
+ * Parse the binary wire format for protocol buffer
13
+ * Serialize data to the binary wire format for protocol buffer
14
+
15
+ == SYNOPSIS:
16
+
17
+ bin/rprotoc -I lib test/addressbook.proto
18
+
19
+ == REQUIREMENTS:
20
+
21
+ * All you need are included.
22
+
23
+ == INSTALL:
24
+
25
+ * sudo gem install ruby-protobuf
26
+
27
+ == LICENSE:
28
+
29
+ (The MIT License)
30
+
31
+ Copyright (c) 2008 FIX
32
+
33
+ Permission is hereby granted, free of charge, to any person obtaining
34
+ a copy of this software and associated documentation files (the
35
+ 'Software'), to deal in the Software without restriction, including
36
+ without limitation the rights to use, copy, modify, merge, publish,
37
+ distribute, sublicense, and/or sell copies of the Software, and to
38
+ permit persons to whom the Software is furnished to do so, subject to
39
+ the following conditions:
40
+
41
+ The above copyright notice and this permission notice shall be
42
+ included in all copies or substantial portions of the Software.
43
+
44
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
45
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
46
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
47
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
48
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
49
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
50
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,18 @@
1
+ # -*- ruby -*-
2
+
3
+ $:.push(File.dirname(__FILE__) + '/lib')
4
+ require 'rubygems'
5
+ require 'hoe'
6
+ require 'ruby_protobuf'
7
+
8
+ Hoe.new('ruby_protobuf', RubyProtobuf::VERSION) do |p|
9
+ p.rubyforge_name = 'ruby-protobuf'
10
+ p.author = 'ANDO Yasushi'
11
+ p.email = 'andyjpn@gmail.com'
12
+ p.summary = 'Protocol Buffers for Ruby'
13
+ p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
14
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
15
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
16
+ end
17
+
18
+ # vim: syntax=Ruby
@@ -0,0 +1,21 @@
1
+ #!/usr/local/bin/ruby
2
+ $: << "#{File.dirname(__FILE__)}/../lib"
3
+ require 'optparse'
4
+ require 'ruby_protobuf'
5
+
6
+
7
+ COMMAND_LINE = "#{$0} #{ARGV.join(' ')} PROTO_FILE"
8
+ OPT = {}
9
+ opts = OptionParser.new
10
+ #opts.on('-p', '--proto_path <PATH>', 'Specify the directory in which to search for imports. The current directory is default.'){|v| OPT[:proto_path] = v}
11
+ opts.on('-o', '--out <OUT_DIR>', 'Specify the directory in which Ruby source file is generated. The current directory is default.'){|v| OPT[:out] = v}
12
+ opts.on_tail('-v', '--version', 'Show version.'){puts(opts.ver); exit}
13
+ opts.on_tail('-h', '--help', 'Show this message.'){puts(opts.help); exit}
14
+
15
+ ::Version = RubyProtobuf::VERSION
16
+ opts.order! ARGV
17
+ PROTO_FILE = ARGV.shift
18
+
19
+ RubyProtobuf.new.start PROTO_FILE, OPT
20
+
21
+
File without changes
@@ -0,0 +1,90 @@
1
+ # This is a quite temporary implementation.
2
+ # I'll create a compiler class using Racc.
3
+
4
+ module Protobuf
5
+ class Compiler
6
+ INDENT_UNIT = ' '
7
+
8
+ def self.compile(filename)
9
+ self.new.compile filename
10
+ end
11
+
12
+ def initialize
13
+ @indent_level = 0
14
+ @ret = <<-eos
15
+ require 'protobuf/message'
16
+ require 'protobuf/enum'
17
+ require 'protobuf/service'
18
+ require 'protobuf/extend'
19
+
20
+ eos
21
+ end
22
+
23
+ def indent
24
+ INDENT_UNIT * @indent_level
25
+ end
26
+
27
+ def puts_with_indent(string)
28
+ #puts "#{indent}#{string}"
29
+ @ret += "#{indent}#{string}\n"
30
+ end
31
+ alias putswi puts_with_indent
32
+
33
+ def compile(filename)
34
+ File.open filename, 'r' do |file|
35
+ file.each_line do |line|
36
+ line.sub! /^(.*)\/\/.*/, '\1'
37
+ line.strip!
38
+ case line
39
+ when /^package\s+(\w+(\.\w+)?)\s*;$/
40
+ $1.split('.').each do |path|
41
+ putswi "module #{path.capitalize}"
42
+ @indent_level += 1
43
+ end
44
+ when /^message\s+(\w+)\s*\{$/
45
+ putswi "class #{$1} < Protobuf::Message"
46
+ @indent_level += 1
47
+ when /^(required|optional|repeated)\s+(\w+(\.\w+)?)\s+(\w+)\s*=\s*(\d+)\s*(\[\s*default\s*=\s*(\w+)\s*\])?\s*;$/
48
+ rule, type, name, tag, default = $1, $2, $4, $5, $7
49
+ if default
50
+ default = default =~ /\d+(\.\d+)/ \
51
+ ? ", {:default => #{default}}" \
52
+ : ", {:default => :#{default}}"
53
+ end
54
+ putswi "#{rule} :#{type}, :#{name}, #{tag}#{default}"
55
+ when /^enum\s+(\w+)\s*\{$/
56
+ putswi "class #{$1} < Protobuf::Enum"
57
+ @indent_level += 1
58
+ when /^(\w+)\s*=\s*(\w+)\s*;$/
59
+ putswi "#{$1} = #{$2}"
60
+ when /^extensions\s+(\w+)\s+to\s+(\w+)\s*;/
61
+ low, high = $1, $2
62
+ low = 'Protobuf::Extend.MIN' if low == 'min'
63
+ high = 'Protobuf::Extend.MAX' if high == 'max'
64
+ putswi "extensions #{min}..#{max}"
65
+ when /^extend\s+(\w+)\s*\{/
66
+ putswi "class #{$1} < Protobuf::Extend"
67
+ @indent_level += 1
68
+ when /^service\s+(\w+)\s*\{/
69
+ putswi "class #{$1} < Protobuf::Service"
70
+ @indent_level += 1
71
+ when /^rpc\s+(\w+)\s+\(\s*(\w+)\s*\)\s+returns\s+\(\s*(\w+)\s*\)\s*;/
72
+ putswi "rpc :#{$1} => :#{$2}, :#{$3} => :#{$4}"
73
+ when /^option\s+(\w+)\s*=\s*(.+)\s*;/
74
+ putswi "Protobuf::OPTIONS[:#{$1}] = :#{$2}"
75
+ when /^\}$/
76
+ @indent_level -= 1
77
+ putswi "end"
78
+ when ''
79
+ putswi ''
80
+ end
81
+ end
82
+ while 0 < @indent_level
83
+ @indent_level -= 1
84
+ putswi "end"
85
+ end
86
+ end
87
+ @ret
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,87 @@
1
+ require 'protobuf/wire_type'
2
+
3
+ module Protobuf
4
+ class InvalidWireType < StandardError; end
5
+
6
+ class Decoder
7
+ class <<self
8
+ def decode(stream, message)
9
+ self.new(stream, message).decode
10
+ end
11
+ end
12
+
13
+ def initialize(stream=nil, message=nil)
14
+ @stream, @message = stream, message
15
+ end
16
+
17
+ def decode(stream=@stream, message=@message)
18
+ until stream.eof?
19
+ tag, wire_type = read_key stream
20
+ bytes =
21
+ case wire_type
22
+ when WireType::VARINT
23
+ read_varint stream
24
+ when WireType::FIXED64
25
+ read_fixed64 stream
26
+ when WireType::LENGTH_DELIMITED
27
+ read_length_delimited stream
28
+ when WireType::START_GROUP
29
+ read_start_group stream
30
+ when WireType::END_GROUP
31
+ read_end_group stream
32
+ when WireType::FIXED32
33
+ read_fixed32 stream
34
+ else
35
+ raise InvalidWireType.new(wire_type)
36
+ end
37
+ message.set_field tag, bytes
38
+ end
39
+ message
40
+ end
41
+
42
+ protected
43
+
44
+ def read_key(stream)
45
+ bytes = read_varint stream
46
+ #TODO 1 < bytes.size のときエラー
47
+ wire_type = bytes[0] & 0b00000111
48
+ tag = bytes[0] >> 3 # TODO
49
+ [tag, wire_type]
50
+ end
51
+
52
+ def read_varint(stream)
53
+ bytes = []
54
+ begin
55
+ byte = stream.readchar
56
+ bytes << (byte & 0b01111111)
57
+ end while byte >> 7 == 1
58
+ bytes
59
+ end
60
+
61
+ def read_fixed64(stream)
62
+ stream.read(8)
63
+ end
64
+
65
+ def read_length_delimited(stream)
66
+ bytes = read_varint stream
67
+ value_length = 0
68
+ bytes.each_with_index do |byte, index|
69
+ value_length |= byte << (7 * index)
70
+ end
71
+ value = stream.read value_length
72
+ value.unpack('c*')
73
+ end
74
+
75
+ def read_start_group(stream)
76
+ raise NotImplementedError.new('Group is duplecated.')
77
+ end
78
+
79
+ def read_end_group(stream)
80
+ raise NotImplementedError.new('Group is duplecated.')
81
+ end
82
+
83
+ def read_fixed32(stream)
84
+ stream.read(4)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,36 @@
1
+ require 'protobuf/wire_type'
2
+
3
+ module Protobuf
4
+ class Encoder
5
+ class <<self
6
+ def encode(stream, message)
7
+ self.new(stream, message).encode
8
+ end
9
+ end
10
+
11
+ def initialize(stream=nil, message=nil)
12
+ @stream, @message = stream, message
13
+ end
14
+
15
+ def encode(stream=@stream, message=@message)
16
+ message.each_field do |field, value|
17
+ key = (field.tag << 3) | field.wire_type
18
+ key_bytes = Protobuf::Field::Int.get_bytes key
19
+ #stream.write key_bytes.pack('C*')
20
+ stream.write key_bytes
21
+
22
+ if field.repeated?
23
+ value.each do |val|
24
+ bytes = field.get val
25
+ #stream.write bytes.pack('C*')
26
+ stream.write bytes
27
+ end
28
+ else
29
+ bytes = field.get value
30
+ #stream.write bytes.pack('C*')
31
+ stream.write bytes
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,13 @@
1
+ module Protobuf
2
+ class Enum
3
+ def self.get_name_by_tag(tag)
4
+ constants.find do |name|
5
+ class_eval(name) == tag
6
+ end
7
+ end
8
+
9
+ def self.valid_tag?(tag)
10
+ not get_name_by_tag(tag).nil?
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ require 'protobuf/message'
2
+
3
+ module Protobuf
4
+ class Extend < Message
5
+ MIN = -1.0/0
6
+ MAX = 1.0/0
7
+ end
8
+ end
@@ -0,0 +1,547 @@
1
+ require 'protobuf/wire_type'
2
+
3
+ module Protobuf
4
+ module Field
5
+ def self.build(message_class, rule, type, name, tag, opts={})
6
+ Base.build message_class, rule, type, name, tag, opts
7
+ end
8
+
9
+ class InvalidRuleError < StandardError; end
10
+
11
+ class Base
12
+ class <<self
13
+ def build(message_class, rule, type, name, tag, opts={})
14
+ field_class = nil
15
+ begin
16
+ field_class = eval "Protobuf::Field::#{type.to_s.capitalize}Field"
17
+ rescue NameError
18
+ type = typename_to_class message_class, type
19
+ field_class =
20
+ if type.superclass == Protobuf::Enum
21
+ Protobuf::Field::Enum
22
+ elsif type.superclass == Protobuf::Message
23
+ Protobuf::Field::Message
24
+ else
25
+ raise $!
26
+ end
27
+ end
28
+ field_class.new message_class, rule, type, name, tag, opts
29
+ end
30
+
31
+ def typename_to_class(message_class, type)
32
+ modules = message_class.to_s.split('::')
33
+ while
34
+ begin
35
+ type = eval((modules | [type.to_s]).join('::'))
36
+ break
37
+ rescue NameError
38
+ modules.empty? ? raise($!) : modules.pop
39
+ end
40
+ end
41
+ type
42
+ end
43
+ end
44
+
45
+ attr_accessor :message_class, :rule, :type, :name, :tag, :default
46
+
47
+ def initialize(message_class, rule, type, name, tag, opts={})
48
+ @message_class, @rule, @type, @name, @tag, @default =
49
+ message_class, rule, type, name, tag, opts[:default]
50
+ @error_message = 'Type invalid'
51
+ end
52
+
53
+ def default_value
54
+ case rule
55
+ when :repeated
56
+ FieldArray.new self
57
+ when :required, :optional
58
+ typed_default_value default
59
+ else
60
+ raise InvalidRuleError
61
+ end
62
+ end
63
+
64
+ def typed_default_value(default=nil)
65
+ default
66
+ end
67
+
68
+ def define_accessor(message_instance)
69
+ message_instance.instance_variable_set "@#{name}", default_value
70
+ define_getter message_instance
71
+ define_setter message_instance unless rule == :repeated
72
+ end
73
+
74
+ def define_getter(message_instance)
75
+ message_instance.instance_eval %Q{
76
+ def #{name}
77
+ @#{name}
78
+ end
79
+ }
80
+ end
81
+
82
+ def define_setter(message_instance)
83
+ message_instance.instance_eval %Q{
84
+ def #{name}=(val)
85
+ field = get_field_by_name #{name.inspect}
86
+ if field.acceptable? val
87
+ @#{name} = val
88
+ end
89
+ end
90
+ }
91
+ end
92
+
93
+ def set(message_instance, bytes)
94
+ if repeated?
95
+ set_array message_instance, bytes
96
+ else
97
+ set_bytes message_instance, bytes
98
+ end
99
+ end
100
+
101
+ def set_array(message_instance, bytes)
102
+ raise NotImplementedError
103
+ end
104
+
105
+ def set_bytes(message_instance, bytes)
106
+ raise NotImplementedError
107
+ end
108
+
109
+ def get(value)
110
+ get_bytes value
111
+ end
112
+
113
+ def get_bytes(value)
114
+ raise NotImplementedError
115
+ end
116
+
117
+ def merge(message_instance, bytes)
118
+ if repeated?
119
+ merge_array method_instance, bytes
120
+ else
121
+ merge_value method_instance, bytes
122
+ end
123
+ end
124
+
125
+ def merge_array(message_instance, bytes)
126
+ raise NotImplementedError
127
+ end
128
+
129
+ def merge_value(message_instance, bytes)
130
+ raise NotImplementedError
131
+ end
132
+
133
+ def repeated?; rule == :repeated end
134
+ def required?; rule == :required end
135
+ def optional?; rule == :optional end
136
+
137
+ def max; self.class.max end
138
+ def min; self.class.min end
139
+
140
+ def acceptable?(val)
141
+ true
142
+ end
143
+
144
+ def error_message
145
+ @error_message
146
+ end
147
+
148
+ def to_s
149
+ "#{rule} #{type} #{name} = #{tag} #{default ? "[default=#{default}]" : ''}"
150
+ end
151
+ end
152
+
153
+ class FieldArray < Array
154
+ def initialize(field)
155
+ @field = field
156
+ end
157
+
158
+ def []=(nth, val)
159
+ if @field.acceptable? val
160
+ super
161
+ end
162
+ end
163
+
164
+ def <<(val)
165
+ if @field.acceptable? val
166
+ super
167
+ end
168
+ end
169
+
170
+ def push(val)
171
+ if @field.acceptable? val
172
+ super
173
+ end
174
+ end
175
+
176
+ def unshift(val)
177
+ if @field.acceptable? val
178
+ super
179
+ end
180
+ end
181
+
182
+ def to_s
183
+ "[#{@field.name}]"
184
+ end
185
+ end
186
+
187
+ class StringField < Base
188
+ def wire_type
189
+ Protobuf::WireType::LENGTH_DELIMITED
190
+ end
191
+
192
+ def typed_default_value(default=nil)
193
+ default or ''
194
+ end
195
+
196
+ def acceptable?(val)
197
+ raise TypeError unless val.instance_of? String
198
+ true
199
+ end
200
+
201
+ def set_bytes(method_instance, bytes)
202
+ method_instance.send("#{name}=", bytes.pack('U*'))
203
+ end
204
+
205
+ def get_bytes(value)
206
+ bytes = value.unpack('U*')
207
+ string_size = Int.get_bytes bytes.size
208
+ #(string_size + bytes).pack('C*')
209
+ string_size + bytes.pack('C*')
210
+ end
211
+ end
212
+
213
+ class BytesField < Base
214
+ def wire_type
215
+ Protobuf::WireType::VARINT
216
+ end
217
+
218
+ def typed_default_value(default=nil)
219
+ default or []
220
+ end
221
+
222
+ def set_bytes(method_instance, bytes)
223
+ method_instance.send("#{name}=", bytes)
224
+ end
225
+
226
+ def get_bytes(value)
227
+ string_size = Int.get_bytes value.size
228
+ string_size + value.pack('C*')
229
+ end
230
+ end
231
+
232
+ class Int < Base
233
+ def wire_type
234
+ Protobuf::WireType::VARINT
235
+ end
236
+
237
+ def typed_default_value(default=nil)
238
+ default or 0
239
+ end
240
+
241
+ def set_bytes(method_instance, bytes)
242
+ # TODO should refactor using pack('w*')
243
+ value = 0
244
+ bytes.each_with_index do |byte, index|
245
+ value |= byte << (7 * index)
246
+ end
247
+ method_instance.send("#{name}=", value)
248
+ end
249
+
250
+ def self.get_bytes(value)
251
+ # TODO should refactor using unpack('w*')
252
+ #return [value].pack('w*').unpack('C*')
253
+ return [0].pack('C') if value == 0
254
+ bytes = []
255
+ until value == 0
256
+ byte = 0
257
+ 7.times do |i|
258
+ byte |= (value & 1) << i
259
+ value >>= 1
260
+ end
261
+ byte |= 0b10000000
262
+ bytes << byte
263
+ end
264
+ #bytes[0] &= 0b01111111
265
+ #bytes
266
+ bytes[bytes.size - 1] &= 0b01111111
267
+ bytes.pack('C*')
268
+ end
269
+
270
+ def get_bytes(value)
271
+ self.class.get_bytes value
272
+ end
273
+
274
+ def acceptable?(val)
275
+ raise TypeError.new(val.class.name) unless val.is_a? Integer
276
+ raise RangeError.new(val) if val < min or max < val
277
+ true
278
+ end
279
+ end
280
+
281
+ class Int32Field < Int
282
+ def self.max; 1.0/0.0 end
283
+ def self.min; -1.0/0.0 end
284
+ end
285
+
286
+ class Int64Field < Int
287
+ def self.max; 1.0/0.0 end
288
+ def self.min; -1.0/0.0 end
289
+ end
290
+
291
+ class Uint32Field < Int
292
+ def self.max; 1.0/0.0 end
293
+ def self.min; 0 end
294
+ end
295
+
296
+ class Uint64Field < Int
297
+ def self.max; 1.0/0.0 end
298
+ def self.min; 0 end
299
+ end
300
+
301
+ class Sint32Field < Int
302
+ def self.max; 1.0/0.0 end
303
+ def self.min; -1.0/0.0 end
304
+
305
+ def set_bytes(method_instance, bytes)
306
+ # TODO use only bit-operations
307
+ byte = bytes.first
308
+ value =
309
+ if byte % 2 == 0
310
+ byte / 2
311
+ else
312
+ -(byte + 1) / 2
313
+ end
314
+ method_instance.send("#{name}=", value)
315
+ end
316
+
317
+ def get_bytes(value)
318
+ #(value << 1) ^ (value >> 31)
319
+ [(value << 1) ^ (value >> 31)].pack('C*')
320
+ end
321
+ end
322
+
323
+ class Sint64Field < Int
324
+ def self.max; 1.0/0.0 end
325
+ def self.min; -1.0/0.0 end
326
+
327
+ def set_bytes(method_instance, bytes)
328
+ # TODO use only bit-operations
329
+ byte = bytes.first
330
+ value =
331
+ if byte % 2 == 0
332
+ byte / 2
333
+ else
334
+ -(byte + 1) / 2
335
+ end
336
+ method_instance.send("#{name}=", value)
337
+ end
338
+
339
+ def get_bytes(value)
340
+ #(value << 1) ^ (value >> 63)
341
+ [(value << 1) ^ (value >> 63)].pack('C*')
342
+ end
343
+ end
344
+
345
+ class DoubleField < Int
346
+ def wire_type
347
+ Protobuf::WireType::FIXED64
348
+ end
349
+
350
+ #TODO
351
+ def self.max
352
+ '0x7fefffffffffffff'.unpack('d').first
353
+ end
354
+
355
+ #TODO
356
+ def self.min
357
+ -(2**(64/2) - 1)
358
+ end
359
+
360
+ def set_bytes(method_instance, bytes)
361
+ method_instance.send("#{name}=", bytes.unpack('E').first)
362
+ end
363
+
364
+ def get_bytes(value)
365
+ [value].pack('E')
366
+ end
367
+
368
+ def acceptable?(val)
369
+ raise TypeError.new(val.class.name) unless val.is_a? Numeric
370
+ raise RangeError.new(val) if val < min or max < val
371
+ true
372
+ end
373
+ end
374
+
375
+ class FloatField < Int
376
+ def wire_type
377
+ Protobuf::WireType::FIXED32
378
+ end
379
+
380
+ #TODO
381
+ def self.max
382
+ '0x7fefffffffffffff'.unpack('e').first
383
+ end
384
+
385
+ #TODO
386
+ def self.min
387
+ -(2**(32/2) - 1)
388
+ end
389
+
390
+ def set_bytes(method_instance, bytes)
391
+ method_instance.send("#{name}=", bytes.unpack('e').first)
392
+ end
393
+
394
+ def get_bytes(value)
395
+ [value].pack('e')
396
+ end
397
+
398
+ def acceptable?(val)
399
+ raise TypeError unless val.is_a? Numeric
400
+ raise RangeError if val < min or max < val
401
+ true
402
+ end
403
+ end
404
+
405
+ class Fixed32Field < Int
406
+ def wire_type
407
+ Protobuf::WireType::FIXED32
408
+ end
409
+
410
+ def self.max
411
+ 2**32
412
+ end
413
+
414
+ def self.min
415
+ 0
416
+ end
417
+
418
+ def set_bytes(method_instance, bytes)
419
+ method_instance.send("#{name}=", bytes.unpack('L').first)
420
+ end
421
+
422
+ def get_bytes(value)
423
+ [value].pack('L')
424
+ end
425
+ end
426
+
427
+ class Fixed64Field < Int
428
+ def wire_type
429
+ Protobuf::WireType::FIXED64
430
+ end
431
+
432
+ def self.max
433
+ 2**64
434
+ end
435
+
436
+ def self.min
437
+ 0
438
+ end
439
+
440
+ def set_bytes(method_instance, bytes)
441
+ method_instance.send("#{name}=", bytes.unpack('l').first)
442
+ end
443
+
444
+ def get_bytes(value)
445
+ [value].pack('Q')
446
+ end
447
+ end
448
+
449
+ class Sfinxed32Field < Int
450
+ def wire_type
451
+ Protobuf::WireType::FIXED32
452
+ end
453
+
454
+ def self.max
455
+ 2**(32/2)
456
+ end
457
+
458
+ def self.min
459
+ -(2**(32/2) - 1)
460
+ end
461
+ end
462
+
463
+ class Sfixed64Field < Int
464
+ def wire_type
465
+ Protobuf::WireType::FIXED64
466
+ end
467
+
468
+ def self.max
469
+ 2**(64/2)
470
+ end
471
+
472
+ def self.min
473
+ -(2**(64/2) - 1)
474
+ end
475
+ end
476
+
477
+ class BoolField < Int
478
+ def typed_default_value(default=nil)
479
+ default or false
480
+ end
481
+
482
+ def acceptable?(val)
483
+ raise TypeError unless [TrueClass, FalseClass].include? val.class
484
+ true
485
+ end
486
+
487
+ def set_bytes(method_instance, bytes)
488
+ method_instance.send("#{name}=", bytes.first == 1)
489
+ end
490
+
491
+ def get_bytes(value)
492
+ [value ? 1 : 0].pack('C')
493
+ end
494
+ end
495
+
496
+ class Message < Base
497
+ def wire_type
498
+ Protobuf::WireType::LENGTH_DELIMITED
499
+ end
500
+
501
+ def typed_default_value(default=nil)
502
+ if default.is_a? Symbol
503
+ type.module_eval default.to_s
504
+ else
505
+ default
506
+ end
507
+ end
508
+
509
+ def acceptable?(val)
510
+ raise TypeError unless val.instance_of? type
511
+ true
512
+ end
513
+
514
+ def set_bytes(method_instance, bytes)
515
+ message = type.new
516
+ #message.parse_from bytes
517
+ message.parse_from_string bytes.pack('U*') # TODO
518
+ method_instance.send("#{name}=", message)
519
+ end
520
+
521
+ def set_array(method_instance, bytes)
522
+ message = type.new
523
+ #message.parse_from bytes
524
+ message.parse_from_string bytes.pack('U*')
525
+ arr = method_instance.send name
526
+ arr << message
527
+ end
528
+
529
+ def get_bytes(value)
530
+ stringio = StringIO.new ''
531
+ value.serialize_to stringio
532
+ bytes = stringio.string.unpack 'C*'
533
+ string_size = Int.get_bytes bytes.size
534
+ #(string_size + bytes).pack('C*')
535
+ #bytes + string_size
536
+ string_size + bytes.pack('C*')
537
+ end
538
+ end
539
+
540
+ class Enum < Int
541
+ def acceptable?(val)
542
+ raise TypeError unless type.valid_tag? val
543
+ true
544
+ end
545
+ end
546
+ end
547
+ end