ruby_protobuf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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