google-protobuf 3.0.0.alpha.3.1.pre → 3.0.0.alpha.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

@@ -28,9 +28,45 @@
28
28
  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
29
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
 
31
+ # require mixins before we hook them into the java & c code
32
+ require 'google/protobuf/message_exts'
33
+
34
+ # We define these before requiring the platform-specific modules.
35
+ # That way the module init can grab references to these.
36
+ module Google
37
+ module Protobuf
38
+ class Error < StandardError; end
39
+ class ParseError < Error; end
40
+ end
41
+ end
42
+
31
43
  if RUBY_PLATFORM == "java"
32
44
  require 'json'
33
45
  require 'google/protobuf_java'
34
46
  else
35
47
  require 'google/protobuf_c'
36
48
  end
49
+
50
+ require 'google/protobuf/repeated_field'
51
+
52
+ module Google
53
+ module Protobuf
54
+
55
+ def self.encode(msg)
56
+ msg.to_proto
57
+ end
58
+
59
+ def self.encode_json(msg)
60
+ msg.to_json
61
+ end
62
+
63
+ def self.decode(klass, proto)
64
+ klass.decode(proto)
65
+ end
66
+
67
+ def self.decode_json(klass, json)
68
+ klass.decode_json(json)
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,53 @@
1
+ # Protocol Buffers - Google's data interchange format
2
+ # Copyright 2008 Google Inc. All rights reserved.
3
+ # https://developers.google.com/protocol-buffers/
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following disclaimer
13
+ # in the documentation and/or other materials provided with the
14
+ # distribution.
15
+ # * Neither the name of Google Inc. nor the names of its
16
+ # contributors may be used to endorse or promote products derived from
17
+ # this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ module Google
32
+ module Protobuf
33
+ module MessageExts
34
+
35
+ #this is only called in jruby; mri loades the ClassMethods differently
36
+ def self.included(klass)
37
+ klass.extend(ClassMethods)
38
+ end
39
+
40
+ module ClassMethods
41
+ end
42
+
43
+ def to_json
44
+ self.class.encode_json(self)
45
+ end
46
+
47
+ def to_proto
48
+ self.class.encode(self)
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,188 @@
1
+ # Protocol Buffers - Google's data interchange format
2
+ # Copyright 2008 Google Inc. All rights reserved.
3
+ # https://developers.google.com/protocol-buffers/
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following disclaimer
13
+ # in the documentation and/or other materials provided with the
14
+ # distribution.
15
+ # * Neither the name of Google Inc. nor the names of its
16
+ # contributors may be used to endorse or promote products derived from
17
+ # this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ require 'forwardable'
32
+
33
+ #
34
+ # This class makes RepeatedField act (almost-) like a Ruby Array.
35
+ # It has convenience methods that extend the core C or Java based
36
+ # methods.
37
+ #
38
+ # This is a best-effort to mirror Array behavior. Two comments:
39
+ # 1) patches always welcome :)
40
+ # 2) if performance is an issue, feel free to rewrite the method
41
+ # in jruby and C. The source code has plenty of examples
42
+ #
43
+ # KNOWN ISSUES
44
+ # - #[]= doesn't allow less used approaches such as `arr[1, 2] = 'fizz'`
45
+ # - #concat should return the orig array
46
+ # - #push should accept multiple arguments and push them all at the same time
47
+ #
48
+ module Google
49
+ module Protobuf
50
+ class RepeatedField
51
+ extend Forwardable
52
+
53
+ # methods defined in C or Java:
54
+ # +
55
+ # [], at
56
+ # []=
57
+ # concat
58
+ # clear
59
+ # dup, clone
60
+ # each
61
+ # push, <<
62
+ # replace
63
+ # length, size
64
+ # ==
65
+ # to_ary, to_a
66
+ # also all enumerable
67
+ #
68
+ # NOTE: using delegators rather than method_missing to make the
69
+ # relationship explicit instead of implicit
70
+ def_delegators :to_ary,
71
+ :&, :*, :-, :'<=>',
72
+ :assoc, :bsearch, :combination, :compact, :count, :cycle,
73
+ :drop, :drop_while, :eql?, :fetch, :find_index, :flatten,
74
+ :include?, :index, :inspect, :join,
75
+ :pack, :permutation, :product, :pretty_print, :pretty_print_cycle,
76
+ :rassoc, :repeated_combination, :repeated_permutation, :reverse,
77
+ :rindex, :rotate, :sample, :shuffle, :shelljoin, :slice,
78
+ :to_s, :transpose, :uniq, :|
79
+
80
+
81
+ def first(n=nil)
82
+ n ? self[0..n] : self[0]
83
+ end
84
+
85
+
86
+ def last(n=nil)
87
+ n ? self[(self.size-n-1)..-1] : self[-1]
88
+ end
89
+
90
+
91
+ def pop(n=nil)
92
+ if n
93
+ results = []
94
+ n.times{ results << pop_one }
95
+ return results
96
+ else
97
+ return pop_one
98
+ end
99
+ end
100
+
101
+
102
+ def empty?
103
+ self.size == 0
104
+ end
105
+
106
+ # array aliases into enumerable
107
+ alias_method :each_index, :each_with_index
108
+ alias_method :slice, :[]
109
+ alias_method :values_at, :select
110
+ alias_method :map, :collect
111
+
112
+
113
+ class << self
114
+ def define_array_wrapper_method(method_name)
115
+ define_method(method_name) do |*args, &block|
116
+ arr = self.to_a
117
+ result = arr.send(method_name, *args)
118
+ self.replace(arr)
119
+ return result if result
120
+ return block ? block.call : result
121
+ end
122
+ end
123
+ private :define_array_wrapper_method
124
+
125
+
126
+ def define_array_wrapper_with_result_method(method_name)
127
+ define_method(method_name) do |*args, &block|
128
+ # result can be an Enumerator, Array, or nil
129
+ # Enumerator can sometimes be returned if a block is an optional argument and it is not passed in
130
+ # nil usually specifies that no change was made
131
+ result = self.to_a.send(method_name, *args, &block)
132
+ if result
133
+ new_arr = result.to_a
134
+ self.replace(new_arr)
135
+ if result.is_a?(Enumerator)
136
+ # generate a fresh enum; rewinding the exiting one, in Ruby 2.2, will
137
+ # reset the enum with the same length, but all the #next calls will
138
+ # return nil
139
+ result = new_arr.to_enum
140
+ # generate a wrapper enum so any changes which occur by a chained
141
+ # enum can be captured
142
+ ie = ProxyingEnumerator.new(self, result)
143
+ result = ie.to_enum
144
+ end
145
+ end
146
+ result
147
+ end
148
+ end
149
+ private :define_array_wrapper_with_result_method
150
+ end
151
+
152
+
153
+ %w(delete delete_at delete_if shift slice! unshift).each do |method_name|
154
+ define_array_wrapper_method(method_name)
155
+ end
156
+
157
+
158
+ %w(collect! compact! fill flatten! insert reverse!
159
+ rotate! select! shuffle! sort! sort_by! uniq!).each do |method_name|
160
+ define_array_wrapper_with_result_method(method_name)
161
+ end
162
+ alias_method :keep_if, :select!
163
+ alias_method :map!, :collect!
164
+ alias_method :reject!, :delete_if
165
+
166
+
167
+ # propagates changes made by user of enumerator back to the original repeated field.
168
+ # This only applies in cases where the calling function which created the enumerator,
169
+ # such as #sort!, modifies itself rather than a new array, such as #sort
170
+ class ProxyingEnumerator < Struct.new(:repeated_field, :external_enumerator)
171
+ def each(*args, &block)
172
+ results = []
173
+ external_enumerator.each_with_index do |val, i|
174
+ result = yield(val)
175
+ results << result
176
+ #nil means no change occured from yield; usually occurs when #to_a is called
177
+ if result
178
+ repeated_field[i] = result if result != val
179
+ end
180
+ end
181
+ results
182
+ end
183
+ end
184
+
185
+
186
+ end
187
+ end
188
+ end
@@ -154,6 +154,8 @@ module BasicTest
154
154
  assert m.optional_bytes == "world"
