google-protobuf 3.20.0 → 4.34.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 +60 -86
- data/ext/google/protobuf_c/convert.h +3 -28
- data/ext/google/protobuf_c/defs.c +961 -157
- data/ext/google/protobuf_c/defs.h +3 -28
- data/ext/google/protobuf_c/extconf.rb +21 -11
- data/ext/google/protobuf_c/glue.c +135 -0
- data/ext/google/protobuf_c/map.c +187 -121
- data/ext/google/protobuf_c/map.h +12 -30
- data/ext/google/protobuf_c/message.c +354 -294
- data/ext/google/protobuf_c/message.h +11 -33
- data/ext/google/protobuf_c/protobuf.c +65 -188
- data/ext/google/protobuf_c/protobuf.h +21 -41
- data/ext/google/protobuf_c/repeated_field.c +145 -74
- data/ext/google/protobuf_c/repeated_field.h +11 -29
- data/ext/google/protobuf_c/ruby-upb.c +15734 -8866
- data/ext/google/protobuf_c/ruby-upb.h +16769 -4511
- 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 +1 -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 +20 -7
- 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/lib/google/protobuf/any_pb.rb +6 -8
- data/lib/google/protobuf/api_pb.rb +6 -26
- data/lib/google/protobuf/descriptor_pb.rb +27 -226
- 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 +83 -0
- data/lib/google/protobuf/ffi/enum_descriptor.rb +183 -0
- data/lib/google/protobuf/ffi/ffi.rb +213 -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 +12 -26
- 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 +5 -34
- data/lib/google/protobuf/wrappers_pb.rb +6 -31
- data/lib/google/protobuf.rb +27 -45
- 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 +103 -32
- data/ext/google/protobuf_c/third_party/utf8_range/naive.c +0 -92
- data/ext/google/protobuf_c/third_party/utf8_range/range2-neon.c +0 -157
- data/ext/google/protobuf_c/third_party/utf8_range/range2-sse.c +0 -170
- data/ext/google/protobuf_c/wrap_memcpy.c +0 -52
- data/lib/google/protobuf/descriptor_dsl.rb +0 -465
- data/tests/basic.rb +0 -670
- 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"
|
|
@@ -61,9 +38,11 @@ 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
44
|
"Google::Protobuf::Map",
|
|
66
|
-
{Map_mark, RUBY_DEFAULT_FREE,
|
|
45
|
+
{Map_mark, RUBY_DEFAULT_FREE, Map_memsize},
|
|
67
46
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY,
|
|
68
47
|
};
|
|
69
48
|
|
|
@@ -84,16 +63,16 @@ static VALUE Map_alloc(VALUE klass) {
|
|
|
84
63
|
return TypedData_Wrap_Struct(klass, &Map_type, self);
|
|
85
64
|
}
|
|
86
65
|
|
|
87
|
-
VALUE Map_GetRubyWrapper(upb_Map* map, upb_CType key_type,
|
|
88
|
-
VALUE arena) {
|
|
66
|
+
VALUE Map_GetRubyWrapper(const upb_Map* map, upb_CType key_type,
|
|
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;
|
|
@@ -103,8 +82,8 @@ VALUE Map_GetRubyWrapper(upb_Map* map, upb_CType key_type, TypeInfo value_type,
|
|
|
103
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
|
|
|
@@ -126,21 +105,21 @@ static TypeInfo Map_keyinfo(Map* self) {
|
|
|
126
105
|
}
|
|
127
106
|
|
|
128
107
|
static upb_Map* Map_GetMutable(VALUE _self) {
|
|
129
|
-
|
|
130
|
-
|
|
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
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 = kUpb_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);
|
|
@@ -156,9 +135,8 @@ VALUE Map_deep_copy(VALUE obj) {
|
|
|
156
135
|
upb_Map* new_map =
|
|
157
136
|
upb_Map_New(arena, self->key_type, self->value_type_info.type);
|
|
158
137
|
size_t iter = kUpb_Map_Begin;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
|
|
138
|
+
upb_MessageValue key, val;
|
|
139
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
|
162
140
|
upb_MessageValue val_copy =
|
|
163
141
|
Msgval_DeepCopy(val, self->value_type_info, arena);
|
|
164
142
|
upb_Map_Set(new_map, key, val_copy, arena);
|
|
@@ -202,9 +180,8 @@ void Map_Inspect(StringBuilder* b, const upb_Map* map, upb_CType key_type,
|
|
|
202
180
|
StringBuilder_Printf(b, "{");
|
|
203
181
|
if (map) {
|
|
204
182
|
size_t iter = kUpb_Map_Begin;
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
upb_MessageValue val = upb_MapIterator_Value(map, iter);
|
|
183
|
+
upb_MessageValue key, val;
|
|
184
|
+
while (upb_Map_Next(map, &key, &val, &iter)) {
|
|
208
185
|
if (first) {
|
|
209
186
|
first = false;
|
|
210
187
|
} else {
|
|
@@ -238,8 +215,7 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
|
|
|
238
215
|
Map* self = ruby_to_Map(_self);
|
|
239
216
|
Map* other = ruby_to_Map(hashmap);
|
|
240
217
|
upb_Arena* arena = Arena_get(self->arena);
|
|
241
|
-
|
|
242
|
-
size_t iter = kUpb_Map_Begin;
|
|
218
|
+
upb_Map* self_map = Map_GetMutable(_self);
|
|
243
219
|
|
|
244
220
|
Arena_fuse(other->arena, arena);
|
|
245
221
|
|
|
@@ -249,10 +225,10 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
|
|
|
249
225
|
rb_raise(rb_eArgError, "Attempt to merge Map with mismatching types");
|
|
250
226
|
}
|
|
251
227
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
upb_Map_Set(
|
|
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);
|
|
256
232
|
}
|
|
257
233
|
} else {
|
|
258
234
|
rb_raise(rb_eArgError, "Unknown type merging into Map");
|
|
@@ -260,10 +236,15 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
|
|
|
260
236
|
return _self;
|
|
261
237
|
}
|
|
262
238
|
|
|
239
|
+
/**
|
|
240
|
+
* ruby-doc: Map
|
|
241
|
+
*
|
|
242
|
+
* This class represents a Protobuf Map. It is largely automatically transformed
|
|
243
|
+
* to and from a Ruby hash.
|
|
244
|
+
*/
|
|
245
|
+
|
|
263
246
|
/*
|
|
264
|
-
*
|
|
265
|
-
* Map.new(key_type, value_type, value_typeclass = nil, init_hashmap = {})
|
|
266
|
-
* => new map
|
|
247
|
+
* ruby-doc: Map#initialize
|
|
267
248
|
*
|
|
268
249
|
* Allocates a new Map container. This constructor may be called with 2, 3, or 4
|
|
269
250
|
* arguments. The first two arguments are always present and are symbols (taking
|
|
@@ -289,6 +270,13 @@ static VALUE Map_merge_into_self(VALUE _self, VALUE hashmap) {
|
|
|
289
270
|
* shallow-copied into the new Map: the original map is unmodified, but
|
|
290
271
|
* references to underlying objects will be shared if the value type is a
|
|
291
272
|
* message type.
|
|
273
|
+
*
|
|
274
|
+
* @param key_type [Symbol]
|
|
275
|
+
* @param value_type [Symbol]
|
|
276
|
+
* @param value_typeclass [Class<AbstractMessage>,Module]
|
|
277
|
+
* @paramdefault value_typeclass nil
|
|
278
|
+
* @param init_hashmap [Hash,Map]
|
|
279
|
+
* @paramdefault init_hashmap {}
|
|
292
280
|
*/
|
|
293
281
|
static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
|
|
294
282
|
Map* self = ruby_to_Map(_self);
|
|
@@ -323,7 +311,9 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
|
|
|
323
311
|
|
|
324
312
|
self->map = upb_Map_New(Arena_get(self->arena), self->key_type,
|
|
325
313
|
self->value_type_info.type);
|
|
326
|
-
|
|
314
|
+
VALUE stored = ObjectCache_TryAdd(self->map, _self);
|
|
315
|
+
(void)stored;
|
|
316
|
+
PBRUBY_ASSERT(stored == _self);
|
|
327
317
|
|
|
328
318
|
if (init_arg != Qnil) {
|
|
329
319
|
Map_merge_into_self(_self, init_arg);
|
|
@@ -333,20 +323,21 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
|
|
|
333
323
|
}
|
|
334
324
|
|
|
335
325
|
/*
|
|
336
|
-
*
|
|
337
|
-
* Map.each(&block)
|
|
326
|
+
* ruby-doc: Map#each
|
|
338
327
|
*
|
|
339
328
|
* Invokes &block on each |key, value| pair in the map, in unspecified order.
|
|
340
329
|
* Note that Map also includes Enumerable; map thus acts like a normal Ruby
|
|
341
330
|
* sequence.
|
|
331
|
+
*
|
|
332
|
+
* @yield [Object, Object]
|
|
333
|
+
* @return [nil]
|
|
342
334
|
*/
|
|
343
335
|
static VALUE Map_each(VALUE _self) {
|
|
344
336
|
Map* self = ruby_to_Map(_self);
|
|
345
337
|
size_t iter = kUpb_Map_Begin;
|
|
338
|
+
upb_MessageValue key, val;
|
|
346
339
|
|
|
347
|
-
while (
|
|
348
|
-
upb_MessageValue key = upb_MapIterator_Key(self->map, iter);
|
|
349
|
-
upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
|
|
340
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
|
350
341
|
VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena);
|
|
351
342
|
VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena);
|
|
352
343
|
rb_yield_values(2, key_val, val_val);
|
|
@@ -356,18 +347,19 @@ static VALUE Map_each(VALUE _self) {
|
|
|
356
347
|
}
|
|
357
348
|
|
|
358
349
|
/*
|
|
359
|
-
*
|
|
360
|
-
* Map.keys => [list_of_keys]
|
|
350
|
+
* ruby-doc: Map#keys
|
|
361
351
|
*
|
|
362
352
|
* Returns the list of keys contained in the map, in unspecified order.
|
|
353
|
+
*
|
|
354
|
+
* @return [Array<Object>]
|
|
363
355
|
*/
|
|
364
356
|
static VALUE Map_keys(VALUE _self) {
|
|
365
357
|
Map* self = ruby_to_Map(_self);
|
|
366
358
|
size_t iter = kUpb_Map_Begin;
|
|
367
359
|
VALUE ret = rb_ary_new();
|
|
360
|
+
upb_MessageValue key, val;
|
|
368
361
|
|
|
369
|
-
while (
|
|
370
|
-
upb_MessageValue key = upb_MapIterator_Key(self->map, iter);
|
|
362
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
|
371
363
|
VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena);
|
|
372
364
|
rb_ary_push(ret, key_val);
|
|
373
365
|
}
|
|
@@ -376,18 +368,19 @@ static VALUE Map_keys(VALUE _self) {
|
|
|
376
368
|
}
|
|
377
369
|
|
|
378
370
|
/*
|
|
379
|
-
*
|
|
380
|
-
* Map.values => [list_of_values]
|
|
371
|
+
* ruby-doc: Map#values
|
|
381
372
|
*
|
|
382
373
|
* Returns the list of values contained in the map, in unspecified order.
|
|
374
|
+
*
|
|
375
|
+
* @return [Array<Object>]
|
|
383
376
|
*/
|
|
384
377
|
static VALUE Map_values(VALUE _self) {
|
|
385
378
|
Map* self = ruby_to_Map(_self);
|
|
386
379
|
size_t iter = kUpb_Map_Begin;
|
|
387
380
|
VALUE ret = rb_ary_new();
|
|
381
|
+
upb_MessageValue key, val;
|
|
388
382
|
|
|
389
|
-
while (
|
|
390
|
-
upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
|
|
383
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
|
391
384
|
VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena);
|
|
392
385
|
rb_ary_push(ret, val_val);
|
|
393
386
|
}
|
|
@@ -396,11 +389,13 @@ static VALUE Map_values(VALUE _self) {
|
|
|
396
389
|
}
|
|
397
390
|
|
|
398
391
|
/*
|
|
399
|
-
*
|
|
400
|
-
* Map.[](key) => value
|
|
392
|
+
* ruby-doc: Map#[]
|
|
401
393
|
*
|
|
402
394
|
* Accesses the element at the given key. Throws an exception if the key type is
|
|
403
395
|
* incorrect. Returns nil when the key is not present in the map.
|
|
396
|
+
*
|
|
397
|
+
* @param key [Object]
|
|
398
|
+
* @return [Object]
|
|
404
399
|
*/
|
|
405
400
|
static VALUE Map_index(VALUE _self, VALUE key) {
|
|
406
401
|
Map* self = ruby_to_Map(_self);
|
|
@@ -416,12 +411,15 @@ static VALUE Map_index(VALUE _self, VALUE key) {
|
|
|
416
411
|
}
|
|
417
412
|
|
|
418
413
|
/*
|
|
419
|
-
*
|
|
420
|
-
* Map.[]=(key, value) => value
|
|
414
|
+
* ruby-doc: Map#[]=
|
|
421
415
|
*
|
|
422
416
|
* Inserts or overwrites the value at the given key with the given new value.
|
|
423
417
|
* Throws an exception if the key type is incorrect. Returns the new value that
|
|
424
418
|
* was just inserted.
|
|
419
|
+
*
|
|
420
|
+
* @param key [Object]
|
|
421
|
+
* @param value [Object]
|
|
422
|
+
* @return [Object]
|
|
425
423
|
*/
|
|
426
424
|
static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) {
|
|
427
425
|
Map* self = ruby_to_Map(_self);
|
|
@@ -437,11 +435,13 @@ static VALUE Map_index_set(VALUE _self, VALUE key, VALUE val) {
|
|
|
437
435
|
}
|
|
438
436
|
|
|
439
437
|
/*
|
|
440
|
-
*
|
|
441
|
-
* Map.has_key?(key) => bool
|
|
438
|
+
* ruby-doc: Map#has_key?
|
|
442
439
|
*
|
|
443
440
|
* Returns true if the given key is present in the map. Throws an exception if
|
|
444
441
|
* the key has the wrong type.
|
|
442
|
+
*
|
|
443
|
+
* @param key [Object]
|
|
444
|
+
* @return [Boolean]
|
|
445
445
|
*/
|
|
446
446
|
static VALUE Map_has_key(VALUE _self, VALUE key) {
|
|
447
447
|
Map* self = ruby_to_Map(_self);
|
|
@@ -456,39 +456,35 @@ static VALUE Map_has_key(VALUE _self, VALUE key) {
|
|
|
456
456
|
}
|
|
457
457
|
|
|
458
458
|
/*
|
|
459
|
-
*
|
|
460
|
-
* Map.delete(key) => old_value
|
|
459
|
+
* ruby-doc: Map#delete
|
|
461
460
|
*
|
|
462
461
|
* Deletes the value at the given key, if any, returning either the old value or
|
|
463
462
|
* nil if none was present. Throws an exception if the key is of the wrong type.
|
|
463
|
+
*
|
|
464
|
+
* @param key [Object]
|
|
465
|
+
* @return [Object]
|
|
464
466
|
*/
|
|
465
467
|
static VALUE Map_delete(VALUE _self, VALUE key) {
|
|
468
|
+
upb_Map* map = Map_GetMutable(_self);
|
|
466
469
|
Map* self = ruby_to_Map(_self);
|
|
470
|
+
|
|
467
471
|
upb_MessageValue key_upb =
|
|
468
472
|
Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
|
|
469
473
|
upb_MessageValue val_upb;
|
|
470
|
-
VALUE ret;
|
|
471
474
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
// TODO(haberman): make upb_Map_Delete() also capable of returning the deleted
|
|
475
|
-
// value.
|
|
476
|
-
if (upb_Map_Get(self->map, key_upb, &val_upb)) {
|
|
477
|
-
ret = Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
|
|
475
|
+
if (upb_Map_Delete(map, key_upb, &val_upb)) {
|
|
476
|
+
return Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
|
|
478
477
|
} else {
|
|
479
|
-
|
|
478
|
+
return Qnil;
|
|
480
479
|
}
|
|
481
|
-
|
|
482
|
-
upb_Map_Delete(Map_GetMutable(_self), key_upb);
|
|
483
|
-
|
|
484
|
-
return ret;
|
|
485
480
|
}
|
|
486
481
|
|
|
487
482
|
/*
|
|
488
|
-
*
|
|
489
|
-
* Map.clear
|
|
483
|
+
* ruby-doc: Map#clear
|
|
490
484
|
*
|
|
491
485
|
* Removes all entries from the map.
|
|
486
|
+
*
|
|
487
|
+
* @return [nil]
|
|
492
488
|
*/
|
|
493
489
|
static VALUE Map_clear(VALUE _self) {
|
|
494
490
|
upb_Map_Clear(Map_GetMutable(_self));
|
|
@@ -496,10 +492,11 @@ static VALUE Map_clear(VALUE _self) {
|
|
|
496
492
|
}
|
|
497
493
|
|
|
498
494
|
/*
|
|
499
|
-
*
|
|
500
|
-
* Map.length
|
|
495
|
+
* ruby-doc: Map#length
|
|
501
496
|
*
|
|
502
497
|
* Returns the number of entries (key-value pairs) in the map.
|
|
498
|
+
*
|
|
499
|
+
* @return [Integer]
|
|
503
500
|
*/
|
|
504
501
|
static VALUE Map_length(VALUE _self) {
|
|
505
502
|
Map* self = ruby_to_Map(_self);
|
|
@@ -507,11 +504,12 @@ static VALUE Map_length(VALUE _self) {
|
|
|
507
504
|
}
|
|
508
505
|
|
|
509
506
|
/*
|
|
510
|
-
*
|
|
511
|
-
* Map.dup => new_map
|
|
507
|
+
* ruby-doc: Map#dup
|
|
512
508
|
*
|
|
513
509
|
* Duplicates this map with a shallow copy. References to all non-primitive
|
|
514
510
|
* element objects (e.g., submessages) are shared.
|
|
511
|
+
*
|
|
512
|
+
* @return [Map]
|
|
515
513
|
*/
|
|
516
514
|
static VALUE Map_dup(VALUE _self) {
|
|
517
515
|
Map* self = ruby_to_Map(_self);
|
|
@@ -523,9 +521,8 @@ static VALUE Map_dup(VALUE _self) {
|
|
|
523
521
|
|
|
524
522
|
Arena_fuse(self->arena, arena);
|
|
525
523
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
|
|
524
|
+
upb_MessageValue key, val;
|
|
525
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
|
529
526
|
upb_Map_Set(new_map, key, val, arena);
|
|
530
527
|
}
|
|
531
528
|
|
|
@@ -533,8 +530,7 @@ static VALUE Map_dup(VALUE _self) {
|
|
|
533
530
|
}
|
|
534
531
|
|
|
535
532
|
/*
|
|
536
|
-
*
|
|
537
|
-
* Map.==(other) => boolean
|
|
533
|
+
* ruby-doc: Map#==
|
|
538
534
|
*
|
|
539
535
|
* Compares this map to another. Maps are equal if they have identical key sets,
|
|
540
536
|
* and for each key, the values in both maps compare equal. Elements are
|
|
@@ -544,6 +540,9 @@ static VALUE Map_dup(VALUE _self) {
|
|
|
544
540
|
* Maps with dissimilar key types or value types/typeclasses are never equal,
|
|
545
541
|
* even if value comparison (for example, between integers and floats) would
|
|
546
542
|
* have otherwise indicated that every element has equal value.
|
|
543
|
+
*
|
|
544
|
+
* @param other [Map]
|
|
545
|
+
* @return [Boolean]
|
|
547
546
|
*/
|
|
548
547
|
VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
549
548
|
Map* self = ruby_to_Map(_self);
|
|
@@ -574,9 +573,8 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
|
574
573
|
// For each member of self, check that an equal member exists at the same key
|
|
575
574
|
// in other.
|
|
576
575
|
size_t iter = kUpb_Map_Begin;
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
|
|
576
|
+
upb_MessageValue key, val;
|
|
577
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
|
580
578
|
upb_MessageValue other_val;
|
|
581
579
|
if (!upb_Map_Get(other->map, key, &other_val)) {
|
|
582
580
|
// Not present in other map.
|
|
@@ -592,26 +590,90 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
|
592
590
|
}
|
|
593
591
|
|
|
594
592
|
/*
|
|
595
|
-
*
|
|
596
|
-
*
|
|
593
|
+
* ruby-doc: Map#frozen?
|
|
594
|
+
*
|
|
595
|
+
* Returns true if the map is frozen in either Ruby or the underlying
|
|
596
|
+
* representation. Freezes the Ruby map object if it is not already frozen in
|
|
597
|
+
* Ruby but it is frozen in the underlying representation.
|
|
598
|
+
*
|
|
599
|
+
* @return [Boolean]
|
|
600
|
+
*/
|
|
601
|
+
VALUE Map_frozen(VALUE _self) {
|
|
602
|
+
Map* self = ruby_to_Map(_self);
|
|
603
|
+
if (!upb_Map_IsFrozen(self->map)) {
|
|
604
|
+
PBRUBY_ASSERT(!RB_OBJ_FROZEN(_self));
|
|
605
|
+
return Qfalse;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
// Lazily freeze the Ruby wrapper.
|
|
609
|
+
if (!RB_OBJ_FROZEN(_self)) RB_OBJ_FREEZE(_self);
|
|
610
|
+
return Qtrue;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/*
|
|
614
|
+
* ruby-doc: Map#freeze
|
|
597
615
|
*
|
|
598
|
-
* Freezes the
|
|
599
|
-
*
|
|
616
|
+
* Freezes the map object. We have to intercept this so we can freeze the
|
|
617
|
+
* underlying representation, not just the Ruby wrapper.
|
|
618
|
+
*
|
|
619
|
+
* @return [self]
|
|
600
620
|
*/
|
|
601
|
-
|
|
621
|
+
VALUE Map_freeze(VALUE _self) {
|
|
602
622
|
Map* self = ruby_to_Map(_self);
|
|
603
|
-
if (
|
|
604
|
-
|
|
605
|
-
|
|
623
|
+
if (RB_OBJ_FROZEN(_self)) {
|
|
624
|
+
PBRUBY_ASSERT(upb_Map_IsFrozen(self->map));
|
|
625
|
+
return _self;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
if (!upb_Map_IsFrozen(self->map)) {
|
|
629
|
+
if (self->value_type_info.type == kUpb_CType_Message) {
|
|
630
|
+
upb_Map_Freeze(
|
|
631
|
+
Map_GetMutable(_self),
|
|
632
|
+
upb_MessageDef_MiniTable(self->value_type_info.def.msgdef));
|
|
633
|
+
} else {
|
|
634
|
+
upb_Map_Freeze(Map_GetMutable(_self), NULL);
|
|
635
|
+
}
|
|
606
636
|
}
|
|
637
|
+
|
|
638
|
+
RB_OBJ_FREEZE(_self);
|
|
639
|
+
|
|
607
640
|
return _self;
|
|
608
641
|
}
|
|
609
642
|
|
|
643
|
+
VALUE Map_EmptyFrozen(const upb_FieldDef* f) {
|
|
644
|
+
PBRUBY_ASSERT(upb_FieldDef_IsMap(f));
|
|
645
|
+
VALUE val = ObjectCache_Get(f);
|
|
646
|
+
|
|
647
|
+
if (val == Qnil) {
|
|
648
|
+
const upb_FieldDef* key_f = map_field_key(f);
|
|
649
|
+
const upb_FieldDef* val_f = map_field_value(f);
|
|
650
|
+
upb_CType key_type = upb_FieldDef_CType(key_f);
|
|
651
|
+
TypeInfo value_type_info = TypeInfo_get(val_f);
|
|
652
|
+
val = Map_alloc(cMap);
|
|
653
|
+
Map* self;
|
|
654
|
+
TypedData_Get_Struct(val, Map, &Map_type, self);
|
|
655
|
+
self->arena = Arena_new();
|
|
656
|
+
self->map =
|
|
657
|
+
upb_Map_New(Arena_get(self->arena), key_type, value_type_info.type);
|
|
658
|
+
self->key_type = key_type;
|
|
659
|
+
self->value_type_info = value_type_info;
|
|
660
|
+
if (self->value_type_info.type == kUpb_CType_Message) {
|
|
661
|
+
const upb_MessageDef* val_m = value_type_info.def.msgdef;
|
|
662
|
+
self->value_type_class = Descriptor_DefToClass(val_m);
|
|
663
|
+
}
|
|
664
|
+
return ObjectCache_TryAdd(f, Map_freeze(val));
|
|
665
|
+
}
|
|
666
|
+
PBRUBY_ASSERT(RB_OBJ_FROZEN(val));
|
|
667
|
+
PBRUBY_ASSERT(upb_Map_IsFrozen(ruby_to_Map(val)->map));
|
|
668
|
+
return val;
|
|
669
|
+
}
|
|
670
|
+
|
|
610
671
|
/*
|
|
611
|
-
*
|
|
612
|
-
* Map.hash => hash_value
|
|
672
|
+
* ruby-doc: Map#hash
|
|
613
673
|
*
|
|
614
674
|
* Returns a hash value based on this map's contents.
|
|
675
|
+
*
|
|
676
|
+
* @return [Integer]
|
|
615
677
|
*/
|
|
616
678
|
VALUE Map_hash(VALUE _self) {
|
|
617
679
|
Map* self = ruby_to_Map(_self);
|
|
@@ -619,21 +681,21 @@ VALUE Map_hash(VALUE _self) {
|
|
|
619
681
|
|
|
620
682
|
size_t iter = kUpb_Map_Begin;
|
|
621
683
|
TypeInfo key_info = {self->key_type};
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
hash
|
|
626
|
-
hash = Msgval_GetHash(val, self->value_type_info, hash);
|
|
684
|
+
upb_MessageValue key, val;
|
|
685
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
|
686
|
+
hash += Msgval_GetHash(key, key_info, 0);
|
|
687
|
+
hash += Msgval_GetHash(val, self->value_type_info, 0);
|
|
627
688
|
}
|
|
628
689
|
|
|
629
690
|
return LL2NUM(hash);
|
|
630
691
|
}
|
|
631
692
|
|
|
632
693
|
/*
|
|
633
|
-
*
|
|
634
|
-
* Map.to_h => {}
|
|
694
|
+
* ruby-doc: Map#to_h
|
|
635
695
|
*
|
|
636
696
|
* Returns a Ruby Hash object containing all the values within the map
|
|
697
|
+
*
|
|
698
|
+
* @return [Hash]
|
|
637
699
|
*/
|
|
638
700
|
VALUE Map_to_h(VALUE _self) {
|
|
639
701
|
Map* self = ruby_to_Map(_self);
|
|
@@ -641,12 +703,13 @@ VALUE Map_to_h(VALUE _self) {
|
|
|
641
703
|
}
|
|
642
704
|
|
|
643
705
|
/*
|
|
644
|
-
*
|
|
645
|
-
* Map.inspect => string
|
|
706
|
+
* ruby-doc: Map#inspect
|
|
646
707
|
*
|
|
647
708
|
* Returns a string representing this map's elements. It will be formatted as
|
|
648
709
|
* "{key => value, key => value, ...}", with each key and value string
|
|
649
710
|
* representation computed by its own #inspect method.
|
|
711
|
+
*
|
|
712
|
+
* @return [String]
|
|
650
713
|
*/
|
|
651
714
|
VALUE Map_inspect(VALUE _self) {
|
|
652
715
|
Map* self = ruby_to_Map(_self);
|
|
@@ -659,13 +722,15 @@ VALUE Map_inspect(VALUE _self) {
|
|
|
659
722
|
}
|
|
660
723
|
|
|
661
724
|
/*
|
|
662
|
-
*
|
|
663
|
-
* Map.merge(other_map) => map
|
|
725
|
+
* ruby-doc: Map#merge
|
|
664
726
|
*
|
|
665
727
|
* Copies key/value pairs from other_map into a copy of this map. If a key is
|
|
666
728
|
* set in other_map and this map, the value from other_map overwrites the value
|
|
667
729
|
* in the new copy of this map. Returns the new copy of this map with merged
|
|
668
730
|
* contents.
|
|
731
|
+
*
|
|
732
|
+
* @param other_map [Map]
|
|
733
|
+
* @return [Map]
|
|
669
734
|
*/
|
|
670
735
|
static VALUE Map_merge(VALUE _self, VALUE hashmap) {
|
|
671
736
|
VALUE dupped = Map_dup(_self);
|
|
@@ -694,6 +759,7 @@ void Map_register(VALUE module) {
|
|
|
694
759
|
rb_define_method(klass, "clone", Map_dup, 0);
|
|
695
760
|
rb_define_method(klass, "==", Map_eq, 1);
|
|
696
761
|
rb_define_method(klass, "freeze", Map_freeze, 0);
|
|
762
|
+
rb_define_method(klass, "frozen?", Map_frozen, 0);
|
|
697
763
|
rb_define_method(klass, "hash", Map_hash, 0);
|
|
698
764
|
rb_define_method(klass, "to_h", Map_to_h, 0);
|
|
699
765
|
rb_define_method(klass, "inspect", Map_inspect, 0);
|
data/ext/google/protobuf_c/map.h
CHANGED
|
@@ -1,45 +1,24 @@
|
|
|
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(upb_Map *map, upb_CType key_type,
|
|
42
|
-
VALUE arena);
|
|
20
|
+
VALUE Map_GetRubyWrapper(const upb_Map *map, upb_CType key_type,
|
|
21
|
+
TypeInfo value_type, VALUE arena);
|
|
43
22
|
|
|
44
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
|
|
@@ -63,4 +42,7 @@ extern VALUE cMap;
|
|
|
63
42
|
// Call at startup to register all types in this module.
|
|
64
43
|
void Map_register(VALUE module);
|
|
65
44
|
|
|
45
|
+
// Recursively freeze map
|
|
46
|
+
VALUE Map_freeze(VALUE _self);
|
|
47
|
+
|
|
66
48
|
#endif // RUBY_PROTOBUF_MAP_H_
|