macks-ruby_protobuf 0.3.2.1 → 0.3.2.2
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/Manifest.txt +1 -1
- data/README.txt +3 -2
- data/Rakefile +1 -1
- data/lib/protobuf/compiler/visitors.rb +1 -1
- data/lib/protobuf/message/decoder.rb +10 -18
- data/lib/protobuf/message/encoder.rb +4 -1
- data/lib/protobuf/message/field.rb +196 -271
- data/lib/protobuf/message/message.rb +9 -13
- data/lib/ruby_protobuf.rb +1 -1
- data/{bin → script}/mk_parser +0 -0
- data/test/proto/types.proto +20 -0
- data/test/test_compiler.rb +1 -1
- data/test/test_message.rb +3 -0
- data/test/test_types.rb +49 -4
- data/test/types.rb +23 -2
- metadata +5 -6
data/Manifest.txt
CHANGED
@@ -2,7 +2,6 @@ History.txt
|
|
2
2
|
Manifest.txt
|
3
3
|
README.txt
|
4
4
|
Rakefile
|
5
|
-
bin/mk_parser
|
6
5
|
bin/rprotoc
|
7
6
|
examples/addressbook.proto
|
8
7
|
examples/addressbook.pb.rb
|
@@ -37,6 +36,7 @@ lib/protobuf/rpc/client.rb
|
|
37
36
|
lib/protobuf/rpc/handler.rb
|
38
37
|
lib/protobuf/rpc/server.rb
|
39
38
|
lib/ruby_protobuf.rb
|
39
|
+
script/mk_parser
|
40
40
|
test/addressbook.rb
|
41
41
|
test/addressbook_base.rb
|
42
42
|
test/addressbook_ext.rb
|
data/README.txt
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
= RubyProtobuf
|
2
2
|
|
3
3
|
* http://github.com/macks/ruby-protobuf
|
4
|
-
* http://code.google.com/p/ruby-protobuf
|
5
4
|
|
6
5
|
== DESCRIPTION:
|
7
6
|
|
@@ -23,7 +22,8 @@ Protocol Buffers for Ruby.
|
|
23
22
|
|
24
23
|
== INSTALL:
|
25
24
|
|
26
|
-
*
|
25
|
+
* gem source -a http://gems.github.com
|
26
|
+
* sudo gem install macks-ruby_protobuf
|
27
27
|
|
28
28
|
== AUTHOR:
|
29
29
|
|
@@ -31,6 +31,7 @@ MATSUYAMA Kengo <macksx@gmail.com>
|
|
31
31
|
|
32
32
|
Original Author:
|
33
33
|
ANDO Yasushi <andyjpn@gmail.com>
|
34
|
+
http://code.google.com/p/ruby-protobuf
|
34
35
|
|
35
36
|
== LICENSE:
|
36
37
|
|
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ Hoe.new('ruby_protobuf', RubyProtobuf::VERSION) do |p|
|
|
11
11
|
p.email = 'macksx@gmail.com'
|
12
12
|
p.summary = 'Protocol Buffers for Ruby'
|
13
13
|
p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
14
|
-
p.url =
|
14
|
+
p.url = 'http://github.com/macks/ruby-protobuf'
|
15
15
|
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
16
16
|
end
|
17
17
|
|
@@ -42,14 +42,9 @@ 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
|
@@ -59,21 +54,22 @@ module Protobuf
|
|
59
54
|
bytes = []
|
60
55
|
begin
|
61
56
|
byte = stream.send(read_method)
|
62
|
-
bytes << (byte &
|
63
|
-
end while byte
|
57
|
+
bytes << (byte & 0x7f)
|
58
|
+
end while (byte & 0x80).nonzero?
|
64
59
|
bytes
|
65
60
|
end
|
66
61
|
|
62
|
+
def read_fixed32(stream)
|
63
|
+
stream.read(4)
|
64
|
+
end
|
65
|
+
|
67
66
|
def read_fixed64(stream)
|
68
67
|
stream.read(8)
|
69
68
|
end
|
70
69
|
|
71
70
|
def read_length_delimited(stream)
|
72
71
|
bytes = read_varint stream
|
73
|
-
value_length =
|
74
|
-
bytes.each_with_index do |byte, index|
|
75
|
-
value_length |= byte << (7 * index)
|
76
|
-
end
|
72
|
+
value_length = Protobuf::Field::VarintField.decode bytes
|
77
73
|
value = stream.read value_length
|
78
74
|
value.unpack('C*')
|
79
75
|
end
|
@@ -81,13 +77,9 @@ module Protobuf
|
|
81
77
|
def read_start_group(stream)
|
82
78
|
raise NotImplementedError.new('Group is duplecated.')
|
83
79
|
end
|
84
|
-
|
80
|
+
|
85
81
|
def read_end_group(stream)
|
86
82
|
raise NotImplementedError.new('Group is duplecated.')
|
87
83
|
end
|
88
|
-
|
89
|
-
def read_fixed32(stream)
|
90
|
-
stream.read(4)
|
91
|
-
end
|
92
84
|
end
|
93
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,6 +15,7 @@ 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
20
|
next unless message.has_field?(field.name)
|
18
21
|
|
@@ -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
|
@@ -33,7 +33,7 @@ module Protobuf
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def initialize(message_class, rule, type, name, tag, opts={})
|
36
|
-
@message_class, @rule, @type, @name, @tag, @default, @extension =
|
36
|
+
@message_class, @rule, @type, @name, @tag, @default, @extension =
|
37
37
|
message_class, rule, type, name, tag, opts[:default], opts[:extension]
|
38
38
|
@error_message = 'Type invalid'
|
39
39
|
end
|
@@ -46,9 +46,9 @@ module Protobuf
|
|
46
46
|
return false if message[name].nil?
|
47
47
|
return false if is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
|
48
48
|
when :repeated
|
49
|
-
return message[name].
|
50
|
-
|
51
|
-
|
49
|
+
return message[name].all? {|msg|
|
50
|
+
(not is_a?(Protobuf::Field::MessageField)) or msg.initialized?
|
51
|
+
}
|
52
52
|
when :optional
|
53
53
|
return false if message[name] and is_a?(Protobuf::Field::MessageField) and not message[name].initialized?
|
54
54
|
end
|
@@ -91,7 +91,11 @@ module Protobuf
|
|
91
91
|
metaclass = (class << message_instance; self; end)
|
92
92
|
metaclass.class_eval do
|
93
93
|
define_method(field.name) do
|
94
|
-
|
94
|
+
if @values.has_key?(field.name)
|
95
|
+
@values[field.name]
|
96
|
+
else
|
97
|
+
field.default_value
|
98
|
+
end
|
95
99
|
end
|
96
100
|
end
|
97
101
|
end
|
@@ -110,29 +114,30 @@ module Protobuf
|
|
110
114
|
end
|
111
115
|
end
|
112
116
|
|
117
|
+
# encoder/decoder related methods
|
118
|
+
|
113
119
|
def set(message_instance, bytes)
|
120
|
+
value = decode(bytes)
|
114
121
|
if repeated?
|
115
|
-
|
122
|
+
message_instance.send(name) << value
|
116
123
|
else
|
117
|
-
|
124
|
+
message_instance.send("#{name}=", value)
|
118
125
|
end
|
119
126
|
end
|
120
127
|
|
121
|
-
def
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
def set_bytes(message_instance, bytes)
|
126
|
-
raise NotImplementedError
|
128
|
+
def get(value)
|
129
|
+
encode(value)
|
127
130
|
end
|
128
131
|
|
129
|
-
def
|
130
|
-
|
132
|
+
def decode(bytes)
|
133
|
+
raise NotImplementedError.new("#{self.class.name}\#decode")
|
131
134
|
end
|
135
|
+
private :decode
|
132
136
|
|
133
|
-
def
|
134
|
-
raise NotImplementedError
|
137
|
+
def encode(value)
|
138
|
+
raise NotImplementedError.new("#{self.class.name}\#encode")
|
135
139
|
end
|
140
|
+
private :encode
|
136
141
|
|
137
142
|
def merge(message_instance, value)
|
138
143
|
if repeated?
|
@@ -143,13 +148,15 @@ module Protobuf
|
|
143
148
|
end
|
144
149
|
|
145
150
|
def merge_array(message_instance, value)
|
146
|
-
message_instance[tag].concat value
|
151
|
+
message_instance[tag].concat value
|
147
152
|
end
|
148
153
|
|
149
154
|
def merge_value(message_instance, value)
|
150
155
|
message_instance[tag] = value
|
151
156
|
end
|
152
157
|
|
158
|
+
# utility methods
|
159
|
+
|
153
160
|
def repeated?; rule == :repeated end
|
154
161
|
def required?; rule == :required end
|
155
162
|
def optional?; rule == :optional end
|
@@ -186,44 +193,27 @@ module Protobuf
|
|
186
193
|
elsif type.superclass == Protobuf::Message
|
187
194
|
Protobuf::Field::MessageField
|
188
195
|
else
|
189
|
-
raise
|
196
|
+
raise TypeError.new(type.inspect)
|
190
197
|
end
|
191
198
|
field_class.new @message_class, @rule, type, @name, @tag, @opts
|
192
199
|
end
|
193
200
|
|
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
201
|
def typename_to_class(message_class, type)
|
208
202
|
suffix = type.to_s.split('::')
|
209
203
|
modules = message_class.to_s.split('::')
|
204
|
+
args = (Object.method(:const_defined?).arity == 1) ? [] : [nil, false]
|
210
205
|
while
|
211
206
|
mod = modules.empty? ? Object : eval(modules.join('::'))
|
212
|
-
suffix.
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
mod = nil
|
217
|
-
break
|
218
|
-
end
|
219
|
-
end
|
207
|
+
mod = suffix.inject(mod) {|m, s|
|
208
|
+
args[0] = s
|
209
|
+
m and m.const_defined?(*args) and m.const_get(s)
|
210
|
+
}
|
220
211
|
break if mod
|
221
212
|
raise NameError.new("type not found: #{type}", type) if modules.empty?
|
222
213
|
modules.pop
|
223
214
|
end
|
224
215
|
mod
|
225
216
|
end
|
226
|
-
=end
|
227
217
|
end
|
228
218
|
|
229
219
|
class FieldArray < Array
|
@@ -260,7 +250,7 @@ module Protobuf
|
|
260
250
|
end
|
261
251
|
end
|
262
252
|
|
263
|
-
class
|
253
|
+
class BytesField < BaseField
|
264
254
|
class <<self
|
265
255
|
def default; '' end
|
266
256
|
end
|
@@ -274,96 +264,68 @@ module Protobuf
|
|
274
264
|
true
|
275
265
|
end
|
276
266
|
|
277
|
-
def
|
278
|
-
|
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
|
267
|
+
def decode(bytes)
|
268
|
+
bytes.pack('C*')
|
288
269
|
end
|
289
270
|
|
290
|
-
def
|
291
|
-
|
292
|
-
|
293
|
-
string_size
|
271
|
+
def encode(value)
|
272
|
+
value = value.dup
|
273
|
+
value.force_encoding('ASCII-8BIT') if value.respond_to?(:force_encoding)
|
274
|
+
string_size = VarintField.encode(value.size)
|
275
|
+
string_size << value
|
294
276
|
end
|
295
277
|
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
278
|
|
311
|
-
|
312
|
-
|
313
|
-
end
|
314
|
-
|
315
|
-
def set_array(message_instance, bytes)
|
279
|
+
class StringField < BytesField
|
280
|
+
def decode(bytes)
|
316
281
|
message = bytes.pack('C*')
|
317
|
-
|
318
|
-
|
319
|
-
end
|
320
|
-
|
321
|
-
def get_bytes(value)
|
322
|
-
string_size = VarintField.get_bytes value.unpack('C*').size
|
323
|
-
string_size + value
|
282
|
+
message.force_encoding('UTF-8') if message.respond_to?(:force_encoding)
|
283
|
+
message
|
324
284
|
end
|
325
285
|
end
|
326
286
|
|
327
287
|
class VarintField < BaseField
|
288
|
+
INT32_MAX = 2**31 - 1
|
289
|
+
INT32_MIN = -2**31
|
290
|
+
INT64_MAX = 2**63 - 1
|
291
|
+
INT64_MIN = -2**63
|
292
|
+
UINT32_MAX = 2**32 - 1
|
293
|
+
UINT64_MAX = 2**64 - 1
|
294
|
+
|
328
295
|
class <<self
|
329
296
|
def default; 0 end
|
297
|
+
|
298
|
+
def decode(bytes)
|
299
|
+
value = 0
|
300
|
+
bytes.each_with_index do |byte, index|
|
301
|
+
value |= byte << (7 * index)
|
302
|
+
end
|
303
|
+
value
|
304
|
+
end
|
305
|
+
|
306
|
+
def encode(value)
|
307
|
+
raise RangeError.new(value) if value < 0
|
308
|
+
return [value].pack('C') if value < 128
|
309
|
+
bytes = []
|
310
|
+
until value == 0
|
311
|
+
bytes << (0x80 | (value & 0x7f))
|
312
|
+
value >>= 7
|
313
|
+
end
|
314
|
+
bytes[-1] &= 0x7f
|
315
|
+
bytes.pack('C*')
|
316
|
+
end
|
330
317
|
end
|
331
318
|
|
332
319
|
def wire_type
|
333
320
|
Protobuf::WireType::VARINT
|
334
321
|
end
|
335
|
-
|
336
|
-
def
|
337
|
-
|
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*')
|
322
|
+
|
323
|
+
def decode(bytes)
|
324
|
+
self.class.decode(bytes)
|
363
325
|
end
|
364
326
|
|
365
|
-
def
|
366
|
-
self.class.
|
327
|
+
def encode(value)
|
328
|
+
self.class.encode(value)
|
367
329
|
end
|
368
330
|
|
369
331
|
def acceptable?(val)
|
@@ -372,92 +334,86 @@ module Protobuf
|
|
372
334
|
true
|
373
335
|
end
|
374
336
|
end
|
375
|
-
|
376
|
-
class
|
377
|
-
|
378
|
-
def
|
337
|
+
|
338
|
+
# Base class for int32 and int64
|
339
|
+
class IntegerField < VarintField
|
340
|
+
def encode(value)
|
341
|
+
# original Google's library uses 64bits integer for negative value
|
342
|
+
VarintField.encode(value & 0xffff_ffff_ffff_ffff)
|
343
|
+
end
|
344
|
+
|
345
|
+
def decode(bytes)
|
346
|
+
value = VarintField.decode(bytes)
|
347
|
+
value -= 0x1_0000_0000_0000_0000 if (value & 0x8000_0000_0000_0000).nonzero?
|
348
|
+
value
|
349
|
+
end
|
379
350
|
end
|
380
|
-
|
381
|
-
class
|
382
|
-
def self.max;
|
383
|
-
def self.min;
|
351
|
+
|
352
|
+
class Int32Field < IntegerField
|
353
|
+
def self.max; INT32_MAX; end
|
354
|
+
def self.min; INT32_MIN; end
|
384
355
|
end
|
385
|
-
|
356
|
+
|
357
|
+
class Int64Field < IntegerField
|
358
|
+
def self.max; INT64_MAX; end
|
359
|
+
def self.min; INT64_MIN; end
|
360
|
+
end
|
361
|
+
|
386
362
|
class Uint32Field < VarintField
|
387
|
-
def self.max;
|
388
|
-
def self.min; 0 end
|
363
|
+
def self.max; UINT32_MAX; end
|
364
|
+
def self.min; 0; end
|
389
365
|
end
|
390
|
-
|
366
|
+
|
391
367
|
class Uint64Field < VarintField
|
392
|
-
def self.max;
|
393
|
-
def self.min; 0 end
|
368
|
+
def self.max; UINT64_MAX; end
|
369
|
+
def self.min; 0; end
|
394
370
|
end
|
395
|
-
|
396
|
-
class
|
397
|
-
|
398
|
-
def
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
byte / 2
|
406
|
-
else
|
407
|
-
-(byte + 1) / 2
|
408
|
-
end
|
409
|
-
message_instance.send("#{name}=", value)
|
371
|
+
|
372
|
+
# Base class for sint32 and sint64
|
373
|
+
class SignedIntegerField < VarintField
|
374
|
+
def decode(bytes)
|
375
|
+
value = VarintField.decode(bytes)
|
376
|
+
if (value & 1).zero?
|
377
|
+
value >> 1 # positive value
|
378
|
+
else
|
379
|
+
~value >> 1 # negative value
|
380
|
+
end
|
410
381
|
end
|
411
382
|
|
412
|
-
def
|
413
|
-
|
414
|
-
|
383
|
+
def encode(value)
|
384
|
+
if value >= 0
|
385
|
+
VarintField.encode(value << 1)
|
386
|
+
else
|
387
|
+
VarintField.encode(~(value << 1))
|
388
|
+
end
|
415
389
|
end
|
416
390
|
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
391
|
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
end
|
392
|
+
class Sint32Field < SignedIntegerField
|
393
|
+
def self.max; INT32_MAX; end
|
394
|
+
def self.min; INT32_MIN; end
|
438
395
|
end
|
439
|
-
|
440
|
-
class
|
396
|
+
|
397
|
+
class Sint64Field < SignedIntegerField
|
398
|
+
def self.max; INT64_MAX; end
|
399
|
+
def self.min; INT64_MIN; end
|
400
|
+
end
|
401
|
+
|
402
|
+
class FloatField < BaseField
|
403
|
+
def self.default; 0.0; end
|
404
|
+
def self.max; 1.0/0; end
|
405
|
+
def self.min; -1.0/0; end
|
406
|
+
|
441
407
|
def wire_type
|
442
|
-
Protobuf::WireType::
|
443
|
-
end
|
444
|
-
|
445
|
-
#TODO
|
446
|
-
def self.max
|
447
|
-
'0x7fefffffffffffff'.unpack('d').first
|
408
|
+
Protobuf::WireType::FIXED32
|
448
409
|
end
|
449
410
|
|
450
|
-
|
451
|
-
|
452
|
-
-(2**(64/2) - 1)
|
453
|
-
end
|
454
|
-
|
455
|
-
def set_bytes(message_instance, bytes)
|
456
|
-
message_instance.send("#{name}=", bytes.unpack('E').first)
|
411
|
+
def decode(bytes)
|
412
|
+
bytes.unpack('e').first
|
457
413
|
end
|
458
414
|
|
459
|
-
def
|
460
|
-
[value].pack('
|
415
|
+
def encode(value)
|
416
|
+
[value].pack('e')
|
461
417
|
end
|
462
418
|
|
463
419
|
def acceptable?(val)
|
@@ -466,109 +422,87 @@ module Protobuf
|
|
466
422
|
true
|
467
423
|
end
|
468
424
|
end
|
469
|
-
|
470
|
-
class
|
425
|
+
|
426
|
+
class DoubleField < FloatField
|
471
427
|
def wire_type
|
472
|
-
Protobuf::WireType::
|
473
|
-
end
|
474
|
-
|
475
|
-
#TODO
|
476
|
-
def self.max
|
477
|
-
'0x7fefffffffffffff'.unpack('e').first
|
428
|
+
Protobuf::WireType::FIXED64
|
478
429
|
end
|
479
430
|
|
480
|
-
|
481
|
-
|
482
|
-
-(2**(32/2) - 1)
|
483
|
-
end
|
484
|
-
|
485
|
-
def set_bytes(message_instance, bytes)
|
486
|
-
message_instance.send("#{name}=", bytes.unpack('e').first)
|
431
|
+
def decode(bytes)
|
432
|
+
bytes.unpack('E').first
|
487
433
|
end
|
488
434
|
|
489
|
-
def
|
490
|
-
[value].pack('
|
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
|
435
|
+
def encode(value)
|
436
|
+
[value].pack('E')
|
497
437
|
end
|
498
|
-
|
499
|
-
|
500
|
-
class Fixed32Field <
|
438
|
+
end
|
439
|
+
|
440
|
+
class Fixed32Field < Uint32Field
|
501
441
|
def wire_type
|
502
442
|
Protobuf::WireType::FIXED32
|
503
443
|
end
|
504
444
|
|
505
|
-
def
|
506
|
-
|
445
|
+
def decode(bytes)
|
446
|
+
bytes.unpack('V').first
|
507
447
|
end
|
508
448
|
|
509
|
-
def
|
510
|
-
|
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')
|
449
|
+
def encode(value)
|
450
|
+
[value].pack('V')
|
519
451
|
end
|
520
452
|
end
|
521
|
-
|
522
|
-
class Fixed64Field <
|
453
|
+
|
454
|
+
class Fixed64Field < Uint64Field
|
523
455
|
def wire_type
|
524
456
|
Protobuf::WireType::FIXED64
|
525
457
|
end
|
526
458
|
|
527
|
-
def
|
528
|
-
|
459
|
+
def decode(bytes)
|
460
|
+
# we don't use 'Q' for pack/unpack. 'Q' is machine-dependent.
|
461
|
+
values = bytes.unpack('VV')
|
462
|
+
values[0] + (values[1] << 32)
|
529
463
|
end
|
530
464
|
|
531
|
-
def
|
532
|
-
|
533
|
-
|
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')
|
465
|
+
def encode(value)
|
466
|
+
# we don't use 'Q' for pack/unpack. 'Q' is machine-dependent.
|
467
|
+
[value & 0xffff_ffff, value >> 32].pack('VV')
|
541
468
|
end
|
542
469
|
end
|
543
|
-
|
544
|
-
class
|
470
|
+
|
471
|
+
class Sfixed32Field < Int32Field
|
545
472
|
def wire_type
|
546
473
|
Protobuf::WireType::FIXED32
|
547
474
|
end
|
548
475
|
|
549
|
-
def
|
550
|
-
|
476
|
+
def decode(bytes)
|
477
|
+
value = bytes.unpack('V').first
|
478
|
+
value -= 0x1_0000_0000 if (value & 0x8000_0000).nonzero?
|
479
|
+
value
|
551
480
|
end
|
552
481
|
|
553
|
-
def
|
554
|
-
|
482
|
+
def encode(value)
|
483
|
+
[value].pack('V')
|
555
484
|
end
|
556
485
|
end
|
557
|
-
|
558
|
-
class Sfixed64Field <
|
486
|
+
|
487
|
+
class Sfixed64Field < Int64Field
|
559
488
|
def wire_type
|
560
489
|
Protobuf::WireType::FIXED64
|
561
490
|
end
|
562
491
|
|
563
|
-
def
|
564
|
-
|
492
|
+
def decode(bytes)
|
493
|
+
# we don't use 'Q' for pack/unpack. 'Q' is machine-dependent.
|
494
|
+
values = bytes.unpack('VV')
|
495
|
+
value = values[0] + (values[1] << 32)
|
496
|
+
value -= 0x1_0000_0000_0000_0000 if (value & 0x8000_0000_0000_0000).nonzero?
|
497
|
+
value
|
565
498
|
end
|
566
499
|
|
567
|
-
def
|
568
|
-
|
500
|
+
def encode(value)
|
501
|
+
# we don't use 'Q' for pack/unpack. 'Q' is machine-dependent.
|
502
|
+
[value & 0xffff_ffff, value >> 32].pack('VV')
|
569
503
|
end
|
570
504
|
end
|
571
|
-
|
505
|
+
|
572
506
|
class BoolField < VarintField
|
573
507
|
class <<self
|
574
508
|
def default; false end
|
@@ -578,16 +512,16 @@ module Protobuf
|
|
578
512
|
raise TypeError unless [TrueClass, FalseClass].include? val.class
|
579
513
|
true
|
580
514
|
end
|
581
|
-
|
582
|
-
def
|
583
|
-
|
515
|
+
|
516
|
+
def decode(bytes)
|
517
|
+
bytes.first == 1
|
584
518
|
end
|
585
519
|
|
586
|
-
def
|
520
|
+
def encode(value)
|
587
521
|
[value ? 1 : 0].pack('C')
|
588
522
|
end
|
589
523
|
end
|
590
|
-
|
524
|
+
|
591
525
|
class MessageField < BaseField
|
592
526
|
class <<self
|
593
527
|
def default; nil end
|
@@ -609,26 +543,17 @@ module Protobuf
|
|
609
543
|
raise TypeError unless val.instance_of? type
|
610
544
|
true
|
611
545
|
end
|
612
|
-
|
613
|
-
def
|
546
|
+
|
547
|
+
def decode(bytes)
|
614
548
|
message = type.new
|
615
549
|
message.parse_from_string bytes.pack('C*') # TODO
|
616
|
-
|
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
|
550
|
+
message
|
624
551
|
end
|
625
552
|
|
626
|
-
def
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
string_size = VarintField.get_bytes bytes.size
|
631
|
-
string_size + bytes.pack('C*')
|
553
|
+
def encode(value)
|
554
|
+
bytes = value.serialize_to_string
|
555
|
+
string_size = VarintField.encode bytes.size
|
556
|
+
string_size << bytes
|
632
557
|
end
|
633
558
|
|
634
559
|
def merge_value(message_instance, value)
|
@@ -127,12 +127,8 @@ module Protobuf
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def initialized?
|
130
|
-
fields.
|
131
|
-
|
132
|
-
end and
|
133
|
-
extension_fields.to_a.inject(true) do |result, (tag, field)|
|
134
|
-
result and field.initialized?(self)
|
135
|
-
end
|
130
|
+
fields.all? {|tag, field| field.initialized?(self) } && \
|
131
|
+
extension_fields.all? {|tag, field| field.initialized?(self) }
|
136
132
|
end
|
137
133
|
|
138
134
|
def has_field?(tag_or_name)
|
@@ -185,9 +181,9 @@ module Protobuf
|
|
185
181
|
"#{i}#{field.name} {\n#{value.inspect(indent + 1)}#{i}}\n"
|
186
182
|
end
|
187
183
|
elsif field.is_a? Protobuf::Field::EnumField
|
188
|
-
|
189
|
-
|
190
|
-
|
184
|
+
if field.optional? and not has_field?(field.name)
|
185
|
+
''
|
186
|
+
else
|
191
187
|
"#{i}#{field.name}: #{field.type.name_by_value(value)}\n"
|
192
188
|
end
|
193
189
|
else
|
@@ -204,10 +200,10 @@ module Protobuf
|
|
204
200
|
end
|
205
201
|
each_field do |field, value|
|
206
202
|
if field.repeated?
|
207
|
-
value.each do |v|
|
203
|
+
value.each do |v|
|
208
204
|
field_value_to_string.call field, v
|
209
205
|
end
|
210
|
-
else
|
206
|
+
else
|
211
207
|
field_value_to_string.call field, value
|
212
208
|
end
|
213
209
|
end
|
@@ -263,12 +259,12 @@ module Protobuf
|
|
263
259
|
#get_field_by_tag(tag).set self, bytes # TODO
|
264
260
|
(get_field_by_tag(tag) or get_ext_field_by_tag(tag)).set self, bytes
|
265
261
|
end
|
266
|
-
|
262
|
+
|
267
263
|
def merge_field(tag, value)
|
268
264
|
#get_field_by_tag(tag).merge self, bytes #TODO
|
269
265
|
(get_field_by_tag(tag) or get_ext_field_by_tag(tag)).merge self, value
|
270
266
|
end
|
271
|
-
|
267
|
+
|
272
268
|
def [](tag_or_name)
|
273
269
|
if field = get_field(tag_or_name)
|
274
270
|
send field.name
|
data/lib/ruby_protobuf.rb
CHANGED
data/{bin → script}/mk_parser
RENAMED
File without changes
|
data/test/proto/types.proto
CHANGED
@@ -14,4 +14,24 @@ message TestTypes {
|
|
14
14
|
required bool type11 = 11;
|
15
15
|
required string type12 = 12;
|
16
16
|
required bytes type13 = 13;
|
17
|
+
required sfixed32 type14 = 14;
|
18
|
+
required sfixed64 type15 = 15;
|
19
|
+
}
|
20
|
+
|
21
|
+
message RepeatedTypes {
|
22
|
+
repeated double type1 = 1;
|
23
|
+
repeated float type2 = 2;
|
24
|
+
repeated int32 type3 = 3;
|
25
|
+
repeated int64 type4 = 4;
|
26
|
+
repeated uint32 type5 = 5;
|
27
|
+
repeated uint64 type6 = 6;
|
28
|
+
repeated sint32 type7 = 7;
|
29
|
+
repeated sint64 type8 = 8;
|
30
|
+
repeated fixed32 type9 = 9;
|
31
|
+
repeated fixed64 type10 = 10;
|
32
|
+
repeated bool type11 = 11;
|
33
|
+
repeated string type12 = 12;
|
34
|
+
repeated bytes type13 = 13;
|
35
|
+
repeated sfixed32 type14 = 14;
|
36
|
+
repeated sfixed64 type15 = 15;
|
17
37
|
}
|
data/test/test_compiler.rb
CHANGED
@@ -136,7 +136,7 @@ end
|
|
136
136
|
def test_nested_message
|
137
137
|
Protobuf::Visitor::CreateMessageVisitor.instance_eval {remove_const :Baaz}
|
138
138
|
file_contents = Protobuf::Compiler.new.create_message('test/proto/nested.proto', '.', '.', false)
|
139
|
-
assert_nothing_raised {
|
139
|
+
assert_nothing_raised {Object.class_eval file_contents}
|
140
140
|
assert_raise(TypeError) {Baaz.new.x = 1}
|
141
141
|
assert_nothing_raised {Baaz.new.x = Foo::Bar.new}
|
142
142
|
end
|
data/test/test_message.rb
CHANGED
@@ -3,6 +3,9 @@ require 'test/addressbook'
|
|
3
3
|
require 'test/merge'
|
4
4
|
require 'test/unit'
|
5
5
|
|
6
|
+
# It should not conflict with Test::InnerMessage1 which is included in merge.proto
|
7
|
+
class InnerMessage1; end
|
8
|
+
|
6
9
|
class MessageTest < Test::Unit::TestCase
|
7
10
|
def test_equality
|
8
11
|
person1 = Tutorial::Person.new :name => 'ando'
|
data/test/test_types.rb
CHANGED
@@ -18,6 +18,8 @@ class TypesTest < Test::Unit::TestCase
|
|
18
18
|
types.type12 = 'hello all types'
|
19
19
|
image_bin = File.open('test/data/unk.png', 'r+b'){|f| f.read}
|
20
20
|
types.type13 = image_bin
|
21
|
+
types.type14 = -100
|
22
|
+
types.type15 = -1000
|
21
23
|
|
22
24
|
serialized_string = types.serialize_to_string
|
23
25
|
|
@@ -37,6 +39,49 @@ class TypesTest < Test::Unit::TestCase
|
|
37
39
|
assert_equal 'hello all types', types2.type12
|
38
40
|
assert_equal 10938, types2.type13.size
|
39
41
|
assert_equal image_bin, types2.type13
|
42
|
+
assert_equal(-100, types2.type14)
|
43
|
+
assert_equal(-1000, types2.type15)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_serialize2
|
47
|
+
types = Test::Types::TestTypes.new
|
48
|
+
types.type1 = 1.0/0 # double (Inf)
|
49
|
+
types.type2 = -1.0/0 # float (-Inf)
|
50
|
+
types.type3 = -1 # int32
|
51
|
+
types.type4 = -10 # int64
|
52
|
+
types.type5 = 100 # uint32
|
53
|
+
types.type6 = 1000 # uint64
|
54
|
+
types.type7 = -1000 # sint32
|
55
|
+
types.type8 = -10000 # sint64
|
56
|
+
types.type9 = 10000 # fixed32
|
57
|
+
types.type10 = 100000 # fixed64
|
58
|
+
types.type11 = true
|
59
|
+
types.type12 = 'hello all types'
|
60
|
+
image_bin = File.open('test/data/unk.png', 'r+b'){|f| f.read}
|
61
|
+
types.type13 = image_bin
|
62
|
+
types.type14 = -2_000_000_000 # sfixed32
|
63
|
+
types.type15 = -8_000_000_000_000_000_000 # sfixed64
|
64
|
+
|
65
|
+
serialized_string = types.serialize_to_string
|
66
|
+
|
67
|
+
types2 = Test::Types::TestTypes.new
|
68
|
+
types2.parse_from_string serialized_string
|
69
|
+
assert_equal(1.0/0.0, types2.type1)
|
70
|
+
assert_equal(-1.0/0.0, types2.type2)
|
71
|
+
assert_equal(-1, types2.type3)
|
72
|
+
assert_equal(-10, types2.type4)
|
73
|
+
assert_equal(100, types2.type5)
|
74
|
+
assert_equal(1000, types2.type6)
|
75
|
+
assert_equal(-1000, types2.type7)
|
76
|
+
assert_equal(-10000, types2.type8)
|
77
|
+
assert_equal(10000, types2.type9)
|
78
|
+
assert_equal(100000, types2.type10)
|
79
|
+
assert types2.type11
|
80
|
+
assert_equal('hello all types', types2.type12)
|
81
|
+
assert_equal(10938, types2.type13.size)
|
82
|
+
assert_equal(image_bin, types2.type13)
|
83
|
+
assert_equal(-2_000_000_000, types2.type14)
|
84
|
+
assert_equal(-8_000_000_000_000_000_000, types2.type15)
|
40
85
|
end
|
41
86
|
|
42
87
|
def test_parse
|
@@ -64,9 +109,7 @@ class TypesTest < Test::Unit::TestCase
|
|
64
109
|
assert_nothing_raised do types.type1 = 1.0 end
|
65
110
|
assert_raise TypeError do types.type1 = '' end
|
66
111
|
assert_nothing_raised do types.type1 = Protobuf::Field::DoubleField.max end
|
67
|
-
assert_raise RangeError do types.type1 = Protobuf::Field::DoubleField.max * 2 end
|
68
112
|
assert_nothing_raised do types.type1 = Protobuf::Field::DoubleField.min end
|
69
|
-
assert_raise RangeError do types.type1 = Protobuf::Field::DoubleField.min * 2 end
|
70
113
|
end
|
71
114
|
|
72
115
|
def test_float
|
@@ -76,9 +119,7 @@ class TypesTest < Test::Unit::TestCase
|
|
76
119
|
assert_nothing_raised do types.type2 = 1.0 end
|
77
120
|
assert_raise TypeError do types.type2 = '' end
|
78
121
|
assert_nothing_raised do types.type2 = Protobuf::Field::FloatField.max end
|
79
|
-
assert_raise RangeError do types.type2 = Protobuf::Field::FloatField.max * 2 end
|
80
122
|
assert_nothing_raised do types.type2 = Protobuf::Field::FloatField.min end
|
81
|
-
assert_raise RangeError do types.type2 = Protobuf::Field::FloatField.min * 2 end
|
82
123
|
end
|
83
124
|
|
84
125
|
def test_int32
|
@@ -178,4 +219,8 @@ class TypesTest < Test::Unit::TestCase
|
|
178
219
|
assert_raise TypeError do types.type13 = true end
|
179
220
|
assert_raise TypeError do types.type13 = [] end
|
180
221
|
end
|
222
|
+
|
223
|
+
def test_varint_getbytes
|
224
|
+
assert_equal "\xac\x02", Protobuf::Field::VarintField.encode(300)
|
225
|
+
end
|
181
226
|
end
|
data/test/types.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'protobuf/message/message'
|
2
|
+
require 'protobuf/message/enum'
|
2
3
|
|
3
4
|
module Test
|
4
5
|
module Types
|
5
|
-
|
6
|
-
|
6
|
+
class TestTypes < ::Protobuf::Message
|
7
|
+
defined_in __FILE__
|
7
8
|
required :double, :type1, 1
|
8
9
|
required :float, :type2, 2
|
9
10
|
required :int32, :type3, 3
|
@@ -17,6 +18,26 @@ module Test
|
|
17
18
|
required :bool, :type11, 11
|
18
19
|
required :string, :type12, 12
|
19
20
|
required :bytes, :type13, 13
|
21
|
+
required :sfixed32, :type14, 14
|
22
|
+
required :sfixed64, :type15, 15
|
23
|
+
end
|
24
|
+
class RepeatedTypes < ::Protobuf::Message
|
25
|
+
defined_in __FILE__
|
26
|
+
repeated :double, :type1, 1
|
27
|
+
repeated :float, :type2, 2
|
28
|
+
repeated :int32, :type3, 3
|
29
|
+
repeated :int64, :type4, 4
|
30
|
+
repeated :uint32, :type5, 5
|
31
|
+
repeated :uint64, :type6, 6
|
32
|
+
repeated :sint32, :type7, 7
|
33
|
+
repeated :sint64, :type8, 8
|
34
|
+
repeated :fixed32, :type9, 9
|
35
|
+
repeated :fixed64, :type10, 10
|
36
|
+
repeated :bool, :type11, 11
|
37
|
+
repeated :string, :type12, 12
|
38
|
+
repeated :bytes, :type13, 13
|
39
|
+
repeated :sfixed32, :type14, 14
|
40
|
+
repeated :sfixed64, :type15, 15
|
20
41
|
end
|
21
42
|
end
|
22
43
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: macks-ruby_protobuf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.2.
|
4
|
+
version: 0.3.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- MATSUYAMA Kengo
|
@@ -9,8 +9,8 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-04-
|
13
|
-
default_executable:
|
12
|
+
date: 2009-04-22 00:00:00 -07:00
|
13
|
+
default_executable: rprotoc
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: hoe
|
@@ -25,7 +25,6 @@ dependencies:
|
|
25
25
|
description: "== DESCRIPTION: Protocol Buffers for Ruby. == FEATURES/PROBLEMS: * Compile .proto file to ruby script * Parse the binary wire format for protocol buffer * Serialize data to the binary wire format for protocol buffer"
|
26
26
|
email: macksx@gmail.com
|
27
27
|
executables:
|
28
|
-
- mk_parser
|
29
28
|
- rprotoc
|
30
29
|
extensions: []
|
31
30
|
|
@@ -38,7 +37,6 @@ files:
|
|
38
37
|
- Manifest.txt
|
39
38
|
- README.txt
|
40
39
|
- Rakefile
|
41
|
-
- bin/mk_parser
|
42
40
|
- bin/rprotoc
|
43
41
|
- examples/addressbook.proto
|
44
42
|
- examples/addressbook.pb.rb
|
@@ -73,6 +71,7 @@ files:
|
|
73
71
|
- lib/protobuf/rpc/handler.rb
|
74
72
|
- lib/protobuf/rpc/server.rb
|
75
73
|
- lib/ruby_protobuf.rb
|
74
|
+
- script/mk_parser
|
76
75
|
- test/addressbook.rb
|
77
76
|
- test/addressbook_base.rb
|
78
77
|
- test/addressbook_ext.rb
|
@@ -110,7 +109,7 @@ files:
|
|
110
109
|
- test/types.rb
|
111
110
|
- test/test_optional_field.rb
|
112
111
|
has_rdoc: true
|
113
|
-
homepage:
|
112
|
+
homepage: http://github.com/macks/ruby-protobuf
|
114
113
|
post_install_message:
|
115
114
|
rdoc_options:
|
116
115
|
- --main
|