ruby_protobuf 0.3.3 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +10 -2
- data/Manifest.txt +26 -12
- data/README.txt +6 -1
- data/Rakefile +51 -14
- data/TODO +15 -0
- data/VERSION +1 -0
- data/bin/rprotoc +11 -6
- data/lib/protobuf/common/exceptions.rb +11 -0
- data/lib/protobuf/common/util.rb +9 -0
- data/lib/protobuf/common/wire_type.rb +6 -6
- data/lib/protobuf/compiler/compiler.rb +16 -16
- data/lib/protobuf/compiler/nodes.rb +67 -65
- data/lib/protobuf/compiler/proto.y +31 -38
- data/lib/protobuf/compiler/proto_parser.rb +315 -294
- data/lib/protobuf/compiler/template/rpc_bin.erb +1 -1
- data/lib/protobuf/compiler/template/rpc_client.erb +1 -1
- data/lib/protobuf/compiler/template/rpc_service.erb +2 -2
- data/lib/protobuf/compiler/visitors.rb +45 -39
- data/lib/protobuf/descriptor/descriptor.proto +0 -0
- data/lib/protobuf/descriptor/descriptor.rb +11 -10
- data/lib/protobuf/descriptor/descriptor_builder.rb +6 -7
- data/lib/protobuf/descriptor/descriptor_proto.rb +51 -31
- data/lib/protobuf/descriptor/enum_descriptor.rb +5 -5
- data/lib/protobuf/descriptor/field_descriptor.rb +8 -9
- data/lib/protobuf/descriptor/file_descriptor.rb +0 -1
- data/lib/protobuf/message/decoder.rb +33 -35
- data/lib/protobuf/message/encoder.rb +23 -19
- data/lib/protobuf/message/enum.rb +43 -9
- data/lib/protobuf/message/field.rb +281 -193
- data/lib/protobuf/message/message.rb +166 -110
- data/lib/protobuf/message/protoable.rb +4 -3
- data/lib/protobuf/message/service.rb +1 -1
- data/lib/protobuf/rpc/client.rb +3 -3
- data/lib/protobuf/rpc/handler.rb +1 -1
- data/lib/protobuf/rpc/server.rb +8 -8
- data/lib/ruby_protobuf.rb +1 -1
- data/test/check_unbuild.rb +7 -7
- data/test/proto/addressbook.pb.rb +67 -0
- data/test/proto/addressbook.proto +2 -0
- data/test/proto/addressbook_base.pb.rb +59 -0
- data/test/proto/addressbook_base.proto +1 -1
- data/test/proto/addressbook_ext.pb.rb +21 -0
- data/test/proto/addressbook_ext.proto +2 -2
- data/test/{collision.rb → proto/collision.pb.rb} +0 -0
- data/test/{ext_collision.rb → proto/ext_collision.pb.rb} +1 -1
- data/test/{ext_range.rb → proto/ext_range.pb.rb} +4 -4
- data/test/proto/ext_range.proto +2 -2
- data/test/proto/float_default.proto +10 -0
- data/test/proto/lowercase.pb.rb +31 -0
- data/test/proto/lowercase.proto +9 -0
- data/test/{merge.rb → proto/merge.pb.rb} +2 -2
- data/test/proto/nested.pb.rb +31 -0
- data/test/proto/nested.proto +2 -0
- data/test/proto/optional_field.pb.rb +36 -0
- data/test/proto/optional_field.proto +12 -0
- data/test/proto/packed.pb.rb +23 -0
- data/test/proto/packed.proto +6 -0
- data/test/{types.rb → proto/types.pb.rb} +43 -1
- data/test/test_addressbook.rb +30 -17
- data/test/test_compiler.rb +79 -78
- data/test/test_descriptor.rb +12 -12
- data/test/test_enum_value.rb +41 -0
- data/test/test_extension.rb +10 -14
- data/test/test_lowercase.rb +11 -0
- data/test/test_message.rb +44 -41
- data/test/test_optional_field.rb +61 -38
- data/test/test_packed_field.rb +40 -0
- data/test/test_parse.rb +8 -8
- data/test/test_repeated_types.rb +29 -3
- data/test/test_serialize.rb +12 -12
- data/test/test_standard_message.rb +30 -30
- data/test/test_types.rb +95 -95
- metadata +69 -39
- data/test/addressbook.rb +0 -98
- data/test/addressbook_base.rb +0 -62
- data/test/addressbook_ext.rb +0 -12
- data/test/nested.rb +0 -25
- data/test/test_ruby_protobuf.rb +0 -1
@@ -1,91 +1,178 @@
|
|
1
|
+
require 'protobuf/common/util'
|
1
2
|
require 'protobuf/common/wire_type'
|
2
3
|
require 'protobuf/descriptor/field_descriptor'
|
3
4
|
|
4
5
|
module Protobuf
|
5
6
|
module Field
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
|
8
|
+
PREDEFINED_TYPES = [
|
9
|
+
:double, :float,
|
10
|
+
:int32, :int64,
|
11
|
+
:uint32, :uint64,
|
12
|
+
:sint32, :sint64,
|
13
|
+
:fixed32, :fixed64,
|
14
|
+
:sfixed32, :sfixed64,
|
15
|
+
:string, :bytes,
|
16
|
+
:bool,
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
def self.build(message_class, rule, type, name, tag, options={})
|
20
|
+
field_class = \
|
21
|
+
if PREDEFINED_TYPES.include?(type)
|
22
|
+
const_get("#{type.to_s.capitalize}Field")
|
12
23
|
else
|
13
|
-
|
24
|
+
FieldProxy
|
14
25
|
end
|
15
|
-
field_class.new
|
26
|
+
field_class.new(message_class, rule, type, name, tag, options)
|
16
27
|
end
|
17
28
|
|
18
|
-
class InvalidRuleError < StandardError; end
|
19
|
-
|
20
29
|
class BaseField
|
21
|
-
class <<self
|
22
|
-
def descriptor
|
23
|
-
@descriptor ||= Protobuf::Descriptor::FieldDescriptor.new
|
24
|
-
end
|
25
30
|
|
26
|
-
|
31
|
+
def self.descriptor
|
32
|
+
@descriptor ||= Descriptor::FieldDescriptor.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.default
|
36
|
+
nil
|
27
37
|
end
|
28
38
|
|
29
|
-
|
39
|
+
attr_reader :message_class, :rule, :type, :name, :tag, :default
|
40
|
+
attr_reader :default_value
|
30
41
|
|
31
42
|
def descriptor
|
32
|
-
@descriptor ||=
|
43
|
+
@descriptor ||= Descriptor::FieldDescriptor.new(self)
|
33
44
|
end
|
34
45
|
|
35
|
-
def initialize(message_class, rule, type, name, tag,
|
36
|
-
@message_class, @rule, @type, @name, @tag
|
37
|
-
message_class, rule, type, name, tag
|
38
|
-
|
46
|
+
def initialize(message_class, rule, type, name, tag, options)
|
47
|
+
@message_class, @rule, @type, @name, @tag = \
|
48
|
+
message_class, rule, type, name, tag
|
49
|
+
|
50
|
+
@default = options.delete(:default)
|
51
|
+
@extension = options.delete(:extension)
|
52
|
+
@packed = repeated? && options.delete(:packed)
|
53
|
+
unless options.empty?
|
54
|
+
warn "WARNING: Invalid options: #{options.inspect} (in #{@message_class.name.split('::').last}.#{@name})"
|
55
|
+
end
|
56
|
+
if packed? && ! [WireType::VARINT, WireType::FIXED32, WireType::FIXED64].include?(wire_type)
|
57
|
+
raise "Can't use packed encoding for `#{@type}' type"
|
58
|
+
end
|
59
|
+
|
60
|
+
@default_value = \
|
61
|
+
case @rule
|
62
|
+
when :repeated
|
63
|
+
FieldArray.new(self).freeze
|
64
|
+
when :required
|
65
|
+
nil
|
66
|
+
when :optional
|
67
|
+
typed_default_value
|
68
|
+
end
|
69
|
+
|
39
70
|
define_accessor
|
40
71
|
end
|
41
72
|
|
42
|
-
def ready
|
73
|
+
def ready?
|
74
|
+
true
|
75
|
+
end
|
43
76
|
|
44
|
-
def initialized?(
|
45
|
-
|
77
|
+
def initialized?(message_instance)
|
78
|
+
value = message_instance.__send__(@name)
|
79
|
+
case @rule
|
46
80
|
when :required
|
47
|
-
|
48
|
-
return false if is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
|
81
|
+
! value.nil? && (! kind_of?(MessageField) || value.initialized?)
|
49
82
|
when :repeated
|
50
|
-
|
51
|
-
(not is_a?(Protobuf::Field::MessageField)) or msg.initialized?
|
52
|
-
}
|
83
|
+
value.all? {|msg| ! kind_of?(MessageField) || msg.initialized? }
|
53
84
|
when :optional
|
54
|
-
|
85
|
+
value.nil? || ! kind_of?(MessageField) || value.initialized?
|
55
86
|
end
|
56
|
-
true
|
57
87
|
end
|
58
88
|
|
59
|
-
|
60
|
-
|
61
|
-
|
89
|
+
# Decode +bytes+ and pass to +message_instance+.
|
90
|
+
def set(message_instance, bytes)
|
91
|
+
if packed?
|
92
|
+
array = message_instance.__send__(@name)
|
93
|
+
method = \
|
94
|
+
case wire_type
|
95
|
+
when WireType::FIXED32 then :read_fixed32
|
96
|
+
when WireType::FIXED64 then :read_fixed64
|
97
|
+
when WireType::VARINT then :read_varint
|
98
|
+
end
|
99
|
+
stream = StringIO.new(bytes)
|
100
|
+
until stream.eof?
|
101
|
+
array << decode(Decoder.__send__(method, stream))
|
102
|
+
end
|
62
103
|
else
|
63
|
-
|
104
|
+
value = decode(bytes)
|
105
|
+
if repeated?
|
106
|
+
message_instance.__send__(@name) << value
|
107
|
+
else
|
108
|
+
message_instance.__send__("#{@name}=", value)
|
109
|
+
end
|
64
110
|
end
|
65
111
|
end
|
66
112
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
113
|
+
# Decode +bytes+ and return a field value.
|
114
|
+
def decode(bytes)
|
115
|
+
raise NotImplementedError, "#{self.class.name}\#decode"
|
116
|
+
end
|
117
|
+
|
118
|
+
# Encode +value+ and return a byte string.
|
119
|
+
def encode(value)
|
120
|
+
raise NotImplementedError, "#{self.class.name}\#encode"
|
121
|
+
end
|
122
|
+
|
123
|
+
# Merge +value+ with +message_instance+.
|
124
|
+
def merge(message_instance, value)
|
125
|
+
if repeated?
|
126
|
+
merge_array(message_instance, value)
|
75
127
|
else
|
76
|
-
|
128
|
+
merge_value(message_instance, value)
|
77
129
|
end
|
78
130
|
end
|
79
131
|
|
80
|
-
|
81
|
-
|
132
|
+
# Is this a repeated field?
|
133
|
+
def repeated?
|
134
|
+
@rule == :repeated
|
135
|
+
end
|
136
|
+
|
137
|
+
# Is this a required field?
|
138
|
+
def required?
|
139
|
+
@rule == :required
|
140
|
+
end
|
141
|
+
|
142
|
+
# Is this a optional field?
|
143
|
+
def optional?
|
144
|
+
@rule == :optional
|
145
|
+
end
|
146
|
+
|
147
|
+
# Is this a packed repeated field?
|
148
|
+
def packed?
|
149
|
+
!!@packed
|
150
|
+
end
|
151
|
+
|
152
|
+
# Upper limit for this field.
|
153
|
+
def max
|
154
|
+
self.class.max
|
155
|
+
end
|
156
|
+
|
157
|
+
# Lower limit for this field.
|
158
|
+
def min
|
159
|
+
self.class.min
|
160
|
+
end
|
161
|
+
|
162
|
+
# Is a +value+ acceptable for this field?
|
163
|
+
def acceptable?(value)
|
164
|
+
true
|
165
|
+
end
|
166
|
+
|
167
|
+
def to_s
|
168
|
+
"#{@rule} #{@type} #{@name} = #{@tag} #{@default ? "[default=#{@default.inspect}]" : ''}"
|
82
169
|
end
|
83
170
|
|
84
171
|
private
|
85
172
|
|
86
173
|
def define_accessor
|
87
174
|
define_getter
|
88
|
-
if
|
175
|
+
if repeated?
|
89
176
|
define_array_setter
|
90
177
|
else
|
91
178
|
define_setter
|
@@ -111,7 +198,7 @@ module Protobuf
|
|
111
198
|
define_method("#{field.name}=") do |val|
|
112
199
|
if val.nil?
|
113
200
|
@values.delete(field.name)
|
114
|
-
elsif field.acceptable?
|
201
|
+
elsif field.acceptable?(val)
|
115
202
|
@values[field.name] = val
|
116
203
|
end
|
117
204
|
end
|
@@ -127,117 +214,77 @@ module Protobuf
|
|
127
214
|
end
|
128
215
|
end
|
129
216
|
|
130
|
-
|
131
|
-
|
132
|
-
# encoder/decoder related methods
|
133
|
-
|
134
|
-
def set(message_instance, bytes)
|
135
|
-
value = decode(bytes)
|
136
|
-
if repeated?
|
137
|
-
message_instance.send(name) << value
|
138
|
-
else
|
139
|
-
message_instance.send("#{name}=", value)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def get(value)
|
144
|
-
encode(value)
|
145
|
-
end
|
146
|
-
|
147
|
-
def decode(bytes)
|
148
|
-
raise NotImplementedError.new("#{self.class.name}\#decode")
|
217
|
+
def merge_array(message_instance, value)
|
218
|
+
message_instance.__send__(@name).concat(value)
|
149
219
|
end
|
150
|
-
private :decode
|
151
220
|
|
152
|
-
def
|
153
|
-
|
221
|
+
def merge_value(message_instance, value)
|
222
|
+
message_instance.__send__("#{@name}=", value)
|
154
223
|
end
|
155
|
-
private :encode
|
156
224
|
|
157
|
-
def
|
158
|
-
if
|
159
|
-
|
225
|
+
def typed_default_value
|
226
|
+
if @default.nil?
|
227
|
+
self.class.default
|
160
228
|
else
|
161
|
-
|
229
|
+
@default
|
162
230
|
end
|
163
231
|
end
|
164
232
|
|
165
|
-
|
166
|
-
message_instance[tag].concat value
|
167
|
-
end
|
233
|
+
end # BaseField
|
168
234
|
|
169
|
-
def merge_value(message_instance, value)
|
170
|
-
message_instance[tag] = value
|
171
|
-
end
|
172
|
-
|
173
|
-
# utility methods
|
174
|
-
|
175
|
-
def repeated?; rule == :repeated end
|
176
|
-
def required?; rule == :required end
|
177
|
-
def optional?; rule == :optional end
|
178
|
-
|
179
|
-
def max; self.class.max end
|
180
|
-
def min; self.class.min end
|
181
|
-
|
182
|
-
def acceptable?(val)
|
183
|
-
true
|
184
|
-
end
|
185
235
|
|
186
|
-
|
187
|
-
@error_message
|
188
|
-
end
|
236
|
+
class FieldProxy
|
189
237
|
|
190
|
-
def
|
191
|
-
|
238
|
+
def initialize(message_class, rule, type, name, tag, options)
|
239
|
+
@message_class, @rule, @type, @name, @tag, @options =
|
240
|
+
message_class, rule, type, name, tag, options
|
192
241
|
end
|
193
|
-
end
|
194
242
|
|
195
|
-
|
196
|
-
|
197
|
-
@message_class, @rule, @type, @name, @tag, @opts =
|
198
|
-
message_class, rule, type, name, tag, opts
|
243
|
+
def ready?
|
244
|
+
false
|
199
245
|
end
|
200
246
|
|
201
|
-
def ready?; false end
|
202
|
-
|
203
247
|
def setup
|
204
|
-
type = typename_to_class
|
205
|
-
field_class =
|
206
|
-
if type
|
207
|
-
|
208
|
-
elsif type
|
209
|
-
|
248
|
+
type = typename_to_class(@message_class, @type)
|
249
|
+
field_class = \
|
250
|
+
if type < Enum
|
251
|
+
EnumField
|
252
|
+
elsif type < Message
|
253
|
+
MessageField
|
210
254
|
else
|
211
|
-
raise TypeError
|
255
|
+
raise TypeError, type.inspect
|
212
256
|
end
|
213
|
-
field_class.new
|
257
|
+
field_class.new(@message_class, @rule, type, @name, @tag, @options)
|
214
258
|
end
|
215
259
|
|
260
|
+
private
|
261
|
+
|
216
262
|
def typename_to_class(message_class, type)
|
217
|
-
|
218
|
-
|
219
|
-
args = (Object.method(:const_defined?).arity == 1) ? [] : [
|
263
|
+
names = type.to_s.split('::').map {|s| Util.camelize(s) }
|
264
|
+
outer = message_class.to_s.split('::')
|
265
|
+
args = (Object.method(:const_defined?).arity == 1) ? [] : [false]
|
220
266
|
while
|
221
|
-
mod =
|
222
|
-
mod =
|
223
|
-
args
|
224
|
-
m and m.const_defined?(*args) and m.const_get(s)
|
267
|
+
mod = outer.empty? ? Object : eval(outer.join('::'))
|
268
|
+
mod = names.inject(mod) {|m, s|
|
269
|
+
m && m.const_defined?(s, *args) && m.const_get(s)
|
225
270
|
}
|
226
271
|
break if mod
|
227
|
-
raise NameError.new("type not found: #{type}", type) if
|
228
|
-
|
272
|
+
raise NameError.new("type not found: #{type}", type) if outer.empty?
|
273
|
+
outer.pop
|
229
274
|
end
|
230
275
|
mod
|
231
276
|
end
|
277
|
+
|
232
278
|
end
|
233
279
|
|
234
280
|
class FieldArray < Array
|
281
|
+
|
235
282
|
def initialize(field)
|
236
283
|
@field = field
|
237
284
|
end
|
238
285
|
|
239
286
|
def []=(nth, val)
|
240
|
-
super(normalize(val))
|
287
|
+
super(nth, normalize(val))
|
241
288
|
end
|
242
289
|
|
243
290
|
def <<(val)
|
@@ -272,39 +319,49 @@ module Protobuf
|
|
272
319
|
val
|
273
320
|
end
|
274
321
|
end
|
322
|
+
|
275
323
|
end
|
276
324
|
|
325
|
+
# Field class for +bytes+ type.
|
277
326
|
class BytesField < BaseField
|
278
|
-
|
279
|
-
|
327
|
+
def self.default
|
328
|
+
''
|
280
329
|
end
|
281
330
|
|
282
331
|
def wire_type
|
283
|
-
|
332
|
+
WireType::LENGTH_DELIMITED
|
284
333
|
end
|
285
334
|
|
286
335
|
def acceptable?(val)
|
287
|
-
raise TypeError unless val.instance_of?
|
336
|
+
raise TypeError unless val.instance_of?(String)
|
288
337
|
true
|
289
338
|
end
|
290
339
|
|
291
340
|
def decode(bytes)
|
292
|
-
bytes.
|
341
|
+
bytes.force_encoding(Encoding::ASCII_8BIT) if bytes.respond_to?(:force_encoding)
|
342
|
+
bytes
|
293
343
|
end
|
294
344
|
|
295
345
|
def encode(value)
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
346
|
+
if value.respond_to?(:force_encoding)
|
347
|
+
# Ruby 1.9
|
348
|
+
old_encoding = value.encoding
|
349
|
+
result = VarintField.encode(value.bytesize)
|
350
|
+
result << value.force_encoding(Encoding::ASCII_8BIT)
|
351
|
+
value.force_encoding(old_encoding)
|
352
|
+
result
|
353
|
+
else
|
354
|
+
# Ruby 1.8
|
355
|
+
result = VarintField.encode(value.size)
|
356
|
+
result << value
|
357
|
+
end
|
300
358
|
end
|
301
359
|
end
|
302
360
|
|
303
361
|
class StringField < BytesField
|
304
362
|
def decode(bytes)
|
305
|
-
|
306
|
-
|
307
|
-
message
|
363
|
+
bytes.force_encoding(Encoding::UTF_8) if bytes.respond_to?(:force_encoding)
|
364
|
+
bytes
|
308
365
|
end
|
309
366
|
end
|
310
367
|
|
@@ -317,7 +374,9 @@ module Protobuf
|
|
317
374
|
UINT64_MAX = 2**64 - 1
|
318
375
|
|
319
376
|
class <<self
|
320
|
-
def default
|
377
|
+
def default
|
378
|
+
0
|
379
|
+
end
|
321
380
|
|
322
381
|
def decode(bytes)
|
323
382
|
value = 0
|
@@ -328,7 +387,7 @@ module Protobuf
|
|
328
387
|
end
|
329
388
|
|
330
389
|
def encode(value)
|
331
|
-
raise RangeError
|
390
|
+
raise RangeError, "#{value} is negative" if value < 0
|
332
391
|
return [value].pack('C') if value < 128
|
333
392
|
bytes = []
|
334
393
|
until value == 0
|
@@ -341,11 +400,11 @@ module Protobuf
|
|
341
400
|
end
|
342
401
|
|
343
402
|
def wire_type
|
344
|
-
|
403
|
+
WireType::VARINT
|
345
404
|
end
|
346
405
|
|
347
|
-
def decode(
|
348
|
-
|
406
|
+
def decode(value)
|
407
|
+
value
|
349
408
|
end
|
350
409
|
|
351
410
|
def encode(value)
|
@@ -353,8 +412,8 @@ module Protobuf
|
|
353
412
|
end
|
354
413
|
|
355
414
|
def acceptable?(val)
|
356
|
-
raise TypeError
|
357
|
-
raise RangeError
|
415
|
+
raise TypeError, val.class.name unless val.is_a?(Integer)
|
416
|
+
raise RangeError if val < min || max < val
|
358
417
|
true
|
359
418
|
end
|
360
419
|
end
|
@@ -366,8 +425,7 @@ module Protobuf
|
|
366
425
|
VarintField.encode(value & 0xffff_ffff_ffff_ffff)
|
367
426
|
end
|
368
427
|
|
369
|
-
def decode(
|
370
|
-
value = VarintField.decode(bytes)
|
428
|
+
def decode(value)
|
371
429
|
value -= 0x1_0000_0000_0000_0000 if (value & 0x8000_0000_0000_0000).nonzero?
|
372
430
|
value
|
373
431
|
end
|
@@ -395,8 +453,7 @@ module Protobuf
|
|
395
453
|
|
396
454
|
# Base class for sint32 and sint64
|
397
455
|
class SignedIntegerField < VarintField
|
398
|
-
def decode(
|
399
|
-
value = VarintField.decode(bytes)
|
456
|
+
def decode(value)
|
400
457
|
if (value & 1).zero?
|
401
458
|
value >> 1 # positive value
|
402
459
|
else
|
@@ -429,7 +486,7 @@ module Protobuf
|
|
429
486
|
def self.min; -1.0/0; end
|
430
487
|
|
431
488
|
def wire_type
|
432
|
-
|
489
|
+
WireType::FIXED32
|
433
490
|
end
|
434
491
|
|
435
492
|
def decode(bytes)
|
@@ -441,15 +498,15 @@ module Protobuf
|
|
441
498
|
end
|
442
499
|
|
443
500
|
def acceptable?(val)
|
444
|
-
raise TypeError
|
445
|
-
raise RangeError
|
501
|
+
raise TypeError, val.class.name unless val.is_a?(Numeric)
|
502
|
+
raise RangeError if val < min || max < val
|
446
503
|
true
|
447
504
|
end
|
448
505
|
end
|
449
506
|
|
450
507
|
class DoubleField < FloatField
|
451
508
|
def wire_type
|
452
|
-
|
509
|
+
WireType::FIXED64
|
453
510
|
end
|
454
511
|
|
455
512
|
def decode(bytes)
|
@@ -463,7 +520,7 @@ module Protobuf
|
|
463
520
|
|
464
521
|
class Fixed32Field < Uint32Field
|
465
522
|
def wire_type
|
466
|
-
|
523
|
+
WireType::FIXED32
|
467
524
|
end
|
468
525
|
|
469
526
|
def decode(bytes)
|
@@ -477,7 +534,7 @@ module Protobuf
|
|
477
534
|
|
478
535
|
class Fixed64Field < Uint64Field
|
479
536
|
def wire_type
|
480
|
-
|
537
|
+
WireType::FIXED64
|
481
538
|
end
|
482
539
|
|
483
540
|
def decode(bytes)
|
@@ -494,7 +551,7 @@ module Protobuf
|
|
494
551
|
|
495
552
|
class Sfixed32Field < Int32Field
|
496
553
|
def wire_type
|
497
|
-
|
554
|
+
WireType::FIXED32
|
498
555
|
end
|
499
556
|
|
500
557
|
def decode(bytes)
|
@@ -510,7 +567,7 @@ module Protobuf
|
|
510
567
|
|
511
568
|
class Sfixed64Field < Int64Field
|
512
569
|
def wire_type
|
513
|
-
|
570
|
+
WireType::FIXED64
|
514
571
|
end
|
515
572
|
|
516
573
|
def decode(bytes)
|
@@ -528,17 +585,17 @@ module Protobuf
|
|
528
585
|
end
|
529
586
|
|
530
587
|
class BoolField < VarintField
|
531
|
-
|
532
|
-
|
588
|
+
def self.default
|
589
|
+
false
|
533
590
|
end
|
534
591
|
|
535
592
|
def acceptable?(val)
|
536
|
-
raise TypeError unless [
|
593
|
+
raise TypeError unless [true, false].include?(val)
|
537
594
|
true
|
538
595
|
end
|
539
596
|
|
540
|
-
def decode(
|
541
|
-
|
597
|
+
def decode(value)
|
598
|
+
value == 1
|
542
599
|
end
|
543
600
|
|
544
601
|
def encode(value)
|
@@ -546,11 +603,31 @@ module Protobuf
|
|
546
603
|
end
|
547
604
|
end
|
548
605
|
|
606
|
+
|
549
607
|
class MessageField < BaseField
|
550
|
-
|
551
|
-
|
608
|
+
def wire_type
|
609
|
+
WireType::LENGTH_DELIMITED
|
610
|
+
end
|
611
|
+
|
612
|
+
def acceptable?(val)
|
613
|
+
raise TypeError unless val.instance_of?(type) || val.instance_of?(Hash)
|
614
|
+
true
|
615
|
+
end
|
616
|
+
|
617
|
+
def decode(bytes)
|
618
|
+
message = type.new
|
619
|
+
message.parse_from_string(bytes)
|
620
|
+
message
|
621
|
+
end
|
622
|
+
|
623
|
+
def encode(value)
|
624
|
+
bytes = value.serialize_to_string
|
625
|
+
result = VarintField.encode(bytes.size)
|
626
|
+
result << bytes
|
552
627
|
end
|
553
628
|
|
629
|
+
private
|
630
|
+
|
554
631
|
def define_setter
|
555
632
|
field = self
|
556
633
|
@message_class.class_eval do
|
@@ -563,59 +640,70 @@ module Protobuf
|
|
563
640
|
when field.type
|
564
641
|
@values[field.name] = val
|
565
642
|
else
|
566
|
-
raise TypeError
|
643
|
+
raise TypeError, "Expected value of type '#{field.type}', but got '#{val.class}'"
|
567
644
|
end
|
568
645
|
end
|
569
646
|
end
|
570
647
|
end
|
571
648
|
|
572
|
-
def
|
573
|
-
|
649
|
+
def merge_value(message_instance, value)
|
650
|
+
message_instance.__send__(@name).merge_from(value)
|
574
651
|
end
|
652
|
+
end
|
575
653
|
|
576
|
-
def typed_default_value(default=nil)
|
577
|
-
if default.is_a? Symbol
|
578
|
-
type.module_eval default.to_s
|
579
|
-
else
|
580
|
-
default
|
581
|
-
end
|
582
|
-
end
|
583
654
|
|
655
|
+
class EnumField < VarintField
|
584
656
|
def acceptable?(val)
|
585
|
-
|
657
|
+
case val
|
658
|
+
when Symbol
|
659
|
+
raise TypeError unless @type.const_defined?(val)
|
660
|
+
when EnumValue
|
661
|
+
raise TypeError if val.parent_class != @type
|
662
|
+
else
|
663
|
+
raise TypeError unless @type.valid_tag?(val)
|
664
|
+
end
|
586
665
|
true
|
587
666
|
end
|
588
667
|
|
589
|
-
def decode(bytes)
|
590
|
-
message = type.new
|
591
|
-
message.parse_from_string bytes.pack('C*') # TODO
|
592
|
-
message
|
593
|
-
end
|
594
|
-
|
595
668
|
def encode(value)
|
596
|
-
|
597
|
-
string_size = VarintField.encode bytes.size
|
598
|
-
string_size << bytes
|
669
|
+
super(value.to_i)
|
599
670
|
end
|
600
671
|
|
601
|
-
|
602
|
-
message_instance[tag].merge_from value
|
603
|
-
end
|
604
|
-
end
|
672
|
+
private
|
605
673
|
|
606
|
-
|
607
|
-
def default
|
674
|
+
def typed_default_value
|
608
675
|
if @default.is_a?(Symbol)
|
609
|
-
type.const_get
|
676
|
+
@type.const_get(@default)
|
610
677
|
else
|
611
|
-
|
678
|
+
self.class.default
|
612
679
|
end
|
613
680
|
end
|
614
681
|
|
615
|
-
def
|
616
|
-
|
617
|
-
|
682
|
+
def define_setter
|
683
|
+
field = self
|
684
|
+
@message_class.class_eval do
|
685
|
+
define_method("#{field.name}=") do |val|
|
686
|
+
if val.nil?
|
687
|
+
@values.delete(field.name)
|
688
|
+
else
|
689
|
+
val = \
|
690
|
+
case val
|
691
|
+
when Symbol
|
692
|
+
field.type.const_get(val) rescue nil
|
693
|
+
when Integer
|
694
|
+
field.type.const_get(field.type.name_by_value(val)) rescue nil
|
695
|
+
when EnumValue
|
696
|
+
raise TypeError, "Invalid value: #{val.inspect}" if val.parent_class != field.type
|
697
|
+
val
|
698
|
+
end
|
699
|
+
raise TypeError, "Invalid value: #{val.inspect}" unless val
|
700
|
+
|
701
|
+
@values[field.name] = val
|
702
|
+
end
|
703
|
+
end
|
704
|
+
end
|
618
705
|
end
|
706
|
+
|
619
707
|
end
|
620
708
|
end
|
621
709
|
end
|