google-protobuf 3.21.2 → 4.29.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/Rakefile +3 -0
- data/ext/google/protobuf_c/convert.c +67 -86
- data/ext/google/protobuf_c/convert.h +3 -28
- data/ext/google/protobuf_c/defs.c +538 -77
- data/ext/google/protobuf_c/defs.h +3 -28
- data/ext/google/protobuf_c/extconf.rb +4 -4
- data/ext/google/protobuf_c/glue.c +72 -0
- data/ext/google/protobuf_c/map.c +114 -85
- data/ext/google/protobuf_c/map.h +12 -30
- data/ext/google/protobuf_c/message.c +264 -238
- data/ext/google/protobuf_c/message.h +11 -33
- data/ext/google/protobuf_c/protobuf.c +63 -187
- data/ext/google/protobuf_c/protobuf.h +27 -39
- data/ext/google/protobuf_c/repeated_field.c +72 -38
- data/ext/google/protobuf_c/repeated_field.h +11 -29
- data/ext/google/protobuf_c/ruby-upb.c +13783 -8236
- data/ext/google/protobuf_c/ruby-upb.h +14077 -4495
- 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 +467 -0
- data/ext/google/protobuf_c/third_party/utf8_range/utf8_range.h +20 -7
- data/ext/google/protobuf_c/wrap_memcpy.c +3 -26
- 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 +23 -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 +165 -0
- data/lib/google/protobuf/ffi/descriptor_pool.rb +77 -0
- data/lib/google/protobuf/ffi/enum_descriptor.rb +173 -0
- data/lib/google/protobuf/ffi/ffi.rb +215 -0
- data/lib/google/protobuf/ffi/field_descriptor.rb +330 -0
- data/lib/google/protobuf/ffi/file_descriptor.rb +49 -0
- data/lib/google/protobuf/ffi/internal/arena.rb +60 -0
- data/lib/google/protobuf/ffi/internal/convert.rb +296 -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 +785 -0
- data/lib/google/protobuf/ffi/method_descriptor.rb +114 -0
- data/lib/google/protobuf/ffi/object_cache.rb +30 -0
- data/lib/google/protobuf/ffi/oneof_descriptor.rb +97 -0
- data/lib/google/protobuf/ffi/repeated_field.rb +411 -0
- data/lib/google/protobuf/ffi/service_descriptor.rb +107 -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 +8 -26
- data/lib/google/protobuf/plugin_pb.rb +25 -0
- data/lib/google/protobuf/repeated_field.rb +7 -31
- 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 +51 -0
- data/lib/google/protobuf_native.rb +19 -0
- data/lib/google/tasks/ffi.rake +100 -0
- metadata +92 -16
- 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/lib/google/protobuf/descriptor_dsl.rb +0 -465
- data/tests/basic.rb +0 -739
- data/tests/generated_code_test.rb +0 -23
- data/tests/stress.rb +0 -38
@@ -1,38 +1,13 @@
|
|
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_DEFS_H_
|
32
9
|
#define RUBY_PROTOBUF_DEFS_H_
|
33
10
|
|
34
|
-
#include <ruby/ruby.h>
|
35
|
-
|
36
11
|
#include "protobuf.h"
|
37
12
|
#include "ruby-upb.h"
|
38
13
|
|
@@ -6,23 +6,23 @@ ext_name = "google/protobuf_c"
|
|
6
6
|
|
7
7
|
dir_config(ext_name)
|
8
8
|
|
9
|
-
if RUBY_PLATFORM =~ /darwin/ || RUBY_PLATFORM =~ /linux/
|
9
|
+
if RUBY_PLATFORM =~ /darwin/ || RUBY_PLATFORM =~ /linux/ || RUBY_PLATFORM =~ /freebsd/
|
10
10
|
$CFLAGS += " -std=gnu99 -O3 -DNDEBUG -fvisibility=hidden -Wall -Wsign-compare -Wno-declaration-after-statement"
|
11
11
|
else
|
12
12
|
$CFLAGS += " -std=gnu99 -O3 -DNDEBUG"
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
15
|
if RUBY_PLATFORM =~ /linux/
|
17
16
|
# Instruct the linker to point memcpy calls at our __wrap_memcpy wrapper.
|
18
17
|
$LDFLAGS += " -Wl,-wrap,memcpy"
|
19
18
|
end
|
20
19
|
|
21
20
|
$VPATH << "$(srcdir)/third_party/utf8_range"
|
22
|
-
$INCFLAGS
|
21
|
+
$INCFLAGS += " -I$(srcdir)/third_party/utf8_range"
|
23
22
|
|
24
23
|
$srcs = ["protobuf.c", "convert.c", "defs.c", "message.c",
|
25
24
|
"repeated_field.c", "map.c", "ruby-upb.c", "wrap_memcpy.c",
|
26
|
-
"
|
25
|
+
"utf8_range.c", "shared_convert.c",
|
26
|
+
"shared_message.c"]
|
27
27
|
|
28
28
|
create_makefile(ext_name)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
// Protocol Buffers - Google's data interchange format
|
2
|
+
// Copyright 2023 Google Inc. All rights reserved.
|
3
|
+
//
|
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
|
+
// -----------------------------------------------------------------------------
|
9
|
+
// Exposing inlined UPB functions. Strictly free of dependencies on
|
10
|
+
// Ruby interpreter internals.
|
11
|
+
|
12
|
+
#include "ruby-upb.h"
|
13
|
+
|
14
|
+
upb_Arena* Arena_create() { return upb_Arena_Init(NULL, 0, &upb_alloc_global); }
|
15
|
+
|
16
|
+
google_protobuf_FileDescriptorProto* FileDescriptorProto_parse(
|
17
|
+
const char* serialized_file_proto, size_t length, upb_Arena* arena) {
|
18
|
+
return google_protobuf_FileDescriptorProto_parse(serialized_file_proto,
|
19
|
+
length, arena);
|
20
|
+
}
|
21
|
+
|
22
|
+
char* EnumDescriptor_serialized_options(const upb_EnumDef* enumdef,
|
23
|
+
size_t* size, upb_Arena* arena) {
|
24
|
+
const google_protobuf_EnumOptions* opts = upb_EnumDef_Options(enumdef);
|
25
|
+
char* serialized = google_protobuf_EnumOptions_serialize(opts, arena, size);
|
26
|
+
return serialized;
|
27
|
+
}
|
28
|
+
|
29
|
+
char* FileDescriptor_serialized_options(const upb_FileDef* filedef,
|
30
|
+
size_t* size, upb_Arena* arena) {
|
31
|
+
const google_protobuf_FileOptions* opts = upb_FileDef_Options(filedef);
|
32
|
+
char* serialized = google_protobuf_FileOptions_serialize(opts, arena, size);
|
33
|
+
return serialized;
|
34
|
+
}
|
35
|
+
|
36
|
+
char* Descriptor_serialized_options(const upb_MessageDef* msgdef, size_t* size,
|
37
|
+
upb_Arena* arena) {
|
38
|
+
const google_protobuf_MessageOptions* opts = upb_MessageDef_Options(msgdef);
|
39
|
+
char* serialized =
|
40
|
+
google_protobuf_MessageOptions_serialize(opts, arena, size);
|
41
|
+
return serialized;
|
42
|
+
}
|
43
|
+
|
44
|
+
char* OneOfDescriptor_serialized_options(const upb_OneofDef* oneofdef,
|
45
|
+
size_t* size, upb_Arena* arena) {
|
46
|
+
const google_protobuf_OneofOptions* opts = upb_OneofDef_Options(oneofdef);
|
47
|
+
char* serialized = google_protobuf_OneofOptions_serialize(opts, arena, size);
|
48
|
+
return serialized;
|
49
|
+
}
|
50
|
+
|
51
|
+
char* FieldDescriptor_serialized_options(const upb_FieldDef* fielddef,
|
52
|
+
size_t* size, upb_Arena* arena) {
|
53
|
+
const google_protobuf_FieldOptions* opts = upb_FieldDef_Options(fielddef);
|
54
|
+
char* serialized = google_protobuf_FieldOptions_serialize(opts, arena, size);
|
55
|
+
return serialized;
|
56
|
+
}
|
57
|
+
|
58
|
+
char* ServiceDescriptor_serialized_options(const upb_ServiceDef* servicedef,
|
59
|
+
size_t* size, upb_Arena* arena) {
|
60
|
+
const google_protobuf_ServiceOptions* opts =
|
61
|
+
upb_ServiceDef_Options(servicedef);
|
62
|
+
char* serialized =
|
63
|
+
google_protobuf_ServiceOptions_serialize(opts, arena, size);
|
64
|
+
return serialized;
|
65
|
+
}
|
66
|
+
|
67
|
+
char* MethodDescriptor_serialized_options(const upb_MethodDef* methoddef,
|
68
|
+
size_t* size, upb_Arena* arena) {
|
69
|
+
const google_protobuf_MethodOptions* opts = upb_MethodDef_Options(methoddef);
|
70
|
+
char* serialized = google_protobuf_MethodOptions_serialize(opts, arena, size);
|
71
|
+
return serialized;
|
72
|
+
}
|
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");
|
@@ -323,7 +299,9 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
|
|
323
299
|
|
324
300
|
self->map = upb_Map_New(Arena_get(self->arena), self->key_type,
|
325
301
|
self->value_type_info.type);
|
326
|
-
|
302
|
+
VALUE stored = ObjectCache_TryAdd(self->map, _self);
|
303
|
+
(void)stored;
|
304
|
+
PBRUBY_ASSERT(stored == _self);
|
327
305
|
|
328
306
|
if (init_arg != Qnil) {
|
329
307
|
Map_merge_into_self(_self, init_arg);
|
@@ -343,10 +321,9 @@ static VALUE Map_init(int argc, VALUE* argv, VALUE _self) {
|
|
343
321
|
static VALUE Map_each(VALUE _self) {
|
344
322
|
Map* self = ruby_to_Map(_self);
|
345
323
|
size_t iter = kUpb_Map_Begin;
|
324
|
+
upb_MessageValue key, val;
|
346
325
|
|
347
|
-
while (
|
348
|
-
upb_MessageValue key = upb_MapIterator_Key(self->map, iter);
|
349
|
-
upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
|
326
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
350
327
|
VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena);
|
351
328
|
VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena);
|
352
329
|
rb_yield_values(2, key_val, val_val);
|
@@ -365,9 +342,9 @@ static VALUE Map_keys(VALUE _self) {
|
|
365
342
|
Map* self = ruby_to_Map(_self);
|
366
343
|
size_t iter = kUpb_Map_Begin;
|
367
344
|
VALUE ret = rb_ary_new();
|
345
|
+
upb_MessageValue key, val;
|
368
346
|
|
369
|
-
while (
|
370
|
-
upb_MessageValue key = upb_MapIterator_Key(self->map, iter);
|
347
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
371
348
|
VALUE key_val = Convert_UpbToRuby(key, Map_keyinfo(self), self->arena);
|
372
349
|
rb_ary_push(ret, key_val);
|
373
350
|
}
|
@@ -385,9 +362,9 @@ static VALUE Map_values(VALUE _self) {
|
|
385
362
|
Map* self = ruby_to_Map(_self);
|
386
363
|
size_t iter = kUpb_Map_Begin;
|
387
364
|
VALUE ret = rb_ary_new();
|
365
|
+
upb_MessageValue key, val;
|
388
366
|
|
389
|
-
while (
|
390
|
-
upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
|
367
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
391
368
|
VALUE val_val = Convert_UpbToRuby(val, self->value_type_info, self->arena);
|
392
369
|
rb_ary_push(ret, val_val);
|
393
370
|
}
|
@@ -463,25 +440,18 @@ static VALUE Map_has_key(VALUE _self, VALUE key) {
|
|
463
440
|
* nil if none was present. Throws an exception if the key is of the wrong type.
|
464
441
|
*/
|
465
442
|
static VALUE Map_delete(VALUE _self, VALUE key) {
|
443
|
+
upb_Map* map = Map_GetMutable(_self);
|
466
444
|
Map* self = ruby_to_Map(_self);
|
445
|
+
|
467
446
|
upb_MessageValue key_upb =
|
468
447
|
Convert_RubyToUpb(key, "", Map_keyinfo(self), NULL);
|
469
448
|
upb_MessageValue val_upb;
|
470
|
-
VALUE ret;
|
471
449
|
|
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);
|
450
|
+
if (upb_Map_Delete(map, key_upb, &val_upb)) {
|
451
|
+
return Convert_UpbToRuby(val_upb, self->value_type_info, self->arena);
|
478
452
|
} else {
|
479
|
-
|
453
|
+
return Qnil;
|
480
454
|
}
|
481
|
-
|
482
|
-
upb_Map_Delete(Map_GetMutable(_self), key_upb);
|
483
|
-
|
484
|
-
return ret;
|
485
455
|
}
|
486
456
|
|
487
457
|
/*
|
@@ -523,9 +493,8 @@ static VALUE Map_dup(VALUE _self) {
|
|
523
493
|
|
524
494
|
Arena_fuse(self->arena, arena);
|
525
495
|
|
526
|
-
|
527
|
-
|
528
|
-
upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
|
496
|
+
upb_MessageValue key, val;
|
497
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
529
498
|
upb_Map_Set(new_map, key, val, arena);
|
530
499
|
}
|
531
500
|
|
@@ -574,9 +543,8 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
574
543
|
// For each member of self, check that an equal member exists at the same key
|
575
544
|
// in other.
|
576
545
|
size_t iter = kUpb_Map_Begin;
|
577
|
-
|
578
|
-
|
579
|
-
upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
|
546
|
+
upb_MessageValue key, val;
|
547
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
580
548
|
upb_MessageValue other_val;
|
581
549
|
if (!upb_Map_Get(other->map, key, &other_val)) {
|
582
550
|
// Not present in other map.
|
@@ -593,20 +561,81 @@ VALUE Map_eq(VALUE _self, VALUE _other) {
|
|
593
561
|
|
594
562
|
/*
|
595
563
|
* call-seq:
|
596
|
-
*
|
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
|
597
585
|
*
|
598
|
-
* Freezes the
|
599
|
-
*
|
586
|
+
* Freezes the map object. We have to intercept this so we can freeze the
|
587
|
+
* underlying representation, not just the Ruby wrapper.
|
600
588
|
*/
|
601
|
-
|
589
|
+
VALUE Map_freeze(VALUE _self) {
|
602
590
|
Map* self = ruby_to_Map(_self);
|
603
|
-
if (
|
604
|
-
|
605
|
-
|
591
|
+
if (RB_OBJ_FROZEN(_self)) {
|
592
|
+
PBRUBY_ASSERT(upb_Map_IsFrozen(self->map));
|
593
|
+
return _self;
|
606
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
|
+
|
607
608
|
return _self;
|
608
609
|
}
|
609
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
|
+
|
610
639
|
/*
|
611
640
|
* call-seq:
|
612
641
|
* Map.hash => hash_value
|
@@ -619,9 +648,8 @@ VALUE Map_hash(VALUE _self) {
|
|
619
648
|
|
620
649
|
size_t iter = kUpb_Map_Begin;
|
621
650
|
TypeInfo key_info = {self->key_type};
|
622
|
-
|
623
|
-
|
624
|
-
upb_MessageValue val = upb_MapIterator_Value(self->map, iter);
|
651
|
+
upb_MessageValue key, val;
|
652
|
+
while (upb_Map_Next(self->map, &key, &val, &iter)) {
|
625
653
|
hash = Msgval_GetHash(key, key_info, hash);
|
626
654
|
hash = Msgval_GetHash(val, self->value_type_info, hash);
|
627
655
|
}
|
@@ -694,6 +722,7 @@ void Map_register(VALUE module) {
|
|
694
722
|
rb_define_method(klass, "clone", Map_dup, 0);
|
695
723
|
rb_define_method(klass, "==", Map_eq, 1);
|
696
724
|
rb_define_method(klass, "freeze", Map_freeze, 0);
|
725
|
+
rb_define_method(klass, "frozen?", Map_frozen, 0);
|
697
726
|
rb_define_method(klass, "hash", Map_hash, 0);
|
698
727
|
rb_define_method(klass, "to_h", Map_to_h, 0);
|
699
728
|
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_
|