macks-ruby_protobuf 0.3.2.1 → 0.3.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|