ruby_protobuf 0.3.2 → 0.3.3
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 +7 -2
- data/Manifest.txt +74 -0
- data/README.txt +1 -1
- data/Rakefile +5 -5
- data/bin/rprotoc +25 -10
- data/{test/proto → examples}/addressbook.pb.rb +1 -14
- 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/compiler/compiler.rb +9 -11
- data/lib/protobuf/compiler/nodes.rb +15 -7
- data/lib/protobuf/compiler/proto.y +56 -36
- data/lib/protobuf/compiler/proto_parser.rb +373 -236
- data/lib/protobuf/compiler/visitors.rb +5 -1
- data/lib/protobuf/descriptor/enum_descriptor.rb +1 -1
- data/lib/protobuf/message/decoder.rb +12 -19
- data/lib/protobuf/message/encoder.rb +5 -2
- data/lib/protobuf/message/enum.rb +1 -1
- data/lib/protobuf/message/field.rb +302 -298
- data/lib/protobuf/message/message.rb +63 -35
- data/lib/ruby_protobuf.rb +1 -1
- data/{bin → script}/mk_parser +0 -0
- data/test/merge.rb +1 -1
- data/test/proto/types.proto +20 -0
- data/test/test_addressbook.rb +1 -0
- data/test/test_compiler.rb +21 -7
- data/test/test_message.rb +19 -0
- data/test/test_optional_field.rb +80 -0
- data/test/test_repeated_types.rb +106 -0
- data/test/test_serialize.rb +34 -0
- data/test/test_standard_message.rb +10 -0
- data/test/test_types.rb +49 -4
- data/test/types.rb +23 -2
- metadata +22 -20
- data/lib/protobuf/compiler/compiler_old.rb +0 -123
- data/test/proto/addressbook.rb +0 -69
- data/test/proto/bool_default.pb.rb +0 -16
- data/test/proto/bool_default.proto +0 -3
- data/test/proto/float_default.proto +0 -2
@@ -48,7 +48,11 @@ module Protobuf
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def commented_proto_contents
|
51
|
-
|
51
|
+
if proto_file
|
52
|
+
proto_filepath = File.exist?(proto_file) ?
|
53
|
+
proto_file : "#{@proto_dir}/#{proto_file}"
|
54
|
+
File.read(proto_filepath).gsub(/^/, '# ')
|
55
|
+
end
|
52
56
|
end
|
53
57
|
|
54
58
|
def write(str)
|
@@ -22,7 +22,7 @@ module Protobuf
|
|
22
22
|
enum_proto.name = @enum_class.name.split('::').last
|
23
23
|
@enum_class.constants.each do |const|
|
24
24
|
enum_value_proto = Google::Protobuf::EnumValueDescriptorProto.new
|
25
|
-
enum_value_proto.name = const
|
25
|
+
enum_value_proto.name = const.to_s
|
26
26
|
enum_value_proto.number = @enum_class.const_get const
|
27
27
|
enum_proto.value << enum_value_proto
|
28
28
|
end
|
@@ -42,39 +42,36 @@ module Protobuf
|
|
42
42
|
protected
|
43
43
|
|
44
44
|
def read_key(stream)
|
45
|
-
# TODO is there more clear way to do this?
|
46
|
-
bits = 0
|
47
45
|
bytes = read_varint stream
|
48
|
-
|
49
|
-
|
50
|
-
bits |= byte << (7 * index)
|
51
|
-
end
|
52
|
-
wire_type = bits & 0b00000111
|
46
|
+
bits = Protobuf::Field::VarintField.decode bytes
|
47
|
+
wire_type = bits & 0x07
|
53
48
|
tag = bits >> 3
|
54
49
|
[tag, wire_type]
|
55
50
|
end
|
56
51
|
|
57
52
|
def read_varint(stream)
|
53
|
+
read_method = stream.respond_to?(:readbyte) ? :readbyte : :readchar
|
58
54
|
bytes = []
|
59
55
|
begin
|
60
|
-
byte = stream.
|
61
|
-
bytes << (byte &
|
62
|
-
end while byte
|
56
|
+
byte = stream.send(read_method)
|
57
|
+
bytes << (byte & 0x7f)
|
58
|
+
end while (byte & 0x80).nonzero?
|
63
59
|
bytes
|
64
60
|
end
|
65
61
|
|
62
|
+
def read_fixed32(stream)
|
63
|
+
stream.read(4)
|
64
|
+
end
|
65
|
+
|
66
66
|
def read_fixed64(stream)
|
67
67
|
stream.read(8)
|
68
68
|
end
|
69
69
|
|
70
70
|
def read_length_delimited(stream)
|
71
71
|
bytes = read_varint stream
|
72
|
-
value_length =
|
73
|
-
bytes.each_with_index do |byte, index|
|
74
|
-
value_length |= byte << (7 * index)
|
75
|
-
end
|
72
|
+
value_length = Protobuf::Field::VarintField.decode bytes
|
76
73
|
value = stream.read value_length
|
77
|
-
value.unpack('
|
74
|
+
value.unpack('C*')
|
78
75
|
end
|
79
76
|
|
80
77
|
def read_start_group(stream)
|
@@ -84,9 +81,5 @@ module Protobuf
|
|
84
81
|
def read_end_group(stream)
|
85
82
|
raise NotImplementedError.new('Group is duplecated.')
|
86
83
|
end
|
87
|
-
|
88
|
-
def read_fixed32(stream)
|
89
|
-
stream.read(4)
|
90
|
-
end
|
91
84
|
end
|
92
85
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'protobuf/common/wire_type'
|
2
2
|
|
3
3
|
module Protobuf
|
4
|
+
class NotInitializedError < StandardError; end
|
5
|
+
|
4
6
|
class Encoder
|
5
7
|
class <<self
|
6
8
|
def encode(stream, message)
|
@@ -13,8 +15,9 @@ module Protobuf
|
|
13
15
|
end
|
14
16
|
|
15
17
|
def encode(stream=@stream, message=@message)
|
18
|
+
raise NotInitializedError unless message.initialized?
|
16
19
|
message.each_field do |field, value|
|
17
|
-
next unless
|
20
|
+
next unless message.has_field?(field.name)
|
18
21
|
|
19
22
|
if field.repeated?
|
20
23
|
value.each do |val|
|
@@ -28,7 +31,7 @@ module Protobuf
|
|
28
31
|
|
29
32
|
def write_pair(field, value, stream)
|
30
33
|
key = (field.tag << 3) | field.wire_type
|
31
|
-
key_bytes = Protobuf::Field::VarintField.
|
34
|
+
key_bytes = Protobuf::Field::VarintField.encode key
|
32
35
|
stream.write key_bytes
|
33
36
|
bytes = field.get value
|
34
37
|
stream.write bytes
|
@@ -4,9 +4,9 @@ require 'protobuf/descriptor/field_descriptor'
|
|
4
4
|
module Protobuf
|
5
5
|
module Field
|
6
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,
|
7
|
+
field_class =
|
8
|
+
if [:double, :float, :int32, :int64, :uint32, :uint64,
|
9
|
+
:sint32, :sint64, :fixed32, :fixed64, :sfixed32, :sfixed64,
|
10
10
|
:bool, :string, :bytes].include? type
|
11
11
|
eval "Protobuf::Field::#{type.to_s.capitalize}Field"
|
12
12
|
else
|
@@ -22,6 +22,8 @@ module Protobuf
|
|
22
22
|
def descriptor
|
23
23
|
@descriptor ||= Protobuf::Descriptor::FieldDescriptor.new
|
24
24
|
end
|
25
|
+
|
26
|
+
def default; nil end
|
25
27
|
end
|
26
28
|
|
27
29
|
attr_accessor :message_class, :rule, :type, :name, :tag, :default
|
@@ -31,9 +33,10 @@ module Protobuf
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def initialize(message_class, rule, type, name, tag, opts={})
|
34
|
-
@message_class, @rule, @type, @name, @tag, @default, @extension =
|
36
|
+
@message_class, @rule, @type, @name, @tag, @default, @extension =
|
35
37
|
message_class, rule, type, name, tag, opts[:default], opts[:extension]
|
36
38
|
@error_message = 'Type invalid'
|
39
|
+
define_accessor
|
37
40
|
end
|
38
41
|
|
39
42
|
def ready?; true end
|
@@ -44,9 +47,11 @@ module Protobuf
|
|
44
47
|
return false if message[name].nil?
|
45
48
|
return false if is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
|
46
49
|
when :repeated
|
47
|
-
return message[name].
|
48
|
-
|
49
|
-
|
50
|
+
return message[name].all? {|msg|
|
51
|
+
(not is_a?(Protobuf::Field::MessageField)) or msg.initialized?
|
52
|
+
}
|
53
|
+
when :optional
|
54
|
+
return false if message[name] and is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
|
50
55
|
end
|
51
56
|
true
|
52
57
|
end
|
@@ -55,7 +60,7 @@ module Protobuf
|
|
55
60
|
if repeated?
|
56
61
|
message[name].clear
|
57
62
|
else
|
58
|
-
message
|
63
|
+
message.instance_variable_get(:@values).delete(name)
|
59
64
|
end
|
60
65
|
end
|
61
66
|
|
@@ -73,60 +78,81 @@ module Protobuf
|
|
73
78
|
end
|
74
79
|
|
75
80
|
def typed_default_value(default=nil)
|
76
|
-
default
|
81
|
+
default or self.class.default
|
77
82
|
end
|
78
83
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
84
|
+
private
|
85
|
+
|
86
|
+
def define_accessor
|
87
|
+
define_getter
|
88
|
+
if rule == :repeated
|
89
|
+
define_array_setter
|
90
|
+
else
|
91
|
+
define_setter
|
92
|
+
end
|
83
93
|
end
|
84
94
|
|
85
|
-
def define_getter
|
86
|
-
|
87
|
-
|
88
|
-
|
95
|
+
def define_getter
|
96
|
+
field = self
|
97
|
+
@message_class.class_eval do
|
98
|
+
define_method(field.name) do
|
99
|
+
if @values.has_key?(field.name)
|
100
|
+
@values[field.name]
|
101
|
+
else
|
102
|
+
field.default_value
|
103
|
+
end
|
89
104
|
end
|
90
|
-
|
105
|
+
end
|
91
106
|
end
|
92
107
|
|
93
|
-
def define_setter
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
field = get_#{extension ? 'ext_' : ''}field_by_name #{name.inspect}
|
108
|
+
def define_setter
|
109
|
+
field = self
|
110
|
+
@message_class.class_eval do
|
111
|
+
define_method("#{field.name}=") do |val|
|
98
112
|
if val.nil?
|
99
|
-
|
113
|
+
@values.delete(field.name)
|
100
114
|
elsif field.acceptable? val
|
101
|
-
|
115
|
+
@values[field.name] = val
|
102
116
|
end
|
103
117
|
end
|
104
|
-
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def define_array_setter
|
122
|
+
field = self
|
123
|
+
@message_class.class_eval do
|
124
|
+
define_method("#{field.name}=") do |val|
|
125
|
+
@values[field.name].replace(val)
|
126
|
+
end
|
127
|
+
end
|
105
128
|
end
|
106
129
|
|
130
|
+
public
|
131
|
+
|
132
|
+
# encoder/decoder related methods
|
133
|
+
|
107
134
|
def set(message_instance, bytes)
|
135
|
+
value = decode(bytes)
|
108
136
|
if repeated?
|
109
|
-
|
137
|
+
message_instance.send(name) << value
|
110
138
|
else
|
111
|
-
|
139
|
+
message_instance.send("#{name}=", value)
|
112
140
|
end
|
113
141
|
end
|
114
142
|
|
115
|
-
def
|
116
|
-
|
143
|
+
def get(value)
|
144
|
+
encode(value)
|
117
145
|
end
|
118
146
|
|
119
|
-
def
|
120
|
-
raise NotImplementedError
|
147
|
+
def decode(bytes)
|
148
|
+
raise NotImplementedError.new("#{self.class.name}\#decode")
|
121
149
|
end
|
150
|
+
private :decode
|
122
151
|
|
123
|
-
def
|
124
|
-
|
125
|
-
end
|
126
|
-
|
127
|
-
def get_bytes(value)
|
128
|
-
raise NotImplementedError
|
152
|
+
def encode(value)
|
153
|
+
raise NotImplementedError.new("#{self.class.name}\#encode")
|
129
154
|
end
|
155
|
+
private :encode
|
130
156
|
|
131
157
|
def merge(message_instance, value)
|
132
158
|
if repeated?
|
@@ -137,13 +163,15 @@ module Protobuf
|
|
137
163
|
end
|
138
164
|
|
139
165
|
def merge_array(message_instance, value)
|
140
|
-
message_instance[tag].concat value
|
166
|
+
message_instance[tag].concat value
|
141
167
|
end
|
142
168
|
|
143
169
|
def merge_value(message_instance, value)
|
144
170
|
message_instance[tag] = value
|
145
171
|
end
|
146
172
|
|
173
|
+
# utility methods
|
174
|
+
|
147
175
|
def repeated?; rule == :repeated end
|
148
176
|
def required?; rule == :required end
|
149
177
|
def optional?; rule == :optional end
|
@@ -180,22 +208,26 @@ module Protobuf
|
|
180
208
|
elsif type.superclass == Protobuf::Message
|
181
209
|
Protobuf::Field::MessageField
|
182
210
|
else
|
183
|
-
raise
|
211
|
+
raise TypeError.new(type.inspect)
|
184
212
|
end
|
185
213
|
field_class.new @message_class, @rule, type, @name, @tag, @opts
|
186
214
|
end
|
187
215
|
|
188
216
|
def typename_to_class(message_class, type)
|
217
|
+
suffix = type.to_s.split('::')
|
189
218
|
modules = message_class.to_s.split('::')
|
219
|
+
args = (Object.method(:const_defined?).arity == 1) ? [] : [nil, false]
|
190
220
|
while
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
221
|
+
mod = modules.empty? ? Object : eval(modules.join('::'))
|
222
|
+
mod = suffix.inject(mod) {|m, s|
|
223
|
+
args[0] = s
|
224
|
+
m and m.const_defined?(*args) and m.const_get(s)
|
225
|
+
}
|
226
|
+
break if mod
|
227
|
+
raise NameError.new("type not found: #{type}", type) if modules.empty?
|
228
|
+
modules.pop
|
197
229
|
end
|
198
|
-
|
230
|
+
mod
|
199
231
|
end
|
200
232
|
end
|
201
233
|
|
@@ -205,136 +237,119 @@ module Protobuf
|
|
205
237
|
end
|
206
238
|
|
207
239
|
def []=(nth, val)
|
208
|
-
|
209
|
-
super
|
210
|
-
end
|
240
|
+
super(normalize(val))
|
211
241
|
end
|
212
242
|
|
213
243
|
def <<(val)
|
214
|
-
|
215
|
-
super
|
216
|
-
end
|
244
|
+
super(normalize(val))
|
217
245
|
end
|
218
246
|
|
219
247
|
def push(val)
|
220
|
-
|
221
|
-
super
|
222
|
-
end
|
248
|
+
super(normalize(val))
|
223
249
|
end
|
224
250
|
|
225
251
|
def unshift(val)
|
226
|
-
|
227
|
-
super
|
228
|
-
end
|
252
|
+
super(normalize(val))
|
229
253
|
end
|
230
254
|
|
231
|
-
def
|
232
|
-
|
255
|
+
def replace(val)
|
256
|
+
raise TypeError unless val.is_a?(Array)
|
257
|
+
val = val.map {|v| normalize(v)}
|
258
|
+
super(val)
|
233
259
|
end
|
234
|
-
end
|
235
260
|
|
236
|
-
|
237
|
-
|
238
|
-
Protobuf::WireType::LENGTH_DELIMITED
|
261
|
+
def to_s
|
262
|
+
"[#{@field.name}]"
|
239
263
|
end
|
240
264
|
|
241
|
-
|
242
|
-
default or ''
|
243
|
-
end
|
265
|
+
private
|
244
266
|
|
245
|
-
def
|
246
|
-
raise TypeError unless
|
247
|
-
|
267
|
+
def normalize(val)
|
268
|
+
raise TypeError unless @field.acceptable?(val)
|
269
|
+
if @field.is_a?(MessageField) && val.is_a?(Hash)
|
270
|
+
@field.type.new(val)
|
271
|
+
else
|
272
|
+
val
|
273
|
+
end
|
248
274
|
end
|
275
|
+
end
|
249
276
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
def set_array(message_instance, bytes)
|
255
|
-
message = bytes.pack('U*')
|
256
|
-
arr = message_instance.send name
|
257
|
-
arr << message
|
277
|
+
class BytesField < BaseField
|
278
|
+
class <<self
|
279
|
+
def default; '' end
|
258
280
|
end
|
259
281
|
|
260
|
-
def get_bytes(value)
|
261
|
-
bytes = value.unpack('U*')
|
262
|
-
string_size = VarintField.get_bytes bytes.size
|
263
|
-
#(string_size + bytes).pack('C*')
|
264
|
-
string_size + bytes.pack('C*')
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
class BytesField < BaseField
|
269
282
|
def wire_type
|
270
283
|
Protobuf::WireType::LENGTH_DELIMITED
|
271
284
|
end
|
272
285
|
|
273
|
-
def typed_default_value(default=nil)
|
274
|
-
default or ''
|
275
|
-
end
|
276
|
-
|
277
286
|
def acceptable?(val)
|
278
287
|
raise TypeError unless val.instance_of? String
|
279
288
|
true
|
280
289
|
end
|
281
290
|
|
282
|
-
def
|
283
|
-
|
291
|
+
def decode(bytes)
|
292
|
+
bytes.pack('C*')
|
284
293
|
end
|
285
|
-
|
286
|
-
def
|
287
|
-
|
288
|
-
|
289
|
-
|
294
|
+
|
295
|
+
def encode(value)
|
296
|
+
value = value.dup
|
297
|
+
value.force_encoding('ASCII-8BIT') if value.respond_to?(:force_encoding)
|
298
|
+
string_size = VarintField.encode(value.size)
|
299
|
+
string_size << value
|
290
300
|
end
|
301
|
+
end
|
291
302
|
|
292
|
-
|
293
|
-
|
294
|
-
|
303
|
+
class StringField < BytesField
|
304
|
+
def decode(bytes)
|
305
|
+
message = bytes.pack('C*')
|
306
|
+
message.force_encoding('UTF-8') if message.respond_to?(:force_encoding)
|
307
|
+
message
|
295
308
|
end
|
296
309
|
end
|
297
310
|
|
298
311
|
class VarintField < BaseField
|
299
|
-
|
300
|
-
|
301
|
-
|
312
|
+
INT32_MAX = 2**31 - 1
|
313
|
+
INT32_MIN = -2**31
|
314
|
+
INT64_MAX = 2**63 - 1
|
315
|
+
INT64_MIN = -2**63
|
316
|
+
UINT32_MAX = 2**32 - 1
|
317
|
+
UINT64_MAX = 2**64 - 1
|
302
318
|
|
303
|
-
|
304
|
-
default
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
value
|
319
|
+
class <<self
|
320
|
+
def default; 0 end
|
321
|
+
|
322
|
+
def decode(bytes)
|
323
|
+
value = 0
|
324
|
+
bytes.each_with_index do |byte, index|
|
325
|
+
value |= byte << (7 * index)
|
326
|
+
end
|
327
|
+
value
|
312
328
|
end
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
until value == 0
|
322
|
-
byte = 0
|
323
|
-
7.times do |i|
|
324
|
-
byte |= (value & 1) << i
|
325
|
-
value >>= 1
|
329
|
+
|
330
|
+
def encode(value)
|
331
|
+
raise RangeError.new(value) if value < 0
|
332
|
+
return [value].pack('C') if value < 128
|
333
|
+
bytes = []
|
334
|
+
until value == 0
|
335
|
+
bytes << (0x80 | (value & 0x7f))
|
336
|
+
value >>= 7
|
326
337
|
end
|
327
|
-
|
328
|
-
bytes
|
338
|
+
bytes[-1] &= 0x7f
|
339
|
+
bytes.pack('C*')
|
329
340
|
end
|
330
|
-
#bytes[0] &= 0b01111111
|
331
|
-
#bytes
|
332
|
-
bytes[bytes.size - 1] &= 0b01111111
|
333
|
-
bytes.pack('C*')
|
334
341
|
end
|
335
342
|
|
336
|
-
def
|
337
|
-
|
343
|
+
def wire_type
|
344
|
+
Protobuf::WireType::VARINT
|
345
|
+
end
|
346
|
+
|
347
|
+
def decode(bytes)
|
348
|
+
self.class.decode(bytes)
|
349
|
+
end
|
350
|
+
|
351
|
+
def encode(value)
|
352
|
+
self.class.encode(value)
|
338
353
|
end
|
339
354
|
|
340
355
|
def acceptable?(val)
|
@@ -343,92 +358,86 @@ module Protobuf
|
|
343
358
|
true
|
344
359
|
end
|
345
360
|
end
|
346
|
-
|
347
|
-
class
|
348
|
-
|
349
|
-
def
|
361
|
+
|
362
|
+
# Base class for int32 and int64
|
363
|
+
class IntegerField < VarintField
|
364
|
+
def encode(value)
|
365
|
+
# original Google's library uses 64bits integer for negative value
|
366
|
+
VarintField.encode(value & 0xffff_ffff_ffff_ffff)
|
367
|
+
end
|
368
|
+
|
369
|
+
def decode(bytes)
|
370
|
+
value = VarintField.decode(bytes)
|
371
|
+
value -= 0x1_0000_0000_0000_0000 if (value & 0x8000_0000_0000_0000).nonzero?
|
372
|
+
value
|
373
|
+
end
|
350
374
|
end
|
351
|
-
|
352
|
-
class
|
353
|
-
def self.max;
|
354
|
-
def self.min;
|
375
|
+
|
376
|
+
class Int32Field < IntegerField
|
377
|
+
def self.max; INT32_MAX; end
|
378
|
+
def self.min; INT32_MIN; end
|
355
379
|
end
|
356
|
-
|
380
|
+
|
381
|
+
class Int64Field < IntegerField
|
382
|
+
def self.max; INT64_MAX; end
|
383
|
+
def self.min; INT64_MIN; end
|
384
|
+
end
|
385
|
+
|
357
386
|
class Uint32Field < VarintField
|
358
|
-
def self.max;
|
359
|
-
def self.min; 0 end
|
387
|
+
def self.max; UINT32_MAX; end
|
388
|
+
def self.min; 0; end
|
360
389
|
end
|
361
|
-
|
390
|
+
|
362
391
|
class Uint64Field < VarintField
|
363
|
-
def self.max;
|
364
|
-
def self.min; 0 end
|
392
|
+
def self.max; UINT64_MAX; end
|
393
|
+
def self.min; 0; end
|
365
394
|
end
|
366
|
-
|
367
|
-
class
|
368
|
-
|
369
|
-
def
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
byte / 2
|
377
|
-
else
|
378
|
-
-(byte + 1) / 2
|
379
|
-
end
|
380
|
-
message_instance.send("#{name}=", value)
|
395
|
+
|
396
|
+
# Base class for sint32 and sint64
|
397
|
+
class SignedIntegerField < VarintField
|
398
|
+
def decode(bytes)
|
399
|
+
value = VarintField.decode(bytes)
|
400
|
+
if (value & 1).zero?
|
401
|
+
value >> 1 # positive value
|
402
|
+
else
|
403
|
+
~value >> 1 # negative value
|
404
|
+
end
|
381
405
|
end
|
382
406
|
|
383
|
-
def
|
384
|
-
|
385
|
-
|
407
|
+
def encode(value)
|
408
|
+
if value >= 0
|
409
|
+
VarintField.encode(value << 1)
|
410
|
+
else
|
411
|
+
VarintField.encode(~(value << 1))
|
412
|
+
end
|
386
413
|
end
|
387
414
|
end
|
388
|
-
|
389
|
-
class Sint64Field < VarintField
|
390
|
-
def self.max; 1.0/0.0 end
|
391
|
-
def self.min; -1.0/0.0 end
|
392
|
-
|
393
|
-
def set_bytes(message_instance, bytes)
|
394
|
-
# TODO use only bit-operations
|
395
|
-
byte = bytes.first
|
396
|
-
value =
|
397
|
-
if byte % 2 == 0
|
398
|
-
byte / 2
|
399
|
-
else
|
400
|
-
-(byte + 1) / 2
|
401
|
-
end
|
402
|
-
message_instance.send("#{name}=", value)
|
403
|
-
end
|
404
415
|
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
end
|
416
|
+
class Sint32Field < SignedIntegerField
|
417
|
+
def self.max; INT32_MAX; end
|
418
|
+
def self.min; INT32_MIN; end
|
409
419
|
end
|
410
|
-
|
411
|
-
class
|
420
|
+
|
421
|
+
class Sint64Field < SignedIntegerField
|
422
|
+
def self.max; INT64_MAX; end
|
423
|
+
def self.min; INT64_MIN; end
|
424
|
+
end
|
425
|
+
|
426
|
+
class FloatField < BaseField
|
427
|
+
def self.default; 0.0; end
|
428
|
+
def self.max; 1.0/0; end
|
429
|
+
def self.min; -1.0/0; end
|
430
|
+
|
412
431
|
def wire_type
|
413
|
-
Protobuf::WireType::
|
414
|
-
end
|
415
|
-
|
416
|
-
#TODO
|
417
|
-
def self.max
|
418
|
-
'0x7fefffffffffffff'.unpack('d').first
|
432
|
+
Protobuf::WireType::FIXED32
|
419
433
|
end
|
420
434
|
|
421
|
-
|
422
|
-
|
423
|
-
-(2**(64/2) - 1)
|
424
|
-
end
|
425
|
-
|
426
|
-
def set_bytes(message_instance, bytes)
|
427
|
-
message_instance.send("#{name}=", bytes.unpack('E').first)
|
435
|
+
def decode(bytes)
|
436
|
+
bytes.unpack('e').first
|
428
437
|
end
|
429
438
|
|
430
|
-
def
|
431
|
-
[value].pack('
|
439
|
+
def encode(value)
|
440
|
+
[value].pack('e')
|
432
441
|
end
|
433
442
|
|
434
443
|
def acceptable?(val)
|
@@ -437,129 +446,129 @@ module Protobuf
|
|
437
446
|
true
|
438
447
|
end
|
439
448
|
end
|
440
|
-
|
441
|
-
class
|
449
|
+
|
450
|
+
class DoubleField < FloatField
|
442
451
|
def wire_type
|
443
|
-
Protobuf::WireType::
|
444
|
-
end
|
445
|
-
|
446
|
-
#TODO
|
447
|
-
def self.max
|
448
|
-
'0x7fefffffffffffff'.unpack('e').first
|
452
|
+
Protobuf::WireType::FIXED64
|
449
453
|
end
|
450
454
|
|
451
|
-
|
452
|
-
|
453
|
-
-(2**(32/2) - 1)
|
454
|
-
end
|
455
|
-
|
456
|
-
def set_bytes(message_instance, bytes)
|
457
|
-
message_instance.send("#{name}=", bytes.unpack('e').first)
|
455
|
+
def decode(bytes)
|
456
|
+
bytes.unpack('E').first
|
458
457
|
end
|
459
458
|
|
460
|
-
def
|
461
|
-
[value].pack('
|
462
|
-
end
|
463
|
-
|
464
|
-
def acceptable?(val)
|
465
|
-
raise TypeError unless val.is_a? Numeric
|
466
|
-
raise RangeError if val < min or max < val
|
467
|
-
true
|
459
|
+
def encode(value)
|
460
|
+
[value].pack('E')
|
468
461
|
end
|
469
|
-
|
470
|
-
|
471
|
-
class Fixed32Field <
|
462
|
+
end
|
463
|
+
|
464
|
+
class Fixed32Field < Uint32Field
|
472
465
|
def wire_type
|
473
466
|
Protobuf::WireType::FIXED32
|
474
467
|
end
|
475
468
|
|
476
|
-
def
|
477
|
-
|
469
|
+
def decode(bytes)
|
470
|
+
bytes.unpack('V').first
|
478
471
|
end
|
479
472
|
|
480
|
-
def
|
481
|
-
|
482
|
-
end
|
483
|
-
|
484
|
-
def set_bytes(message_instance, bytes)
|
485
|
-
message_instance.send("#{name}=", bytes.unpack('L').first)
|
486
|
-
end
|
487
|
-
|
488
|
-
def get_bytes(value)
|
489
|
-
[value].pack('L')
|
473
|
+
def encode(value)
|
474
|
+
[value].pack('V')
|
490
475
|
end
|
491
476
|
end
|
492
|
-
|
493
|
-
class Fixed64Field <
|
477
|
+
|
478
|
+
class Fixed64Field < Uint64Field
|
494
479
|
def wire_type
|
495
480
|
Protobuf::WireType::FIXED64
|
496
481
|
end
|
497
482
|
|
498
|
-
def
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
def self.min
|
503
|
-
0
|
504
|
-
end
|
505
|
-
|
506
|
-
def set_bytes(message_instance, bytes)
|
507
|
-
message_instance.send("#{name}=", bytes.unpack('l').first)
|
483
|
+
def decode(bytes)
|
484
|
+
# we don't use 'Q' for pack/unpack. 'Q' is machine-dependent.
|
485
|
+
values = bytes.unpack('VV')
|
486
|
+
values[0] + (values[1] << 32)
|
508
487
|
end
|
509
488
|
|
510
|
-
def
|
511
|
-
|
489
|
+
def encode(value)
|
490
|
+
# we don't use 'Q' for pack/unpack. 'Q' is machine-dependent.
|
491
|
+
[value & 0xffff_ffff, value >> 32].pack('VV')
|
512
492
|
end
|
513
493
|
end
|
514
|
-
|
515
|
-
class
|
494
|
+
|
495
|
+
class Sfixed32Field < Int32Field
|
516
496
|
def wire_type
|
517
497
|
Protobuf::WireType::FIXED32
|
518
498
|
end
|
519
499
|
|
520
|
-
def
|
521
|
-
|
500
|
+
def decode(bytes)
|
501
|
+
value = bytes.unpack('V').first
|
502
|
+
value -= 0x1_0000_0000 if (value & 0x8000_0000).nonzero?
|
503
|
+
value
|
522
504
|
end
|
523
505
|
|
524
|
-
def
|
525
|
-
|
506
|
+
def encode(value)
|
507
|
+
[value].pack('V')
|
526
508
|
end
|
527
509
|
end
|
528
|
-
|
529
|
-
class Sfixed64Field <
|
510
|
+
|
511
|
+
class Sfixed64Field < Int64Field
|
530
512
|
def wire_type
|
531
513
|
Protobuf::WireType::FIXED64
|
532
514
|
end
|
533
515
|
|
534
|
-
def
|
535
|
-
|
516
|
+
def decode(bytes)
|
517
|
+
# we don't use 'Q' for pack/unpack. 'Q' is machine-dependent.
|
518
|
+
values = bytes.unpack('VV')
|
519
|
+
value = values[0] + (values[1] << 32)
|
520
|
+
value -= 0x1_0000_0000_0000_0000 if (value & 0x8000_0000_0000_0000).nonzero?
|
521
|
+
value
|
536
522
|
end
|
537
523
|
|
538
|
-
def
|
539
|
-
|
524
|
+
def encode(value)
|
525
|
+
# we don't use 'Q' for pack/unpack. 'Q' is machine-dependent.
|
526
|
+
[value & 0xffff_ffff, value >> 32].pack('VV')
|
540
527
|
end
|
541
528
|
end
|
542
|
-
|
529
|
+
|
543
530
|
class BoolField < VarintField
|
544
|
-
|
545
|
-
default
|
531
|
+
class <<self
|
532
|
+
def default; false end
|
546
533
|
end
|
547
534
|
|
548
535
|
def acceptable?(val)
|
549
536
|
raise TypeError unless [TrueClass, FalseClass].include? val.class
|
550
537
|
true
|
551
538
|
end
|
552
|
-
|
553
|
-
def
|
554
|
-
|
539
|
+
|
540
|
+
def decode(bytes)
|
541
|
+
bytes.first == 1
|
555
542
|
end
|
556
543
|
|
557
|
-
def
|
544
|
+
def encode(value)
|
558
545
|
[value ? 1 : 0].pack('C')
|
559
546
|
end
|
560
547
|
end
|
561
|
-
|
548
|
+
|
562
549
|
class MessageField < BaseField
|
550
|
+
class <<self
|
551
|
+
def default; nil end
|
552
|
+
end
|
553
|
+
|
554
|
+
def define_setter
|
555
|
+
field = self
|
556
|
+
@message_class.class_eval do
|
557
|
+
define_method("#{field.name}=") do |val|
|
558
|
+
case val
|
559
|
+
when nil
|
560
|
+
@values.delete(field.name)
|
561
|
+
when Hash
|
562
|
+
@values[field.name] = field.type.new(val)
|
563
|
+
when field.type
|
564
|
+
@values[field.name] = val
|
565
|
+
else
|
566
|
+
raise TypeError
|
567
|
+
end
|
568
|
+
end
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
563
572
|
def wire_type
|
564
573
|
Protobuf::WireType::LENGTH_DELIMITED
|
565
574
|
end
|
@@ -573,33 +582,20 @@ module Protobuf
|
|
573
582
|
end
|
574
583
|
|
575
584
|
def acceptable?(val)
|
576
|
-
raise TypeError unless val.instance_of?
|
585
|
+
raise TypeError unless val.instance_of?(type) or val.instance_of?(Hash)
|
577
586
|
true
|
578
587
|
end
|
579
|
-
|
580
|
-
def
|
581
|
-
message = type.new
|
582
|
-
#message.parse_from bytes
|
583
|
-
message.parse_from_string bytes.pack('U*') # TODO
|
584
|
-
message_instance.send("#{name}=", message)
|
585
|
-
end
|
586
|
-
|
587
|
-
def set_array(message_instance, bytes)
|
588
|
+
|
589
|
+
def decode(bytes)
|
588
590
|
message = type.new
|
589
|
-
|
590
|
-
message
|
591
|
-
arr = message_instance.send name
|
592
|
-
arr << message
|
591
|
+
message.parse_from_string bytes.pack('C*') # TODO
|
592
|
+
message
|
593
593
|
end
|
594
594
|
|
595
|
-
def
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
string_size = VarintField.get_bytes bytes.size
|
600
|
-
#(string_size + bytes).pack('C*')
|
601
|
-
#bytes + string_size
|
602
|
-
string_size + bytes.pack('C*')
|
595
|
+
def encode(value)
|
596
|
+
bytes = value.serialize_to_string
|
597
|
+
string_size = VarintField.encode bytes.size
|
598
|
+
string_size << bytes
|
603
599
|
end
|
604
600
|
|
605
601
|
def merge_value(message_instance, value)
|
@@ -608,6 +604,14 @@ module Protobuf
|
|
608
604
|
end
|
609
605
|
|
610
606
|
class EnumField < VarintField
|
607
|
+
def default
|
608
|
+
if @default.is_a?(Symbol)
|
609
|
+
type.const_get @default
|
610
|
+
else
|
611
|
+
@default
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
611
615
|
def acceptable?(val)
|
612
616
|
raise TypeError unless type.valid_tag? val
|
613
617
|
true
|