155
155
  m.optional_msg = TestMessage2.new(:foo => 42)
156
156
  assert m.optional_msg == TestMessage2.new(:foo => 42)
157
+ m.optional_msg = nil
158
+ assert m.optional_msg == nil
157
159
  end
158
160
 
159
161
  def test_ctor_args
@@ -176,7 +178,7 @@ module BasicTest
176
178
  :optional_msg => TestMessage2.new,
177
179
  :repeated_string => ["hello", "there", "world"])
178
180
  expected = '<BasicTest::TestMessage: optional_int32: -42, optional_int64: 0, optional_uint32: 0, optional_uint64: 0, optional_bool: false, optional_float: 0.0, optional_double: 0.0, optional_string: "", optional_bytes: "", optional_msg: <BasicTest::TestMessage2: foo: 0>, optional_enum: :A, repeated_int32: [], repeated_int64: [], repeated_uint32: [], repeated_uint64: [], repeated_bool: [], repeated_float: [], repeated_double: [], repeated_string: ["hello", "there", "world"], repeated_bytes: [], repeated_msg: [], repeated_enum: []>'
179
- assert m.inspect == expected
181
+ assert_equal expected, m.inspect
180
182
  end
181
183
 
182
184
  def test_hash
@@ -274,7 +276,7 @@ module BasicTest
274
276
 
