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
data/ext/google/protobuf_c/map.c
CHANGED
@@ -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 "convert.h"
|
32
9
|
#include "defs.h"
|
@@ -34,7 +11,7 @@
|
|
34
11
|
#include "protobuf.h"
|
35
12
|
|
36
13
|
// -----------------------------------------------------------------------------
|
37
|
-
// Basic map operations on top of
|
14
|
+
// Basic map operations on top of upb_Map.
|
38
15
|
//
|
39
16
|
// Note that we roll our own `Map` container here because, as for
|
40
17
|
// `RepeatedField`, we want a strongly-typed container. This is so that any user
|
@@ -48,8 +25,8 @@
|
|
48
25
|
// -----------------------------------------------------------------------------
|
49
26
|
|
50
27
|
typedef struct {
|
51
|
-
const
|
52
|
-
|
28
|
+
const upb_Map* map; // Can convert to mutable when non-frozen.
|
29
|
+
upb_CType key_type;
|
53
30
|
TypeInfo value_type_info;
|
54
31
|
VALUE value_type_class;
|
55
32
|
VALUE arena;
|
@@ -61,10 +38,12 @@ static void Map_mark(void* _self) {
|
|
61
38
|
rb_gc_mark(self->arena);
|
62
39
|
}
|
63
40
|
|
41
|
+
static size_t Map_memsize(const void* _self) { return sizeof(Map); }
|
42
|
+
|
64
43
|
const rb_data_type_t Map_type = {
|
65
|
-
|
66
|
-
|
67
|
-
|
44
|
+
"Google::Protobuf::Map",
|
45
|
+
{Map_mark, RUBY_DEFAULT_FREE, Map_memsize},
|
46
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
68
47
|
};
|
69
48
|
|
70
49
|
VALUE cMap;
|
@@ -84,33 +63,33 @@ static VALUE Map_alloc(VALUE klass) {
|
|
84
63
|
return TypedData_Wrap_Struct(klass, &Map_type, self);
|
85
64
|
}
|
86
65
|
|
87
|
-
VALUE Map_GetRubyWrapper(
|
66
|
+
VALUE Map_GetRubyWrapper(const upb_Map* map, upb_CType key_type,
|
88
67
|
TypeInfo value_type, VALUE arena) {
|
89
68
|
PBRUBY_ASSERT(map);
|
69
|
+
PBRUBY_ASSERT(arena != Qnil);
|
90
70
|
|
91
71
|
VALUE val = ObjectCache_Get(map);
|
92
72
|
|
93
73
|
if (val == Qnil) {
|
94
74
|
val = Map_alloc(cMap);
|
95
75
|
Map* self;
|
96
|
-
ObjectCache_Add(map, val);
|
97
76
|
TypedData_Get_Struct(val, Map, &Map_type, self);
|
98
77
|
self->map = map;
|
99
78
|
self->arena = arena;
|
100
79
|
self->key_type = key_type;
|
101
80
|
self->value_type_info = value_type;
|
102
|
-
if (self->value_type_info.type ==
|
103
|
-
const
|
81
|
+
if (self->value_type_info.type == kUpb_CType_Message) {
|
82
|
+
const upb_MessageDef* val_m = self->value_type_info.def.msgdef;
|
104
83
|
self->value_type_class = Descriptor_DefToClass(val_m);
|
105
84
|
}
|
85
|
+
return ObjectCache_TryAdd(map, val);
|
106
86
|
}
|
107
|
-
|
108
87
|
return val;
|
109
88
|
}
|
110
89
|
|
111
|
-
static VALUE Map_new_this_type(Map
|
90
|
+
static VALUE Map_new_this_type(Map* from) {
|
112
91
|
VALUE arena_rb = Arena_new();
|
113
|
-
|
92
|
+
upb_Map* map = upb_Map_New(Arena_get(arena_rb), from->key_type,
|
114
93
|
from->value_type_info.type);
|
115
94
|
VALUE ret =
|
116
95
|
Map_GetRubyWrapper(map, from->key_type, from->value_type_info, arena_rb);
|
@@ -125,22 +104,22 @@ static TypeInfo Map_keyinfo(Map* self) {
|
|
125
104
|
return ret;
|
126
105
|
}
|
127
106
|
|
128
|
-
static
|
129
|
-
|
130
|
-
|
107
|
+
static upb_Map* Map_GetMutable(VALUE _self) {
|
108
|
+
const upb_Map* map = ruby_to_Map(_self)->map;
|
109
|
+
Protobuf_CheckNotFrozen(_self, upb_Map_IsFrozen(map));
|
110
|
+
return (upb_Map*)map;
|
131
111
|
}
|
132
112
|
|
133
|
-
VALUE Map_CreateHash(const
|
113
|
+
VALUE Map_CreateHash(const upb_Map* map, upb_CType key_type,
|
134
114
|
TypeInfo val_info) {
|
135
115
|
VALUE hash = rb_hash_new();
|
136
|
-
size_t iter = UPB_MAP_BEGIN;
|
137
116
|
TypeInfo key_info = TypeInfo_from_type(key_type);
|
138
117
|
|
139
118
|
if (!map) return hash;
|
140
119
|
|
141
|
-
|
142
|
-
|
143
|
-
|
120
|
+
size_t iter = kUpb_Map_Begin;
|
121
|
+
upb_MessageValue key, val;
|
122
|
+
while (upb_Map_Next(map, &key, &val, &iter)) {
|
144
123
|
VALUE key_val = Convert_UpbToRuby(key, key_info, Qnil);
|
145
124
|
VALUE val_val = Scalar_CreateHash(val, val_info);
|
146
125
|
rb_hash_aset(hash, key_val, val_val);
|
@@ -152,25 +131,25 @@ VALUE Map_CreateHash(const upb_map* map, upb_fieldtype_t key_type,
|
|
152
131
|
VALUE Map_deep_copy(VALUE obj) {
|
153
132
|
Map* self = ruby_to_Map(obj);
|
154
133
|
VALUE new_arena_rb = Arena_new();
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
size_t iter =
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
134
|
+
upb_Arena* arena = Arena_get(new_arena_rb);
|
135
|
+
upb_Map* new_map =
|
136
|
+
upb_Map_New(arena, self->key_type, self->value_type_info.type);
|
137
|
+
size_t iter = kUpb_Map_Begin;
|
138
|
+
upb_MessageValue key, val;
|
139
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
140
|
+
upb_MessageValue val_copy =
|
141
|
+
Msgval_DeepCopy(val, self->value_type_info, arena);
|
142
|
+
upb_Map_Set(new_map, key, val_copy, arena);
|
164
143
|
}
|
165
144
|
|
166
145
|
return Map_GetRubyWrapper(new_map, self->key_type, self->value_type_info,
|
167
146
|
new_arena_rb);
|
168
147
|
}
|
169
148
|
|
170
|
-
const
|
171
|
-
|
172
|
-
const
|
173
|
-
const
|
149
|
+
const upb_Map* Map_GetUpbMap(VALUE val, const upb_FieldDef* field,
|
150
|
+
upb_Arena* arena) {
|
151
|
+
const upb_FieldDef* key_field = map_field_key(field);
|
152
|
+
const upb_FieldDef* value_field = map_field_value(field);
|
174
153
|
TypeInfo value_type_info = TypeInfo_get(value_field);
|
175
154
|
Map* self;
|
176
155
|
|
@@ -180,7 +159,7 @@ const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef* field,
|
|
180
159
|
}
|
181
160
|
|
182
161
|
self = ruby_to_Map(val);
|
183
|
-
if (self->key_type !=
|
162
|
+
if (self->key_type != upb_FieldDef_CType(key_field)) {
|
184
163
|
rb_raise(cTypeError, "Map key type does not match field's key type");
|
185
164
|
}
|
186
165
|
if (self->value_type_info.type != value_type_info.type) {
|
@@ -194,16 +173,15 @@ const upb_map* Map_GetUpbMap(VALUE val, const upb_fielddef* field,
|
|
194
173
|
return self->map;
|
195
174
|
}
|
196
175
|
|
197
|
-
void Map_Inspect(StringBuilder* b, const
|
176
|
+
void Map_Inspect(StringBuilder* b, const upb_Map* map, upb_CType key_type,
|
198
177
|
TypeInfo val_type) {
|
199
178
|
bool first = true;
|
200
179
|
TypeInfo key_type_info = {key_type};
|
201
180
|
StringBuilder_Printf(b, "{");
|
202
181
|
if (map) {
|
203
|
-
size_t iter =
|
204
|
-
|
205
|
-
|
206
|
-
upb_msgval val = upb_mapiter_value(map, iter);
|
182
|
+
size_t iter = kUpb_Map_Begin;
|
183
|
+
upb_MessageValue key, val;
|
184
|
+
while (upb_Map_Next(map, &key, &val, &iter)) {
|
207
185
|
if (first) {
|
208
186
|
first = false;
|
209
187
|
} else {
|
@@ -219,10 +197,12 @@ void Map_Inspect(StringBuilder* b, const upb_map* map, upb_fieldtype_t key_type,
|
|
219
197
|
|
220
198
|
static int merge_into_self_callback(VALUE key, VALUE val, VALUE _self) {
|
221
199
|
Map* self = ruby_to_Map(_self);
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
200
|
+
upb_Arena* arena = Arena_get(self->arena);
|
201
|
+
upb_MessageValue key_val =
|
202
|
+
Convert_RubyToUpb(key, "", Map_keyinfo(self), arena);
|
203
|
+
upb_MessageValue val_val =
|
204
|
+
Convert_RubyToUpb(val, "", self->value_type_info, arena);
|
205
|
+
upb_Map_Set(Map_GetMutable(_self), key_val, val_val, arena);
|
226
206
|
return ST_CONTINUE;
|
227
207
|
}
|
228
208
|
|
@@ -234,9 +214,8 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
|
|
234
214
|
RTYPEDDATA_TYPE(hashmap) == &Map_type) {
|
235
215
|
Map* self = ruby_to_Map(_self);
|
236
216
|
Map* other = ruby_to_Map(hashmap);
|
237
|
-
|
238
|
-
|
239
|
-
size_t iter = UPB_MAP_BEGIN;
|
217
|
+
upb_Arena* arena = Arena_get(self->arena);
|
218
|
+
upb_Map* self_map = Map_GetMutable(_self);
|
240
219
|
|
241
220
|
Arena_fuse(other->arena, arena);
|
242
221
|
|
@@ -246,10 +225,10 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
|
|
246
225
|
rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types");
|
247
226
|
}
|
248
227
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
228
|
+
size_t iter = kUpb_Map_Begin;
|
229
|
+
upb_MessageValue key, val;
|
230
|
+
while (upb_Map_Next(other->map, &key, &val, &iter)) {
|
231
|
+
upb_Map_Set(self_map, key, val, arena);
|
253
232
|
}
|
254
233
|
} else {
|
255
234
|
rb_raise(rb_eArgError, "Unknown type merging into Map");
|
@@ -305,22 +284,24 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
|
|
305
284
|
|
306
285
|
// Check that the key type is an allowed type.
|
307
286
|
switch (self->key_type) {
|
308
|
-
case
|
309
|
-
case
|
310
|
-
case
|
311
|
-
case
|
312
|
-
case
|
313
|
-
case
|
314
|
-
case
|
287
|
+
case kUpb_CType_Int32:
|
288
|
+
case kUpb_CType_Int64:
|
289
|
+
case kUpb_CType_UInt32:
|
290
|
+
case kUpb_CType_UInt64:
|
291
|
+
case kUpb_CType_Bool:
|
292
|
+
case kUpb_CType_String:
|
293
|
+
case kUpb_CType_Bytes:
|
315
294
|
// These are OK.
|
316
295
|
break;
|
317
296
|
default:
|
318
297
|
rb_raise(rb_eArgError, "Invalid key type for map.");
|
319
298
|
}
|
320
299
|
|
321
|
-
self->map =
|
300
|
+
self->map = upb_Map_New(Arena_get(self->arena), self->key_type,
|
322
301
|
self->value_type_info.type);
|
323
|
-
|
302
|
+
VALUE stored = ObjectCache_TryAdd(self->map, _self);
|
303
|
+
(void)stored;
|
304
|
+
PBRUBY_ASSERT(stored == _self);
|
324
305
|
|
325
306
|
if (init_arg != Qnil) {
|
326
307
|
Map_merge_into_self(_self, init_arg);
|
@@ -339,11 +320,10 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
|
|
339
320
|
*/
|
340
321
|
static VALUE Map_each(VALUE _self) {
|
341
322
|
Map* self = ruby_to_Map(_self);
|
342
|
-
size_t iter =
|
323
|
+
size_t iter = kUpb_Map_Begin;
|
324
|
+
upb_MessageValue key, val;
|
343
325
|
|
344
|
-
while (
|
345
|
-
upb_msgval key = upb_mapiter_key(self->map, iter);
|
346
|
-
upb_msgval val = upb_mapiter_value(self->map, iter);
|
326
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
347
327
|
VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena);
|
348
328
|
VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena);
|
349
329
|
rb_yield_values(2, key_val, val_val);
|
@@ -360,11 +340,11 @@ static VALUE Map_each(VALUE _self) {
|
|
360
340
|
*/
|
361
341
|
static VALUE Map_keys(VALUE _self) {
|
362
342
|
Map* self = ruby_to_Map(_self);
|
363
|
-
size_t iter =
|
343
|
+
size_t iter = kUpb_Map_Begin;
|
364
344
|
VALUE ret = rb_ary_new();
|
345
|
+
upb_MessageValue key, val;
|
365
346
|
|
366
|
-
while (
|
367
|
-
upb_msgval key = upb_mapiter_key(self->map, iter);
|
347
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
368
348
|
VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena);
|
369
349
|
rb_ary_push(ret, key_val);
|
370
350
|
}
|
@@ -380,11 +360,11 @@ static VALUE Map_keys(VALUE _self) {
|
|
380
360
|
*/
|
381
361
|
static VALUE Map_values(VALUE _self) {
|
382
362
|
Map* self = ruby_to_Map(_self);
|
383
|
-
size_t iter =
|
363
|
+
size_t iter = kUpb_Map_Begin;
|
384
364
|
VALUE ret = rb_ary_new();
|
365
|
+
upb_MessageValue key, val;
|
385
366
|
|
386
|
-
while (
|
387
|
-
upb_msgval val = upb_mapiter_value(self->map, iter);
|
367
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
388
368
|
VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena);
|
389
369
|
rb_ary_push(ret, val_val);
|
390
370
|
}
|
@@ -401,10 +381,11 @@ static VALUE Map_values(VALUE _self) {
|
|
401
381
|
*/
|
402
382
|
static VALUE Map_index(VALUE _self, VALUE key) {
|
403
383
|
Map* self = ruby_to_Map(_self);
|
404
|
-
|
405
|
-
|
384
|
+
upb_MessageValue key_upb =
|
385
|
+
Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
|
386
|
+
upb_MessageValue val;
|
406
387
|
|
407
|
-
if (
|
388
|
+
if (upb_Map_Get(self->map, key_upb, &val)) {
|
408
389
|
return Convert_UpbToRuby(val, self->value_type_info, self->arena);
|
409
390
|
} else {
|
410
391
|
return Qnil;
|
@@ -421,11 +402,13 @@ static VALUE Map_index(VALUE _self, VALUE key) {
|
|
421
402
|
*/
|
422
403
|
static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) {
|
423
404
|
Map* self = ruby_to_Map(_self);
|
424
|
-
|
425
|
-
|
426
|
-
|
405
|
+
upb_Arena* arena = Arena_get(self->arena);
|
406
|
+
upb_MessageValue key_upb =
|
407
|
+
Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
|
408
|
+
upb_MessageValue val_upb =
|
409
|
+
Convert_RubyToUpb(val, "", self->value_type_info, arena);
|
427
410
|
|
428
|
-
|
411
|
+
upb_Map_Set(Map_GetMutable(_self), key_upb, val_upb, arena);
|
429
412
|
|
430
413
|
return val;
|
431
414
|
}
|
@@ -439,9 +422,10 @@ static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) {
|
|
439
422
|
*/
|
440
423
|
static VALUE Map_has_key(VALUE _self, VALUE key) {
|
441
424
|
Map* self = ruby_to_Map(_self);
|
442
|
-
|
425
|
+
upb_MessageValue key_upb =
|
426
|
+
Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
|
443
427
|
|
444
|
-
if (
|
428
|
+
if (upb_Map_Get(self->map, key_upb, NULL)) {
|
445
429
|
return Qtrue;
|
446
430
|
} else {
|
447
431
|
return Qfalse;
|
@@ -456,24 +440,18 @@ static VALUE Map_has_key(VALUE _self, VALUE key) {
|
|
456
440
|
* nil if none was present. Throws an exception if the key is of the wrong type.
|
457
441
|
*/
|
458
442
|
static VALUE Map_delete(VALUE _self, VALUE key) {
|
443
|
+
upb_Map* map = Map_GetMutable(_self);
|
459
444
|
Map* self = ruby_to_Map(_self);
|
460
|
-
upb_msgval key_upb = Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
|
461
|
-
upb_msgval val_upb;
|
462
|
-
VALUE ret;
|
463
445
|
|
464
|
-
|
446
|
+
upb_MessageValue key_upb =
|
447
|
+
Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
|
448
|
+
upb_MessageValue val_upb;
|
465
449
|
|
466
|
-
|
467
|
-
|
468
|
-
if (upb_map_get(self->map, key_upb, &val_upb)) {
|
469
|
-
ret = Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
|
450
|
+
if (upb_Map_Delete(map, key_upb, &val_upb)) {
|
451
|
+
return Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
|
470
452
|
} else {
|
471
|
-
|
453
|
+
return Qnil;
|
472
454
|
}
|
473
|
-
|
474
|
-
upb_map_delete(Map_GetMutable(_self), key_upb);
|
475
|
-
|
476
|
-
return ret;
|
477
455
|
}
|
478
456
|
|
479
457
|
/*
|
@@ -483,7 +461,7 @@ static VALUE Map_delete(VALUE _self, VALUE key) {
|
|
483
461
|
* Removes all entries from the map.
|
484
462
|
*/
|
485
463
|
static VALUE Map_clear(VALUE _self) {
|
486
|
-
|
464
|
+
upb_Map_Clear(Map_GetMutable(_self));
|
487
465
|
return Qnil;
|
488
466
|
}
|
489
467
|
|
@@ -495,7 +473,7 @@ static VALUE Map_clear(VALUE _self) {
|
|
495
473
|
*/
|
496
474
|
static VALUE Map_length(VALUE _self) {
|
497
475
|
Map* self = ruby_to_Map(_self);
|
498
|
-
return ULL2NUM(
|
476
|
+
return ULL2NUM(upb_Map_Size(self->map));
|
499
477
|
}
|
500
478
|
|
501
479
|
/*
|
@@ -509,16 +487,15 @@ static VALUE Map_dup(VALUE _self) {
|
|
509
487
|
Map* self = ruby_to_Map(_self);
|
510
488
|
VALUE new_map_rb = Map_new_this_type(self);
|
511
489
|
Map* new_self = ruby_to_Map(new_map_rb);
|
512
|
-
size_t iter =
|
513
|
-
|
514
|
-
|
490
|
+
size_t iter = kUpb_Map_Begin;
|
491
|
+
upb_Arena* arena = Arena_get(new_self->arena);
|
492
|
+
upb_Map* new_map = Map_GetMutable(new_map_rb);
|
515
493
|
|
516
494
|
Arena_fuse(self->arena, arena);
|
517
495
|
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
upb_map_set(new_map, key, val, arena);
|
496
|
+
upb_MessageValue key, val;
|
497
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
498
|
+
upb_Map_Set(new_map, key, val, arena);
|
522
499
|
}
|
523
500
|
|
524
501
|
return new_map_rb;
|
@@ -559,18 +536,17 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
559
536
|
self->value_type_class != other->value_type_class) {
|
560
537
|
return Qfalse;
|
561
538
|
}
|
562
|
-
if (
|
539
|
+
if (upb_Map_Size(self->map) != upb_Map_Size(other->map)) {
|
563
540
|
return Qfalse;
|
564
541
|
}
|
565
542
|
|
566
543
|
// For each member of self, check that an equal member exists at the same key
|
567
544
|
// in other.
|
568
|
-
size_t iter =
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
if (!upb_map_get(other->map, key, &other_val)) {
|
545
|
+
size_t iter = kUpb_Map_Begin;
|
546
|
+
upb_MessageValue key, val;
|
547
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
548
|
+
upb_MessageValue other_val;
|
549
|
+
if (!upb_Map_Get(other->map, key, &other_val)) {
|
574
550
|
// Not present in other map.
|
575
551
|
return Qfalse;
|
576
552
|
}
|
@@ -585,20 +561,81 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
585
561
|
|
586
562
|
/*
|
587
563
|
* call-seq:
|
588
|
-
*
|
564
|
+
* Map.frozen? => bool
|
565
|
+
*
|
566
|
+
* Returns true if the map is frozen in either Ruby or the underlying
|
567
|
+
* representation. Freezes the Ruby map object if it is not already frozen in
|
568
|
+
* Ruby but it is frozen in the underlying representation.
|
569
|
+
*/
|
570
|
+
VALUE Map_frozen(VALUE _self) {
|
571
|
+
Map* self = ruby_to_Map(_self);
|
572
|
+
if (!upb_Map_IsFrozen(self->map)) {
|
573
|
+
PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
|
574
|
+
return Qfalse;
|
575
|
+
}
|
576
|
+
|
577
|
+
// Lazily freeze the Ruby wrapper.
|
578
|
+
if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
|
579
|
+
return Qtrue;
|
580
|
+
}
|
581
|
+
|
582
|
+
/*
|
583
|
+
* call-seq:
|
584
|
+
* Map.freeze => self
|
589
585
|
*
|
590
|
-
* Freezes the
|
591
|
-
*
|
586
|
+
* Freezes the map object. We have to intercept this so we can freeze the
|
587
|
+
* underlying representation, not just the Ruby wrapper.
|
592
588
|
*/
|
593
|
-
|
589
|
+
VALUE Map_freeze(VALUE _self) {
|
594
590
|
Map* self = ruby_to_Map(_self);
|
595
|
-
if (
|
596
|
-
|
597
|
-
|
591
|
+
if (RB_OBJ_FROZEN(_self)) {
|
592
|
+
PBRUBY_ASSERT(upb_Map_IsFrozen(self->map));
|
593
|
+
return _self;
|
598
594
|
}
|
595
|
+
|
596
|
+
if (!upb_Map_IsFrozen(self->map)) {
|
597
|
+
if (self->value_type_info.type == kUpb_CType_Message) {
|
598
|
+
upb_Map_Freeze(
|
599
|
+
Map_GetMutable(_self),
|
600
|
+
upb_MessageDef_MiniTable(self->value_type_info.def.msgdef));
|
601
|
+
} else {
|
602
|
+
upb_Map_Freeze(Map_GetMutable(_self), NULL);
|
603
|
+
}
|
604
|
+
}
|
605
|
+
|
606
|
+
RB_OBJ_FREEZE(_self);
|
607
|
+
|
599
608
|
return _self;
|
600
609
|
}
|
601
610
|
|
611
|
+
VALUE Map_EmptyFrozen(const upb_FieldDef* f) {
|
612
|
+
PBRUBY_ASSERT(upb_FieldDef_IsMap(f));
|
613
|
+
VALUE val = ObjectCache_Get(f);
|
614
|
+
|
615
|
+
if (val == Qnil) {
|
616
|
+
const upb_FieldDef* key_f = map_field_key(f);
|
617
|
+
const upb_FieldDef* val_f = map_field_value(f);
|
618
|
+
upb_CType key_type = upb_FieldDef_CType(key_f);
|
619
|
+
TypeInfo value_type_info = TypeInfo_get(val_f);
|
620
|
+
val = Map_alloc(cMap);
|
621
|
+
Map* self;
|
622
|
+
TypedData_Get_Struct(val, Map, &Map_type, self);
|
623
|
+
self->arena = Arena_new();
|
624
|
+
self->map =
|
625
|
+
upb_Map_New(Arena_get(self->arena), key_type, value_type_info.type);
|
626
|
+
self->key_type = key_type;
|
627
|
+
self->value_type_info = value_type_info;
|
628
|
+
if (self->value_type_info.type == kUpb_CType_Message) {
|
629
|
+
const upb_MessageDef* val_m = value_type_info.def.msgdef;
|
630
|
+
self->value_type_class = Descriptor_DefToClass(val_m);
|
631
|
+
}
|
632
|
+
return ObjectCache_TryAdd(f, Map_freeze(val));
|
633
|
+
}
|
634
|
+
PBRUBY_ASSERT(RB_OBJ_FROZEN(val));
|
635
|
+
PBRUBY_ASSERT(upb_Map_IsFrozen(ruby_to_Map(val)->map));
|
636
|
+
return val;
|
637
|
+
}
|
638
|
+
|
602
639
|
/*
|
603
640
|
* call-seq:
|
604
641
|
* Map.hash => hash_value
|
@@ -609,11 +646,10 @@ VALUE Map_hash(VALUE _self) {
|
|
609
646
|
Map* self = ruby_to_Map(_self);
|
610
647
|
uint64_t hash = 0;
|
611
648
|
|
612
|
-
size_t iter =
|
649
|
+
size_t iter = kUpb_Map_Begin;
|
613
650
|
TypeInfo key_info = {self->key_type};
|
614
|
-
|
615
|
-
|
616
|
-
upb_msgval val = upb_mapiter_value(self->map, iter);
|
651
|
+
upb_MessageValue key, val;
|
652
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
617
653
|
hash = Msgval_GetHash(key, key_info, hash);
|
618
654
|
hash = Msgval_GetHash(val, self->value_type_info, hash);
|
619
655
|
}
|
@@ -686,6 +722,7 @@ void Map_register(VALUE module) {
|
|
686
722
|
rb_define_method(klass, "clone", Map_dup, 0);
|
687
723
|
rb_define_method(klass, "==", Map_eq, 1);
|
688
724
|
rb_define_method(klass, "freeze", Map_freeze, 0);
|
725
|
+
rb_define_method(klass, "frozen?", Map_frozen, 0);
|
689
726
|
rb_define_method(klass, "hash", Map_hash, 0);
|
690
727
|
rb_define_method(klass, "to_h", Map_to_h, 0);
|
691
728
|
rb_define_method(klass, "inspect", Map_inspect, 0);
|
data/ext/google/protobuf_c/map.h
CHANGED
@@ -1,59 +1,37 @@
|
|
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_MAP_H_
|
32
9
|
#define RUBY_PROTOBUF_MAP_H_
|
33
10
|
|
34
|
-
#include <ruby/ruby.h>
|
35
|
-
|
36
11
|
#include "protobuf.h"
|
37
12
|
#include "ruby-upb.h"
|
38
13
|
|
14
|
+
// Returns a frozen sentinel Ruby wrapper object for an empty upb_Map with the
|
15
|
+
// key and value types specified by the field. Creates one if it doesn't exist.
|
16
|
+
VALUE Map_EmptyFrozen(const upb_FieldDef* f);
|
17
|
+
|
39
18
|
// Returns a Ruby wrapper object for the given map, which will be created if
|
40
19
|
// one does not exist already.
|
41
|
-
VALUE Map_GetRubyWrapper(
|
20
|
+
VALUE Map_GetRubyWrapper(const upb_Map *map, upb_CType key_type,
|
42
21
|
TypeInfo value_type, VALUE arena);
|
43
22
|
|
44
|
-
// Gets the underlying
|
23
|
+
// Gets the underlying upb_Map for this Ruby map object, which must have
|
45
24
|
// key/value type that match |field|. If this is not a map or the type doesn't
|
46
25
|
// match, raises an exception.
|
47
|
-
const
|
48
|
-
|
26
|
+
const upb_Map *Map_GetUpbMap(VALUE val, const upb_FieldDef *field,
|
27
|
+
upb_Arena *arena);
|
49
28
|
|
50
29
|
// Implements #inspect for this map by appending its contents to |b|.
|
51
|
-
void Map_Inspect(StringBuilder *b, const
|
30
|
+
void Map_Inspect(StringBuilder *b, const upb_Map *map, upb_CType key_type,
|
52
31
|
TypeInfo val_type);
|
53
32
|
|
54
33
|
// Returns a new Hash object containing the contents of this Map.
|
55
|
-
VALUE Map_CreateHash(const
|
56
|
-
TypeInfo val_info);
|
34
|
+
VALUE Map_CreateHash(const upb_Map *map, upb_CType key_type, TypeInfo val_info);
|
57
35
|
|
58
36
|
// Returns a deep copy of this Map object.
|
59
37
|
VALUE Map_deep_copy(VALUE obj);
|
@@ -64,4 +42,7 @@ extern VALUE cMap;
|
|
64
42
|
// Call at startup to register all types in this module.
|
65
43
|
void Map_register(VALUE module);
|
66
44
|
|
45
|
+
// Recursively freeze map
|
46
|
+
VALUE Map_freeze(VALUE _self);
|
47
|
+
|
67
48
|
#endif // RUBY_PROTOBUF_MAP_H_
|