google-protobuf 4.31.0.rc.1-aarch64-linux-gnu
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 +7 -0
- 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 +1932 -0
- data/ext/google/protobuf_c/defs.h +82 -0
- data/ext/google/protobuf_c/extconf.rb +44 -0
- data/ext/google/protobuf_c/glue.c +135 -0
- data/ext/google/protobuf_c/map.c +731 -0
- data/ext/google/protobuf_c/map.h +48 -0
- data/ext/google/protobuf_c/message.c +1426 -0
- data/ext/google/protobuf_c/message.h +82 -0
- data/ext/google/protobuf_c/protobuf.c +357 -0
- data/ext/google/protobuf_c/protobuf.h +102 -0
- data/ext/google/protobuf_c/repeated_field.c +691 -0
- 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 +29 -0
- data/lib/google/3.1/protobuf_c.so +0 -0
- data/lib/google/3.2/protobuf_c.so +0 -0
- data/lib/google/3.3/protobuf_c.so +0 -0
- data/lib/google/3.4/protobuf_c.so +0 -0
- data/lib/google/protobuf/any_pb.rb +17 -0
- data/lib/google/protobuf/api_pb.rb +22 -0
- data/lib/google/protobuf/descriptor_pb.rb +70 -0
- data/lib/google/protobuf/duration_pb.rb +17 -0
- data/lib/google/protobuf/empty_pb.rb +17 -0
- 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 +17 -0
- data/lib/google/protobuf/internal/object_cache.rb +99 -0
- data/lib/google/protobuf/message_exts.rb +39 -0
- data/lib/google/protobuf/plugin_pb.rb +25 -0
- data/lib/google/protobuf/repeated_field.rb +177 -0
- data/lib/google/protobuf/source_context_pb.rb +17 -0
- data/lib/google/protobuf/struct_pb.rb +20 -0
- data/lib/google/protobuf/timestamp_pb.rb +17 -0
- data/lib/google/protobuf/type_pb.rb +27 -0
- data/lib/google/protobuf/well_known_types.rb +211 -0
- data/lib/google/protobuf/wrappers_pb.rb +25 -0
- data/lib/google/protobuf.rb +61 -0
- 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 +215 -0
@@ -0,0 +1,82 @@
|
|
1
|
+
// Protocol Buffers - Google's data interchange format
|
2
|
+
// Copyright 2008 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
|
+
#ifndef RUBY_PROTOBUF_MESSAGE_H_
|
9
|
+
#define RUBY_PROTOBUF_MESSAGE_H_
|
10
|
+
|
11
|
+
#include "protobuf.h"
|
12
|
+
#include "ruby-upb.h"
|
13
|
+
|
14
|
+
// Gets the underlying upb_Message* and upb_MessageDef for the given Ruby
|
15
|
+
// message wrapper. Requires that |value| is indeed a message object.
|
16
|
+
const upb_Message* Message_Get(VALUE value, const upb_MessageDef** m);
|
17
|
+
|
18
|
+
// Like Message_Get(), but checks that the object is not frozen and returns a
|
19
|
+
// mutable pointer.
|
20
|
+
upb_Message* Message_GetMutable(VALUE value, const upb_MessageDef** m);
|
21
|
+
|
22
|
+
// Returns the Arena object for this message.
|
23
|
+
VALUE Message_GetArena(VALUE value);
|
24
|
+
|
25
|
+
// Converts |value| into a upb_Message value of the expected upb_MessageDef
|
26
|
+
// type, raising an error if this is not possible. Used when assigning |value|
|
27
|
+
// to a field of another message, which means the message must be of a
|
28
|
+
// particular type.
|
29
|
+
//
|
30
|
+
// This will perform automatic conversions in some cases (for example, Time ->
|
31
|
+
// Google::Protobuf::Timestamp). If any new message is created, it will be
|
32
|
+
// created on |arena|, and any existing message will have its arena fused with
|
33
|
+
// |arena|.
|
34
|
+
const upb_Message* Message_GetUpbMessage(VALUE value, const upb_MessageDef* m,
|
35
|
+
const char* name, upb_Arena* arena);
|
36
|
+
|
37
|
+
// Gets or constructs a Ruby wrapper object for the given message. The wrapper
|
38
|
+
// object will reference |arena| and ensure that it outlives this object.
|
39
|
+
VALUE Message_GetRubyWrapper(const upb_Message* msg, const upb_MessageDef* m,
|
40
|
+
VALUE arena);
|
41
|
+
|
42
|
+
// Gets the given field from this message.
|
43
|
+
VALUE Message_getfield(VALUE _self, const upb_FieldDef* f);
|
44
|
+
|
45
|
+
// Implements #inspect for this message, printing the text to |b|.
|
46
|
+
void Message_PrintMessage(StringBuilder* b, const upb_Message* msg,
|
47
|
+
const upb_MessageDef* m);
|
48
|
+
|
49
|
+
// Returns a hash value for the given message.
|
50
|
+
uint64_t Message_Hash(const upb_Message* msg, const upb_MessageDef* m,
|
51
|
+
uint64_t seed);
|
52
|
+
|
53
|
+
// Returns a deep copy of the given message.
|
54
|
+
upb_Message* Message_deep_copy(const upb_Message* msg, const upb_MessageDef* m,
|
55
|
+
upb_Arena* arena);
|
56
|
+
|
57
|
+
// Checks that this Ruby object is a message, and raises an exception if not.
|
58
|
+
void Message_CheckClass(VALUE klass);
|
59
|
+
|
60
|
+
// Returns a new Hash object containing the contents of this message.
|
61
|
+
VALUE Scalar_CreateHash(upb_MessageValue val, TypeInfo type_info);
|
62
|
+
|
63
|
+
// Creates a message class or enum module for this descriptor, respectively.
|
64
|
+
VALUE build_class_from_descriptor(VALUE descriptor);
|
65
|
+
VALUE build_module_from_enumdesc(VALUE _enumdesc);
|
66
|
+
|
67
|
+
// Returns the Descriptor/EnumDescriptor for the given message class or enum
|
68
|
+
// module, respectively. Returns nil if this is not a message class or enum
|
69
|
+
// module.
|
70
|
+
VALUE MessageOrEnum_GetDescriptor(VALUE klass);
|
71
|
+
|
72
|
+
// Decodes a Message from a byte sequence.
|
73
|
+
VALUE Message_decode_bytes(int size, const char* bytes, int options,
|
74
|
+
VALUE klass, bool freeze);
|
75
|
+
|
76
|
+
// Recursively freeze message
|
77
|
+
VALUE Message_freeze(VALUE _self);
|
78
|
+
|
79
|
+
// Call at startup to register all types in this module.
|
80
|
+
void Message_register(VALUE protobuf);
|
81
|
+
|
82
|
+
#endif // RUBY_PROTOBUF_MESSAGE_H_
|
@@ -0,0 +1,357 @@
|
|
1
|
+
// Protocol Buffers - Google's data interchange format
|
2
|
+
// Copyright 2014 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
|
+
#include "protobuf.h"
|
9
|
+
|
10
|
+
#include "defs.h"
|
11
|
+
#include "map.h"
|
12
|
+
#include "message.h"
|
13
|
+
#include "repeated_field.h"
|
14
|
+
|
15
|
+
VALUE cParseError;
|
16
|
+
VALUE cTypeError;
|
17
|
+
|
18
|
+
const upb_FieldDef *map_field_key(const upb_FieldDef *field) {
|
19
|
+
const upb_MessageDef *entry = upb_FieldDef_MessageSubDef(field);
|
20
|
+
return upb_MessageDef_FindFieldByNumber(entry, 1);
|
21
|
+
}
|
22
|
+
|
23
|
+
const upb_FieldDef *map_field_value(const upb_FieldDef *field) {
|
24
|
+
const upb_MessageDef *entry = upb_FieldDef_MessageSubDef(field);
|
25
|
+
return upb_MessageDef_FindFieldByNumber(entry, 2);
|
26
|
+
}
|
27
|
+
|
28
|
+
// -----------------------------------------------------------------------------
|
29
|
+
// StringBuilder, for inspect
|
30
|
+
// -----------------------------------------------------------------------------
|
31
|
+
|
32
|
+
struct StringBuilder {
|
33
|
+
size_t size;
|
34
|
+
size_t cap;
|
35
|
+
char *data;
|
36
|
+
};
|
37
|
+
|
38
|
+
typedef struct StringBuilder StringBuilder;
|
39
|
+
|
40
|
+
static size_t StringBuilder_SizeOf(size_t cap) {
|
41
|
+
return sizeof(StringBuilder) + cap;
|
42
|
+
}
|
43
|
+
|
44
|
+
StringBuilder *StringBuilder_New() {
|
45
|
+
const size_t cap = 128;
|
46
|
+
StringBuilder *builder = malloc(sizeof(*builder));
|
47
|
+
builder->size = 0;
|
48
|
+
builder->cap = cap;
|
49
|
+
builder->data = malloc(builder->cap);
|
50
|
+
return builder;
|
51
|
+
}
|
52
|
+
|
53
|
+
void StringBuilder_Free(StringBuilder *b) {
|
54
|
+
free(b->data);
|
55
|
+
free(b);
|
56
|
+
}
|
57
|
+
|
58
|
+
void StringBuilder_Printf(StringBuilder *b, const char *fmt, ...) {
|
59
|
+
size_t have = b->cap - b->size;
|
60
|
+
size_t n;
|
61
|
+
va_list args;
|
62
|
+
|
63
|
+
va_start(args, fmt);
|
64
|
+
n = vsnprintf(&b->data[b->size], have, fmt, args);
|
65
|
+
va_end(args);
|
66
|
+
|
67
|
+
if (have <= n) {
|
68
|
+
while (have <= n) {
|
69
|
+
b->cap *= 2;
|
70
|
+
have = b->cap - b->size;
|
71
|
+
}
|
72
|
+
b->data = realloc(b->data, StringBuilder_SizeOf(b->cap));
|
73
|
+
va_start(args, fmt);
|
74
|
+
n = vsnprintf(&b->data[b->size], have, fmt, args);
|
75
|
+
va_end(args);
|
76
|
+
PBRUBY_ASSERT(n < have);
|
77
|
+
}
|
78
|
+
|
79
|
+
b->size += n;
|
80
|
+
}
|
81
|
+
|
82
|
+
VALUE StringBuilder_ToRubyString(StringBuilder *b) {
|
83
|
+
VALUE ret = rb_str_new(b->data, b->size);
|
84
|
+
rb_enc_associate(ret, rb_utf8_encoding());
|
85
|
+
return ret;
|
86
|
+
}
|
87
|
+
|
88
|
+
static void StringBuilder_PrintEnum(StringBuilder *b, int32_t val,
|
89
|
+
const upb_EnumDef *e) {
|
90
|
+
const upb_EnumValueDef *ev = upb_EnumDef_FindValueByNumber(e, val);
|
91
|
+
if (ev) {
|
92
|
+
StringBuilder_Printf(b, ":%s", upb_EnumValueDef_Name(ev));
|
93
|
+
} else {
|
94
|
+
StringBuilder_Printf(b, "%" PRId32, val);
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
void StringBuilder_PrintMsgval(StringBuilder *b, upb_MessageValue val,
|
99
|
+
TypeInfo info) {
|
100
|
+
switch (info.type) {
|
101
|
+
case kUpb_CType_Bool:
|
102
|
+
StringBuilder_Printf(b, "%s", val.bool_val ? "true" : "false");
|
103
|
+
break;
|
104
|
+
case kUpb_CType_Float: {
|
105
|
+
VALUE str = rb_inspect(DBL2NUM(val.float_val));
|
106
|
+
StringBuilder_Printf(b, "%s", RSTRING_PTR(str));
|
107
|
+
break;
|
108
|
+
}
|
109
|
+
case kUpb_CType_Double: {
|
110
|
+
VALUE str = rb_inspect(DBL2NUM(val.double_val));
|
111
|
+
StringBuilder_Printf(b, "%s", RSTRING_PTR(str));
|
112
|
+
break;
|
113
|
+
}
|
114
|
+
case kUpb_CType_Int32:
|
115
|
+
StringBuilder_Printf(b, "%" PRId32, val.int32_val);
|
116
|
+
break;
|
117
|
+
case kUpb_CType_UInt32:
|
118
|
+
StringBuilder_Printf(b, "%" PRIu32, val.uint32_val);
|
119
|
+
break;
|
120
|
+
case kUpb_CType_Int64:
|
121
|
+
StringBuilder_Printf(b, "%" PRId64, val.int64_val);
|
122
|
+
break;
|
123
|
+
case kUpb_CType_UInt64:
|
124
|
+
StringBuilder_Printf(b, "%" PRIu64, val.uint64_val);
|
125
|
+
break;
|
126
|
+
case kUpb_CType_String:
|
127
|
+
StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size,
|
128
|
+
val.str_val.data);
|
129
|
+
break;
|
130
|
+
case kUpb_CType_Bytes:
|
131
|
+
StringBuilder_Printf(b, "\"%.*s\"", (int)val.str_val.size,
|
132
|
+
val.str_val.data);
|
133
|
+
break;
|
134
|
+
case kUpb_CType_Enum:
|
135
|
+
StringBuilder_PrintEnum(b, val.int32_val, info.def.enumdef);
|
136
|
+
break;
|
137
|
+
case kUpb_CType_Message:
|
138
|
+
Message_PrintMessage(b, val.msg_val, info.def.msgdef);
|
139
|
+
break;
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
// -----------------------------------------------------------------------------
|
144
|
+
// Arena
|
145
|
+
// -----------------------------------------------------------------------------
|
146
|
+
|
147
|
+
typedef struct {
|
148
|
+
upb_Arena *arena;
|
149
|
+
// IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE()
|
150
|
+
// macro to update VALUE references, as to trigger write barriers.
|
151
|
+
VALUE pinned_objs;
|
152
|
+
} Arena;
|
153
|
+
|
154
|
+
static void Arena_mark(void *data) {
|
155
|
+
Arena *arena = data;
|
156
|
+
rb_gc_mark(arena->pinned_objs);
|
157
|
+
}
|
158
|
+
|
159
|
+
static void Arena_free(void *data) {
|
160
|
+
Arena *arena = data;
|
161
|
+
upb_Arena_Free(arena->arena);
|
162
|
+
xfree(arena);
|
163
|
+
}
|
164
|
+
|
165
|
+
static size_t Arena_memsize(const void *data) {
|
166
|
+
const Arena *arena = data;
|
167
|
+
size_t fused_count;
|
168
|
+
size_t memsize = upb_Arena_SpaceAllocated(arena->arena, &fused_count);
|
169
|
+
if (fused_count > 1) {
|
170
|
+
// If other arena were fused we attribute an equal
|
171
|
+
// share of memory usage to each one.
|
172
|
+
memsize /= fused_count;
|
173
|
+
}
|
174
|
+
return memsize + sizeof(Arena);
|
175
|
+
}
|
176
|
+
|
177
|
+
static VALUE cArena;
|
178
|
+
|
179
|
+
const rb_data_type_t Arena_type = {
|
180
|
+
"Google::Protobuf::Internal::Arena",
|
181
|
+
{Arena_mark, Arena_free, Arena_memsize},
|
182
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
|
183
|
+
};
|
184
|
+
|
185
|
+
static void *ruby_upb_allocfunc(upb_alloc *alloc, void *ptr, size_t oldsize,
|
186
|
+
size_t size) {
|
187
|
+
if (size == 0) {
|
188
|
+
xfree(ptr);
|
189
|
+
return NULL;
|
190
|
+
} else {
|
191
|
+
return xrealloc(ptr, size);
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|
195
|
+
upb_alloc ruby_upb_alloc = {&ruby_upb_allocfunc};
|
196
|
+
|
197
|
+
static VALUE Arena_alloc(VALUE klass) {
|
198
|
+
Arena *arena = ALLOC(Arena);
|
199
|
+
arena->arena = upb_Arena_Init(NULL, 0, &ruby_upb_alloc);
|
200
|
+
arena->pinned_objs = Qnil;
|
201
|
+
return TypedData_Wrap_Struct(klass, &Arena_type, arena);
|
202
|
+
}
|
203
|
+
|
204
|
+
upb_Arena *Arena_get(VALUE _arena) {
|
205
|
+
Arena *arena;
|
206
|
+
TypedData_Get_Struct(_arena, Arena, &Arena_type, arena);
|
207
|
+
return arena->arena;
|
208
|
+
}
|
209
|
+
|
210
|
+
void Arena_fuse(VALUE _arena, upb_Arena *other) {
|
211
|
+
Arena *arena;
|
212
|
+
TypedData_Get_Struct(_arena, Arena, &Arena_type, arena);
|
213
|
+
if (!upb_Arena_Fuse(arena->arena, other)) {
|
214
|
+
rb_raise(rb_eRuntimeError,
|
215
|
+
"Unable to fuse arenas. This should never happen since Ruby does "
|
216
|
+
"not use initial blocks");
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
VALUE Arena_new() { return Arena_alloc(cArena); }
|
221
|
+
|
222
|
+
void Arena_register(VALUE module) {
|
223
|
+
VALUE internal = rb_define_module_under(module, "Internal");
|
224
|
+
VALUE klass = rb_define_class_under(internal, "Arena", rb_cObject);
|
225
|
+
rb_define_alloc_func(klass, Arena_alloc);
|
226
|
+
rb_gc_register_address(&cArena);
|
227
|
+
cArena = klass;
|
228
|
+
}
|
229
|
+
|
230
|
+
// -----------------------------------------------------------------------------
|
231
|
+
// Object Cache
|
232
|
+
// -----------------------------------------------------------------------------
|
233
|
+
|
234
|
+
// Public ObjectCache API.
|
235
|
+
|
236
|
+
VALUE weak_obj_cache = Qnil;
|
237
|
+
ID item_get;
|
238
|
+
ID item_try_add;
|
239
|
+
|
240
|
+
static void ObjectCache_Init(VALUE protobuf) {
|
241
|
+
item_get = rb_intern("get");
|
242
|
+
item_try_add = rb_intern("try_add");
|
243
|
+
|
244
|
+
rb_gc_register_address(&weak_obj_cache);
|
245
|
+
VALUE internal = rb_const_get(protobuf, rb_intern("Internal"));
|
246
|
+
#if SIZEOF_LONG >= SIZEOF_VALUE
|
247
|
+
VALUE cache_class = rb_const_get(internal, rb_intern("ObjectCache"));
|
248
|
+
#else
|
249
|
+
VALUE cache_class = rb_const_get(internal, rb_intern("LegacyObjectCache"));
|
250
|
+
#endif
|
251
|
+
|
252
|
+
weak_obj_cache = rb_class_new_instance(0, NULL, cache_class);
|
253
|
+
rb_const_set(internal, rb_intern("OBJECT_CACHE"), weak_obj_cache);
|
254
|
+
rb_const_set(internal, rb_intern("SIZEOF_LONG"), INT2NUM(SIZEOF_LONG));
|
255
|
+
rb_const_set(internal, rb_intern("SIZEOF_VALUE"), INT2NUM(SIZEOF_VALUE));
|
256
|
+
}
|
257
|
+
|
258
|
+
static VALUE ObjectCache_GetKey(const void *key) {
|
259
|
+
VALUE key_val = (VALUE)key;
|
260
|
+
PBRUBY_ASSERT((key_val & 3) == 0);
|
261
|
+
// Ensure the key can be stored as a Fixnum since 1 bit is needed for
|
262
|
+
// FIXNUM_FLAG and 1 bit is needed for the sign bit.
|
263
|
+
VALUE new_key = LL2NUM(key_val >> 2);
|
264
|
+
PBRUBY_ASSERT(FIXNUM_P(new_key));
|
265
|
+
return new_key;
|
266
|
+
}
|
267
|
+
|
268
|
+
VALUE ObjectCache_TryAdd(const void *key, VALUE val) {
|
269
|
+
VALUE key_val = ObjectCache_GetKey(key);
|
270
|
+
return rb_funcall(weak_obj_cache, item_try_add, 2, key_val, val);
|
271
|
+
}
|
272
|
+
|
273
|
+
// Returns the cached object for this key, if any. Otherwise returns Qnil.
|
274
|
+
VALUE ObjectCache_Get(const void *key) {
|
275
|
+
VALUE key_val = ObjectCache_GetKey(key);
|
276
|
+
return rb_funcall(weak_obj_cache, item_get, 1, key_val);
|
277
|
+
}
|
278
|
+
|
279
|
+
/*
|
280
|
+
* call-seq:
|
281
|
+
* Google::Protobuf.discard_unknown(msg)
|
282
|
+
*
|
283
|
+
* Discard unknown fields in the given message object and recursively discard
|
284
|
+
* unknown fields in submessages.
|
285
|
+
*/
|
286
|
+
static VALUE Google_Protobuf_discard_unknown(VALUE self, VALUE msg_rb) {
|
287
|
+
const upb_MessageDef *m;
|
288
|
+
upb_Message *msg = Message_GetMutable(msg_rb, &m);
|
289
|
+
const upb_DefPool* ext_pool = upb_FileDef_Pool(upb_MessageDef_File(m));
|
290
|
+
if (!upb_Message_DiscardUnknown(msg, m, ext_pool, 128)) {
|
291
|
+
rb_raise(rb_eRuntimeError, "Messages nested too deeply.");
|
292
|
+
}
|
293
|
+
|
294
|
+
return Qnil;
|
295
|
+
}
|
296
|
+
|
297
|
+
/*
|
298
|
+
* call-seq:
|
299
|
+
* Google::Protobuf.deep_copy(obj) => copy_of_obj
|
300
|
+
*
|
301
|
+
* Performs a deep copy of a RepeatedField instance, a Map instance, or a
|
302
|
+
* message object, recursively copying its members.
|
303
|
+
*/
|
304
|
+
VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) {
|
305
|
+
VALUE klass = CLASS_OF(obj);
|
306
|
+
if (klass == cRepeatedField) {
|
307
|
+
return RepeatedField_deep_copy(obj);
|
308
|
+
} else if (klass == cMap) {
|
309
|
+
return Map_deep_copy(obj);
|
310
|
+
} else {
|
311
|
+
VALUE new_arena_rb = Arena_new();
|
312
|
+
upb_Arena *new_arena = Arena_get(new_arena_rb);
|
313
|
+
const upb_MessageDef *m;
|
314
|
+
const upb_Message *msg = Message_Get(obj, &m);
|
315
|
+
upb_Message *new_msg = Message_deep_copy(msg, m, new_arena);
|
316
|
+
return Message_GetRubyWrapper(new_msg, m, new_arena_rb);
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
// -----------------------------------------------------------------------------
|
321
|
+
// Initialization/entry point.
|
322
|
+
// -----------------------------------------------------------------------------
|
323
|
+
|
324
|
+
// This must be named "Init_protobuf_c" because the Ruby module is named
|
325
|
+
// "protobuf_c" -- the VM looks for this symbol in our .so.
|
326
|
+
__attribute__((visibility("default"))) void Init_protobuf_c() {
|
327
|
+
VALUE google = rb_define_module("Google");
|
328
|
+
VALUE protobuf = rb_define_module_under(google, "Protobuf");
|
329
|
+
|
330
|
+
ObjectCache_Init(protobuf);
|
331
|
+
Arena_register(protobuf);
|
332
|
+
Defs_register(protobuf);
|
333
|
+
RepeatedField_register(protobuf);
|
334
|
+
Map_register(protobuf);
|
335
|
+
Message_register(protobuf);
|
336
|
+
|
337
|
+
cParseError = rb_const_get(protobuf, rb_intern("ParseError"));
|
338
|
+
rb_gc_register_mark_object(cParseError);
|
339
|
+
cTypeError = rb_const_get(protobuf, rb_intern("TypeError"));
|
340
|
+
rb_gc_register_mark_object(cTypeError);
|
341
|
+
|
342
|
+
rb_define_singleton_method(protobuf, "discard_unknown",
|
343
|
+
Google_Protobuf_discard_unknown, 1);
|
344
|
+
rb_define_singleton_method(protobuf, "deep_copy", Google_Protobuf_deep_copy,
|
345
|
+
1);
|
346
|
+
}
|
347
|
+
|
348
|
+
// -----------------------------------------------------------------------------
|
349
|
+
// Utilities
|
350
|
+
// -----------------------------------------------------------------------------
|
351
|
+
|
352
|
+
// Raises a Ruby error if val is frozen in Ruby or UPB.
|
353
|
+
void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen) {
|
354
|
+
if (RB_UNLIKELY(rb_obj_frozen_p(val)||upb_frozen)) {
|
355
|
+
rb_error_frozen_object(val);
|
356
|
+
}
|
357
|
+
}
|
@@ -0,0 +1,102 @@
|
|
1
|
+
// Protocol Buffers - Google's data interchange format
|
2
|
+
// Copyright 2014 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
|
+
#ifndef __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
|
9
|
+
#define __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
|
10
|
+
|
11
|
+
// Ruby 3+ defines NDEBUG itself, see: https://bugs.ruby-lang.org/issues/18777
|
12
|
+
#ifdef NDEBUG
|
13
|
+
#include <ruby.h>
|
14
|
+
#else
|
15
|
+
#include <ruby.h>
|
16
|
+
#undef NDEBUG
|
17
|
+
#endif
|
18
|
+
|
19
|
+
#include <assert.h> // Must be included after the NDEBUG logic above.
|
20
|
+
#include <ruby/encoding.h>
|
21
|
+
#include <ruby/vm.h>
|
22
|
+
|
23
|
+
#include "defs.h"
|
24
|
+
#include "ruby-upb.h"
|
25
|
+
|
26
|
+
// These operate on a map field (i.e., a repeated field of submessages whose
|
27
|
+
// submessage type is a map-entry msgdef).
|
28
|
+
const upb_FieldDef* map_field_key(const upb_FieldDef* field);
|
29
|
+
const upb_FieldDef* map_field_value(const upb_FieldDef* field);
|
30
|
+
|
31
|
+
// -----------------------------------------------------------------------------
|
32
|
+
// Arena
|
33
|
+
// -----------------------------------------------------------------------------
|
34
|
+
|
35
|
+
// A Ruby object that wraps an underlying upb_Arena. Any objects that are
|
36
|
+
// allocated from this arena should reference the Arena in rb_gc_mark(), to
|
37
|
+
// ensure that the object's underlying memory outlives any Ruby object that can
|
38
|
+
// reach it.
|
39
|
+
|
40
|
+
VALUE Arena_new();
|
41
|
+
upb_Arena* Arena_get(VALUE arena);
|
42
|
+
|
43
|
+
// Fuses this arena to another, throwing a Ruby exception if this is not
|
44
|
+
// possible.
|
45
|
+
void Arena_fuse(VALUE arena, upb_Arena* other);
|
46
|
+
|
47
|
+
// -----------------------------------------------------------------------------
|
48
|
+
// ObjectCache
|
49
|
+
// -----------------------------------------------------------------------------
|
50
|
+
|
51
|
+
// Global object cache from upb array/map/message/symtab to wrapper object.
|
52
|
+
//
|
53
|
+
// This is a conceptually "weak" cache, in that it does not prevent "val" from
|
54
|
+
// being collected (though in Ruby <2.7 is it effectively strong, due to
|
55
|
+
// implementation limitations).
|
56
|
+
|
57
|
+
// Tries to add a new entry to the cache, returning the newly installed value or
|
58
|
+
// the pre-existing entry.
|
59
|
+
VALUE ObjectCache_TryAdd(const void* key, VALUE val);
|
60
|
+
|
61
|
+
// Returns the cached object for this key, if any. Otherwise returns Qnil.
|
62
|
+
VALUE ObjectCache_Get(const void* key);
|
63
|
+
|
64
|
+
// -----------------------------------------------------------------------------
|
65
|
+
// StringBuilder, for inspect
|
66
|
+
// -----------------------------------------------------------------------------
|
67
|
+
|
68
|
+
struct StringBuilder;
|
69
|
+
typedef struct StringBuilder StringBuilder;
|
70
|
+
|
71
|
+
StringBuilder* StringBuilder_New();
|
72
|
+
void StringBuilder_Free(StringBuilder* b);
|
73
|
+
void StringBuilder_Printf(StringBuilder* b, const char* fmt, ...);
|
74
|
+
VALUE StringBuilder_ToRubyString(StringBuilder* b);
|
75
|
+
|
76
|
+
void StringBuilder_PrintMsgval(StringBuilder* b, upb_MessageValue val,
|
77
|
+
TypeInfo info);
|
78
|
+
|
79
|
+
// -----------------------------------------------------------------------------
|
80
|
+
// Utilities.
|
81
|
+
// -----------------------------------------------------------------------------
|
82
|
+
|
83
|
+
extern VALUE cTypeError;
|
84
|
+
|
85
|
+
#ifdef NDEBUG
|
86
|
+
#define PBRUBY_ASSERT(expr) \
|
87
|
+
do { \
|
88
|
+
} while (false && (expr))
|
89
|
+
#else
|
90
|
+
#define PBRUBY_ASSERT(expr) \
|
91
|
+
if (!(expr)) \
|
92
|
+
rb_bug("Assertion failed at %s:%d, expr: %s", __FILE__, __LINE__, #expr)
|
93
|
+
#endif
|
94
|
+
|
95
|
+
// Raises a Ruby error if val is frozen in Ruby or upb_frozen is true.
|
96
|
+
void Protobuf_CheckNotFrozen(VALUE val, bool upb_frozen);
|
97
|
+
|
98
|
+
#define PBRUBY_MAX(x, y) (((x) > (y)) ? (x) : (y))
|
99
|
+
|
100
|
+
#define UPB_UNUSED(var) (void)var
|
101
|
+
|
102
|
+
#endif // __GOOGLE_PROTOBUF_RUBY_PROTOBUF_H__
|