google-protobuf 3.19.1 → 4.30.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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/Rakefile +3 -0
- data/ext/google/protobuf_c/convert.c +153 -166
- data/ext/google/protobuf_c/convert.h +15 -37
- data/ext/google/protobuf_c/defs.c +867 -251
- data/ext/google/protobuf_c/defs.h +22 -47
- data/ext/google/protobuf_c/extconf.rb +25 -5
- data/ext/google/protobuf_c/glue.c +135 -0
- data/ext/google/protobuf_c/map.c +182 -145
- data/ext/google/protobuf_c/map.h +16 -35
- data/ext/google/protobuf_c/message.c +534 -437
- data/ext/google/protobuf_c/message.h +30 -49
- data/ext/google/protobuf_c/protobuf.c +125 -238
- data/ext/google/protobuf_c/protobuf.h +40 -49
- data/ext/google/protobuf_c/repeated_field.c +152 -120
- data/ext/google/protobuf_c/repeated_field.h +16 -34
- data/ext/google/protobuf_c/ruby-upb.c +15827 -7228
- data/ext/google/protobuf_c/ruby-upb.h +15075 -3866
- data/ext/google/protobuf_c/shared_convert.c +69 -0
- data/ext/google/protobuf_c/shared_convert.h +26 -0
- data/ext/google/protobuf_c/shared_message.c +37 -0
- data/ext/google/protobuf_c/shared_message.h +21 -0
- data/ext/google/protobuf_c/third_party/utf8_range/LICENSE +22 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.c +207 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +22 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_neon.inc +117 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range_sse.inc +272 -0
- data/ext/google/protobuf_c/wrap_memcpy.c +7 -29
- data/lib/google/protobuf/any_pb.rb +6 -8
- data/lib/google/protobuf/api_pb.rb +6 -26
- data/lib/google/protobuf/descriptor_pb.rb +24 -225
- data/lib/google/protobuf/duration_pb.rb +6 -8
- data/lib/google/protobuf/empty_pb.rb +6 -6
- data/lib/google/protobuf/ffi/descriptor.rb +175 -0
- data/lib/google/protobuf/ffi/descriptor_pool.rb +77 -0
- data/lib/google/protobuf/ffi/enum_descriptor.rb +183 -0
- data/lib/google/protobuf/ffi/ffi.rb +214 -0
- data/lib/google/protobuf/ffi/field_descriptor.rb +340 -0
- data/lib/google/protobuf/ffi/file_descriptor.rb +59 -0
- data/lib/google/protobuf/ffi/internal/arena.rb +60 -0
- data/lib/google/protobuf/ffi/internal/convert.rb +292 -0
- data/lib/google/protobuf/ffi/internal/pointer_helper.rb +35 -0
- data/lib/google/protobuf/ffi/internal/type_safety.rb +25 -0
- data/lib/google/protobuf/ffi/map.rb +433 -0
- data/lib/google/protobuf/ffi/message.rb +783 -0
- data/lib/google/protobuf/ffi/method_descriptor.rb +124 -0
- data/lib/google/protobuf/ffi/object_cache.rb +30 -0
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +107 -0
- data/lib/google/protobuf/ffi/repeated_field.rb +411 -0
- data/lib/google/protobuf/ffi/service_descriptor.rb +117 -0
- data/lib/google/protobuf/field_mask_pb.rb +6 -7
- data/lib/google/protobuf/internal/object_cache.rb +99 -0
- data/lib/google/protobuf/message_exts.rb +10 -28
- data/lib/google/protobuf/plugin_pb.rb +25 -0
- data/lib/google/protobuf/repeated_field.rb +22 -33
- data/lib/google/protobuf/source_context_pb.rb +6 -7
- data/lib/google/protobuf/struct_pb.rb +6 -23
- data/lib/google/protobuf/timestamp_pb.rb +6 -8
- data/lib/google/protobuf/type_pb.rb +6 -71
- data/lib/google/protobuf/well_known_types.rb +16 -40
- data/lib/google/protobuf/wrappers_pb.rb +6 -31
- data/lib/google/protobuf.rb +32 -50
- data/lib/google/protobuf_ffi.rb +52 -0
- data/lib/google/protobuf_native.rb +19 -0
- data/lib/google/tasks/ffi.rake +100 -0
- metadata +97 -20
- data/lib/google/protobuf/descriptor_dsl.rb +0 -458
- data/tests/basic.rb +0 -640
- data/tests/generated_code_test.rb +0 -23
- data/tests/stress.rb +0 -38
@@ -1,32 +1,9 @@
|
|
1
1
|
// Protocol Buffers - Google's data interchange format
|
2
2
|
// Copyright 2014 Google Inc. All rights reserved.
|
3
|
-
// https://developers.google.com/protocol-buffers/
|
4
3
|
//
|
5
|
-
//
|
6
|
-
//
|
7
|
-
//
|
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.
|
4
|
+
// Use of this source code is governed by a BSD-style
|
5
|
+
// license that can be found in the LICENSE file or at
|
6
|
+
// https://developers.google.com/open-source/licenses/bsd
|
30
7
|
|
31
8
|
#include "repeated_field.h"
|
32
9
|
|
@@ -40,10 +17,10 @@
|
|
40
17
|
// -----------------------------------------------------------------------------
|
41
18
|
|
42
19
|
typedef struct {
|
43
|
-
const
|
20
|
+
const upb_Array* array; // Can get as mutable when non-frozen.
|
44
21
|
TypeInfo type_info;
|
45
22
|
VALUE type_class; // To GC-root the msgdef/enumdef in type_info.
|
46
|
-
VALUE arena; // To GC-root the
|
23
|
+
VALUE arena; // To GC-root the upb_Array.
|
47
24
|
} RepeatedField;
|
48
25
|
|
49
26
|
VALUE cRepeatedField;
|
@@ -55,9 +32,9 @@ static void RepeatedField_mark(void* _self) {
|
|
55
32
|
}
|
56
33
|
|
57
34
|
const rb_data_type_t RepeatedField_type = {
|
58
|
-
|
59
|
-
|
60
|
-
|
35
|
+
"Google::Protobuf::RepeatedField",
|
36
|
+
{RepeatedField_mark, RUBY_DEFAULT_FREE, NULL},
|
37
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
61
38
|
};
|
62
39
|
|
63
40
|
static RepeatedField* ruby_to_RepeatedField(VALUE _self) {
|
@@ -66,9 +43,10 @@ static RepeatedField* ruby_to_RepeatedField(VALUE _self) {
|
|
66
43
|
return self;
|
67
44
|
}
|
68
45
|
|
69
|
-
static
|
70
|
-
|
71
|
-
|
46
|
+
static upb_Array* RepeatedField_GetMutable(VALUE _self) {
|
47
|
+
const upb_Array* array = ruby_to_RepeatedField(_self)->array;
|
48
|
+
Protobuf_CheckNotFrozen(_self, upb_Array_IsFrozen(array));
|
49
|
+
return (upb_Array*)array;
|
72
50
|
}
|
73
51
|
|
74
52
|
VALUE RepeatedField_alloc(VALUE klass) {
|
@@ -79,50 +57,74 @@ VALUE RepeatedField_alloc(VALUE klass) {
|
|
79
57
|
return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
|
80
58
|
}
|
81
59
|
|
82
|
-
VALUE
|
60
|
+
VALUE RepeatedField_EmptyFrozen(const upb_FieldDef* f) {
|
61
|
+
PBRUBY_ASSERT(upb_FieldDef_IsRepeated(f));
|
62
|
+
VALUE val = ObjectCache_Get(f);
|
63
|
+
|
64
|
+
if (val == Qnil) {
|
65
|
+
val = RepeatedField_alloc(cRepeatedField);
|
66
|
+
RepeatedField* self;
|
67
|
+
TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self);
|
68
|
+
self->arena = Arena_new();
|
69
|
+
TypeInfo type_info = TypeInfo_get(f);
|
70
|
+
self->array = upb_Array_New(Arena_get(self->arena), type_info.type);
|
71
|
+
self->type_info = type_info;
|
72
|
+
if (self->type_info.type == kUpb_CType_Message) {
|
73
|
+
self->type_class = Descriptor_DefToClass(type_info.def.msgdef);
|
74
|
+
}
|
75
|
+
val = ObjectCache_TryAdd(f, RepeatedField_freeze(val));
|
76
|
+
}
|
77
|
+
PBRUBY_ASSERT(RB_OBJ_FROZEN(val));
|
78
|
+
PBRUBY_ASSERT(upb_Array_IsFrozen(ruby_to_RepeatedField(val)->array));
|
79
|
+
return val;
|
80
|
+
}
|
81
|
+
|
82
|
+
VALUE RepeatedField_GetRubyWrapper(const upb_Array* array, TypeInfo type_info,
|
83
83
|
VALUE arena) {
|
84
84
|
PBRUBY_ASSERT(array);
|
85
|
+
PBRUBY_ASSERT(arena != Qnil);
|
85
86
|
VALUE val = ObjectCache_Get(array);
|
86
87
|
|
87
88
|
if (val == Qnil) {
|
88
89
|
val = RepeatedField_alloc(cRepeatedField);
|
89
90
|
RepeatedField* self;
|
90
|
-
ObjectCache_Add(array, val);
|
91
91
|
TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self);
|
92
92
|
self->array = array;
|
93
93
|
self->arena = arena;
|
94
94
|
self->type_info = type_info;
|
95
|
-
if (self->type_info.type ==
|
95
|
+
if (self->type_info.type == kUpb_CType_Message) {
|
96
96
|
self->type_class = Descriptor_DefToClass(type_info.def.msgdef);
|
97
97
|
}
|
98
|
+
val = ObjectCache_TryAdd(array, val);
|
98
99
|
}
|
99
100
|
|
100
101
|
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.type == type_info.type);
|
101
102
|
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.def.msgdef ==
|
102
103
|
type_info.def.msgdef);
|
104
|
+
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->array == array);
|
103
105
|
return val;
|
104
106
|
}
|
105
107
|
|
106
108
|
static VALUE RepeatedField_new_this_type(RepeatedField* from) {
|
107
109
|
VALUE arena_rb = Arena_new();
|
108
|
-
|
110
|
+
upb_Array* array = upb_Array_New(Arena_get(arena_rb), from->type_info.type);
|
109
111
|
VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb);
|
110
112
|
PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class);
|
111
113
|
return ret;
|
112
114
|
}
|
113
115
|
|
114
|
-
void RepeatedField_Inspect(StringBuilder* b, const
|
116
|
+
void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array,
|
115
117
|
TypeInfo info) {
|
116
118
|
bool first = true;
|
117
119
|
StringBuilder_Printf(b, "[");
|
118
|
-
size_t n = array ?
|
120
|
+
size_t n = array ? upb_Array_Size(array) : 0;
|
119
121
|
for (size_t i = 0; i < n; i++) {
|
120
122
|
if (first) {
|
121
123
|
first = false;
|
122
124
|
} else {
|
123
125
|
StringBuilder_Printf(b, ", ");
|
124
126
|
}
|
125
|
-
StringBuilder_PrintMsgval(b,
|
127
|
+
StringBuilder_PrintMsgval(b, upb_Array_Get(array, i), info);
|
126
128
|
}
|
127
129
|
StringBuilder_Printf(b, "]");
|
128
130
|
}
|
@@ -132,24 +134,24 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
|
|
132
134
|
VALUE new_rptfield = RepeatedField_new_this_type(self);
|
133
135
|
RepeatedField* new_self = ruby_to_RepeatedField(new_rptfield);
|
134
136
|
VALUE arena_rb = new_self->arena;
|
135
|
-
|
136
|
-
|
137
|
-
size_t elements =
|
137
|
+
upb_Array* new_array = RepeatedField_GetMutable(new_rptfield);
|
138
|
+
upb_Arena* arena = Arena_get(arena_rb);
|
139
|
+
size_t elements = upb_Array_Size(self->array);
|
138
140
|
|
139
|
-
|
141
|
+
upb_Array_Resize(new_array, elements, arena);
|
140
142
|
|
141
|
-
size_t size =
|
143
|
+
size_t size = upb_Array_Size(self->array);
|
142
144
|
for (size_t i = 0; i < size; i++) {
|
143
|
-
|
144
|
-
|
145
|
-
|
145
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
146
|
+
upb_MessageValue copy = Msgval_DeepCopy(msgval, self->type_info, arena);
|
147
|
+
upb_Array_Set(new_array, i, copy);
|
146
148
|
}
|
147
149
|
|
148
150
|
return new_rptfield;
|
149
151
|
}
|
150
152
|
|
151
|
-
const
|
152
|
-
|
153
|
+
const upb_Array* RepeatedField_GetUpbArray(VALUE val, const upb_FieldDef* field,
|
154
|
+
upb_Arena* arena) {
|
153
155
|
RepeatedField* self;
|
154
156
|
TypeInfo type_info = TypeInfo_get(field);
|
155
157
|
|
@@ -173,17 +175,17 @@ const upb_array* RepeatedField_GetUpbArray(VALUE val, const upb_fielddef* field,
|
|
173
175
|
|
174
176
|
static int index_position(VALUE _index, RepeatedField* repeated_field) {
|
175
177
|
int index = NUM2INT(_index);
|
176
|
-
if (index < 0) index +=
|
178
|
+
if (index < 0) index += upb_Array_Size(repeated_field->array);
|
177
179
|
return index;
|
178
180
|
}
|
179
181
|
|
180
182
|
static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) {
|
181
|
-
size_t size =
|
183
|
+
size_t size = upb_Array_Size(self->array);
|
182
184
|
VALUE ary = rb_ary_new2(size);
|
183
185
|
long i;
|
184
186
|
|
185
187
|
for (i = beg; i < beg + len; i++) {
|
186
|
-
|
188
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
187
189
|
VALUE elem = Convert_UpbToRuby(msgval, self->type_info, self->arena);
|
188
190
|
rb_ary_push(ary, elem);
|
189
191
|
}
|
@@ -200,18 +202,17 @@ static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) {
|
|
200
202
|
*/
|
201
203
|
static VALUE RepeatedField_each(VALUE _self) {
|
202
204
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
203
|
-
int size =
|
205
|
+
int size = upb_Array_Size(self->array);
|
204
206
|
int i;
|
205
207
|
|
206
208
|
for (i = 0; i < size; i++) {
|
207
|
-
|
209
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
208
210
|
VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
|
209
211
|
rb_yield(val);
|
210
212
|
}
|
211
213
|
return _self;
|
212
214
|
}
|
213
215
|
|
214
|
-
|
215
216
|
/*
|
216
217
|
* call-seq:
|
217
218
|
* RepeatedField.[](index) => value
|
@@ -220,20 +221,20 @@ static VALUE RepeatedField_each(VALUE _self) {
|
|
220
221
|
*/
|
221
222
|
static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
|
222
223
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
223
|
-
long size =
|
224
|
+
long size = upb_Array_Size(self->array);
|
224
225
|
|
225
226
|
VALUE arg = argv[0];
|
226
227
|
long beg, len;
|
227
228
|
|
228
|
-
if (argc == 1){
|
229
|
+
if (argc == 1) {
|
229
230
|
if (FIXNUM_P(arg)) {
|
230
231
|
/* standard case */
|
231
|
-
|
232
|
+
upb_MessageValue msgval;
|
232
233
|
int index = index_position(argv[0], self);
|
233
|
-
if (index < 0 || (size_t)index >=
|
234
|
+
if (index < 0 || (size_t)index >= upb_Array_Size(self->array)) {
|
234
235
|
return Qnil;
|
235
236
|
}
|
236
|
-
msgval =
|
237
|
+
msgval = upb_Array_Get(self->array, index);
|
237
238
|
return Convert_UpbToRuby(msgval, self->type_info, self->arena);
|
238
239
|
} else {
|
239
240
|
/* check if idx is Range */
|
@@ -269,10 +270,10 @@ static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
|
|
269
270
|
*/
|
270
271
|
static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
|
271
272
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
272
|
-
int size =
|
273
|
-
|
274
|
-
|
275
|
-
|
273
|
+
int size = upb_Array_Size(self->array);
|
274
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
275
|
+
upb_Arena* arena = Arena_get(self->arena);
|
276
|
+
upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
|
276
277
|
|
277
278
|
int index = index_position(_index, self);
|
278
279
|
if (index < 0 || index >= (INT_MAX - 1)) {
|
@@ -280,17 +281,17 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
|
|
280
281
|
}
|
281
282
|
|
282
283
|
if (index >= size) {
|
283
|
-
|
284
|
-
|
284
|
+
upb_Array_Resize(array, index + 1, arena);
|
285
|
+
upb_MessageValue fill;
|
285
286
|
memset(&fill, 0, sizeof(fill));
|
286
287
|
for (int i = size; i < index; i++) {
|
287
288
|
// Fill default values.
|
288
|
-
// TODO
|
289
|
-
|
289
|
+
// TODO: should this happen at the upb level?
|
290
|
+
upb_Array_Set(array, i, fill);
|
290
291
|
}
|
291
292
|
}
|
292
293
|
|
293
|
-
|
294
|
+
upb_Array_Set(array, index, msgval);
|
294
295
|
return Qnil;
|
295
296
|
}
|
296
297
|
|
@@ -302,13 +303,14 @@ static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
|
|
302
303
|
*/
|
303
304
|
static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
|
304
305
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
305
|
-
|
306
|
-
|
306
|
+
upb_Arena* arena = Arena_get(self->arena);
|
307
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
307
308
|
int i;
|
308
309
|
|
309
310
|
for (i = 0; i < argc; i++) {
|
310
|
-
|
311
|
-
|
311
|
+
upb_MessageValue msgval =
|
312
|
+
Convert_RubyToUpb(argv[i], "", self->type_info, arena);
|
313
|
+
upb_Array_Append(array, msgval, arena);
|
312
314
|
}
|
313
315
|
|
314
316
|
return _self;
|
@@ -322,11 +324,11 @@ static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
|
|
322
324
|
*/
|
323
325
|
static VALUE RepeatedField_push(VALUE _self, VALUE val) {
|
324
326
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
325
|
-
|
326
|
-
|
327
|
+
upb_Arena* arena = Arena_get(self->arena);
|
328
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
327
329
|
|
328
|
-
|
329
|
-
|
330
|
+
upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
|
331
|
+
upb_Array_Append(array, msgval, arena);
|
330
332
|
|
331
333
|
return _self;
|
332
334
|
}
|
@@ -336,19 +338,19 @@ static VALUE RepeatedField_push(VALUE _self, VALUE val) {
|
|
336
338
|
*/
|
337
339
|
static VALUE RepeatedField_pop_one(VALUE _self) {
|
338
340
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
339
|
-
size_t size =
|
340
|
-
|
341
|
-
|
341
|
+
size_t size = upb_Array_Size(self->array);
|
342
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
343
|
+
upb_MessageValue last;
|
342
344
|
VALUE ret;
|
343
345
|
|
344
346
|
if (size == 0) {
|
345
347
|
return Qnil;
|
346
348
|
}
|
347
349
|
|
348
|
-
last =
|
350
|
+
last = upb_Array_Get(self->array, size - 1);
|
349
351
|
ret = Convert_UpbToRuby(last, self->type_info, self->arena);
|
350
352
|
|
351
|
-
|
353
|
+
upb_Array_Resize(array, size - 1, Arena_get(self->arena));
|
352
354
|
return ret;
|
353
355
|
}
|
354
356
|
|
@@ -360,11 +362,11 @@ static VALUE RepeatedField_pop_one(VALUE _self) {
|
|
360
362
|
*/
|
361
363
|
static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
|
362
364
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
363
|
-
|
365
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
364
366
|
int i;
|
365
367
|
|
366
368
|
Check_Type(list, T_ARRAY);
|
367
|
-
|
369
|
+
upb_Array_Resize(array, 0, Arena_get(self->arena));
|
368
370
|
|
369
371
|
for (i = 0; i < RARRAY_LEN(list); i++) {
|
370
372
|
RepeatedField_push(_self, rb_ary_entry(list, i));
|
@@ -381,8 +383,8 @@ static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
|
|
381
383
|
*/
|
382
384
|
static VALUE RepeatedField_clear(VALUE _self) {
|
383
385
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
384
|
-
|
385
|
-
|
386
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
387
|
+
upb_Array_Resize(array, 0, Arena_get(self->arena));
|
386
388
|
return _self;
|
387
389
|
}
|
388
390
|
|
@@ -394,7 +396,7 @@ static VALUE RepeatedField_clear(VALUE _self) {
|
|
394
396
|
*/
|
395
397
|
static VALUE RepeatedField_length(VALUE _self) {
|
396
398
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
397
|
-
return INT2NUM(
|
399
|
+
return INT2NUM(upb_Array_Size(self->array));
|
398
400
|
}
|
399
401
|
|
400
402
|
/*
|
@@ -408,16 +410,16 @@ static VALUE RepeatedField_dup(VALUE _self) {
|
|
408
410
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
409
411
|
VALUE new_rptfield = RepeatedField_new_this_type(self);
|
410
412
|
RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
|
411
|
-
|
412
|
-
|
413
|
-
int size =
|
413
|
+
upb_Array* new_array = RepeatedField_GetMutable(new_rptfield);
|
414
|
+
upb_Arena* arena = Arena_get(new_rptfield_self->arena);
|
415
|
+
int size = upb_Array_Size(self->array);
|
414
416
|
int i;
|
415
417
|
|
416
418
|
Arena_fuse(self->arena, arena);
|
417
419
|
|
418
420
|
for (i = 0; i < size; i++) {
|
419
|
-
|
420
|
-
|
421
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
422
|
+
upb_Array_Append(new_array, msgval, arena);
|
421
423
|
}
|
422
424
|
|
423
425
|
return new_rptfield;
|
@@ -432,12 +434,12 @@ static VALUE RepeatedField_dup(VALUE _self) {
|
|
432
434
|
*/
|
433
435
|
VALUE RepeatedField_to_ary(VALUE _self) {
|
434
436
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
435
|
-
int size =
|
437
|
+
int size = upb_Array_Size(self->array);
|
436
438
|
VALUE ary = rb_ary_new2(size);
|
437
439
|
int i;
|
438
440
|
|
439
441
|
for (i = 0; i < size; i++) {
|
440
|
-
|
442
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
441
443
|
VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
|
442
444
|
rb_ary_push(ary, val);
|
443
445
|
}
|
@@ -473,17 +475,17 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
|
|
473
475
|
|
474
476
|
self = ruby_to_RepeatedField(_self);
|
475
477
|
other = ruby_to_RepeatedField(_other);
|
476
|
-
size_t n =
|
478
|
+
size_t n = upb_Array_Size(self->array);
|
477
479
|
|
478
480
|
if (self->type_info.type != other->type_info.type ||
|
479
481
|
self->type_class != other->type_class ||
|
480
|
-
|
482
|
+
upb_Array_Size(other->array) != n) {
|
481
483
|
return Qfalse;
|
482
484
|
}
|
483
485
|
|
484
486
|
for (size_t i = 0; i < n; i++) {
|
485
|
-
|
486
|
-
|
487
|
+
upb_MessageValue val1 = upb_Array_Get(self->array, i);
|
488
|
+
upb_MessageValue val2 = upb_Array_Get(other->array, i);
|
487
489
|
if (!Msgval_IsEqual(val1, val2, self->type_info)) {
|
488
490
|
return Qfalse;
|
489
491
|
}
|
@@ -492,19 +494,49 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
|
|
492
494
|
return Qtrue;
|
493
495
|
}
|
494
496
|
|
497
|
+
/*
|
498
|
+
* call-seq:
|
499
|
+
* RepeatedField.frozen? => bool
|
500
|
+
*
|
501
|
+
* Returns true if the repeated field is frozen in either Ruby or the underlying
|
502
|
+
* representation. Freezes the Ruby repeated field object if it is not already
|
503
|
+
* frozen in Ruby but it is frozen in the underlying representation.
|
504
|
+
*/
|
505
|
+
VALUE RepeatedField_frozen(VALUE _self) {
|
506
|
+
RepeatedField* self = ruby_to_RepeatedField(_self);
|
507
|
+
if (!upb_Array_IsFrozen(self->array)) {
|
508
|
+
PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
|
509
|
+
return Qfalse;
|
510
|
+
}
|
511
|
+
|
512
|
+
// Lazily freeze the Ruby wrapper.
|
513
|
+
if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
|
514
|
+
return Qtrue;
|
515
|
+
}
|
516
|
+
|
495
517
|
/*
|
496
518
|
* call-seq:
|
497
519
|
* RepeatedField.freeze => self
|
498
520
|
*
|
499
|
-
* Freezes the repeated field. We have to intercept this so we can
|
500
|
-
*
|
521
|
+
* Freezes the repeated field object. We have to intercept this so we can freeze
|
522
|
+
* the underlying representation, not just the Ruby wrapper.
|
501
523
|
*/
|
502
|
-
|
524
|
+
VALUE RepeatedField_freeze(VALUE _self) {
|
503
525
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
504
|
-
if (
|
505
|
-
|
506
|
-
|
526
|
+
if (RB_OBJ_FROZEN(_self)) {
|
527
|
+
PBRUBY_ASSERT(upb_Array_IsFrozen(self->array));
|
528
|
+
return _self;
|
529
|
+
}
|
530
|
+
|
531
|
+
if (!upb_Array_IsFrozen(self->array)) {
|
532
|
+
if (self->type_info.type == kUpb_CType_Message) {
|
533
|
+
upb_Array_Freeze(RepeatedField_GetMutable(_self),
|
534
|
+
upb_MessageDef_MiniTable(self->type_info.def.msgdef));
|
535
|
+
} else {
|
536
|
+
upb_Array_Freeze(RepeatedField_GetMutable(_self), NULL);
|
537
|
+
}
|
507
538
|
}
|
539
|
+
RB_OBJ_FREEZE(_self);
|
508
540
|
return _self;
|
509
541
|
}
|
510
542
|
|
@@ -517,10 +549,10 @@ static VALUE RepeatedField_freeze(VALUE _self) {
|
|
517
549
|
VALUE RepeatedField_hash(VALUE _self) {
|
518
550
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
519
551
|
uint64_t hash = 0;
|
520
|
-
size_t n =
|
552
|
+
size_t n = upb_Array_Size(self->array);
|
521
553
|
|
522
554
|
for (size_t i = 0; i < n; i++) {
|
523
|
-
|
555
|
+
upb_MessageValue val = upb_Array_Get(self->array, i);
|
524
556
|
hash = Msgval_GetHash(val, self->type_info, hash);
|
525
557
|
}
|
526
558
|
|
@@ -549,10 +581,10 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) {
|
|
549
581
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
550
582
|
RepeatedField* list_rptfield = ruby_to_RepeatedField(list);
|
551
583
|
RepeatedField* dupped = ruby_to_RepeatedField(dupped_);
|
552
|
-
|
553
|
-
|
584
|
+
upb_Array* dupped_array = RepeatedField_GetMutable(dupped_);
|
585
|
+
upb_Arena* arena = Arena_get(dupped->arena);
|
554
586
|
Arena_fuse(list_rptfield->arena, arena);
|
555
|
-
int size =
|
587
|
+
int size = upb_Array_Size(list_rptfield->array);
|
556
588
|
int i;
|
557
589
|
|
558
590
|
if (self->type_info.type != list_rptfield->type_info.type ||
|
@@ -562,8 +594,8 @@ VALUE RepeatedField_plus(VALUE _self, VALUE list) {
|
|
562
594
|
}
|
563
595
|
|
564
596
|
for (i = 0; i < size; i++) {
|
565
|
-
|
566
|
-
|
597
|
+
upb_MessageValue msgval = upb_Array_Get(list_rptfield->array, i);
|
598
|
+
upb_Array_Append(dupped_array, msgval, arena);
|
567
599
|
}
|
568
600
|
} else {
|
569
601
|
rb_raise(rb_eArgError, "Unknown type appending to RepeatedField");
|
@@ -601,7 +633,7 @@ VALUE RepeatedField_concat(VALUE _self, VALUE list) {
|
|
601
633
|
*/
|
602
634
|
VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
|
603
635
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
604
|
-
|
636
|
+
upb_Arena* arena;
|
605
637
|
VALUE ary = Qnil;
|
606
638
|
|
607
639
|
self->arena = Arena_new();
|
@@ -612,8 +644,9 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
|
|
612
644
|
}
|
613
645
|
|
614
646
|
self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary);
|
615
|
-
self->array =
|
616
|
-
|
647
|
+
self->array = upb_Array_New(arena, self->type_info.type);
|
648
|
+
VALUE stored_val = ObjectCache_TryAdd(self->array, _self);
|
649
|
+
PBRUBY_ASSERT(stored_val == _self);
|
617
650
|
|
618
651
|
if (ary != Qnil) {
|
619
652
|
if (!RB_TYPE_P(ary, T_ARRAY)) {
|
@@ -627,14 +660,12 @@ VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
|
|
627
660
|
}
|
628
661
|
|
629
662
|
void RepeatedField_register(VALUE module) {
|
630
|
-
VALUE klass = rb_define_class_under(
|
631
|
-
module, "RepeatedField", rb_cObject);
|
663
|
+
VALUE klass = rb_define_class_under(module, "RepeatedField", rb_cObject);
|
632
664
|
rb_define_alloc_func(klass, RepeatedField_alloc);
|
633
665
|
rb_gc_register_address(&cRepeatedField);
|
634
666
|
cRepeatedField = klass;
|
635
667
|
|
636
|
-
rb_define_method(klass, "initialize",
|
637
|
-
RepeatedField_init, -1);
|
668
|
+
rb_define_method(klass, "initialize", RepeatedField_init, -1);
|
638
669
|
rb_define_method(klass, "each", RepeatedField_each, 0);
|
639
670
|
rb_define_method(klass, "[]", RepeatedField_index, -1);
|
640
671
|
rb_define_method(klass, "at", RepeatedField_index, -1);
|
@@ -652,6 +683,7 @@ void RepeatedField_register(VALUE module) {
|
|
652
683
|
rb_define_method(klass, "==", RepeatedField_eq, 1);
|
653
684
|
rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0);
|
654
685
|
rb_define_method(klass, "freeze", RepeatedField_freeze, 0);
|
686
|
+
rb_define_method(klass, "frozen?", RepeatedField_frozen, 0);
|
655
687
|
rb_define_method(klass, "hash", RepeatedField_hash, 0);
|
656
688
|
rb_define_method(klass, "+", RepeatedField_plus, 1);
|
657
689
|
rb_define_method(klass, "concat", RepeatedField_concat, 1);
|
@@ -1,54 +1,33 @@
|
|
1
1
|
// Protocol Buffers - Google's data interchange format
|
2
2
|
// Copyright 2008 Google Inc. All rights reserved.
|
3
|
-
// https://developers.google.com/protocol-buffers/
|
4
3
|
//
|
5
|
-
//
|
6
|
-
//
|
7
|
-
//
|
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.
|
4
|
+
// Use of this source code is governed by a BSD-style
|
5
|
+
// license that can be found in the LICENSE file or at
|
6
|
+
// https://developers.google.com/open-source/licenses/bsd
|
30
7
|
|
31
8
|
#ifndef RUBY_PROTOBUF_REPEATED_FIELD_H_
|
32
9
|
#define RUBY_PROTOBUF_REPEATED_FIELD_H_
|
33
10
|
|
34
|
-
#include <ruby/ruby.h>
|
35
|
-
|
36
11
|
#include "protobuf.h"
|
37
12
|
#include "ruby-upb.h"
|
38
13
|
|
39
|
-
// Returns a Ruby wrapper object for
|
14
|
+
// Returns a frozen sentinel Ruby wrapper object for an empty upb_Array of the
|
15
|
+
// type specified by the field. Creates one if it doesn't exist.
|
16
|
+
VALUE RepeatedField_EmptyFrozen(const upb_FieldDef* f);
|
17
|
+
|
18
|
+
// Returns a Ruby wrapper object for the given upb_Array, which will be created
|
40
19
|
// if one does not exist already.
|
41
|
-
VALUE RepeatedField_GetRubyWrapper(
|
20
|
+
VALUE RepeatedField_GetRubyWrapper(const upb_Array* msg, TypeInfo type_info,
|
42
21
|
VALUE arena);
|
43
22
|
|
44
|
-
// Gets the underlying
|
23
|
+
// Gets the underlying upb_Array for this Ruby RepeatedField object, which must
|
45
24
|
// have a type that matches |f|. If this is not a repeated field or the type
|
46
25
|
// doesn't match, raises an exception.
|
47
|
-
const
|
48
|
-
|
26
|
+
const upb_Array* RepeatedField_GetUpbArray(VALUE value, const upb_FieldDef* f,
|
27
|
+
upb_Arena* arena);
|
49
28
|
|
50
29
|
// Implements #inspect for this repeated field by appending its contents to |b|.
|
51
|
-
void RepeatedField_Inspect(StringBuilder* b, const
|
30
|
+
void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array,
|
52
31
|
TypeInfo info);
|
53
32
|
|
54
33
|
// Returns a deep copy of this RepeatedField object.
|
@@ -60,4 +39,7 @@ extern VALUE cRepeatedField;
|
|
60
39
|
// Call at startup to register all types in this module.
|
61
40
|
void RepeatedField_register(VALUE module);
|
62
41
|
|
42
|
+
// Recursively freeze RepeatedField.
|
43
|
+
VALUE RepeatedField_freeze(VALUE _self);
|
44
|
+
|
63
45
|
#endif // RUBY_PROTOBUF_REPEATED_FIELD_H_
|