ruby_protobuf 0.3.3 → 0.4.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 +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
|