275
277
  assert l.inspect == '[5, 2, 3, 4]'
276
278
 
277
- l.insert(7, 8, 9)
279
+ l.concat([7, 8, 9])
278
280
  assert l == [5, 2, 3, 4, 7, 8, 9]
279
281
  assert l.pop == 9
280
282
  assert l == [5, 2, 3, 4, 7, 8]
@@ -314,6 +316,17 @@ module BasicTest
314
316
  assert l4 == [0, 0, 0, 0, 0, 42, 100, 101, 102]
315
317
  end
316
318
 
319
+ def test_parent_rptfield
320
+ #make sure we set the RepeatedField and can add to it
321
+ m = TestMessage.new
322
+ assert m.repeated_string == []
323
+ m.repeated_string << 'ok'
324
+ m.repeated_string.push('ok2')
325
+ assert m.repeated_string == ['ok', 'ok2']
326
+ m.repeated_string += ['ok3']
327
+ assert m.repeated_string == ['ok', 'ok2', 'ok3']
328
+ end
329
+
317
330
  def test_rptfield_msg
318
331
  l = Google::Protobuf::RepeatedField.new(:message, TestMessage)
319
332
  l.push TestMessage.new
@@ -377,6 +390,39 @@ module BasicTest
377
390
  end
378
391
  end
379
392
 
393
+ def test_rptfield_array_ducktyping
394
+ l = Google::Protobuf::RepeatedField.new(:int32)
395
+ length_methods = %w(count length size)
396
+ length_methods.each do |lm|
397
+ assert l.send(lm) == 0
398
+ end
399
+ # out of bounds returns a nil
400
+ assert l[0] == nil
401
+ assert l[1] == nil
402
+ assert l[-1] == nil
403
+ l.push 4
404
+ length_methods.each do |lm|
405
+ assert l.send(lm) == 1
406
+ end
407
+ assert l[0] == 4
408
+ assert l[1] == nil
409
+ assert l[-1] == 4
410
+ assert l[-2] == nil
411
+
412
+ l.push 2
413
+ length_methods.each do |lm|
414
+ assert l.send(lm) == 2
415
+ end
416
+ assert l[0] == 4
417
+ assert l[1] == 2
418
+ assert l[2] == nil
419
+ assert l[-1] == 2
420
+ assert l[-2] == 4
421
+ assert l[-3] == nil
422
+
423
+ #adding out of scope will backfill with empty objects
424
+ end
425
+
380
426
  def test_map_basic
381
427
  # allowed key types:
382
428
  # :int32, :int64, :uint32, :uint64, :bool, :string, :bytes.
@@ -712,9 +758,12 @@ module BasicTest
712
758
  m = TestMessage.new
713
759
  m.optional_string = "hello"
714
760
  m.optional_int32 = 42
715
- m.repeated_msg.push TestMessage2.new(:foo => 100)
716
- m.repeated_msg.push TestMessage2.new(:foo => 200)
717
-
761
+ tm1 = TestMessage2.new(:foo => 100)
762
+ tm2 = TestMessage2.new(:foo => 200)
763
+ m.repeated_msg.push tm1
764
+ assert m.repeated_msg[-1] == tm1
765
+ m.repeated_msg.push tm2
766
+ assert m.repeated_msg[-1] == tm2
718
767
  m2 = m.dup
719
768
  assert m == m2
720
769
  m.optional_int32 += 1
@@ -773,6 +822,67 @@ module BasicTest
773
822
  assert m == m2
774
823
  end
775
824
 
