google-protobuf 3.14.0 → 4.31.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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/Rakefile +3 -0
- data/ext/google/protobuf_c/convert.c +335 -0
- data/ext/google/protobuf_c/convert.h +50 -0
- data/ext/google/protobuf_c/defs.c +1174 -1608
- data/ext/google/protobuf_c/defs.h +82 -0
- data/ext/google/protobuf_c/extconf.rb +31 -8
- data/ext/google/protobuf_c/glue.c +135 -0
- data/ext/google/protobuf_c/map.c +380 -485
- data/ext/google/protobuf_c/map.h +48 -0
- data/ext/google/protobuf_c/message.c +1098 -531
- data/ext/google/protobuf_c/message.h +82 -0
- data/ext/google/protobuf_c/protobuf.c +313 -92
- data/ext/google/protobuf_c/protobuf.h +59 -624
- data/ext/google/protobuf_c/repeated_field.c +358 -353
- data/ext/google/protobuf_c/repeated_field.h +45 -0
- data/ext/google/protobuf_c/ruby-upb.c +18305 -0
- data/ext/google/protobuf_c/ruby-upb.h +16315 -0
- 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 +7 -26
- data/lib/google/protobuf/descriptor_pb.rb +70 -0
- 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 +79 -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 +346 -0
- data/lib/google/protobuf/ffi/file_descriptor.rb +85 -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 +36 -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 +14 -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 +7 -71
- data/lib/google/protobuf/well_known_types.rb +17 -36
- data/lib/google/protobuf/wrappers_pb.rb +6 -31
- data/lib/google/protobuf.rb +32 -118
- 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 +107 -38
- data/ext/google/protobuf_c/encode_decode.c +0 -1795
- data/ext/google/protobuf_c/storage.c +0 -1198
- data/ext/google/protobuf_c/upb.c +0 -13817
- data/ext/google/protobuf_c/upb.h +0 -6777
- data/tests/basic.rb +0 -543
- data/tests/generated_code_test.rb +0 -23
- data/tests/stress.rb +0 -38
@@ -1,76 +1,192 @@
|
|
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
|
-
|
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
|
7
|
+
|
8
|
+
#include "repeated_field.h"
|
30
9
|
|
10
|
+
#include "convert.h"
|
11
|
+
#include "defs.h"
|
12
|
+
#include "message.h"
|
31
13
|
#include "protobuf.h"
|
32
14
|
|
33
15
|
// -----------------------------------------------------------------------------
|
34
16
|
// Repeated field container type.
|
35
17
|
// -----------------------------------------------------------------------------
|
36
18
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
19
|
+
typedef struct {
|
20
|
+
const upb_Array* array; // Can get as mutable when non-frozen.
|
21
|
+
TypeInfo type_info;
|
22
|
+
VALUE type_class; // To GC-root the msgdef/enumdef in type_info.
|
23
|
+
VALUE arena; // To GC-root the upb_Array.
|
24
|
+
} RepeatedField;
|
41
25
|
|
42
26
|
VALUE cRepeatedField;
|
43
27
|
|
44
|
-
|
28
|
+
static void RepeatedField_mark(void* _self) {
|
29
|
+
RepeatedField* self = (RepeatedField*)_self;
|
30
|
+
rb_gc_mark(self->type_class);
|
31
|
+
rb_gc_mark(self->arena);
|
32
|
+
}
|
33
|
+
|
34
|
+
const rb_data_type_t RepeatedField_type = {
|
35
|
+
"Google::Protobuf::RepeatedField",
|
36
|
+
{RepeatedField_mark, RUBY_DEFAULT_FREE, NULL},
|
37
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
38
|
+
};
|
39
|
+
|
40
|
+
static RepeatedField* ruby_to_RepeatedField(VALUE _self) {
|
45
41
|
RepeatedField* self;
|
46
42
|
TypedData_Get_Struct(_self, RepeatedField, &RepeatedField_type, self);
|
47
43
|
return self;
|
48
44
|
}
|
49
45
|
|
50
|
-
|
51
|
-
|
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;
|
50
|
+
}
|
51
|
+
|
52
|
+
VALUE RepeatedField_alloc(VALUE klass) {
|
53
|
+
RepeatedField* self = ALLOC(RepeatedField);
|
54
|
+
self->arena = Qnil;
|
55
|
+
self->type_class = Qnil;
|
56
|
+
self->array = NULL;
|
57
|
+
return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
|
58
|
+
}
|
59
|
+
|
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
|
+
VALUE arena) {
|
84
|
+
PBRUBY_ASSERT(array);
|
85
|
+
PBRUBY_ASSERT(arena != Qnil);
|
86
|
+
VALUE val = ObjectCache_Get(array);
|
87
|
+
|
88
|
+
if (val == Qnil) {
|
89
|
+
val = RepeatedField_alloc(cRepeatedField);
|
90
|
+
RepeatedField* self;
|
91
|
+
TypedData_Get_Struct(val, RepeatedField, &RepeatedField_type, self);
|
92
|
+
self->array = array;
|
93
|
+
self->arena = arena;
|
94
|
+
self->type_info = type_info;
|
95
|
+
if (self->type_info.type == kUpb_CType_Message) {
|
96
|
+
self->type_class = Descriptor_DefToClass(type_info.def.msgdef);
|
97
|
+
}
|
98
|
+
val = ObjectCache_TryAdd(array, val);
|
99
|
+
}
|
100
|
+
|
101
|
+
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.type == type_info.type);
|
102
|
+
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->type_info.def.msgdef ==
|
103
|
+
type_info.def.msgdef);
|
104
|
+
PBRUBY_ASSERT(ruby_to_RepeatedField(val)->array == array);
|
105
|
+
return val;
|
106
|
+
}
|
107
|
+
|
108
|
+
static VALUE RepeatedField_new_this_type(RepeatedField* from) {
|
109
|
+
VALUE arena_rb = Arena_new();
|
110
|
+
upb_Array* array = upb_Array_New(Arena_get(arena_rb), from->type_info.type);
|
111
|
+
VALUE ret = RepeatedField_GetRubyWrapper(array, from->type_info, arena_rb);
|
112
|
+
PBRUBY_ASSERT(ruby_to_RepeatedField(ret)->type_class == from->type_class);
|
113
|
+
return ret;
|
114
|
+
}
|
115
|
+
|
116
|
+
void RepeatedField_Inspect(StringBuilder* b, const upb_Array* array,
|
117
|
+
TypeInfo info) {
|
118
|
+
bool first = true;
|
119
|
+
StringBuilder_Printf(b, "[");
|
120
|
+
size_t n = array ? upb_Array_Size(array) : 0;
|
121
|
+
for (size_t i = 0; i < n; i++) {
|
122
|
+
if (first) {
|
123
|
+
first = false;
|
124
|
+
} else {
|
125
|
+
StringBuilder_Printf(b, ", ");
|
126
|
+
}
|
127
|
+
StringBuilder_PrintMsgval(b, upb_Array_Get(array, i), info);
|
128
|
+
}
|
129
|
+
StringBuilder_Printf(b, "]");
|
130
|
+
}
|
131
|
+
|
132
|
+
VALUE RepeatedField_deep_copy(VALUE _self) {
|
133
|
+
RepeatedField* self = ruby_to_RepeatedField(_self);
|
134
|
+
VALUE new_rptfield = RepeatedField_new_this_type(self);
|
135
|
+
RepeatedField* new_self = ruby_to_RepeatedField(new_rptfield);
|
136
|
+
VALUE arena_rb = new_self->arena;
|
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);
|
140
|
+
|
141
|
+
upb_Array_Resize(new_array, elements, arena);
|
142
|
+
|
143
|
+
size_t size = upb_Array_Size(self->array);
|
144
|
+
for (size_t i = 0; i < size; i++) {
|
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);
|
148
|
+
}
|
149
|
+
|
150
|
+
return new_rptfield;
|
151
|
+
}
|
152
|
+
|
153
|
+
const upb_Array* RepeatedField_GetUpbArray(VALUE val, const upb_FieldDef* field,
|
154
|
+
upb_Arena* arena) {
|
155
|
+
RepeatedField* self;
|
156
|
+
TypeInfo type_info = TypeInfo_get(field);
|
157
|
+
|
158
|
+
if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
|
159
|
+
RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
|
160
|
+
rb_raise(cTypeError, "Expected repeated field array");
|
161
|
+
}
|
162
|
+
|
163
|
+
self = ruby_to_RepeatedField(val);
|
164
|
+
if (self->type_info.type != type_info.type) {
|
165
|
+
rb_raise(cTypeError, "Repeated field array has wrong element type");
|
166
|
+
}
|
167
|
+
|
168
|
+
if (self->type_info.def.msgdef != type_info.def.msgdef) {
|
169
|
+
rb_raise(cTypeError, "Repeated field array has wrong message/enum class");
|
170
|
+
}
|
171
|
+
|
172
|
+
Arena_fuse(self->arena, arena);
|
173
|
+
return self->array;
|
52
174
|
}
|
53
175
|
|
54
176
|
static int index_position(VALUE _index, RepeatedField* repeated_field) {
|
55
177
|
int index = NUM2INT(_index);
|
56
|
-
if (index < 0
|
57
|
-
index = repeated_field->size + index;
|
58
|
-
}
|
178
|
+
if (index < 0) index += upb_Array_Size(repeated_field->array);
|
59
179
|
return index;
|
60
180
|
}
|
61
181
|
|
62
|
-
VALUE RepeatedField_subarray(
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
VALUE field_type_class = self->field_type_class;
|
67
|
-
size_t off = beg * element_size;
|
68
|
-
VALUE ary = rb_ary_new2(len);
|
69
|
-
int i;
|
182
|
+
static VALUE RepeatedField_subarray(RepeatedField* self, long beg, long len) {
|
183
|
+
size_t size = upb_Array_Size(self->array);
|
184
|
+
VALUE ary = rb_ary_new2(size);
|
185
|
+
long i;
|
70
186
|
|
71
|
-
for (i = beg; i < beg + len; i
|
72
|
-
|
73
|
-
VALUE elem =
|
187
|
+
for (i = beg; i < beg + len; i++) {
|
188
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
189
|
+
VALUE elem = Convert_UpbToRuby(msgval, self->type_info, self->arena);
|
74
190
|
rb_ary_push(ary, elem);
|
75
191
|
}
|
76
192
|
return ary;
|
@@ -84,70 +200,65 @@ VALUE RepeatedField_subarray(VALUE _self, long beg, long len) {
|
|
84
200
|
* also includes Enumerable; combined with this method, the repeated field thus
|
85
201
|
* acts like an ordinary Ruby sequence.
|
86
202
|
*/
|
87
|
-
VALUE RepeatedField_each(VALUE _self) {
|
203
|
+
static VALUE RepeatedField_each(VALUE _self) {
|
88
204
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
89
|
-
|
90
|
-
VALUE field_type_class = self->field_type_class;
|
91
|
-
int element_size = native_slot_size(field_type);
|
92
|
-
size_t off = 0;
|
205
|
+
int size = upb_Array_Size(self->array);
|
93
206
|
int i;
|
94
207
|
|
95
|
-
for (i = 0; i <
|
96
|
-
|
97
|
-
VALUE val =
|
208
|
+
for (i = 0; i < size; i++) {
|
209
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
210
|
+
VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
|
98
211
|
rb_yield(val);
|
99
212
|
}
|
100
213
|
return _self;
|
101
214
|
}
|
102
215
|
|
103
|
-
|
104
216
|
/*
|
105
217
|
* call-seq:
|
106
218
|
* RepeatedField.[](index) => value
|
107
219
|
*
|
108
220
|
* Accesses the element at the given index. Returns nil on out-of-bounds
|
109
221
|
*/
|
110
|
-
VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
|
222
|
+
static VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
|
111
223
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
112
|
-
|
113
|
-
upb_fieldtype_t field_type = self->field_type;
|
114
|
-
VALUE field_type_class = self->field_type_class;
|
224
|
+
long size = upb_Array_Size(self->array);
|
115
225
|
|
116
226
|
VALUE arg = argv[0];
|
117
227
|
long beg, len;
|
118
228
|
|
119
|
-
if (argc == 1){
|
229
|
+
if (argc == 1) {
|
120
230
|
if (FIXNUM_P(arg)) {
|
121
231
|
/* standard case */
|
122
|
-
|
232
|
+
upb_MessageValue msgval;
|
123
233
|
int index = index_position(argv[0], self);
|
124
|
-
if (index < 0 || index >= self->
|
234
|
+
if (index < 0 || (size_t)index >= upb_Array_Size(self->array)) {
|
125
235
|
return Qnil;
|
126
236
|
}
|
127
|
-
|
128
|
-
return
|
129
|
-
}else{
|
237
|
+
msgval = upb_Array_Get(self->array, index);
|
238
|
+
return Convert_UpbToRuby(msgval, self->type_info, self->arena);
|
239
|
+
} else {
|
130
240
|
/* check if idx is Range */
|
131
|
-
switch (rb_range_beg_len(arg, &beg, &len,
|
241
|
+
switch (rb_range_beg_len(arg, &beg, &len, size, 0)) {
|
132
242
|
case Qfalse:
|
133
243
|
break;
|
134
244
|
case Qnil:
|
135
245
|
return Qnil;
|
136
246
|
default:
|
137
|
-
return RepeatedField_subarray(
|
247
|
+
return RepeatedField_subarray(self, beg, len);
|
138
248
|
}
|
139
249
|
}
|
140
250
|
}
|
251
|
+
|
141
252
|
/* assume 2 arguments */
|
142
253
|
beg = NUM2LONG(argv[0]);
|
143
254
|
len = NUM2LONG(argv[1]);
|
144
255
|
if (beg < 0) {
|
145
|
-
beg +=
|
256
|
+
beg += size;
|
146
257
|
}
|
147
|
-
if (beg >=
|
258
|
+
if (beg >= size) {
|
148
259
|
return Qnil;
|
149
260
|
}
|
150
|
-
return RepeatedField_subarray(
|
261
|
+
return RepeatedField_subarray(self, beg, len);
|
151
262
|
}
|
152
263
|
|
153
264
|
/*
|
@@ -157,128 +268,89 @@ VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
|
|
157
268
|
* Sets the element at the given index. On out-of-bounds assignments, extends
|
158
269
|
* the array and fills the hole (if any) with default values.
|
159
270
|
*/
|
160
|
-
VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
|
271
|
+
static VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
|
161
272
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
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);
|
166
277
|
|
167
278
|
int index = index_position(_index, self);
|
168
279
|
if (index < 0 || index >= (INT_MAX - 1)) {
|
169
280
|
return Qnil;
|
170
281
|
}
|
171
|
-
if (index >= self->size) {
|
172
|
-
upb_fieldtype_t field_type = self->field_type;
|
173
|
-
int element_size = native_slot_size(field_type);
|
174
|
-
int i;
|
175
282
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
283
|
+
if (index >= size) {
|
284
|
+
upb_Array_Resize(array, index + 1, arena);
|
285
|
+
upb_MessageValue fill;
|
286
|
+
memset(&fill, 0, sizeof(fill));
|
287
|
+
for (int i = size; i < index; i++) {
|
288
|
+
// Fill default values.
|
289
|
+
// TODO: should this happen at the upb level?
|
290
|
+
upb_Array_Set(array, i, fill);
|
180
291
|
}
|
181
|
-
self->size = index + 1;
|
182
292
|
}
|
183
293
|
|
184
|
-
|
185
|
-
native_slot_set("", field_type, field_type_class, memory, val);
|
294
|
+
upb_Array_Set(array, index, msgval);
|
186
295
|
return Qnil;
|
187
296
|
}
|
188
297
|
|
189
|
-
static int kInitialSize = 8;
|
190
|
-
|
191
|
-
void RepeatedField_reserve(RepeatedField* self, int new_size) {
|
192
|
-
void* old_elems = self->elements;
|
193
|
-
int elem_size = native_slot_size(self->field_type);
|
194
|
-
if (new_size <= self->capacity) {
|
195
|
-
return;
|
196
|
-
}
|
197
|
-
if (self->capacity == 0) {
|
198
|
-
self->capacity = kInitialSize;
|
199
|
-
}
|
200
|
-
while (self->capacity < new_size) {
|
201
|
-
self->capacity *= 2;
|
202
|
-
}
|
203
|
-
self->elements = ALLOC_N(uint8_t, elem_size * self->capacity);
|
204
|
-
if (old_elems != NULL) {
|
205
|
-
memcpy(self->elements, old_elems, self->size * elem_size);
|
206
|
-
xfree(old_elems);
|
207
|
-
}
|
208
|
-
}
|
209
|
-
|
210
298
|
/*
|
211
299
|
* call-seq:
|
212
|
-
* RepeatedField.push(value)
|
300
|
+
* RepeatedField.push(value, ...)
|
213
301
|
*
|
214
302
|
* Adds a new element to the repeated field.
|
215
303
|
*/
|
216
|
-
VALUE
|
304
|
+
static VALUE RepeatedField_push_vararg(int argc, VALUE* argv, VALUE _self) {
|
217
305
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
218
|
-
|
219
|
-
|
220
|
-
void* memory;
|
221
|
-
|
222
|
-
RepeatedField_reserve(self, self->size + 1);
|
223
|
-
memory = (void *) (((uint8_t *)self->elements) + self->size * element_size);
|
224
|
-
native_slot_set("", field_type, self->field_type_class, memory, val);
|
225
|
-
// native_slot_set may raise an error; bump size only after set.
|
226
|
-
self->size++;
|
227
|
-
return _self;
|
228
|
-
}
|
229
|
-
|
230
|
-
VALUE RepeatedField_push_vararg(VALUE _self, VALUE args) {
|
306
|
+
upb_Arena* arena = Arena_get(self->arena);
|
307
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
231
308
|
int i;
|
232
|
-
|
233
|
-
|
309
|
+
|
310
|
+
for (i = 0; i < argc; i++) {
|
311
|
+
upb_MessageValue msgval =
|
312
|
+
Convert_RubyToUpb(argv[i], "", self->type_info, arena);
|
313
|
+
upb_Array_Append(array, msgval, arena);
|
234
314
|
}
|
315
|
+
|
235
316
|
return _self;
|
236
317
|
}
|
237
318
|
|
238
|
-
|
239
|
-
|
319
|
+
/*
|
320
|
+
* call-seq:
|
321
|
+
* RepeatedField.<<(value)
|
322
|
+
*
|
323
|
+
* Adds a new element to the repeated field.
|
324
|
+
*/
|
325
|
+
static VALUE RepeatedField_push(VALUE _self, VALUE val) {
|
240
326
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
241
|
-
|
242
|
-
|
243
|
-
void* memory;
|
244
|
-
|
245
|
-
RepeatedField_reserve(self, self->size + 1);
|
246
|
-
memory = (void *) (((uint8_t *)self->elements) + self->size * element_size);
|
247
|
-
memcpy(memory, data, element_size);
|
248
|
-
self->size++;
|
249
|
-
}
|
327
|
+
upb_Arena* arena = Arena_get(self->arena);
|
328
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
250
329
|
|
251
|
-
|
252
|
-
|
253
|
-
upb_fieldtype_t field_type = self->field_type;
|
254
|
-
int element_size = native_slot_size(field_type);
|
255
|
-
return RepeatedField_memoryat(self, index, element_size);
|
256
|
-
}
|
330
|
+
upb_MessageValue msgval = Convert_RubyToUpb(val, "", self->type_info, arena);
|
331
|
+
upb_Array_Append(array, msgval, arena);
|
257
332
|
|
258
|
-
|
259
|
-
RepeatedField* self = ruby_to_RepeatedField(_self);
|
260
|
-
return self->size;
|
333
|
+
return _self;
|
261
334
|
}
|
262
335
|
|
263
336
|
/*
|
264
337
|
* Private ruby method, used by RepeatedField.pop
|
265
338
|
*/
|
266
|
-
VALUE RepeatedField_pop_one(VALUE _self) {
|
339
|
+
static VALUE RepeatedField_pop_one(VALUE _self) {
|
267
340
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
int index;
|
272
|
-
void* memory;
|
341
|
+
size_t size = upb_Array_Size(self->array);
|
342
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
343
|
+
upb_MessageValue last;
|
273
344
|
VALUE ret;
|
274
345
|
|
275
|
-
if (
|
346
|
+
if (size == 0) {
|
276
347
|
return Qnil;
|
277
348
|
}
|
278
|
-
|
279
|
-
|
280
|
-
ret =
|
281
|
-
|
349
|
+
|
350
|
+
last = upb_Array_Get(self->array, size - 1);
|
351
|
+
ret = Convert_UpbToRuby(last, self->type_info, self->arena);
|
352
|
+
|
353
|
+
upb_Array_Resize(array, size - 1, Arena_get(self->arena));
|
282
354
|
return ret;
|
283
355
|
}
|
284
356
|
|
@@ -288,15 +360,18 @@ VALUE RepeatedField_pop_one(VALUE _self) {
|
|
288
360
|
*
|
289
361
|
* Replaces the contents of the repeated field with the given list of elements.
|
290
362
|
*/
|
291
|
-
VALUE RepeatedField_replace(VALUE _self, VALUE list) {
|
363
|
+
static VALUE RepeatedField_replace(VALUE _self, VALUE list) {
|
292
364
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
365
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
293
366
|
int i;
|
294
367
|
|
295
368
|
Check_Type(list, T_ARRAY);
|
296
|
-
self->
|
369
|
+
upb_Array_Resize(array, 0, Arena_get(self->arena));
|
370
|
+
|
297
371
|
for (i = 0; i < RARRAY_LEN(list); i++) {
|
298
372
|
RepeatedField_push(_self, rb_ary_entry(list, i));
|
299
373
|
}
|
374
|
+
|
300
375
|
return list;
|
301
376
|
}
|
302
377
|
|
@@ -306,9 +381,10 @@ VALUE RepeatedField_replace(VALUE _self, VALUE list) {
|
|
306
381
|
*
|
307
382
|
* Clears (removes all elements from) this repeated field.
|
308
383
|
*/
|
309
|
-
VALUE RepeatedField_clear(VALUE _self) {
|
384
|
+
static VALUE RepeatedField_clear(VALUE _self) {
|
310
385
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
311
|
-
|
386
|
+
upb_Array* array = RepeatedField_GetMutable(_self);
|
387
|
+
upb_Array_Resize(array, 0, Arena_get(self->arena));
|
312
388
|
return _self;
|
313
389
|
}
|
314
390
|
|
@@ -318,23 +394,9 @@ VALUE RepeatedField_clear(VALUE _self) {
|
|
318
394
|
*
|
319
395
|
* Returns the length of this repeated field.
|
320
396
|
*/
|
321
|
-
VALUE RepeatedField_length(VALUE _self) {
|
397
|
+
static VALUE RepeatedField_length(VALUE _self) {
|
322
398
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
323
|
-
return INT2NUM(self->
|
324
|
-
}
|
325
|
-
|
326
|
-
VALUE RepeatedField_new_this_type(VALUE _self) {
|
327
|
-
RepeatedField* self = ruby_to_RepeatedField(_self);
|
328
|
-
VALUE new_rptfield = Qnil;
|
329
|
-
VALUE element_type = fieldtype_to_ruby(self->field_type);
|
330
|
-
if (self->field_type_class != Qnil) {
|
331
|
-
new_rptfield = rb_funcall(CLASS_OF(_self), rb_intern("new"), 2,
|
332
|
-
element_type, self->field_type_class);
|
333
|
-
} else {
|
334
|
-
new_rptfield = rb_funcall(CLASS_OF(_self), rb_intern("new"), 1,
|
335
|
-
element_type);
|
336
|
-
}
|
337
|
-
return new_rptfield;
|
399
|
+
return INT2NUM(upb_Array_Size(self->array));
|
338
400
|
}
|
339
401
|
|
340
402
|
/*
|
@@ -344,42 +406,20 @@ VALUE RepeatedField_new_this_type(VALUE _self) {
|
|
344
406
|
* Duplicates this repeated field with a shallow copy. References to all
|
345
407
|
* non-primitive element objects (e.g., submessages) are shared.
|
346
408
|
*/
|
347
|
-
VALUE RepeatedField_dup(VALUE _self) {
|
409
|
+
static VALUE RepeatedField_dup(VALUE _self) {
|
348
410
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
349
|
-
VALUE new_rptfield = RepeatedField_new_this_type(
|
411
|
+
VALUE new_rptfield = RepeatedField_new_this_type(self);
|
350
412
|
RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
|
351
|
-
|
352
|
-
|
353
|
-
|
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);
|
354
416
|
int i;
|
355
417
|
|
356
|
-
|
357
|
-
for (i = 0; i < self->size; i++, off += elem_size) {
|
358
|
-
void* to_mem = (uint8_t *)new_rptfield_self->elements + off;
|
359
|
-
void* from_mem = (uint8_t *)self->elements + off;
|
360
|
-
native_slot_dup(field_type, to_mem, from_mem);
|
361
|
-
new_rptfield_self->size++;
|
362
|
-
}
|
418
|
+
Arena_fuse(self->arena, arena);
|
363
419
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
// Internal only: used by Google::Protobuf.deep_copy.
|
368
|
-
VALUE RepeatedField_deep_copy(VALUE _self) {
|
369
|
-
RepeatedField* self = ruby_to_RepeatedField(_self);
|
370
|
-
VALUE new_rptfield = RepeatedField_new_this_type(_self);
|
371
|
-
RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
|
372
|
-
upb_fieldtype_t field_type = self->field_type;
|
373
|
-
size_t elem_size = native_slot_size(field_type);
|
374
|
-
size_t off = 0;
|
375
|
-
int i;
|
376
|
-
|
377
|
-
RepeatedField_reserve(new_rptfield_self, self->size);
|
378
|
-
for (i = 0; i < self->size; i++, off += elem_size) {
|
379
|
-
void* to_mem = (uint8_t *)new_rptfield_self->elements + off;
|
380
|
-
void* from_mem = (uint8_t *)self->elements + off;
|
381
|
-
native_slot_deep_copy(field_type, self->field_type_class, to_mem, from_mem);
|
382
|
-
new_rptfield_self->size++;
|
420
|
+
for (i = 0; i < size; i++) {
|
421
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
422
|
+
upb_Array_Append(new_array, msgval, arena);
|
383
423
|
}
|
384
424
|
|
385
425
|
return new_rptfield;
|
@@ -394,17 +434,16 @@ VALUE RepeatedField_deep_copy(VALUE _self) {
|
|
394
434
|
*/
|
395
435
|
VALUE RepeatedField_to_ary(VALUE _self) {
|
396
436
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
397
|
-
|
398
|
-
|
399
|
-
size_t off = 0;
|
400
|
-
VALUE ary = rb_ary_new2(self->size);
|
437
|
+
int size = upb_Array_Size(self->array);
|
438
|
+
VALUE ary = rb_ary_new2(size);
|
401
439
|
int i;
|
402
440
|
|
403
|
-
for (i = 0; i <
|
404
|
-
|
405
|
-
VALUE
|
406
|
-
rb_ary_push(ary,
|
441
|
+
for (i = 0; i < size; i++) {
|
442
|
+
upb_MessageValue msgval = upb_Array_Get(self->array, i);
|
443
|
+
VALUE val = Convert_UpbToRuby(msgval, self->type_info, self->arena);
|
444
|
+
rb_ary_push(ary, val);
|
407
445
|
}
|
446
|
+
|
408
447
|
return ary;
|
409
448
|
}
|
410
449
|
|
@@ -436,28 +475,69 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
|
|
436
475
|
|
437
476
|
self = ruby_to_RepeatedField(_self);
|
438
477
|
other = ruby_to_RepeatedField(_other);
|
439
|
-
|
440
|
-
|
441
|
-
|
478
|
+
size_t n = upb_Array_Size(self->array);
|
479
|
+
|
480
|
+
if (self->type_info.type != other->type_info.type ||
|
481
|
+
self->type_class != other->type_class ||
|
482
|
+
upb_Array_Size(other->array) != n) {
|
442
483
|
return Qfalse;
|
443
484
|
}
|
444
485
|
|
445
|
-
{
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
486
|
+
for (size_t i = 0; i < n; i++) {
|
487
|
+
upb_MessageValue val1 = upb_Array_Get(self->array, i);
|
488
|
+
upb_MessageValue val2 = upb_Array_Get(other->array, i);
|
489
|
+
if (!Msgval_IsEqual(val1, val2, self->type_info)) {
|
490
|
+
return Qfalse;
|
491
|
+
}
|
492
|
+
}
|
450
493
|
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
494
|
+
return Qtrue;
|
495
|
+
}
|
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
|
+
|
517
|
+
/*
|
518
|
+
* call-seq:
|
519
|
+
* RepeatedField.freeze => self
|
520
|
+
*
|
521
|
+
* Freezes the repeated field object. We have to intercept this so we can freeze
|
522
|
+
* the underlying representation, not just the Ruby wrapper.
|
523
|
+
*/
|
524
|
+
VALUE RepeatedField_freeze(VALUE _self) {
|
525
|
+
RepeatedField* self = ruby_to_RepeatedField(_self);
|
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);
|
458
537
|
}
|
459
|
-
return Qtrue;
|
460
538
|
}
|
539
|
+
RB_OBJ_FREEZE(_self);
|
540
|
+
return _self;
|
461
541
|
}
|
462
542
|
|
463
543
|
/*
|
@@ -468,22 +548,15 @@ VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
|
|
468
548
|
*/
|
469
549
|
VALUE RepeatedField_hash(VALUE _self) {
|
470
550
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
471
|
-
|
472
|
-
|
473
|
-
upb_fieldtype_t field_type = self->field_type;
|
474
|
-
VALUE field_type_class = self->field_type_class;
|
475
|
-
size_t elem_size = native_slot_size(field_type);
|
476
|
-
size_t off = 0;
|
477
|
-
int i;
|
551
|
+
uint64_t hash = 0;
|
552
|
+
size_t n = upb_Array_Size(self->array);
|
478
553
|
|
479
|
-
for (i = 0; i <
|
480
|
-
|
481
|
-
|
482
|
-
h = rb_hash_uint(h, NUM2LONG(rb_funcall(elem, hash_sym, 0)));
|
554
|
+
for (size_t i = 0; i < n; i++) {
|
555
|
+
upb_MessageValue val = upb_Array_Get(self->array, i);
|
556
|
+
hash = Msgval_GetHash(val, self->type_info, hash);
|
483
557
|
}
|
484
|
-
h = rb_hash_end(h);
|
485
558
|
|
486
|
-
return
|
559
|
+
return LL2NUM(hash);
|
487
560
|
}
|
488
561
|
|
489
562
|
/*
|
@@ -495,34 +568,40 @@ VALUE RepeatedField_hash(VALUE _self) {
|
|
495
568
|
* be either another repeated field or a Ruby array.
|
496
569
|
*/
|
497
570
|
VALUE RepeatedField_plus(VALUE _self, VALUE list) {
|
498
|
-
VALUE
|
571
|
+
VALUE dupped_ = RepeatedField_dup(_self);
|
499
572
|
|
500
573
|
if (TYPE(list) == T_ARRAY) {
|
501
574
|
int i;
|
502
575
|
for (i = 0; i < RARRAY_LEN(list); i++) {
|
503
576
|
VALUE elem = rb_ary_entry(list, i);
|
504
|
-
RepeatedField_push(
|
577
|
+
RepeatedField_push(dupped_, elem);
|
505
578
|
}
|
506
579
|
} else if (RB_TYPE_P(list, T_DATA) && RTYPEDDATA_P(list) &&
|
507
580
|
RTYPEDDATA_TYPE(list) == &RepeatedField_type) {
|
508
581
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
509
582
|
RepeatedField* list_rptfield = ruby_to_RepeatedField(list);
|
583
|
+
RepeatedField* dupped = ruby_to_RepeatedField(dupped_);
|
584
|
+
upb_Array* dupped_array = RepeatedField_GetMutable(dupped_);
|
585
|
+
upb_Arena* arena = Arena_get(dupped->arena);
|
586
|
+
Arena_fuse(list_rptfield->arena, arena);
|
587
|
+
int size = upb_Array_Size(list_rptfield->array);
|
510
588
|
int i;
|
511
589
|
|
512
|
-
if (self->
|
513
|
-
self->
|
590
|
+
if (self->type_info.type != list_rptfield->type_info.type ||
|
591
|
+
self->type_class != list_rptfield->type_class) {
|
514
592
|
rb_raise(rb_eArgError,
|
515
593
|
"Attempt to append RepeatedField with different element type.");
|
516
594
|
}
|
517
|
-
|
518
|
-
|
519
|
-
|
595
|
+
|
596
|
+
for (i = 0; i < size; i++) {
|
597
|
+
upb_MessageValue msgval = upb_Array_Get(list_rptfield->array, i);
|
598
|
+
upb_Array_Append(dupped_array, msgval, arena);
|
520
599
|
}
|
521
600
|
} else {
|
522
601
|
rb_raise(rb_eArgError, "Unknown type appending to RepeatedField");
|
523
602
|
}
|
524
603
|
|
525
|
-
return
|
604
|
+
return dupped_;
|
526
605
|
}
|
527
606
|
|
528
607
|
/*
|
@@ -541,133 +620,57 @@ VALUE RepeatedField_concat(VALUE _self, VALUE list) {
|
|
541
620
|
return _self;
|
542
621
|
}
|
543
622
|
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
}
|
557
|
-
if (rb_get_alloc_func(klass) != &Message_alloc) {
|
558
|
-
rb_raise(rb_eArgError,
|
559
|
-
"Message class was not returned by the DescriptorPool.");
|
560
|
-
}
|
561
|
-
} else if (type == UPB_TYPE_ENUM) {
|
562
|
-
VALUE enumdesc = rb_ivar_get(klass, descriptor_instancevar_interned);
|
563
|
-
if (!RB_TYPE_P(enumdesc, T_DATA) || !RTYPEDDATA_P(enumdesc) ||
|
564
|
-
RTYPEDDATA_TYPE(enumdesc) != &_EnumDescriptor_type) {
|
565
|
-
rb_raise(rb_eArgError, "Descriptor has an incorrect type.");
|
566
|
-
}
|
567
|
-
}
|
568
|
-
}
|
569
|
-
|
570
|
-
void RepeatedField_init_args(int argc, VALUE* argv,
|
571
|
-
VALUE _self) {
|
623
|
+
/*
|
624
|
+
* call-seq:
|
625
|
+
* RepeatedField.new(type, type_class = nil, initial_elems = [])
|
626
|
+
*
|
627
|
+
* Creates a new repeated field. The provided type must be a Ruby symbol, and
|
628
|
+
* can take on the same values as those accepted by FieldDescriptor#type=. If
|
629
|
+
* the type is :message or :enum, type_class must be non-nil, and must be the
|
630
|
+
* Ruby class or module returned by Descriptor#msgclass or
|
631
|
+
* EnumDescriptor#enummodule, respectively. An initial list of elements may also
|
632
|
+
* be provided.
|
633
|
+
*/
|
634
|
+
VALUE RepeatedField_init(int argc, VALUE* argv, VALUE _self) {
|
572
635
|
RepeatedField* self = ruby_to_RepeatedField(_self);
|
636
|
+
upb_Arena* arena;
|
573
637
|
VALUE ary = Qnil;
|
638
|
+
|
639
|
+
self->arena = Arena_new();
|
640
|
+
arena = Arena_get(self->arena);
|
641
|
+
|
574
642
|
if (argc < 1) {
|
575
643
|
rb_raise(rb_eArgError, "Expected at least 1 argument.");
|
576
644
|
}
|
577
|
-
self->field_type = ruby_to_fieldtype(argv[0]);
|
578
645
|
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
}
|
584
|
-
self->field_type_class = argv[1];
|
585
|
-
if (argc > 2) {
|
586
|
-
ary = argv[2];
|
587
|
-
}
|
588
|
-
validate_type_class(self->field_type, self->field_type_class);
|
589
|
-
} else {
|
590
|
-
if (argc > 2) {
|
591
|
-
rb_raise(rb_eArgError, "Too many arguments: expected 1 or 2.");
|
592
|
-
}
|
593
|
-
if (argc > 1) {
|
594
|
-
ary = argv[1];
|
595
|
-
}
|
596
|
-
}
|
646
|
+
self->type_info = TypeInfo_FromClass(argc, argv, 0, &self->type_class, &ary);
|
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);
|
597
650
|
|
598
651
|
if (ary != Qnil) {
|
599
|
-
int i;
|
600
|
-
|
601
652
|
if (!RB_TYPE_P(ary, T_ARRAY)) {
|
602
653
|
rb_raise(rb_eArgError, "Expected array as initialize argument");
|
603
654
|
}
|
604
|
-
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
655
|
+
for (int i = 0; i < RARRAY_LEN(ary); i++) {
|
605
656
|
RepeatedField_push(_self, rb_ary_entry(ary, i));
|
606
657
|
}
|
607
658
|
}
|
608
|
-
}
|
609
|
-
|
610
|
-
// Mark, free, alloc, init and class setup functions.
|
611
|
-
|
612
|
-
void RepeatedField_mark(void* _self) {
|
613
|
-
RepeatedField* self = (RepeatedField*)_self;
|
614
|
-
upb_fieldtype_t field_type = self->field_type;
|
615
|
-
int element_size = native_slot_size(field_type);
|
616
|
-
int i;
|
617
|
-
|
618
|
-
rb_gc_mark(self->field_type_class);
|
619
|
-
for (i = 0; i < self->size; i++) {
|
620
|
-
void* memory = (((uint8_t *)self->elements) + i * element_size);
|
621
|
-
native_slot_mark(self->field_type, memory);
|
622
|
-
}
|
623
|
-
}
|
624
|
-
|
625
|
-
void RepeatedField_free(void* _self) {
|
626
|
-
RepeatedField* self = (RepeatedField*)_self;
|
627
|
-
xfree(self->elements);
|
628
|
-
xfree(self);
|
629
|
-
}
|
630
|
-
|
631
|
-
/*
|
632
|
-
* call-seq:
|
633
|
-
* RepeatedField.new(type, type_class = nil, initial_elems = [])
|
634
|
-
*
|
635
|
-
* Creates a new repeated field. The provided type must be a Ruby symbol, and
|
636
|
-
* can take on the same values as those accepted by FieldDescriptor#type=. If
|
637
|
-
* the type is :message or :enum, type_class must be non-nil, and must be the
|
638
|
-
* Ruby class or module returned by Descriptor#msgclass or
|
639
|
-
* EnumDescriptor#enummodule, respectively. An initial list of elements may also
|
640
|
-
* be provided.
|
641
|
-
*/
|
642
|
-
VALUE RepeatedField_alloc(VALUE klass) {
|
643
|
-
RepeatedField* self = ALLOC(RepeatedField);
|
644
|
-
self->elements = NULL;
|
645
|
-
self->size = 0;
|
646
|
-
self->capacity = 0;
|
647
|
-
self->field_type = -1;
|
648
|
-
self->field_type_class = Qnil;
|
649
|
-
return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
|
650
|
-
}
|
651
|
-
|
652
|
-
VALUE RepeatedField_init(int argc, VALUE* argv, VALUE self) {
|
653
|
-
RepeatedField_init_args(argc, argv, self);
|
654
659
|
return Qnil;
|
655
660
|
}
|
656
661
|
|
657
662
|
void RepeatedField_register(VALUE module) {
|
658
|
-
VALUE klass = rb_define_class_under(
|
659
|
-
module, "RepeatedField", rb_cObject);
|
663
|
+
VALUE klass = rb_define_class_under(module, "RepeatedField", rb_cObject);
|
660
664
|
rb_define_alloc_func(klass, RepeatedField_alloc);
|
661
665
|
rb_gc_register_address(&cRepeatedField);
|
662
666
|
cRepeatedField = klass;
|
663
667
|
|
664
|
-
rb_define_method(klass, "initialize",
|
665
|
-
RepeatedField_init, -1);
|
668
|
+
rb_define_method(klass, "initialize", RepeatedField_init, -1);
|
666
669
|
rb_define_method(klass, "each", RepeatedField_each, 0);
|
667
670
|
rb_define_method(klass, "[]", RepeatedField_index, -1);
|
668
671
|
rb_define_method(klass, "at", RepeatedField_index, -1);
|
669
672
|
rb_define_method(klass, "[]=", RepeatedField_index_set, 2);
|
670
|
-
rb_define_method(klass, "push", RepeatedField_push_vararg, -
|
673
|
+
rb_define_method(klass, "push", RepeatedField_push_vararg, -1);
|
671
674
|
rb_define_method(klass, "<<", RepeatedField_push, 1);
|
672
675
|
rb_define_private_method(klass, "pop_one", RepeatedField_pop_one, 0);
|
673
676
|
rb_define_method(klass, "replace", RepeatedField_replace, 1);
|
@@ -679,6 +682,8 @@ void RepeatedField_register(VALUE module) {
|
|
679
682
|
rb_define_method(klass, "clone", RepeatedField_dup, 0);
|
680
683
|
rb_define_method(klass, "==", RepeatedField_eq, 1);
|
681
684
|
rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0);
|
685
|
+
rb_define_method(klass, "freeze", RepeatedField_freeze, 0);
|
686
|
+
rb_define_method(klass, "frozen?", RepeatedField_frozen, 0);
|
682
687
|
rb_define_method(klass, "hash", RepeatedField_hash, 0);
|
683
688
|
rb_define_method(klass, "+", RepeatedField_plus, 1);
|
684
689
|
rb_define_method(klass, "concat", RepeatedField_concat, 1);
|