ruby_protobuf 0.3.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +10 -2
- data/Manifest.txt +26 -12
- data/README.txt +6 -1
- data/Rakefile +51 -14
- data/TODO +15 -0
- data/VERSION +1 -0
- data/bin/rprotoc +11 -6
- data/lib/protobuf/common/exceptions.rb +11 -0
- data/lib/protobuf/common/util.rb +9 -0
- data/lib/protobuf/common/wire_type.rb +6 -6
- data/lib/protobuf/compiler/compiler.rb +16 -16
- data/lib/protobuf/compiler/nodes.rb +67 -65
- data/lib/protobuf/compiler/proto.y +31 -38
- data/lib/protobuf/compiler/proto_parser.rb +315 -294
- data/lib/protobuf/compiler/template/rpc_bin.erb +1 -1
- data/lib/protobuf/compiler/template/rpc_client.erb +1 -1
- data/lib/protobuf/compiler/template/rpc_service.erb +2 -2
- data/lib/protobuf/compiler/visitors.rb +45 -39
- data/lib/protobuf/descriptor/descriptor.proto +0 -0
- data/lib/protobuf/descriptor/descriptor.rb +11 -10
- data/lib/protobuf/descriptor/descriptor_builder.rb +6 -7
- data/lib/protobuf/descriptor/descriptor_proto.rb +51 -31
- data/lib/protobuf/descriptor/enum_descriptor.rb +5 -5
- data/lib/protobuf/descriptor/field_descriptor.rb +8 -9
- data/lib/protobuf/descriptor/file_descriptor.rb +0 -1
- data/lib/protobuf/message/decoder.rb +33 -35
- data/lib/protobuf/message/encoder.rb +23 -19
- data/lib/protobuf/message/enum.rb +43 -9
- data/lib/protobuf/message/field.rb +281 -193
- data/lib/protobuf/message/message.rb +166 -110
- data/lib/protobuf/message/protoable.rb +4 -3
- data/lib/protobuf/message/service.rb +1 -1
- data/lib/protobuf/rpc/client.rb +3 -3
- data/lib/protobuf/rpc/handler.rb +1 -1
- data/lib/protobuf/rpc/server.rb +8 -8
- data/lib/ruby_protobuf.rb +1 -1
- data/test/check_unbuild.rb +7 -7
- data/test/proto/addressbook.pb.rb +67 -0
- data/test/proto/addressbook.proto +2 -0
- data/test/proto/addressbook_base.pb.rb +59 -0
- data/test/proto/addressbook_base.proto +1 -1
- data/test/proto/addressbook_ext.pb.rb +21 -0
- data/test/proto/addressbook_ext.proto +2 -2
- data/test/{collision.rb → proto/collision.pb.rb} +0 -0
- data/test/{ext_collision.rb → proto/ext_collision.pb.rb} +1 -1
- data/test/{ext_range.rb → proto/ext_range.pb.rb} +4 -4
- data/test/proto/ext_range.proto +2 -2
- data/test/proto/float_default.proto +10 -0
- data/test/proto/lowercase.pb.rb +31 -0
- data/test/proto/lowercase.proto +9 -0
- data/test/{merge.rb → proto/merge.pb.rb} +2 -2
- data/test/proto/nested.pb.rb +31 -0
- data/test/proto/nested.proto +2 -0
- data/test/proto/optional_field.pb.rb +36 -0
- data/test/proto/optional_field.proto +12 -0
- data/test/proto/packed.pb.rb +23 -0
- data/test/proto/packed.proto +6 -0
- data/test/{types.rb → proto/types.pb.rb} +43 -1
- data/test/test_addressbook.rb +30 -17
- data/test/test_compiler.rb +79 -78
- data/test/test_descriptor.rb +12 -12
- data/test/test_enum_value.rb +41 -0
- data/test/test_extension.rb +10 -14
- data/test/test_lowercase.rb +11 -0
- data/test/test_message.rb +44 -41
- data/test/test_optional_field.rb +61 -38
- data/test/test_packed_field.rb +40 -0
- data/test/test_parse.rb +8 -8
- data/test/test_repeated_types.rb +29 -3
- data/test/test_serialize.rb +12 -12
- data/test/test_standard_message.rb +30 -30
- data/test/test_types.rb +95 -95
- metadata +69 -39
- data/test/addressbook.rb +0 -98
- data/test/addressbook_base.rb +0 -62
- data/test/addressbook_ext.rb +0 -12
- data/test/nested.rb +0 -25
- data/test/test_ruby_protobuf.rb +0 -1
@@ -10,7 +10,6 @@ module Protobuf
|
|
10
10
|
OPTIONS = {}
|
11
11
|
|
12
12
|
class Message
|
13
|
-
class TagCollisionError < StandardError; end
|
14
13
|
|
15
14
|
class ExtensionFields < Hash
|
16
15
|
def initialize(key_range=0..-1)
|
@@ -18,65 +17,78 @@ module Protobuf
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def []=(key, value)
|
21
|
-
raise RangeError
|
20
|
+
raise RangeError, "#{key} is not in #{@key_range}" unless @key_range.include?(key)
|
22
21
|
super
|
23
22
|
end
|
24
23
|
|
25
24
|
def include_tag?(tag)
|
26
|
-
@key_range.include?
|
25
|
+
@key_range.include?(tag)
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
29
|
class <<self
|
31
|
-
include
|
32
|
-
def fields; @fields ||= {} end
|
30
|
+
include Protoable
|
33
31
|
|
32
|
+
# Reserve field numbers for extensions. Don't use this method directly.
|
34
33
|
def extensions(range)
|
35
|
-
@extension_fields = ExtensionFields.new
|
34
|
+
@extension_fields = ExtensionFields.new(range)
|
36
35
|
end
|
37
36
|
|
38
|
-
|
39
|
-
|
37
|
+
# Define a required field. Don't use this method directly.
|
38
|
+
def required(type, name, tag, options={})
|
39
|
+
define_field(:required, type, name, tag, options)
|
40
40
|
end
|
41
41
|
|
42
|
-
|
43
|
-
|
42
|
+
# Define a optional field. Don't use this method directly.
|
43
|
+
def optional(type, name, tag, options={})
|
44
|
+
define_field(:optional, type, name, tag, options)
|
44
45
|
end
|
45
46
|
|
46
|
-
|
47
|
-
|
47
|
+
# Define a repeated field. Don't use this method directly.
|
48
|
+
def repeated(type, name, tag, options={})
|
49
|
+
define_field(:repeated, type, name, tag, options)
|
48
50
|
end
|
49
51
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
# Define a field. Don't use this method directly.
|
53
|
+
def define_field(rule, type, fname, tag, options)
|
54
|
+
field_hash = options[:extension] ? extension_fields : fields
|
55
|
+
if field_hash.keys.include?(tag)
|
56
|
+
raise TagCollisionError, %!{Field number #{tag} has already been used in "#{self.name}" by field "#{fname}".!
|
57
|
+
end
|
58
|
+
field_hash[tag] = Field.build(self, rule, type, fname, tag, options)
|
56
59
|
end
|
57
60
|
|
58
61
|
def extension_tag?(tag)
|
59
|
-
extension_fields.include_tag?
|
62
|
+
extension_fields.include_tag?(tag)
|
63
|
+
end
|
64
|
+
|
65
|
+
# A collection of field object.
|
66
|
+
def fields
|
67
|
+
@fields ||= {}
|
60
68
|
end
|
61
69
|
|
70
|
+
# An extension field object.
|
62
71
|
def extension_fields
|
63
72
|
@extension_fields ||= ExtensionFields.new
|
64
73
|
end
|
65
74
|
|
75
|
+
# Find a field object by +name+.
|
66
76
|
def get_field_by_name(name)
|
67
77
|
name = name.to_sym
|
68
78
|
fields.values.find {|field| field.name == name}
|
69
79
|
end
|
70
80
|
|
81
|
+
# Find a field object by +tag+ number.
|
71
82
|
def get_field_by_tag(tag)
|
72
83
|
fields[tag]
|
73
84
|
end
|
74
85
|
|
86
|
+
# Find a field object by +tag_or_name+.
|
75
87
|
def get_field(tag_or_name)
|
76
88
|
case tag_or_name
|
77
|
-
when Integer
|
78
|
-
when String, Symbol
|
79
|
-
else
|
89
|
+
when Integer then get_field_by_tag(tag_or_name)
|
90
|
+
when String, Symbol then get_field_by_name(tag_or_name)
|
91
|
+
else raise TypeError, tag_or_name.class
|
80
92
|
end
|
81
93
|
end
|
82
94
|
|
@@ -94,38 +106,38 @@ module Protobuf
|
|
94
106
|
#TODO merge to get_field
|
95
107
|
def get_ext_field(tag_or_name)
|
96
108
|
case tag_or_name
|
97
|
-
when Integer
|
98
|
-
when String, Symbol
|
99
|
-
else
|
109
|
+
when Integer then get_ext_field_by_tag(tag_or_name)
|
110
|
+
when String, Symbol then get_ext_field_by_name(tag_or_name)
|
111
|
+
else raise TypeError, tag_or_name.class
|
100
112
|
end
|
101
113
|
end
|
102
114
|
|
103
115
|
def descriptor
|
104
|
-
@descriptor ||=
|
116
|
+
@descriptor ||= Descriptor::Descriptor.new(self)
|
105
117
|
end
|
106
118
|
end
|
107
119
|
|
108
120
|
def initialize(values={})
|
109
121
|
@values = {}
|
110
122
|
|
111
|
-
self.class.fields.each do |tag, field|
|
123
|
+
self.class.fields.to_a.each do |tag, field|
|
112
124
|
unless field.ready?
|
113
125
|
field = field.setup
|
114
|
-
self.class.
|
126
|
+
self.class.fields[tag] = field
|
115
127
|
end
|
116
128
|
if field.repeated?
|
117
|
-
@values[field.name] =
|
129
|
+
@values[field.name] = Field::FieldArray.new(field)
|
118
130
|
end
|
119
131
|
end
|
120
132
|
|
121
133
|
# TODO
|
122
|
-
self.class.extension_fields.each do |tag, field|
|
134
|
+
self.class.extension_fields.to_a.each do |tag, field|
|
123
135
|
unless field.ready?
|
124
136
|
field = field.setup
|
125
|
-
self.class.
|
137
|
+
self.class.extension_fields[tag] = field
|
126
138
|
end
|
127
139
|
if field.repeated?
|
128
|
-
@values[field.name] =
|
140
|
+
@values[field.name] = Field::FieldArray.new(field)
|
129
141
|
end
|
130
142
|
end
|
131
143
|
|
@@ -134,175 +146,219 @@ module Protobuf
|
|
134
146
|
|
135
147
|
def initialized?
|
136
148
|
fields.all? {|tag, field| field.initialized?(self) } && \
|
137
|
-
|
149
|
+
extension_fields.all? {|tag, field| field.initialized?(self) }
|
138
150
|
end
|
139
151
|
|
140
152
|
def has_field?(tag_or_name)
|
141
153
|
field = get_field(tag_or_name) || get_ext_field(tag_or_name)
|
142
|
-
raise ArgumentError
|
154
|
+
raise ArgumentError, "unknown field: #{tag_or_name.inspect}" unless field
|
143
155
|
@values.has_key?(field.name)
|
144
156
|
end
|
145
157
|
|
146
158
|
def ==(obj)
|
147
|
-
return false unless obj.is_a?
|
159
|
+
return false unless obj.is_a?(self.class)
|
148
160
|
each_field do |field, value|
|
149
|
-
return false unless value == obj.
|
161
|
+
return false unless value == obj.__send__(field.name)
|
150
162
|
end
|
151
163
|
true
|
152
164
|
end
|
153
165
|
|
154
166
|
def clear!
|
155
|
-
|
156
|
-
|
167
|
+
@values.delete_if do |_, value|
|
168
|
+
if value.is_a?(Field::FieldArray)
|
169
|
+
value.clear
|
170
|
+
false
|
171
|
+
else
|
172
|
+
true
|
173
|
+
end
|
157
174
|
end
|
175
|
+
self
|
158
176
|
end
|
159
177
|
|
160
178
|
def dup
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
179
|
+
copy_to(super, :dup)
|
180
|
+
end
|
181
|
+
|
182
|
+
def clone
|
183
|
+
copy_to(super, :clone)
|
184
|
+
end
|
185
|
+
|
186
|
+
def copy_to(object, method)
|
187
|
+
duplicate = proc {|obj|
|
188
|
+
case obj
|
189
|
+
when Message, String then obj.__send__(method)
|
190
|
+
else obj
|
191
|
+
end
|
192
|
+
}
|
193
|
+
|
194
|
+
object.__send__(:initialize)
|
195
|
+
@values.each do |name, value|
|
196
|
+
if value.is_a?(Field::FieldArray)
|
197
|
+
object.__send__(name).replace(value.map {|v| duplicate.call(v)})
|
168
198
|
else
|
169
|
-
|
199
|
+
object.__send__("#{name}=", duplicate.call(value))
|
170
200
|
end
|
171
201
|
end
|
172
|
-
|
202
|
+
object
|
173
203
|
end
|
204
|
+
private :copy_to
|
174
205
|
|
175
206
|
def inspect(indent=0)
|
176
|
-
|
207
|
+
result = []
|
177
208
|
i = ' ' * indent
|
178
|
-
field_value_to_string = lambda
|
179
|
-
|
180
|
-
if field.
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
209
|
+
field_value_to_string = lambda {|field, value|
|
210
|
+
result << \
|
211
|
+
if field.optional? && ! has_field?(field.name)
|
212
|
+
''
|
213
|
+
else
|
214
|
+
case field
|
215
|
+
when Field::MessageField
|
216
|
+
if value.nil?
|
185
217
|
"#{i}#{field.name} {}\n"
|
218
|
+
else
|
219
|
+
"#{i}#{field.name} {\n#{value.inspect(indent + 1)}#{i}}\n"
|
186
220
|
end
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
elsif field.is_a? Protobuf::Field::EnumField
|
191
|
-
if field.optional? and not has_field?(field.name)
|
192
|
-
''
|
193
|
-
else
|
194
|
-
"#{i}#{field.name}: #{field.type.name_by_value(value)}\n"
|
195
|
-
end
|
196
|
-
else
|
197
|
-
if $DEBUG
|
198
|
-
"#{i}#{field.name}: #{value.inspect}\n"
|
199
|
-
else
|
200
|
-
if field.optional? and not has_field?(field.name)
|
201
|
-
''
|
221
|
+
when Field::EnumField
|
222
|
+
if value.is_a?(EnumValue)
|
223
|
+
"#{i}#{field.name}: #{value.name}\n"
|
202
224
|
else
|
203
|
-
"#{i}#{field.name}: #{value
|
225
|
+
"#{i}#{field.name}: #{field.type.name_by_value(value)}\n"
|
204
226
|
end
|
227
|
+
else
|
228
|
+
"#{i}#{field.name}: #{value.inspect}\n"
|
205
229
|
end
|
206
230
|
end
|
207
|
-
|
231
|
+
}
|
208
232
|
each_field do |field, value|
|
209
233
|
if field.repeated?
|
210
|
-
value.each do |v|
|
211
|
-
field_value_to_string.call
|
234
|
+
value.each do |v|
|
235
|
+
field_value_to_string.call(field, v)
|
212
236
|
end
|
213
|
-
else
|
214
|
-
field_value_to_string.call
|
237
|
+
else
|
238
|
+
field_value_to_string.call(field, value)
|
215
239
|
end
|
216
240
|
end
|
217
|
-
|
241
|
+
result.join
|
218
242
|
end
|
219
243
|
|
220
244
|
def parse_from_string(string)
|
221
|
-
parse_from
|
245
|
+
parse_from(StringIO.new(string))
|
222
246
|
end
|
223
247
|
|
224
248
|
def parse_from_file(filename)
|
225
|
-
if filename.is_a?
|
226
|
-
parse_from
|
249
|
+
if filename.is_a?(File)
|
250
|
+
parse_from(filename)
|
227
251
|
else
|
228
252
|
File.open(filename, 'rb') do |f|
|
229
|
-
parse_from
|
253
|
+
parse_from(f)
|
230
254
|
end
|
231
255
|
end
|
232
256
|
end
|
233
257
|
|
234
258
|
def parse_from(stream)
|
235
|
-
|
259
|
+
Decoder.decode(stream, self)
|
236
260
|
end
|
237
261
|
|
238
262
|
def serialize_to_string(string='')
|
239
|
-
io = StringIO.new
|
240
|
-
serialize_to
|
263
|
+
io = StringIO.new(string)
|
264
|
+
serialize_to(io)
|
241
265
|
result = io.string
|
242
|
-
result.force_encoding(
|
266
|
+
result.force_encoding(Encoding::ASCII_8BIT) if result.respond_to?(:force_encoding)
|
243
267
|
result
|
244
268
|
end
|
245
269
|
alias to_s serialize_to_string
|
246
270
|
|
247
271
|
def serialize_to_file(filename)
|
248
|
-
if filename.is_a?
|
249
|
-
serialize_to
|
272
|
+
if filename.is_a?(File)
|
273
|
+
serialize_to(filename)
|
250
274
|
else
|
251
275
|
File.open(filename, 'wb') do |f|
|
252
|
-
serialize_to
|
276
|
+
serialize_to(f)
|
253
277
|
end
|
254
278
|
end
|
255
279
|
end
|
256
280
|
|
257
281
|
def serialize_to(stream)
|
258
|
-
|
282
|
+
Encoder.encode(stream, self)
|
259
283
|
end
|
260
284
|
|
261
285
|
def merge_from(message)
|
262
286
|
# TODO
|
263
|
-
fields.each {|tag, field| merge_field
|
264
|
-
|
287
|
+
fields.each {|tag, field| merge_field(tag, message.__send__(field.name))}
|
288
|
+
extension_fields.each {|tag, field| merge_field(tag, message.__send__(field.name))}
|
265
289
|
end
|
266
290
|
|
267
291
|
def set_field(tag, bytes)
|
268
|
-
field = (get_field_by_tag(tag)
|
269
|
-
field.set
|
292
|
+
field = (get_field_by_tag(tag) || get_ext_field_by_tag(tag))
|
293
|
+
field.set(self, bytes) if field
|
270
294
|
end
|
271
|
-
|
295
|
+
|
272
296
|
def merge_field(tag, value)
|
273
297
|
#get_field_by_tag(tag).merge self, bytes #TODO
|
274
|
-
(get_field_by_tag(tag)
|
298
|
+
(get_field_by_tag(tag) || get_ext_field_by_tag(tag)).merge(self, value)
|
275
299
|
end
|
276
|
-
|
300
|
+
|
277
301
|
def [](tag_or_name)
|
278
302
|
if field = get_field(tag_or_name) || get_ext_field(tag_or_name)
|
279
|
-
|
303
|
+
__send__(field.name)
|
280
304
|
else
|
281
|
-
raise NoMethodError
|
305
|
+
raise NoMethodError, "No such field: #{tag_or_name.inspect}"
|
282
306
|
end
|
283
307
|
end
|
284
308
|
|
285
309
|
def []=(tag_or_name, value)
|
286
310
|
if field = get_field(tag_or_name) || get_ext_field(tag_or_name)
|
287
|
-
|
311
|
+
__send__("#{field.name}=", value)
|
288
312
|
else
|
289
|
-
raise NoMethodError
|
313
|
+
raise NoMethodError, "No such field: #{tag_or_name.inspect}"
|
290
314
|
end
|
291
315
|
end
|
292
316
|
|
293
|
-
|
294
|
-
def
|
295
|
-
|
296
|
-
|
317
|
+
# Returns a hash; which key is a tag number, and value is a field object.
|
318
|
+
def fields
|
319
|
+
self.class.fields
|
320
|
+
end
|
321
|
+
|
322
|
+
# Returns field object or +nil+.
|
323
|
+
def get_field_by_name(name)
|
324
|
+
self.class.get_field_by_name(name)
|
325
|
+
end
|
297
326
|
|
298
|
-
|
299
|
-
def
|
300
|
-
|
301
|
-
|
327
|
+
# Returns field object or +nil+.
|
328
|
+
def get_field_by_tag(tag)
|
329
|
+
self.class.get_field_by_tag(tag)
|
330
|
+
end
|
331
|
+
|
332
|
+
# Returns field object or +nil+.
|
333
|
+
def get_field(tag_or_name)
|
334
|
+
self.class.get_field(tag_or_name)
|
335
|
+
end
|
336
|
+
|
337
|
+
# Returns extension fields. See Message#fields method.
|
338
|
+
def extension_fields
|
339
|
+
self.class.extension_fields
|
340
|
+
end
|
341
|
+
|
342
|
+
def get_ext_field_by_name(name) # :nodoc:
|
343
|
+
self.class.get_ext_field_by_name(name)
|
344
|
+
end
|
345
|
+
|
346
|
+
def get_ext_field_by_tag(tag) # :nodoc:
|
347
|
+
self.class.get_ext_field_by_tag(tag)
|
348
|
+
end
|
349
|
+
|
350
|
+
def get_ext_field(tag_or_name) # :nodoc:
|
351
|
+
self.class.get_ext_field(tag_or_name)
|
352
|
+
end
|
302
353
|
|
354
|
+
# Iterate over a field collection.
|
355
|
+
# message.each_field do |field_object, value|
|
356
|
+
# # do something
|
357
|
+
# end
|
303
358
|
def each_field
|
304
|
-
|
305
|
-
|
359
|
+
fields.merge(extension_fields).sort_by {|tag, _| tag}.each do |_, field|
|
360
|
+
value = __send__(field.name)
|
361
|
+
yield(field, value)
|
306
362
|
end
|
307
363
|
end
|
308
364
|
end
|
@@ -5,7 +5,8 @@ module Protobuf
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def defined_in(filename)
|
8
|
-
|
8
|
+
path = File.expand_path(filename)
|
9
|
+
defined_filenames << path unless defined_filenames.include?(path)
|
9
10
|
end
|
10
11
|
|
11
12
|
def proto_filenames
|
@@ -17,8 +18,8 @@ module Protobuf
|
|
17
18
|
def proto_contents
|
18
19
|
#TODO: temporary implementation because the result includes not only this message but also all messages
|
19
20
|
ret = {}
|
20
|
-
defined_filenames.
|
21
|
-
header = retrieve_header
|
21
|
+
defined_filenames.each do |filename|
|
22
|
+
header = retrieve_header(File.read(filename))
|
22
23
|
ret[header.first] = header.last
|
23
24
|
end
|
24
25
|
ret
|
data/lib/protobuf/rpc/client.rb
CHANGED
@@ -8,11 +8,11 @@ module Protobuf
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def call(name, request, response)
|
11
|
-
socket = TCPSocket.open
|
11
|
+
socket = TCPSocket.open(@host, @port)
|
12
12
|
socket.write "#{name}\n"
|
13
|
-
request.serialize_to
|
13
|
+
request.serialize_to(socket)
|
14
14
|
socket.close_write
|
15
|
-
response.parse_from
|
15
|
+
response.parse_from(socket)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
data/lib/protobuf/rpc/handler.rb
CHANGED
data/lib/protobuf/rpc/server.rb
CHANGED
@@ -5,7 +5,7 @@ module Protobuf
|
|
5
5
|
module Rpc
|
6
6
|
class Server < WEBrick::GenericServer
|
7
7
|
def initialize(config={:Port => 9999}, default=WEBrick::Config::General)
|
8
|
-
super
|
8
|
+
super(config, default)
|
9
9
|
setup_handlers
|
10
10
|
end
|
11
11
|
|
@@ -20,17 +20,17 @@ module Protobuf
|
|
20
20
|
def run(socket)
|
21
21
|
handler = get_handler socket
|
22
22
|
request = handler.request_class.new
|
23
|
-
request.parse_from
|
23
|
+
request.parse_from(socket)
|
24
24
|
response = handler.response_class.new
|
25
25
|
begin
|
26
|
-
handler.process_request
|
27
|
-
rescue StandardError
|
28
|
-
@logger.error
|
26
|
+
handler.process_request(request, response)
|
27
|
+
rescue StandardError
|
28
|
+
@logger.error $!
|
29
29
|
ensure
|
30
30
|
begin
|
31
|
-
response.serialize_to
|
32
|
-
rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN
|
33
|
-
@logger.error
|
31
|
+
response.serialize_to(socket)
|
32
|
+
rescue Errno::EPIPE, Errno::ECONNRESET, Errno::ENOTCONN
|
33
|
+
@logger.error $!
|
34
34
|
end
|
35
35
|
end
|
36
36
|
end
|
data/lib/ruby_protobuf.rb
CHANGED
data/test/check_unbuild.rb
CHANGED
@@ -14,17 +14,17 @@ class DescriptorTest < Test::Unit::TestCase
|
|
14
14
|
|
15
15
|
assert_nothing_raised {Tutorial::Person}
|
16
16
|
assert_nothing_raised {Tutorial::Person.new}
|
17
|
-
assert_equal
|
18
|
-
Tutorial::Person.fields.map{|tag, field| field.name}.sort
|
17
|
+
assert_equal(['age', 'email', 'id', 'name', 'phone'],
|
18
|
+
Tutorial::Person.fields.map{|tag, field| field.name}.sort)
|
19
19
|
|
20
20
|
assert_nothing_raised {Tutorial::Person::PhoneNumber}
|
21
21
|
assert_nothing_raised {Tutorial::Person::PhoneNumber.new}
|
22
|
-
assert_equal
|
23
|
-
Tutorial::Person::PhoneNumber.fields.map{|tag, field| field.name}.sort
|
22
|
+
assert_equal(['number', 'type'],
|
23
|
+
Tutorial::Person::PhoneNumber.fields.map{|tag, field| field.name}.sort)
|
24
24
|
|
25
25
|
assert_nothing_raised {Tutorial::Person::PhoneType}
|
26
|
-
assert_equal
|
27
|
-
assert_equal
|
28
|
-
assert_equal
|
26
|
+
assert_equal(0, Tutorial::Person::PhoneType::MOBILE)
|
27
|
+
assert_equal(1, Tutorial::Person::PhoneType::HOME)
|
28
|
+
assert_equal(2, Tutorial::Person::PhoneType::WORK)
|
29
29
|
end
|
30
30
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
### Generated by rprotoc. DO NOT EDIT!
|
2
|
+
### <proto file: test/proto/addressbook.proto>
|
3
|
+
# package tutorial;
|
4
|
+
#
|
5
|
+
# message Person {
|
6
|
+
# required string name = 1;
|
7
|
+
# required int32 id = 2;
|
8
|
+
# optional string email = 3;
|
9
|
+
#
|
10
|
+
# enum PhoneType {
|
11
|
+
# MOBILE = 0;
|
12
|
+
# HOME = 1;
|
13
|
+
# WORK = 2;
|
14
|
+
# }
|
15
|
+
#
|
16
|
+
# message PhoneNumber {
|
17
|
+
# required string number = 1;
|
18
|
+
# optional PhoneType type = 2 [default = HOME];
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# repeated PhoneNumber phone = 4;
|
22
|
+
# optional uint32 age = 5 [default = 20];
|
23
|
+
#
|
24
|
+
# extensions 100 to 200;
|
25
|
+
# }
|
26
|
+
#
|
27
|
+
# /*
|
28
|
+
# extend Person {
|
29
|
+
# optional int32 age = 100;
|
30
|
+
# }
|
31
|
+
# */
|
32
|
+
#
|
33
|
+
# message AddressBook {
|
34
|
+
# repeated Person person = 1;
|
35
|
+
# }
|
36
|
+
|
37
|
+
require 'protobuf/message/message'
|
38
|
+
require 'protobuf/message/enum'
|
39
|
+
require 'protobuf/message/service'
|
40
|
+
require 'protobuf/message/extend'
|
41
|
+
|
42
|
+
module Tutorial
|
43
|
+
class Person < ::Protobuf::Message
|
44
|
+
defined_in __FILE__
|
45
|
+
required :string, :name, 1
|
46
|
+
required :int32, :id, 2
|
47
|
+
optional :string, :email, 3
|
48
|
+
class PhoneType < ::Protobuf::Enum
|
49
|
+
defined_in __FILE__
|
50
|
+
define :MOBILE, 0
|
51
|
+
define :HOME, 1
|
52
|
+
define :WORK, 2
|
53
|
+
end
|
54
|
+
class PhoneNumber < ::Protobuf::Message
|
55
|
+
defined_in __FILE__
|
56
|
+
required :string, :number, 1
|
57
|
+
optional :PhoneType, :type, 2, :default => :HOME
|
58
|
+
end
|
59
|
+
repeated :PhoneNumber, :phone, 4
|
60
|
+
optional :uint32, :age, 5, :default => 20
|
61
|
+
extensions 100..200
|
62
|
+
end
|
63
|
+
class AddressBook < ::Protobuf::Message
|
64
|
+
defined_in __FILE__
|
65
|
+
repeated :Person, :person, 1
|
66
|
+
end
|
67
|
+
end
|