825
+ def test_encode_decode_helpers
826
+ m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
827
+ json = m.to_json
828
+ m2 = TestMessage.decode_json(json)
829
+ assert m2.optional_string == 'foo'
830
+ assert m2.repeated_string == ['bar1', 'bar2']
831
+
832
+ proto = m.to_proto
833
+ m2 = TestMessage.decode(proto)
834
+ assert m2.optional_string == 'foo'
835
+ assert m2.repeated_string == ['bar1', 'bar2']
836
+ end
837
+
838
+ def test_protobuf_encode_decode_helpers
839
+ m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
840
+ encoded_msg = Google::Protobuf.encode(m)
841
+ assert_equal m.to_proto, encoded_msg
842
+
843
+ decoded_msg = Google::Protobuf.decode(TestMessage, encoded_msg)
844
+ assert_equal TestMessage.decode(m.to_proto), decoded_msg
845
+ end
846
+
847
+ def test_protobuf_encode_decode_json_helpers
848
+ m = TestMessage.new(:optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
849
+ encoded_msg = Google::Protobuf.encode_json(m)
850
+ assert_equal m.to_json, encoded_msg
851
+
852
+ decoded_msg = Google::Protobuf.decode_json(TestMessage, encoded_msg)
853
+ assert_equal TestMessage.decode_json(m.to_json), decoded_msg
854
+ end
855
+
856
+ def test_to_h
857
+ m = TestMessage.new(:optional_bool => true, :optional_double => -10.100001, :optional_string => 'foo', :repeated_string => ['bar1', 'bar2'])
858
+ expected_result = {
859
+ :optional_bool=>true,
860
+ :optional_bytes=>"",
861
+ :optional_double=>-10.100001,
862
+ :optional_enum=>:Default,
863
+ :optional_float=>0.0,
864
+ :optional_int32=>0,
865
+ :optional_int64=>0,
866
+ :optional_msg=>nil,
867
+ :optional_string=>"foo",
868
+ :optional_uint32=>0,
869
+ :optional_uint64=>0,
870
+ :repeated_bool=>[],
871
+ :repeated_bytes=>[],
872
+ :repeated_double=>[],
873
+ :repeated_enum=>[],
874
+ :repeated_float=>[],
875
+ :repeated_int32=>[],
876
+ :repeated_int64=>[],
877
+ :repeated_msg=>[],
878
+ :repeated_string=>["bar1", "bar2"],
879
+ :repeated_uint32=>[],
880
+ :repeated_uint64=>[]
881
+ }
882
+ assert_equal expected_result, m.to_h
883
+ end
884
+
885
+
776
886
  def test_def_errors
777
887
  s = Google::Protobuf::DescriptorPool.new
778
888
  assert_raise TypeError do
@@ -827,7 +937,6 @@ module BasicTest
827
937
  assert m['a.b'] == 4
828
938
  end
829
939
 
830
-
831
940
  def test_int_ranges
832
941
  m = TestMessage.new
833
942
 
@@ -933,7 +1042,6 @@ module BasicTest
933
1042
  assert_raise RangeError do
934
1043
  m.optional_uint64 = 1.5
935
1044
  end
936
-
937
1045
  end
938
1046
 
939
1047
  def test_stress_test
@@ -988,7 +1096,8 @@ module BasicTest
988
1096
  end
989
1097
 
990
1098
  def test_json
991
- skip("Unimplemented") if RUBY_PLATFORM == "java"
1099
+ # TODO: Fix JSON in JRuby version.
1100
+ return if RUBY_PLATFORM == "java"
992
1101
  m = TestMessage.new(:optional_int32 => 1234,
993
1102
  :optional_int64 => -0x1_0000_0000,
994
1103
  :optional_uint32 => 0x8000_0000,
@@ -1019,7 +1128,8 @@ module BasicTest
1019
1128
  end
1020
1129
 
1021
1130
  def test_json_maps
1022
- skip("Unimplemented") if RUBY_PLATFORM == "java"
1131
+ # TODO: Fix JSON in JRuby version.
1132
+ return if RUBY_PLATFORM == "java"
1023
1133
  m = MapMessage.new(:map_string_int32 => {"a" => 1})
1024
1134
  expected = '{"map_string_int32":{"a":1},"map_string_msg":{}}'
1025
1135
  assert MapMessage.encode_json(m) == expected