macks-ruby_protobuf 0.3.2.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.
- data/History.txt +14 -0
- data/Manifest.txt +74 -0
- data/README.txt +58 -0
- data/Rakefile +18 -0
- data/bin/mk_parser +2 -0
- data/bin/rprotoc +36 -0
- data/examples/addressbook.pb.rb +56 -0
- data/examples/addressbook.proto +24 -0
- data/examples/reading_a_message.rb +32 -0
- data/examples/writing_a_message.rb +46 -0
- data/lib/protobuf/common/wire_type.rb +10 -0
- data/lib/protobuf/compiler/compiler.rb +54 -0
- data/lib/protobuf/compiler/nodes.rb +319 -0
- data/lib/protobuf/compiler/proto.y +203 -0
- data/lib/protobuf/compiler/proto2.ebnf +79 -0
- data/lib/protobuf/compiler/proto_parser.rb +1394 -0
- data/lib/protobuf/compiler/template/rpc_bin.erb +4 -0
- data/lib/protobuf/compiler/template/rpc_client.erb +18 -0
- data/lib/protobuf/compiler/template/rpc_service.erb +25 -0
- data/lib/protobuf/compiler/visitors.rb +288 -0
- data/lib/protobuf/descriptor/descriptor.proto +286 -0
- data/lib/protobuf/descriptor/descriptor.rb +54 -0
- data/lib/protobuf/descriptor/descriptor_builder.rb +144 -0
- data/lib/protobuf/descriptor/descriptor_proto.rb +119 -0
- data/lib/protobuf/descriptor/enum_descriptor.rb +33 -0
- data/lib/protobuf/descriptor/field_descriptor.rb +50 -0
- data/lib/protobuf/descriptor/file_descriptor.rb +38 -0
- data/lib/protobuf/message/decoder.rb +93 -0
- data/lib/protobuf/message/encoder.rb +37 -0
- data/lib/protobuf/message/enum.rb +28 -0
- data/lib/protobuf/message/extend.rb +8 -0
- data/lib/protobuf/message/field.rb +654 -0
- data/lib/protobuf/message/message.rb +308 -0
- data/lib/protobuf/message/protoable.rb +37 -0
- data/lib/protobuf/message/service.rb +9 -0
- data/lib/protobuf/rpc/client.rb +19 -0
- data/lib/protobuf/rpc/handler.rb +17 -0
- data/lib/protobuf/rpc/server.rb +39 -0
- data/lib/ruby_protobuf.rb +3 -0
- data/test/addressbook.rb +98 -0
- data/test/addressbook_base.rb +62 -0
- data/test/addressbook_ext.rb +12 -0
- data/test/check_unbuild.rb +30 -0
- data/test/collision.rb +18 -0
- data/test/data/data.bin +3 -0
- data/test/data/data_source.py +14 -0
- data/test/data/types.bin +0 -0
- data/test/data/types_source.py +22 -0
- data/test/data/unk.png +0 -0
- data/test/ext_collision.rb +25 -0
- data/test/ext_range.rb +23 -0
- data/test/merge.rb +40 -0
- data/test/nested.rb +25 -0
- data/test/proto/addressbook.proto +31 -0
- data/test/proto/addressbook_base.proto +26 -0
- data/test/proto/addressbook_ext.proto +6 -0
- data/test/proto/collision.proto +5 -0
- data/test/proto/ext_collision.proto +8 -0
- data/test/proto/ext_range.proto +7 -0
- data/test/proto/merge.proto +15 -0
- data/test/proto/nested.proto +7 -0
- data/test/proto/rpc.proto +6 -0
- data/test/proto/types.proto +17 -0
- data/test/test_addressbook.rb +43 -0
- data/test/test_compiler.rb +313 -0
- data/test/test_descriptor.rb +122 -0
- data/test/test_extension.rb +40 -0
- data/test/test_message.rb +106 -0
- data/test/test_optional_field.rb +68 -0
- data/test/test_parse.rb +15 -0
- data/test/test_ruby_protobuf.rb +1 -0
- data/test/test_serialize.rb +42 -0
- data/test/test_standard_message.rb +96 -0
- data/test/test_types.rb +181 -0
- data/test/types.rb +22 -0
- metadata +150 -0
@@ -0,0 +1,654 @@
|
|
1
|
+
require 'protobuf/common/wire_type'
|
2
|
+
require 'protobuf/descriptor/field_descriptor'
|
3
|
+
|
4
|
+
module Protobuf
|
5
|
+
module Field
|
6
|
+
def self.build(message_class, rule, type, name, tag, opts={})
|
7
|
+
field_class =
|
8
|
+
if [:double, :float, :int32, :int64, :uint32, :uint64,
|
9
|
+
:sint32, :sint64, :fixed32, :fixed64, :sfixed32, :sfixed64,
|
10
|
+
:bool, :string, :bytes].include? type
|
11
|
+
eval "Protobuf::Field::#{type.to_s.capitalize}Field"
|
12
|
+
else
|
13
|
+
Protobuf::Field::FieldProxy
|
14
|
+
end
|
15
|
+
field_class.new message_class, rule, type, name, tag, opts
|
16
|
+
end
|
17
|
+
|
18
|
+
class InvalidRuleError < StandardError; end
|
19
|
+
|
20
|
+
class BaseField
|
21
|
+
class <<self
|
22
|
+
def descriptor
|
23
|
+
@descriptor ||= Protobuf::Descriptor::FieldDescriptor.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def default; nil end
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_accessor :message_class, :rule, :type, :name, :tag, :default
|
30
|
+
|
31
|
+
def descriptor
|
32
|
+
@descriptor ||= Protobuf::Descriptor::FieldDescriptor.new self
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(message_class, rule, type, name, tag, opts={})
|
36
|
+
@message_class, @rule, @type, @name, @tag, @default, @extension =
|
37
|
+
message_class, rule, type, name, tag, opts[:default], opts[:extension]
|
38
|
+
@error_message = 'Type invalid'
|
39
|
+
end
|
40
|
+
|
41
|
+
def ready?; true end
|
42
|
+
|
43
|
+
def initialized?(message)
|
44
|
+
case rule
|
45
|
+
when :required
|
46
|
+
return false if message[name].nil?
|
47
|
+
return false if is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
|
48
|
+
when :repeated
|
49
|
+
return message[name].inject(true) do |result, msg|
|
50
|
+
result and msg.initialized?
|
51
|
+
end
|
52
|
+
when :optional
|
53
|
+
return false if message[name] and is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
|
54
|
+
end
|
55
|
+
true
|
56
|
+
end
|
57
|
+
|
58
|
+
def clear(message)
|
59
|
+
if repeated?
|
60
|
+
message[name].clear
|
61
|
+
else
|
62
|
+
message.instance_variable_get(:@values).delete(name)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def default_value
|
67
|
+
case rule
|
68
|
+
when :repeated
|
69
|
+
FieldArray.new self
|
70
|
+
when :required
|
71
|
+
nil
|
72
|
+
when :optional
|
73
|
+
typed_default_value default
|
74
|
+
else
|
75
|
+
raise InvalidRuleError
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def typed_default_value(default=nil)
|
80
|
+
default or self.class.default
|
81
|
+
end
|
82
|
+
|
83
|
+
def define_accessor(message_instance)
|
84
|
+
message_instance.instance_variable_get(:@values)[name] = default_value if rule == :repeated
|
85
|
+
define_getter message_instance
|
86
|
+
define_setter message_instance unless rule == :repeated
|
87
|
+
end
|
88
|
+
|
89
|
+
def define_getter(message_instance)
|
90
|
+
field = self
|
91
|
+
metaclass = (class << message_instance; self; end)
|
92
|
+
metaclass.class_eval do
|
93
|
+
define_method(field.name) do
|
94
|
+
@values[field.name] or field.default_value
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def define_setter(message_instance)
|
100
|
+
field = self
|
101
|
+
metaclass = (class << message_instance; self; end)
|
102
|
+
metaclass.class_eval do
|
103
|
+
define_method("#{field.name}=") do |val|
|
104
|
+
if val.nil?
|
105
|
+
@values.delete(field.name)
|
106
|
+
elsif field.acceptable? val
|
107
|
+
@values[field.name] = val
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def set(message_instance, bytes)
|
114
|
+
if repeated?
|
115
|
+
set_array message_instance, bytes
|
116
|
+
else
|
117
|
+
set_bytes message_instance, bytes
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def set_array(message_instance, bytes)
|
122
|
+
raise NotImplementedError
|
123
|
+
end
|
124
|
+
|
125
|
+
def set_bytes(message_instance, bytes)
|
126
|
+
raise NotImplementedError
|
127
|
+
end
|
128
|
+
|
129
|
+
def get(value)
|
130
|
+
get_bytes value
|
131
|
+
end
|
132
|
+
|
133
|
+
def get_bytes(value)
|
134
|
+
raise NotImplementedError
|
135
|
+
end
|
136
|
+
|
137
|
+
def merge(message_instance, value)
|
138
|
+
if repeated?
|
139
|
+
merge_array message_instance, value
|
140
|
+
else
|
141
|
+
merge_value message_instance, value
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def merge_array(message_instance, value)
|
146
|
+
message_instance[tag].concat value
|
147
|
+
end
|
148
|
+
|
149
|
+
def merge_value(message_instance, value)
|
150
|
+
message_instance[tag] = value
|
151
|
+
end
|
152
|
+
|
153
|
+
def repeated?; rule == :repeated end
|
154
|
+
def required?; rule == :required end
|
155
|
+
def optional?; rule == :optional end
|
156
|
+
|
157
|
+
def max; self.class.max end
|
158
|
+
def min; self.class.min end
|
159
|
+
|
160
|
+
def acceptable?(val)
|
161
|
+
true
|
162
|
+
end
|
163
|
+
|
164
|
+
def error_message
|
165
|
+
@error_message
|
166
|
+
end
|
167
|
+
|
168
|
+
def to_s
|
169
|
+
"#{rule} #{type} #{name} = #{tag} #{default ? "[default=#{default}]" : ''}"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
class FieldProxy
|
174
|
+
def initialize(message_class, rule, type, name, tag, opts={})
|
175
|
+
@message_class, @rule, @type, @name, @tag, @opts =
|
176
|
+
message_class, rule, type, name, tag, opts
|
177
|
+
end
|
178
|
+
|
179
|
+
def ready?; false end
|
180
|
+
|
181
|
+
def setup
|
182
|
+
type = typename_to_class @message_class, @type
|
183
|
+
field_class =
|
184
|
+
if type.superclass == Protobuf::Enum
|
185
|
+
Protobuf::Field::EnumField
|
186
|
+
elsif type.superclass == Protobuf::Message
|
187
|
+
Protobuf::Field::MessageField
|
188
|
+
else
|
189
|
+
raise $!
|
190
|
+
end
|
191
|
+
field_class.new @message_class, @rule, type, @name, @tag, @opts
|
192
|
+
end
|
193
|
+
|
194
|
+
def typename_to_class(message_class, type)
|
195
|
+
modules = message_class.to_s.split('::')
|
196
|
+
while
|
197
|
+
begin
|
198
|
+
type = eval((modules | [type.to_s]).join('::'))
|
199
|
+
break
|
200
|
+
rescue NameError
|
201
|
+
modules.empty? ? raise($!) : modules.pop
|
202
|
+
end
|
203
|
+
end
|
204
|
+
type
|
205
|
+
end
|
206
|
+
=begin
|
207
|
+
def typename_to_class(message_class, type)
|
208
|
+
suffix = type.to_s.split('::')
|
209
|
+
modules = message_class.to_s.split('::')
|
210
|
+
while
|
211
|
+
mod = modules.empty? ? Object : eval(modules.join('::'))
|
212
|
+
suffix.each do |s|
|
213
|
+
if mod.const_defined?(s)
|
214
|
+
mod = mod.const_get(s)
|
215
|
+
else
|
216
|
+
mod = nil
|
217
|
+
break
|
218
|
+
end
|
219
|
+
end
|
220
|
+
break if mod
|
221
|
+
raise NameError.new("type not found: #{type}", type) if modules.empty?
|
222
|
+
modules.pop
|
223
|
+
end
|
224
|
+
mod
|
225
|
+
end
|
226
|
+
=end
|
227
|
+
end
|
228
|
+
|
229
|
+
class FieldArray < Array
|
230
|
+
def initialize(field)
|
231
|
+
@field = field
|
232
|
+
end
|
233
|
+
|
234
|
+
def []=(nth, val)
|
235
|
+
if @field.acceptable? val
|
236
|
+
super
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def <<(val)
|
241
|
+
if @field.acceptable? val
|
242
|
+
super
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def push(val)
|
247
|
+
if @field.acceptable? val
|
248
|
+
super
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
def unshift(val)
|
253
|
+
if @field.acceptable? val
|
254
|
+
super
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def to_s
|
259
|
+
"[#{@field.name}]"
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
class StringField < BaseField
|
264
|
+
class <<self
|
265
|
+
def default; '' end
|
266
|
+
end
|
267
|
+
|
268
|
+
def wire_type
|
269
|
+
Protobuf::WireType::LENGTH_DELIMITED
|
270
|
+
end
|
271
|
+
|
272
|
+
def acceptable?(val)
|
273
|
+
raise TypeError unless val.instance_of? String
|
274
|
+
true
|
275
|
+
end
|
276
|
+
|
277
|
+
def set_bytes(message_instance, bytes)
|
278
|
+
message = bytes.pack('C*')
|
279
|
+
message.force_encoding('UTF-8') if message.respond_to?(:force_encoding)
|
280
|
+
message_instance.send("#{name}=", message)
|
281
|
+
end
|
282
|
+
|
283
|
+
def set_array(message_instance, bytes)
|
284
|
+
message = bytes.pack('C*')
|
285
|
+
message.force_encoding('UTF-8') if message.respond_to?(:force_encoding)
|
286
|
+
arr = message_instance.send name
|
287
|
+
arr << message
|
288
|
+
end
|
289
|
+
|
290
|
+
def get_bytes(value)
|
291
|
+
bytes = value.unpack('C*')
|
292
|
+
string_size = VarintField.get_bytes bytes.size
|
293
|
+
string_size + bytes.pack('C*')
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
class BytesField < BaseField
|
298
|
+
class <<self
|
299
|
+
def default; '' end
|
300
|
+
end
|
301
|
+
|
302
|
+
def wire_type
|
303
|
+
Protobuf::WireType::LENGTH_DELIMITED
|
304
|
+
end
|
305
|
+
|
306
|
+
def acceptable?(val)
|
307
|
+
raise TypeError unless val.instance_of? String
|
308
|
+
true
|
309
|
+
end
|
310
|
+
|
311
|
+
def set_bytes(message_instance, bytes)
|
312
|
+
message_instance.send("#{name}=", bytes.pack('C*'))
|
313
|
+
end
|
314
|
+
|
315
|
+
def set_array(message_instance, bytes)
|
316
|
+
message = bytes.pack('C*')
|
317
|
+
arr = message_instance.send name
|
318
|
+
arr << message
|
319
|
+
end
|
320
|
+
|
321
|
+
def get_bytes(value)
|
322
|
+
string_size = VarintField.get_bytes value.unpack('C*').size
|
323
|
+
string_size + value
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
class VarintField < BaseField
|
328
|
+
class <<self
|
329
|
+
def default; 0 end
|
330
|
+
end
|
331
|
+
|
332
|
+
def wire_type
|
333
|
+
Protobuf::WireType::VARINT
|
334
|
+
end
|
335
|
+
|
336
|
+
def set_bytes(message_instance, bytes)
|
337
|
+
# TODO should refactor using pack('w*')
|
338
|
+
value = 0
|
339
|
+
bytes.each_with_index do |byte, index|
|
340
|
+
value |= byte << (7 * index)
|
341
|
+
end
|
342
|
+
message_instance.send("#{name}=", value)
|
343
|
+
end
|
344
|
+
|
345
|
+
def self.get_bytes(value)
|
346
|
+
# TODO should refactor using unpack('w*')
|
347
|
+
#return [value].pack('w*').unpack('C*')
|
348
|
+
return [0].pack('C') if value == 0
|
349
|
+
bytes = []
|
350
|
+
until value == 0
|
351
|
+
byte = 0
|
352
|
+
7.times do |i|
|
353
|
+
byte |= (value & 1) << i
|
354
|
+
value >>= 1
|
355
|
+
end
|
356
|
+
byte |= 0b10000000
|
357
|
+
bytes << byte
|
358
|
+
end
|
359
|
+
#bytes[0] &= 0b01111111
|
360
|
+
#bytes
|
361
|
+
bytes[bytes.size - 1] &= 0b01111111
|
362
|
+
bytes.pack('C*')
|
363
|
+
end
|
364
|
+
|
365
|
+
def get_bytes(value)
|
366
|
+
self.class.get_bytes value
|
367
|
+
end
|
368
|
+
|
369
|
+
def acceptable?(val)
|
370
|
+
raise TypeError.new(val.class.name) unless val.is_a? Integer
|
371
|
+
raise RangeError.new(val) if val < min or max < val
|
372
|
+
true
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
class Int32Field < VarintField
|
377
|
+
def self.max; 1.0/0.0 end
|
378
|
+
def self.min; -1.0/0.0 end
|
379
|
+
end
|
380
|
+
|
381
|
+
class Int64Field < VarintField
|
382
|
+
def self.max; 1.0/0.0 end
|
383
|
+
def self.min; -1.0/0.0 end
|
384
|
+
end
|
385
|
+
|
386
|
+
class Uint32Field < VarintField
|
387
|
+
def self.max; 1.0/0.0 end
|
388
|
+
def self.min; 0 end
|
389
|
+
end
|
390
|
+
|
391
|
+
class Uint64Field < VarintField
|
392
|
+
def self.max; 1.0/0.0 end
|
393
|
+
def self.min; 0 end
|
394
|
+
end
|
395
|
+
|
396
|
+
class Sint32Field < VarintField
|
397
|
+
def self.max; 1.0/0.0 end
|
398
|
+
def self.min; -1.0/0.0 end
|
399
|
+
|
400
|
+
def set_bytes(message_instance, bytes)
|
401
|
+
# TODO use only bit-operations
|
402
|
+
byte = bytes.first
|
403
|
+
value =
|
404
|
+
if byte % 2 == 0
|
405
|
+
byte / 2
|
406
|
+
else
|
407
|
+
-(byte + 1) / 2
|
408
|
+
end
|
409
|
+
message_instance.send("#{name}=", value)
|
410
|
+
end
|
411
|
+
|
412
|
+
def get_bytes(value)
|
413
|
+
#(value << 1) ^ (value >> 31)
|
414
|
+
[(value << 1) ^ (value >> 31)].pack('C*')
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
class Sint64Field < VarintField
|
419
|
+
def self.max; 1.0/0.0 end
|
420
|
+
def self.min; -1.0/0.0 end
|
421
|
+
|
422
|
+
def set_bytes(message_instance, bytes)
|
423
|
+
# TODO use only bit-operations
|
424
|
+
byte = bytes.first
|
425
|
+
value =
|
426
|
+
if byte % 2 == 0
|
427
|
+
byte / 2
|
428
|
+
else
|
429
|
+
-(byte + 1) / 2
|
430
|
+
end
|
431
|
+
message_instance.send("#{name}=", value)
|
432
|
+
end
|
433
|
+
|
434
|
+
def get_bytes(value)
|
435
|
+
#(value << 1) ^ (value >> 63)
|
436
|
+
[(value << 1) ^ (value >> 63)].pack('C*')
|
437
|
+
end
|
438
|
+
end
|
439
|
+
|
440
|
+
class DoubleField < VarintField
|
441
|
+
def wire_type
|
442
|
+
Protobuf::WireType::FIXED64
|
443
|
+
end
|
444
|
+
|
445
|
+
#TODO
|
446
|
+
def self.max
|
447
|
+
'0x7fefffffffffffff'.unpack('d').first
|
448
|
+
end
|
449
|
+
|
450
|
+
#TODO
|
451
|
+
def self.min
|
452
|
+
-(2**(64/2) - 1)
|
453
|
+
end
|
454
|
+
|
455
|
+
def set_bytes(message_instance, bytes)
|
456
|
+
message_instance.send("#{name}=", bytes.unpack('E').first)
|
457
|
+
end
|
458
|
+
|
459
|
+
def get_bytes(value)
|
460
|
+
[value].pack('E')
|
461
|
+
end
|
462
|
+
|
463
|
+
def acceptable?(val)
|
464
|
+
raise TypeError.new(val.class.name) unless val.is_a? Numeric
|
465
|
+
raise RangeError.new(val) if val < min or max < val
|
466
|
+
true
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
class FloatField < VarintField
|
471
|
+
def wire_type
|
472
|
+
Protobuf::WireType::FIXED32
|
473
|
+
end
|
474
|
+
|
475
|
+
#TODO
|
476
|
+
def self.max
|
477
|
+
'0x7fefffffffffffff'.unpack('e').first
|
478
|
+
end
|
479
|
+
|
480
|
+
#TODO
|
481
|
+
def self.min
|
482
|
+
-(2**(32/2) - 1)
|
483
|
+
end
|
484
|
+
|
485
|
+
def set_bytes(message_instance, bytes)
|
486
|
+
message_instance.send("#{name}=", bytes.unpack('e').first)
|
487
|
+
end
|
488
|
+
|
489
|
+
def get_bytes(value)
|
490
|
+
[value].pack('e')
|
491
|
+
end
|
492
|
+
|
493
|
+
def acceptable?(val)
|
494
|
+
raise TypeError unless val.is_a? Numeric
|
495
|
+
raise RangeError if val < min or max < val
|
496
|
+
true
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
class Fixed32Field < VarintField
|
501
|
+
def wire_type
|
502
|
+
Protobuf::WireType::FIXED32
|
503
|
+
end
|
504
|
+
|
505
|
+
def self.max
|
506
|
+
2**32
|
507
|
+
end
|
508
|
+
|
509
|
+
def self.min
|
510
|
+
0
|
511
|
+
end
|
512
|
+
|
513
|
+
def set_bytes(message_instance, bytes)
|
514
|
+
message_instance.send("#{name}=", bytes.unpack('L').first)
|
515
|
+
end
|
516
|
+
|
517
|
+
def get_bytes(value)
|
518
|
+
[value].pack('L')
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
class Fixed64Field < VarintField
|
523
|
+
def wire_type
|
524
|
+
Protobuf::WireType::FIXED64
|
525
|
+
end
|
526
|
+
|
527
|
+
def self.max
|
528
|
+
2**64
|
529
|
+
end
|
530
|
+
|
531
|
+
def self.min
|
532
|
+
0
|
533
|
+
end
|
534
|
+
|
535
|
+
def set_bytes(message_instance, bytes)
|
536
|
+
message_instance.send("#{name}=", bytes.unpack('l').first)
|
537
|
+
end
|
538
|
+
|
539
|
+
def get_bytes(value)
|
540
|
+
[value].pack('Q')
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
class Sfinxed32Field < VarintField
|
545
|
+
def wire_type
|
546
|
+
Protobuf::WireType::FIXED32
|
547
|
+
end
|
548
|
+
|
549
|
+
def self.max
|
550
|
+
2**(32/2)
|
551
|
+
end
|
552
|
+
|
553
|
+
def self.min
|
554
|
+
-(2**(32/2) - 1)
|
555
|
+
end
|
556
|
+
end
|
557
|
+
|
558
|
+
class Sfixed64Field < VarintField
|
559
|
+
def wire_type
|
560
|
+
Protobuf::WireType::FIXED64
|
561
|
+
end
|
562
|
+
|
563
|
+
def self.max
|
564
|
+
2**(64/2)
|
565
|
+
end
|
566
|
+
|
567
|
+
def self.min
|
568
|
+
-(2**(64/2) - 1)
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
class BoolField < VarintField
|
573
|
+
class <<self
|
574
|
+
def default; false end
|
575
|
+
end
|
576
|
+
|
577
|
+
def acceptable?(val)
|
578
|
+
raise TypeError unless [TrueClass, FalseClass].include? val.class
|
579
|
+
true
|
580
|
+
end
|
581
|
+
|
582
|
+
def set_bytes(message_instance, bytes)
|
583
|
+
message_instance.send("#{name}=", bytes.first == 1)
|
584
|
+
end
|
585
|
+
|
586
|
+
def get_bytes(value)
|
587
|
+
[value ? 1 : 0].pack('C')
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
class MessageField < BaseField
|
592
|
+
class <<self
|
593
|
+
def default; nil end
|
594
|
+
end
|
595
|
+
|
596
|
+
def wire_type
|
597
|
+
Protobuf::WireType::LENGTH_DELIMITED
|
598
|
+
end
|
599
|
+
|
600
|
+
def typed_default_value(default=nil)
|
601
|
+
if default.is_a? Symbol
|
602
|
+
type.module_eval default.to_s
|
603
|
+
else
|
604
|
+
default
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
def acceptable?(val)
|
609
|
+
raise TypeError unless val.instance_of? type
|
610
|
+
true
|
611
|
+
end
|
612
|
+
|
613
|
+
def set_bytes(message_instance, bytes)
|
614
|
+
message = type.new
|
615
|
+
message.parse_from_string bytes.pack('C*') # TODO
|
616
|
+
message_instance.send("#{name}=", message)
|
617
|
+
end
|
618
|
+
|
619
|
+
def set_array(message_instance, bytes)
|
620
|
+
message = type.new
|
621
|
+
message.parse_from_string bytes.pack('C*')
|
622
|
+
arr = message_instance.send name
|
623
|
+
arr << message
|
624
|
+
end
|
625
|
+
|
626
|
+
def get_bytes(value)
|
627
|
+
stringio = StringIO.new ''
|
628
|
+
value.serialize_to stringio
|
629
|
+
bytes = stringio.string.unpack 'C*'
|
630
|
+
string_size = VarintField.get_bytes bytes.size
|
631
|
+
string_size + bytes.pack('C*')
|
632
|
+
end
|
633
|
+
|
634
|
+
def merge_value(message_instance, value)
|
635
|
+
message_instance[tag].merge_from value
|
636
|
+
end
|
637
|
+
end
|
638
|
+
|
639
|
+
class EnumField < VarintField
|
640
|
+
def default
|
641
|
+
if @default.is_a?(Symbol)
|
642
|
+
type.const_get @default
|
643
|
+
else
|
644
|
+
@default
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
def acceptable?(val)
|
649
|
+
raise TypeError unless type.valid_tag? val
|
650
|
+
true
|
651
|
+
end
|
652
|
+
end
|
653
|
+
end
|
654
|
+
end
|