google-protobuf 3.0.0.alpha.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

@@ -0,0 +1,755 @@
1
+ // Protocol Buffers - Google's data interchange format
2
+ // Copyright 2014 Google Inc. All rights reserved.
3
+ // https://developers.google.com/protocol-buffers/
4
+ //
5
+ // Redistribution and use in source and binary forms, with or without
6
+ // modification, are permitted provided that the following conditions are
7
+ // met:
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.
30
+
31
+ #include "protobuf.h"
32
+
33
+ // -----------------------------------------------------------------------------
34
+ // Parsing.
35
+ // -----------------------------------------------------------------------------
36
+
37
+ #define DEREF(msg, ofs, type) *(type*)(((uint8_t *)msg) + ofs)
38
+
39
+ // Creates a handlerdata that simply contains the offset for this field.
40
+ static const void* newhandlerdata(upb_handlers* h, uint32_t ofs) {
41
+ size_t* hd_ofs = ALLOC(size_t);
42
+ *hd_ofs = ofs;
43
+ upb_handlers_addcleanup(h, hd_ofs, free);
44
+ return hd_ofs;
45
+ }
46
+
47
+ typedef struct {
48
+ size_t ofs;
49
+ const upb_msgdef *md;
50
+ } submsg_handlerdata_t;
51
+
52
+ // Creates a handlerdata that contains offset and submessage type information.
53
+ static const void *newsubmsghandlerdata(upb_handlers* h, uint32_t ofs,
54
+ const upb_fielddef* f) {
55
+ submsg_handlerdata_t *hd = ALLOC(submsg_handlerdata_t);
56
+ hd->ofs = ofs;
57
+ hd->md = upb_fielddef_msgsubdef(f);
58
+ upb_handlers_addcleanup(h, hd, free);
59
+ return hd;
60
+ }
61
+
62
+ // A handler that starts a repeated field. Gets the Repeated*Field instance for
63
+ // this field (such an instance always exists even in an empty message).
64
+ static void *startseq_handler(void* closure, const void* hd) {
65
+ MessageHeader* msg = closure;
66
+ const size_t *ofs = hd;
67
+ return (void*)DEREF(Message_data(msg), *ofs, VALUE);
68
+ }
69
+
70
+ // Handlers that append primitive values to a repeated field (a regular Ruby
71
+ // array for now).
72
+ #define DEFINE_APPEND_HANDLER(type, ctype) \
73
+ static bool append##type##_handler(void *closure, const void *hd, \
74
+ ctype val) { \
75
+ VALUE ary = (VALUE)closure; \
76
+ RepeatedField_push_native(ary, &val); \
77
+ return true; \
78
+ }
79
+
80
+ DEFINE_APPEND_HANDLER(bool, bool)
81
+ DEFINE_APPEND_HANDLER(int32, int32_t)
82
+ DEFINE_APPEND_HANDLER(uint32, uint32_t)
83
+ DEFINE_APPEND_HANDLER(float, float)
84
+ DEFINE_APPEND_HANDLER(int64, int64_t)
85
+ DEFINE_APPEND_HANDLER(uint64, uint64_t)
86
+ DEFINE_APPEND_HANDLER(double, double)
87
+
88
+ // Appends a string to a repeated field (a regular Ruby array for now).
89
+ static void* appendstr_handler(void *closure,
90
+ const void *hd,
91
+ size_t size_hint) {
92
+ VALUE ary = (VALUE)closure;
93
+ VALUE str = rb_str_new2("");
94
+ rb_enc_associate(str, kRubyStringUtf8Encoding);
95
+ RepeatedField_push(ary, str);
96
+ return (void*)str;
97
+ }
98
+
99
+ // Appends a 'bytes' string to a repeated field (a regular Ruby array for now).
100
+ static void* appendbytes_handler(void *closure,
101
+ const void *hd,
102
+ size_t size_hint) {
103
+ VALUE ary = (VALUE)closure;
104
+ VALUE str = rb_str_new2("");
105
+ rb_enc_associate(str, kRubyString8bitEncoding);
106
+ RepeatedField_push(ary, str);
107
+ return (void*)str;
108
+ }
109
+
110
+ // Sets a non-repeated string field in a message.
111
+ static void* str_handler(void *closure,
112
+ const void *hd,
113
+ size_t size_hint) {
114
+ MessageHeader* msg = closure;
115
+ const size_t *ofs = hd;
116
+ VALUE str = rb_str_new2("");
117
+ rb_enc_associate(str, kRubyStringUtf8Encoding);
118
+ DEREF(Message_data(msg), *ofs, VALUE) = str;
119
+ return (void*)str;
120
+ }
121
+
122
+ // Sets a non-repeated 'bytes' field in a message.
123
+ static void* bytes_handler(void *closure,
124
+ const void *hd,
125
+ size_t size_hint) {
126
+ MessageHeader* msg = closure;
127
+ const size_t *ofs = hd;
128
+ VALUE str = rb_str_new2("");
129
+ rb_enc_associate(str, kRubyString8bitEncoding);
130
+ DEREF(Message_data(msg), *ofs, VALUE) = str;
131
+ return (void*)str;
132
+ }
133
+
134
+ static size_t stringdata_handler(void* closure, const void* hd,
135
+ const char* str, size_t len,
136
+ const upb_bufhandle* handle) {
137
+ VALUE rb_str = (VALUE)closure;
138
+ rb_str_cat(rb_str, str, len);
139
+ return len;
140
+ }
141
+
142
+ // Appends a submessage to a repeated field (a regular Ruby array for now).
143
+ static void *appendsubmsg_handler(void *closure, const void *hd) {
144
+ VALUE ary = (VALUE)closure;
145
+ const submsg_handlerdata_t *submsgdata = hd;
146
+ VALUE subdesc =
147
+ get_def_obj((void*)submsgdata->md);
148
+ VALUE subklass = Descriptor_msgclass(subdesc);
149
+
150
+ VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass);
151
+ RepeatedField_push(ary, submsg_rb);
152
+
153
+ MessageHeader* submsg;
154
+ TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
155
+ return submsg;
156
+ }
157
+
158
+ // Sets a non-repeated submessage field in a message.
159
+ static void *submsg_handler(void *closure, const void *hd) {
160
+ MessageHeader* msg = closure;
161
+ const submsg_handlerdata_t* submsgdata = hd;
162
+ VALUE subdesc =
163
+ get_def_obj((void*)submsgdata->md);
164
+ VALUE subklass = Descriptor_msgclass(subdesc);
165
+
166
+ if (DEREF(Message_data(msg), submsgdata->ofs, VALUE) == Qnil) {
167
+ DEREF(Message_data(msg), submsgdata->ofs, VALUE) =
168
+ rb_class_new_instance(0, NULL, subklass);
169
+ }
170
+
171
+ VALUE submsg_rb = DEREF(Message_data(msg), submsgdata->ofs, VALUE);
172
+ MessageHeader* submsg;
173
+ TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
174
+ return submsg;
175
+ }
176
+
177
+ static void add_handlers_for_message(const void *closure, upb_handlers *h) {
178
+ Descriptor* desc = ruby_to_Descriptor(
179
+ get_def_obj((void*)upb_handlers_msgdef(h)));
180
+ // Ensure layout exists. We may be invoked to create handlers for a given
181
+ // message if we are included as a submsg of another message type before our
182
+ // class is actually built, so to work around this, we just create the layout
183
+ // (and handlers, in the class-building function) on-demand.
184
+ if (desc->layout == NULL) {
185
+ desc->layout = create_layout(desc->msgdef);
186
+ }
187
+
188
+ upb_msg_iter i;
189
+
190
+ for (upb_msg_begin(&i, desc->msgdef);
191
+ !upb_msg_done(&i);
192
+ upb_msg_next(&i)) {
193
+ const upb_fielddef *f = upb_msg_iter_field(&i);
194
+ size_t offset = desc->layout->offsets[upb_fielddef_index(f)];
195
+
196
+ if (upb_fielddef_isseq(f)) {
197
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
198
+ upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
199
+ upb_handlers_setstartseq(h, f, startseq_handler, &attr);
200
+ upb_handlerattr_uninit(&attr);
201
+
202
+ switch (upb_fielddef_type(f)) {
203
+
204
+ #define SET_HANDLER(utype, ltype) \
205
+ case utype: \
206
+ upb_handlers_set##ltype(h, f, append##ltype##_handler, NULL); \
207
+ break;
208
+
209
+ SET_HANDLER(UPB_TYPE_BOOL, bool);
210
+ SET_HANDLER(UPB_TYPE_INT32, int32);
211
+ SET_HANDLER(UPB_TYPE_UINT32, uint32);
212
+ SET_HANDLER(UPB_TYPE_ENUM, int32);
213
+ SET_HANDLER(UPB_TYPE_FLOAT, float);
214
+ SET_HANDLER(UPB_TYPE_INT64, int64);
215
+ SET_HANDLER(UPB_TYPE_UINT64, uint64);
216
+ SET_HANDLER(UPB_TYPE_DOUBLE, double);
217
+
218
+ #undef SET_HANDLER
219
+
220
+ case UPB_TYPE_STRING:
221
+ case UPB_TYPE_BYTES: {
222
+ bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
223
+ upb_handlers_setstartstr(h, f, is_bytes ?
224
+ appendbytes_handler : appendstr_handler,
225
+ NULL);
226
+ upb_handlers_setstring(h, f, stringdata_handler, NULL);
227
+ }
228
+ case UPB_TYPE_MESSAGE: {
229
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
230
+ upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, 0, f));
231
+ upb_handlers_setstartsubmsg(h, f, appendsubmsg_handler, &attr);
232
+ upb_handlerattr_uninit(&attr);
233
+ break;
234
+ }
235
+ }
236
+ }
237
+
238
+ switch (upb_fielddef_type(f)) {
239
+ case UPB_TYPE_BOOL:
240
+ case UPB_TYPE_INT32:
241
+ case UPB_TYPE_UINT32:
242
+ case UPB_TYPE_ENUM:
243
+ case UPB_TYPE_FLOAT:
244
+ case UPB_TYPE_INT64:
245
+ case UPB_TYPE_UINT64:
246
+ case UPB_TYPE_DOUBLE:
247
+ // The shim writes directly at the given offset (instead of using
248
+ // DEREF()) so we need to add the msg overhead.
249
+ upb_shim_set(h, f, offset + sizeof(MessageHeader), -1);
250
+ break;
251
+ case UPB_TYPE_STRING:
252
+ case UPB_TYPE_BYTES: {
253
+ bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES;
254
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
255
+ upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset));
256
+ upb_handlers_setstartstr(h, f,
257
+ is_bytes ? bytes_handler : str_handler,
258
+ &attr);
259
+ upb_handlers_setstring(h, f, stringdata_handler, &attr);
260
+ upb_handlerattr_uninit(&attr);
261
+ break;
262
+ }
263
+ case UPB_TYPE_MESSAGE: {
264
+ upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
265
+ upb_handlerattr_sethandlerdata(&attr, newsubmsghandlerdata(h, offset, f));
266
+ upb_handlers_setstartsubmsg(h, f, submsg_handler, &attr);
267
+ upb_handlerattr_uninit(&attr);
268
+ break;
269
+ }
270
+ }
271
+ }
272
+ }
273
+
274
+ // Creates upb handlers for populating a message.
275
+ static const upb_handlers *new_fill_handlers(Descriptor* desc,
276
+ const void* owner) {
277
+ // TODO(cfallin, haberman): once upb gets a caching/memoization layer for
278
+ // handlers, reuse subdef handlers so that e.g. if we already parse
279
+ // B-with-field-of-type-C, we don't have to rebuild the whole hierarchy to
280
+ // parse A-with-field-of-type-B-with-field-of-type-C.
281
+ return upb_handlers_newfrozen(desc->msgdef, owner,
282
+ add_handlers_for_message, NULL);
283
+ }
284
+
285
+ // Constructs the handlers for filling a message's data into an in-memory
286
+ // object.
287
+ const upb_handlers* get_fill_handlers(Descriptor* desc) {
288
+ if (!desc->fill_handlers) {
289
+ desc->fill_handlers =
290
+ new_fill_handlers(desc, &desc->fill_handlers);
291
+ }
292
+ return desc->fill_handlers;
293
+ }
294
+
295
+ // Constructs the upb decoder method for parsing messages of this type.
296
+ // This is called from the message class creation code.
297
+ const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor* desc,
298
+ const void* owner) {
299
+ const upb_handlers* handlers = get_fill_handlers(desc);
300
+ upb_pbdecodermethodopts opts;
301
+ upb_pbdecodermethodopts_init(&opts, handlers);
302
+
303
+ const upb_pbdecodermethod *ret = upb_pbdecodermethod_new(&opts, owner);
304
+ return ret;
305
+ }
306
+
307
+ static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
308
+ if (desc->fill_method == NULL) {
309
+ desc->fill_method = new_fillmsg_decodermethod(
310
+ desc, &desc->fill_method);
311
+ }
312
+ return desc->fill_method;
313
+ }
314
+
315
+ /*
316
+ * call-seq:
317
+ * MessageClass.decode(data) => message
318
+ *
319
+ * Decodes the given data (as a string containing bytes in protocol buffers wire
320
+ * format) under the interpretration given by this message class's definition
321
+ * and returns a message object with the corresponding field values.
322
+ */
323
+ VALUE Message_decode(VALUE klass, VALUE data) {
324
+ VALUE descriptor = rb_iv_get(klass, kDescriptorInstanceVar);
325
+ Descriptor* desc = ruby_to_Descriptor(descriptor);
326
+ VALUE msgklass = Descriptor_msgclass(descriptor);
327
+
328
+ if (TYPE(data) != T_STRING) {
329
+ rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
330
+ }
331
+
332
+ VALUE msg_rb = rb_class_new_instance(0, NULL, msgklass);
333
+ MessageHeader* msg;
334
+ TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
335
+
336
+ const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
337
+ const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
338
+ upb_pbdecoder decoder;
339
+ upb_sink sink;
340
+ upb_status status = UPB_STATUS_INIT;
341
+
342
+ upb_pbdecoder_init(&decoder, method, &status);
343
+ upb_sink_reset(&sink, h, msg);
344
+ upb_pbdecoder_resetoutput(&decoder, &sink);
345
+ upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
346
+ upb_pbdecoder_input(&decoder));
347
+
348
+ upb_pbdecoder_uninit(&decoder);
349
+ if (!upb_ok(&status)) {
350
+ rb_raise(rb_eRuntimeError, "Error occurred during parsing: %s.",
351
+ upb_status_errmsg(&status));
352
+ }
353
+
354
+ return msg_rb;
355
+ }
356
+
357
+ /*
358
+ * call-seq:
359
+ * MessageClass.decode_json(data) => message
360
+ *
361
+ * Decodes the given data (as a string containing bytes in protocol buffers wire
362
+ * format) under the interpretration given by this message class's definition
363
+ * and returns a message object with the corresponding field values.
364
+ */
365
+ VALUE Message_decode_json(VALUE klass, VALUE data) {
366
+ VALUE descriptor = rb_iv_get(klass, kDescriptorInstanceVar);
367
+ Descriptor* desc = ruby_to_Descriptor(descriptor);
368
+ VALUE msgklass = Descriptor_msgclass(descriptor);
369
+
370
+ if (TYPE(data) != T_STRING) {
371
+ rb_raise(rb_eArgError, "Expected string for JSON data.");
372
+ }
373
+ // TODO(cfallin): Check and respect string encoding. If not UTF-8, we need to
374
+ // convert, because string handlers pass data directly to message string
375
+ // fields.
376
+
377
+ VALUE msg_rb = rb_class_new_instance(0, NULL, msgklass);
378
+ MessageHeader* msg;
379
+ TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
380
+
381
+ upb_status status = UPB_STATUS_INIT;
382
+ upb_json_parser parser;
383
+ upb_json_parser_init(&parser, &status);
384
+
385
+ upb_sink sink;
386
+ upb_sink_reset(&sink, get_fill_handlers(desc), msg);
387
+ upb_json_parser_resetoutput(&parser, &sink);
388
+ upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
389
+ upb_json_parser_input(&parser));
390
+
391
+ upb_json_parser_uninit(&parser);
392
+ if (!upb_ok(&status)) {
393
+ rb_raise(rb_eRuntimeError, "Error occurred during parsing: %s.",
394
+ upb_status_errmsg(&status));
395
+ }
396
+
397
+ return msg_rb;
398
+ }
399
+
400
+ // -----------------------------------------------------------------------------
401
+ // Serializing.
402
+ // -----------------------------------------------------------------------------
403
+ //
404
+ // The code below also comes from upb's prototype Ruby binding, developed by
405
+ // haberman@.
406
+
407
+ /* stringsink *****************************************************************/
408
+
409
+ // This should probably be factored into a common upb component.
410
+
411
+ typedef struct {
412
+ upb_byteshandler handler;
413
+ upb_bytessink sink;
414
+ char *ptr;
415
+ size_t len, size;
416
+ } stringsink;
417
+
418
+ static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
419
+ stringsink *sink = _sink;
420
+ sink->len = 0;
421
+ return sink;
422
+ }
423
+
424
+ static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
425
+ size_t len, const upb_bufhandle *handle) {
426
+ UPB_UNUSED(hd);
427
+ UPB_UNUSED(handle);
428
+
429
+ stringsink *sink = _sink;
430
+ size_t new_size = sink->size;
431
+
432
+ while (sink->len + len > new_size) {
433
+ new_size *= 2;
434
+ }
435
+
436
+ if (new_size != sink->size) {
437
+ sink->ptr = realloc(sink->ptr, new_size);
438
+ sink->size = new_size;
439
+ }
440
+
441
+ memcpy(sink->ptr + sink->len, ptr, len);
442
+ sink->len += len;
443
+
444
+ return len;
445
+ }
446
+
447
+ void stringsink_init(stringsink *sink) {
448
+ upb_byteshandler_init(&sink->handler);
449
+ upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
450
+ upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);
451
+
452
+ upb_bytessink_reset(&sink->sink, &sink->handler, sink);
453
+
454
+ sink->size = 32;
455
+ sink->ptr = malloc(sink->size);
456
+ sink->len = 0;
457
+ }
458
+
459
+ void stringsink_uninit(stringsink *sink) {
460
+ free(sink->ptr);
461
+ }
462
+
463
+ /* msgvisitor *****************************************************************/
464
+
465
+ // TODO: If/when we support proto2 semantics in addition to the current proto3
466
+ // semantics, which means that we have true field presence, we will want to
467
+ // modify msgvisitor so that it emits all present fields rather than all
468
+ // non-default-value fields.
469
+ //
470
+ // Likewise, when implementing JSON serialization, we may need to have a
471
+ // 'verbose' mode that outputs all fields and a 'concise' mode that outputs only
472
+ // those with non-default values.
473
+
474
+ static void putmsg(VALUE msg, const Descriptor* desc,
475
+ upb_sink *sink, int depth);
476
+
477
+ static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
478
+ upb_selector_t ret;
479
+ bool ok = upb_handlers_getselector(f, type, &ret);
480
+ UPB_ASSERT_VAR(ok, ok);
481
+ return ret;
482
+ }
483
+
484
+ static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
485
+ if (str == Qnil) return;
486
+
487
+ assert(BUILTIN_TYPE(str) == RUBY_T_STRING);
488
+ upb_sink subsink;
489
+
490
+ // Ensure that the string has the correct encoding. We also check at field-set
491
+ // time, but the user may have mutated the string object since then.
492
+ native_slot_validate_string_encoding(upb_fielddef_type(f), str);
493
+
494
+ upb_sink_startstr(sink, getsel(f, UPB_HANDLER_STARTSTR), RSTRING_LEN(str),
495
+ &subsink);
496
+ upb_sink_putstring(&subsink, getsel(f, UPB_HANDLER_STRING), RSTRING_PTR(str),
497
+ RSTRING_LEN(str), NULL);
498
+ upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR));
499
+ }
500
+
501
+ static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
502
+ int depth) {
503
+ if (submsg == Qnil) return;
504
+
505
+ upb_sink subsink;
506
+ VALUE descriptor = rb_iv_get(submsg, kDescriptorInstanceVar);
507
+ Descriptor* subdesc = ruby_to_Descriptor(descriptor);
508
+
509
+ upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
510
+ putmsg(submsg, subdesc, &subsink, depth + 1);
511
+ upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG));
512
+ }
513
+
514
+ static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
515
+ int depth) {
516
+ if (ary == Qnil) return;
517
+
518
+ upb_sink subsink;
519
+
520
+ upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
521
+
522
+ upb_fieldtype_t type = upb_fielddef_type(f);
523
+ upb_selector_t sel = 0;
524
+ if (upb_fielddef_isprimitive(f)) {
525
+ sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
526
+ }
527
+
528
+ int size = NUM2INT(RepeatedField_length(ary));
529
+ for (int i = 0; i < size; i++) {
530
+ void* memory = RepeatedField_index_native(ary, i);
531
+ switch (type) {
532
+ #define T(upbtypeconst, upbtype, ctype) \
533
+ case upbtypeconst: \
534
+ upb_sink_put##upbtype(&subsink, sel, *((ctype *)memory)); \
535
+ break;
536
+
537
+ T(UPB_TYPE_FLOAT, float, float)
538
+ T(UPB_TYPE_DOUBLE, double, double)
539
+ T(UPB_TYPE_BOOL, bool, int8_t)
540
+ case UPB_TYPE_ENUM:
541
+ T(UPB_TYPE_INT32, int32, int32_t)
542
+ T(UPB_TYPE_UINT32, uint32, uint32_t)
543
+ T(UPB_TYPE_INT64, int64, int64_t)
544
+ T(UPB_TYPE_UINT64, uint64, uint64_t)
545
+
546
+ case UPB_TYPE_STRING:
547
+ case UPB_TYPE_BYTES:
548
+ putstr(*((VALUE *)memory), f, &subsink);
549
+ break;
550
+ case UPB_TYPE_MESSAGE:
551
+ putsubmsg(*((VALUE *)memory), f, &subsink, depth);
552
+ break;
553
+
554
+ #undef T
555
+
556
+ }
557
+ }
558
+ upb_sink_endseq(sink, getsel(f, UPB_HANDLER_ENDSEQ));
559
+ }
560
+
561
+ static void putmsg(VALUE msg_rb, const Descriptor* desc,
562
+ upb_sink *sink, int depth) {
563
+ upb_sink_startmsg(sink);
564
+
565
+ // Protect against cycles (possible because users may freely reassign message
566
+ // and repeated fields) by imposing a maximum recursion depth.
567
+ if (depth > UPB_SINK_MAX_NESTING) {
568
+ rb_raise(rb_eRuntimeError,
569
+ "Maximum recursion depth exceeded during encoding.");
570
+ }
571
+
572
+ MessageHeader* msg;
573
+ TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
574
+ void* msg_data = Message_data(msg);
575
+
576
+ upb_msg_iter i;
577
+ for (upb_msg_begin(&i, desc->msgdef);
578
+ !upb_msg_done(&i);
579
+ upb_msg_next(&i)) {
580
+ upb_fielddef *f = upb_msg_iter_field(&i);
581
+ uint32_t offset = desc->layout->offsets[upb_fielddef_index(f)];
582
+
583
+ if (upb_fielddef_isseq(f)) {
584
+ VALUE ary = DEREF(msg_data, offset, VALUE);
585
+ if (ary != Qnil) {
586
+ putary(ary, f, sink, depth);
587
+ }
588
+ } else if (upb_fielddef_isstring(f)) {
589
+ VALUE str = DEREF(msg_data, offset, VALUE);
590
+ if (RSTRING_LEN(str) > 0) {
591
+ putstr(str, f, sink);
592
+ }
593
+ } else if (upb_fielddef_issubmsg(f)) {
594
+ putsubmsg(DEREF(msg_data, offset, VALUE), f, sink, depth);
595
+ } else {
596
+ upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
597
+
598
+ #define T(upbtypeconst, upbtype, ctype, default_value) \
599
+ case upbtypeconst: { \
600
+ ctype value = DEREF(msg_data, offset, ctype); \
601
+ if (value != default_value) { \
602
+ upb_sink_put##upbtype(sink, sel, value); \
603
+ } \
604
+ } \
605
+ break;
606
+
607
+ switch (upb_fielddef_type(f)) {
608
+ T(UPB_TYPE_FLOAT, float, float, 0.0)
609
+ T(UPB_TYPE_DOUBLE, double, double, 0.0)
610
+ T(UPB_TYPE_BOOL, bool, uint8_t, 0)
611
+ case UPB_TYPE_ENUM:
612
+ T(UPB_TYPE_INT32, int32, int32_t, 0)
613
+ T(UPB_TYPE_UINT32, uint32, uint32_t, 0)
614
+ T(UPB_TYPE_INT64, int64, int64_t, 0)
615
+ T(UPB_TYPE_UINT64, uint64, uint64_t, 0)
616
+
617
+ case UPB_TYPE_STRING:
618
+ case UPB_TYPE_BYTES:
619
+ case UPB_TYPE_MESSAGE: rb_raise(rb_eRuntimeError, "Internal error.");
620
+ }
621
+
622
+ #undef T
623
+
624
+ }
625
+ }
626
+
627
+ upb_status status;
628
+ upb_sink_endmsg(sink, &status);
629
+ }
630
+
631
+ static const upb_handlers* msgdef_pb_serialize_handlers(Descriptor* desc) {
632
+ if (desc->pb_serialize_handlers == NULL) {
633
+ desc->pb_serialize_handlers =
634
+ upb_pb_encoder_newhandlers(desc->msgdef, &desc->pb_serialize_handlers);
635
+ }
636
+ return desc->pb_serialize_handlers;
637
+ }
638
+
639
+ static const upb_handlers* msgdef_json_serialize_handlers(Descriptor* desc) {
640
+ if (desc->json_serialize_handlers == NULL) {
641
+ desc->json_serialize_handlers =
642
+ upb_json_printer_newhandlers(
643
+ desc->msgdef, &desc->json_serialize_handlers);
644
+ }
645
+ return desc->json_serialize_handlers;
646
+ }
647
+
648
+ /*
649
+ * call-seq:
650
+ * MessageClass.encode(msg) => bytes
651
+ *
652
+ * Encodes the given message object to its serialized form in protocol buffers
653
+ * wire format.
654
+ */
655
+ VALUE Message_encode(VALUE klass, VALUE msg_rb) {
656
+ VALUE descriptor = rb_iv_get(klass, kDescriptorInstanceVar);
657
+ Descriptor* desc = ruby_to_Descriptor(descriptor);
658
+
659
+ stringsink sink;
660
+ stringsink_init(&sink);
661
+
662
+ const upb_handlers* serialize_handlers =
663
+ msgdef_pb_serialize_handlers(desc);
664
+
665
+ upb_pb_encoder encoder;
666
+ upb_pb_encoder_init(&encoder, serialize_handlers);
667
+ upb_pb_encoder_resetoutput(&encoder, &sink.sink);
668
+
669
+ putmsg(msg_rb, desc, upb_pb_encoder_input(&encoder), 0);
670
+
671
+ VALUE ret = rb_str_new(sink.ptr, sink.len);
672
+
673
+ upb_pb_encoder_uninit(&encoder);
674
+ stringsink_uninit(&sink);
675
+
676
+ return ret;
677
+ }
678
+
679
+ /*
680
+ * call-seq:
681
+ * MessageClass.encode_json(msg) => json_string
682
+ *
683
+ * Encodes the given message object into its serialized JSON representation.
684
+ */
685
+ VALUE Message_encode_json(VALUE klass, VALUE msg_rb) {
686
+ VALUE descriptor = rb_iv_get(klass, kDescriptorInstanceVar);
687
+ Descriptor* desc = ruby_to_Descriptor(descriptor);
688
+
689
+ stringsink sink;
690
+ stringsink_init(&sink);
691
+
692
+ const upb_handlers* serialize_handlers =
693
+ msgdef_json_serialize_handlers(desc);
694
+
695
+ upb_json_printer printer;
696
+ upb_json_printer_init(&printer, serialize_handlers);
697
+ upb_json_printer_resetoutput(&printer, &sink.sink);
698
+
699
+ putmsg(msg_rb, desc, upb_json_printer_input(&printer), 0);
700
+
701
+ VALUE ret = rb_str_new(sink.ptr, sink.len);
702
+
703
+ upb_json_printer_uninit(&printer);
704
+ stringsink_uninit(&sink);
705
+
706
+ return ret;
707
+ }
708
+
709
+ /*
710
+ * call-seq:
711
+ * Google::Protobuf.encode(msg) => bytes
712
+ *
713
+ * Encodes the given message object to protocol buffers wire format. This is an
714
+ * alternative to the #encode method on msg's class.
715
+ */
716
+ VALUE Google_Protobuf_encode(VALUE self, VALUE msg_rb) {
717
+ VALUE klass = CLASS_OF(msg_rb);
718
+ return Message_encode(klass, msg_rb);
719
+ }
720
+
721
+ /*
722
+ * call-seq:
723
+ * Google::Protobuf.encode_json(msg) => json_string
724
+ *
725
+ * Encodes the given message object to its JSON representation. This is an
726
+ * alternative to the #encode_json method on msg's class.
727
+ */
728
+ VALUE Google_Protobuf_encode_json(VALUE self, VALUE msg_rb) {
729
+ VALUE klass = CLASS_OF(msg_rb);
730
+ return Message_encode_json(klass, msg_rb);
731
+ }
732
+
733
+ /*
734
+ * call-seq:
735
+ * Google::Protobuf.decode(class, bytes) => msg
736
+ *
737
+ * Decodes the given bytes as protocol buffers wire format under the
738
+ * interpretation given by the given class's message definition. This is an
739
+ * alternative to the #decode method on the given class.
740
+ */
741
+ VALUE Google_Protobuf_decode(VALUE self, VALUE klass, VALUE msg_rb) {
742
+ return Message_decode(klass, msg_rb);
743
+ }
744
+
745
+ /*
746
+ * call-seq:
747
+ * Google::Protobuf.decode_json(class, json_string) => msg
748
+ *
749
+ * Decodes the given JSON string under the interpretation given by the given
750
+ * class's message definition. This is an alternative to the #decode_json method
751
+ * on the given class.
752
+ */
753
+ VALUE Google_Protobuf_decode_json(VALUE self, VALUE klass, VALUE msg_rb) {
754
+ return Message_decode_json(klass, msg_rb);
755
+ }