google-protobuf 3.0.0.alpha.3.1.pre → 3.0.0.alpha.4.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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/defs.c +160 -83
- data/ext/google/protobuf_c/encode_decode.c +177 -144
- data/ext/google/protobuf_c/extconf.rb +1 -1
- data/ext/google/protobuf_c/map.c +15 -12
- data/ext/google/protobuf_c/message.c +104 -40
- data/ext/google/protobuf_c/protobuf.c +16 -6
- data/ext/google/protobuf_c/protobuf.h +11 -8
- data/ext/google/protobuf_c/repeated_field.c +138 -85
- data/ext/google/protobuf_c/storage.c +35 -20
- data/ext/google/protobuf_c/upb.c +3443 -2673
- data/ext/google/protobuf_c/upb.h +5086 -4919
- data/lib/google/protobuf.rb +36 -0
- data/lib/google/protobuf/message_exts.rb +53 -0
- data/lib/google/protobuf/repeated_field.rb +188 -0
- data/tests/basic.rb +119 -9
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b79422f7e8588e8b5f2d9243a59e26a6a4acb2f8
|
4
|
+
data.tar.gz: b6fae8259944a6a136118a271aea105ef56144ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ec76a4aca5a8b869530e0c40ed71802b7a874d638f530657d5577d76237abeb00a087c8be4b5bddfc1fdc9da33baf76e29bbf2d4beef17f0f79c5524fb4a878
|
7
|
+
data.tar.gz: a17338fc9dd440fc746869a41f45d1fa3319e7d4f0e1a961bb47435586b5d114c9ad2f16e3c965dfbe567e588d5e29df38c396f677dce662b0f7beadcd21a9f7
|
@@ -34,8 +34,6 @@
|
|
34
34
|
// Common utilities.
|
35
35
|
// -----------------------------------------------------------------------------
|
36
36
|
|
37
|
-
const char* kDescriptorInstanceVar = "descriptor";
|
38
|
-
|
39
37
|
static const char* get_str(VALUE str) {
|
40
38
|
Check_Type(str, T_STRING);
|
41
39
|
return RSTRING_PTR(str);
|
@@ -90,7 +88,7 @@ static upb_enumdef* check_enum_notfrozen(const upb_enumdef* def) {
|
|
90
88
|
} \
|
91
89
|
|
92
90
|
#define DEFINE_SELF(type, var, rb_var) \
|
93
|
-
type* var = ruby_to_ ## type(rb_var)
|
91
|
+
type* var = ruby_to_ ## type(rb_var)
|
94
92
|
|
95
93
|
// Global singleton DescriptorPool. The user is free to create others, but this
|
96
94
|
// is used by generated code.
|
@@ -548,11 +546,9 @@ upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
|
|
548
546
|
rb_raise(rb_eArgError, "Expected symbol for field type.");
|
549
547
|
}
|
550
548
|
|
551
|
-
upb_fieldtype_t upb_type = -1;
|
552
|
-
|
553
549
|
#define CONVERT(upb, ruby) \
|
554
550
|
if (SYM2ID(type) == rb_intern( # ruby )) { \
|
555
|
-
|
551
|
+
return UPB_TYPE_ ## upb; \
|
556
552
|
}
|
557
553
|
|
558
554
|
CONVERT(FLOAT, float);
|
@@ -569,11 +565,8 @@ upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
|
|
569
565
|
|
570
566
|
#undef CONVERT
|
571
567
|
|
572
|
-
|
573
|
-
|
574
|
-
}
|
575
|
-
|
576
|
-
return upb_type;
|
568
|
+
rb_raise(rb_eArgError, "Unknown field type.");
|
569
|
+
return 0;
|
577
570
|
}
|
578
571
|
|
579
572
|
VALUE fieldtype_to_ruby(upb_fieldtype_t type) {
|
@@ -596,6 +589,68 @@ VALUE fieldtype_to_ruby(upb_fieldtype_t type) {
|
|
596
589
|
return Qnil;
|
597
590
|
}
|
598
591
|
|
592
|
+
upb_descriptortype_t ruby_to_descriptortype(VALUE type) {
|
593
|
+
if (TYPE(type) != T_SYMBOL) {
|
594
|
+
rb_raise(rb_eArgError, "Expected symbol for field type.");
|
595
|
+
}
|
596
|
+
|
597
|
+
#define CONVERT(upb, ruby) \
|
598
|
+
if (SYM2ID(type) == rb_intern( # ruby )) { \
|
599
|
+
return UPB_DESCRIPTOR_TYPE_ ## upb; \
|
600
|
+
}
|
601
|
+
|
602
|
+
CONVERT(FLOAT, float);
|
603
|
+
CONVERT(DOUBLE, double);
|
604
|
+
CONVERT(BOOL, bool);
|
605
|
+
CONVERT(STRING, string);
|
606
|
+
CONVERT(BYTES, bytes);
|
607
|
+
CONVERT(MESSAGE, message);
|
608
|
+
CONVERT(GROUP, group);
|
609
|
+
CONVERT(ENUM, enum);
|
610
|
+
CONVERT(INT32, int32);
|
611
|
+
CONVERT(INT64, int64);
|
612
|
+
CONVERT(UINT32, uint32);
|
613
|
+
CONVERT(UINT64, uint64);
|
614
|
+
CONVERT(SINT32, sint32);
|
615
|
+
CONVERT(SINT64, sint64);
|
616
|
+
CONVERT(FIXED32, fixed32);
|
617
|
+
CONVERT(FIXED64, fixed64);
|
618
|
+
CONVERT(SFIXED32, sfixed32);
|
619
|
+
CONVERT(SFIXED64, sfixed64);
|
620
|
+
|
621
|
+
#undef CONVERT
|
622
|
+
|
623
|
+
rb_raise(rb_eArgError, "Unknown field type.");
|
624
|
+
return 0;
|
625
|
+
}
|
626
|
+
|
627
|
+
VALUE descriptortype_to_ruby(upb_descriptortype_t type) {
|
628
|
+
switch (type) {
|
629
|
+
#define CONVERT(upb, ruby) \
|
630
|
+
case UPB_DESCRIPTOR_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
|
631
|
+
CONVERT(FLOAT, float);
|
632
|
+
CONVERT(DOUBLE, double);
|
633
|
+
CONVERT(BOOL, bool);
|
634
|
+
CONVERT(STRING, string);
|
635
|
+
CONVERT(BYTES, bytes);
|
636
|
+
CONVERT(MESSAGE, message);
|
637
|
+
CONVERT(GROUP, group);
|
638
|
+
CONVERT(ENUM, enum);
|
639
|
+
CONVERT(INT32, int32);
|
640
|
+
CONVERT(INT64, int64);
|
641
|
+
CONVERT(UINT32, uint32);
|
642
|
+
CONVERT(UINT64, uint64);
|
643
|
+
CONVERT(SINT32, sint32);
|
644
|
+
CONVERT(SINT64, sint64);
|
645
|
+
CONVERT(FIXED32, fixed32);
|
646
|
+
CONVERT(FIXED64, fixed64);
|
647
|
+
CONVERT(SFIXED32, sfixed32);
|
648
|
+
CONVERT(SFIXED64, sfixed64);
|
649
|
+
#undef CONVERT
|
650
|
+
}
|
651
|
+
return Qnil;
|
652
|
+
}
|
653
|
+
|
599
654
|
/*
|
600
655
|
* call-seq:
|
601
656
|
* FieldDescriptor.type => type
|
@@ -611,7 +666,7 @@ VALUE FieldDescriptor_type(VALUE _self) {
|
|
611
666
|
if (!upb_fielddef_typeisset(self->fielddef)) {
|
612
667
|
return Qnil;
|
613
668
|
}
|
614
|
-
return
|
669
|
+
return descriptortype_to_ruby(upb_fielddef_descriptortype(self->fielddef));
|
615
670
|
}
|
616
671
|
|
617
672
|
/*
|
@@ -624,7 +679,7 @@ VALUE FieldDescriptor_type(VALUE _self) {
|
|
624
679
|
VALUE FieldDescriptor_type_set(VALUE _self, VALUE type) {
|
625
680
|
DEFINE_SELF(FieldDescriptor, self, _self);
|
626
681
|
upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
|
627
|
-
|
682
|
+
upb_fielddef_setdescriptortype(mut_def, ruby_to_descriptortype(type));
|
628
683
|
return Qnil;
|
629
684
|
}
|
630
685
|
|
@@ -663,15 +718,17 @@ VALUE FieldDescriptor_label(VALUE _self) {
|
|
663
718
|
VALUE FieldDescriptor_label_set(VALUE _self, VALUE label) {
|
664
719
|
DEFINE_SELF(FieldDescriptor, self, _self);
|
665
720
|
upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
|
721
|
+
upb_label_t upb_label = -1;
|
722
|
+
bool converted = false;
|
723
|
+
|
666
724
|
if (TYPE(label) != T_SYMBOL) {
|
667
725
|
rb_raise(rb_eArgError, "Expected symbol for field label.");
|
668
726
|
}
|
669
727
|
|
670
|
-
upb_label_t upb_label = -1;
|
671
|
-
|
672
728
|
#define CONVERT(upb, ruby) \
|
673
729
|
if (SYM2ID(label) == rb_intern( # ruby )) { \
|
674
730
|
upb_label = UPB_LABEL_ ## upb; \
|
731
|
+
converted = true; \
|
675
732
|
}
|
676
733
|
|
677
734
|
CONVERT(OPTIONAL, optional);
|
@@ -680,7 +737,7 @@ VALUE FieldDescriptor_label_set(VALUE _self, VALUE label) {
|
|
680
737
|
|
681
738
|
#undef CONVERT
|
682
739
|
|
683
|
-
if (
|
740
|
+
if (!converted) {
|
684
741
|
rb_raise(rb_eArgError, "Unknown field label.");
|
685
742
|
}
|
686
743
|
|
@@ -745,10 +802,10 @@ VALUE FieldDescriptor_submsg_name(VALUE _self) {
|
|
745
802
|
VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
|
746
803
|
DEFINE_SELF(FieldDescriptor, self, _self);
|
747
804
|
upb_fielddef* mut_def = check_field_notfrozen(self->fielddef);
|
805
|
+
const char* str = get_str(value);
|
748
806
|
if (!upb_fielddef_hassubdef(self->fielddef)) {
|
749
807
|
rb_raise(rb_eTypeError, "FieldDescriptor does not have subdef.");
|
750
808
|
}
|
751
|
-
const char* str = get_str(value);
|
752
809
|
CHECK_UPB(upb_fielddef_setsubdefname(mut_def, str, &status),
|
753
810
|
"Error setting submessage name");
|
754
811
|
return Qnil;
|
@@ -765,10 +822,12 @@ VALUE FieldDescriptor_submsg_name_set(VALUE _self, VALUE value) {
|
|
765
822
|
*/
|
766
823
|
VALUE FieldDescriptor_subtype(VALUE _self) {
|
767
824
|
DEFINE_SELF(FieldDescriptor, self, _self);
|
825
|
+
const upb_def* def;
|
826
|
+
|
768
827
|
if (!upb_fielddef_hassubdef(self->fielddef)) {
|
769
828
|
return Qnil;
|
770
829
|
}
|
771
|
-
|
830
|
+
def = upb_fielddef_subdef(self->fielddef);
|
772
831
|
if (def == NULL) {
|
773
832
|
return Qnil;
|
774
833
|
}
|
@@ -1192,14 +1251,15 @@ static VALUE msgdef_add_field(VALUE msgdef,
|
|
1192
1251
|
*/
|
1193
1252
|
VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
1194
1253
|
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1254
|
+
VALUE name, type, number, type_class;
|
1195
1255
|
|
1196
1256
|
if (argc < 3) {
|
1197
1257
|
rb_raise(rb_eArgError, "Expected at least 3 arguments.");
|
1198
1258
|
}
|
1199
|
-
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1259
|
+
name = argv[0];
|
1260
|
+
type = argv[1];
|
1261
|
+
number = argv[2];
|
1262
|
+
type_class = (argc > 3) ? argv[3] : Qnil;
|
1203
1263
|
|
1204
1264
|
return msgdef_add_field(self->descriptor, "optional",
|
1205
1265
|
name, type, number, type_class);
|
@@ -1220,14 +1280,15 @@ VALUE MessageBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
|
1220
1280
|
*/
|
1221
1281
|
VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
|
1222
1282
|
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1283
|
+
VALUE name, type, number, type_class;
|
1223
1284
|
|
1224
1285
|
if (argc < 3) {
|
1225
1286
|
rb_raise(rb_eArgError, "Expected at least 3 arguments.");
|
1226
1287
|
}
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
|
1288
|
+
name = argv[0];
|
1289
|
+
type = argv[1];
|
1290
|
+
number = argv[2];
|
1291
|
+
type_class = (argc > 3) ? argv[3] : Qnil;
|
1231
1292
|
|
1232
1293
|
return msgdef_add_field(self->descriptor, "required",
|
1233
1294
|
name, type, number, type_class);
|
@@ -1244,14 +1305,15 @@ VALUE MessageBuilderContext_required(int argc, VALUE* argv, VALUE _self) {
|
|
1244
1305
|
*/
|
1245
1306
|
VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
|
1246
1307
|
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1308
|
+
VALUE name, type, number, type_class;
|
1247
1309
|
|
1248
1310
|
if (argc < 3) {
|
1249
1311
|
rb_raise(rb_eArgError, "Expected at least 3 arguments.");
|
1250
1312
|
}
|
1251
|
-
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1313
|
+
name = argv[0];
|
1314
|
+
type = argv[1];
|
1315
|
+
number = argv[2];
|
1316
|
+
type_class = (argc > 3) ? argv[3] : Qnil;
|
1255
1317
|
|
1256
1318
|
return msgdef_add_field(self->descriptor, "repeated",
|
1257
1319
|
name, type, number, type_class);
|
@@ -1271,15 +1333,17 @@ VALUE MessageBuilderContext_repeated(int argc, VALUE* argv, VALUE _self) {
|
|
1271
1333
|
*/
|
1272
1334
|
VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
|
1273
1335
|
DEFINE_SELF(MessageBuilderContext, self, _self);
|
1336
|
+
VALUE name, key_type, value_type, number, type_class;
|
1337
|
+
VALUE mapentry_desc, mapentry_desc_name;
|
1274
1338
|
|
1275
1339
|
if (argc < 4) {
|
1276
1340
|
rb_raise(rb_eArgError, "Expected at least 4 arguments.");
|
1277
1341
|
}
|
1278
|
-
|
1279
|
-
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1342
|
+
name = argv[0];
|
1343
|
+
key_type = argv[1];
|
1344
|
+
value_type = argv[2];
|
1345
|
+
number = argv[3];
|
1346
|
+
type_class = (argc > 4) ? argv[4] : Qnil;
|
1283
1347
|
|
1284
1348
|
// Validate the key type. We can't accept enums, messages, or floats/doubles
|
1285
1349
|
// as map keys. (We exclude these explicitly, and the field-descriptor setter
|
@@ -1295,55 +1359,67 @@ VALUE MessageBuilderContext_map(int argc, VALUE* argv, VALUE _self) {
|
|
1295
1359
|
|
1296
1360
|
// Create a new message descriptor for the map entry message, and create a
|
1297
1361
|
// repeated submessage field here with that type.
|
1298
|
-
|
1299
|
-
|
1362
|
+
mapentry_desc = rb_class_new_instance(0, NULL, cDescriptor);
|
1363
|
+
mapentry_desc_name = rb_funcall(self->descriptor, rb_intern("name"), 0);
|
1300
1364
|
mapentry_desc_name = rb_str_cat2(mapentry_desc_name, "_MapEntry_");
|
1301
1365
|
mapentry_desc_name = rb_str_cat2(mapentry_desc_name,
|
1302
1366
|
rb_id2name(SYM2ID(name)));
|
1303
1367
|
Descriptor_name_set(mapentry_desc, mapentry_desc_name);
|
1304
1368
|
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
// optional <type> key = 1;
|
1312
|
-
VALUE key_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
|
1313
|
-
FieldDescriptor_name_set(key_field, rb_str_new2("key"));
|
1314
|
-
FieldDescriptor_label_set(key_field, ID2SYM(rb_intern("optional")));
|
1315
|
-
FieldDescriptor_number_set(key_field, INT2NUM(1));
|
1316
|
-
FieldDescriptor_type_set(key_field, key_type);
|
1317
|
-
Descriptor_add_field(mapentry_desc, key_field);
|
1318
|
-
|
1319
|
-
// optional <type> value = 2;
|
1320
|
-
VALUE value_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
|
1321
|
-
FieldDescriptor_name_set(value_field, rb_str_new2("value"));
|
1322
|
-
FieldDescriptor_label_set(value_field, ID2SYM(rb_intern("optional")));
|
1323
|
-
FieldDescriptor_number_set(value_field, INT2NUM(2));
|
1324
|
-
FieldDescriptor_type_set(value_field, value_type);
|
1325
|
-
if (type_class != Qnil) {
|
1326
|
-
VALUE submsg_name = rb_str_new2("."); // prepend '.' to make name absolute.
|
1327
|
-
submsg_name = rb_str_append(submsg_name, type_class);
|
1328
|
-
FieldDescriptor_submsg_name_set(value_field, submsg_name);
|
1369
|
+
{
|
1370
|
+
// The 'mapentry' attribute has no Ruby setter because we do not want the
|
1371
|
+
// user attempting to DIY the setup below; we want to ensure that the fields
|
1372
|
+
// are correct. So we reach into the msgdef here to set the bit manually.
|
1373
|
+
Descriptor* mapentry_desc_self = ruby_to_Descriptor(mapentry_desc);
|
1374
|
+
upb_msgdef_setmapentry((upb_msgdef*)mapentry_desc_self->msgdef, true);
|
1329
1375
|
}
|
1330
|
-
Descriptor_add_field(mapentry_desc, value_field);
|
1331
1376
|
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1377
|
+
{
|
1378
|
+
// optional <type> key = 1;
|
1379
|
+
VALUE key_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
|
1380
|
+
FieldDescriptor_name_set(key_field, rb_str_new2("key"));
|
1381
|
+
FieldDescriptor_label_set(key_field, ID2SYM(rb_intern("optional")));
|
1382
|
+
FieldDescriptor_number_set(key_field, INT2NUM(1));
|
1383
|
+
FieldDescriptor_type_set(key_field, key_type);
|
1384
|
+
Descriptor_add_field(mapentry_desc, key_field);
|
1385
|
+
}
|
1336
1386
|
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
1346
|
-
|
1387
|
+
{
|
1388
|
+
// optional <type> value = 2;
|
1389
|
+
VALUE value_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
|
1390
|
+
FieldDescriptor_name_set(value_field, rb_str_new2("value"));
|
1391
|
+
FieldDescriptor_label_set(value_field, ID2SYM(rb_intern("optional")));
|
1392
|
+
FieldDescriptor_number_set(value_field, INT2NUM(2));
|
1393
|
+
FieldDescriptor_type_set(value_field, value_type);
|
1394
|
+
if (type_class != Qnil) {
|
1395
|
+
VALUE submsg_name = rb_str_new2("."); // prepend '.' to make absolute.
|
1396
|
+
submsg_name = rb_str_append(submsg_name, type_class);
|
1397
|
+
FieldDescriptor_submsg_name_set(value_field, submsg_name);
|
1398
|
+
}
|
1399
|
+
Descriptor_add_field(mapentry_desc, value_field);
|
1400
|
+
}
|
1401
|
+
|
1402
|
+
{
|
1403
|
+
// Add the map-entry message type to the current builder, and use the type
|
1404
|
+
// to create the map field itself.
|
1405
|
+
Builder* builder_self = ruby_to_Builder(self->builder);
|
1406
|
+
rb_ary_push(builder_self->pending_list, mapentry_desc);
|
1407
|
+
}
|
1408
|
+
|
1409
|
+
{
|
1410
|
+
VALUE map_field = rb_class_new_instance(0, NULL, cFieldDescriptor);
|
1411
|
+
VALUE name_str = rb_str_new2(rb_id2name(SYM2ID(name)));
|
1412
|
+
VALUE submsg_name;
|
1413
|
+
|
1414
|
+
FieldDescriptor_name_set(map_field, name_str);
|
1415
|
+
FieldDescriptor_number_set(map_field, number);
|
1416
|
+
FieldDescriptor_label_set(map_field, ID2SYM(rb_intern("repeated")));
|
1417
|
+
FieldDescriptor_type_set(map_field, ID2SYM(rb_intern("message")));
|
1418
|
+
submsg_name = rb_str_new2("."); // prepend '.' to make name absolute.
|
1419
|
+
submsg_name = rb_str_append(submsg_name, mapentry_desc_name);
|
1420
|
+
FieldDescriptor_submsg_name_set(map_field, submsg_name);
|
1421
|
+
Descriptor_add_field(self->descriptor, map_field);
|
1422
|
+
}
|
1347
1423
|
|
1348
1424
|
return Qnil;
|
1349
1425
|
}
|
@@ -1439,14 +1515,15 @@ VALUE OneofBuilderContext_initialize(VALUE _self,
|
|
1439
1515
|
*/
|
1440
1516
|
VALUE OneofBuilderContext_optional(int argc, VALUE* argv, VALUE _self) {
|
1441
1517
|
DEFINE_SELF(OneofBuilderContext, self, _self);
|
1518
|
+
VALUE name, type, number, type_class;
|
1442
1519
|
|
1443
1520
|
if (argc < 3) {
|
1444
1521
|
rb_raise(rb_eArgError, "Expected at least 3 arguments.");
|
1445
1522
|
}
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1523
|
+
name = argv[0];
|
1524
|
+
type = argv[1];
|
1525
|
+
number = argv[2];
|
1526
|
+
type_class = (argc > 3) ? argv[3] : Qnil;
|
1450
1527
|
|
1451
1528
|
return msgdef_add_field(self->descriptor, "optional",
|
1452
1529
|
name, type, number, type_class);
|
@@ -1590,9 +1667,9 @@ VALUE Builder_add_message(VALUE _self, VALUE name) {
|
|
1590
1667
|
* call-seq:
|
1591
1668
|
* Builder.add_enum(name, &block)
|
1592
1669
|
*
|
1593
|
-
* Creates a new, empty enum descriptor with the given name, and invokes the
|
1594
|
-
* the context of an EnumBuilderContext on that descriptor. The block
|
1595
|
-
* call EnumBuilderContext#add_value to define the enum values.
|
1670
|
+
* Creates a new, empty enum descriptor with the given name, and invokes the
|
1671
|
+
* block in the context of an EnumBuilderContext on that descriptor. The block
|
1672
|
+
* can then call EnumBuilderContext#add_value to define the enum values.
|
1596
1673
|
*
|
1597
1674
|
* This is the recommended, idiomatic way to build enum definitions.
|
1598
1675
|
*/
|
@@ -30,6 +30,20 @@
|
|
30
30
|
|
31
31
|
#include "protobuf.h"
|
32
32
|
|
33
|
+
// This function is equivalent to rb_str_cat(), but unlike the real
|
34
|
+
// rb_str_cat(), it doesn't leak memory in some versions of Ruby.
|
35
|
+
// For more information, see:
|
36
|
+
// https://bugs.ruby-lang.org/issues/11328
|
37
|
+
VALUE noleak_rb_str_cat(VALUE rb_str, const char *str, long len) {
|
38
|
+
char *p;
|
39
|
+
size_t oldlen = RSTRING_LEN(rb_str);
|
40
|
+
rb_str_modify_expand(rb_str, len);
|
41
|
+
p = RSTRING_PTR(rb_str);
|
42
|
+
memcpy(p + oldlen, str, len);
|
43
|
+
rb_str_set_len(rb_str, oldlen + len);
|
44
|
+
return rb_str;
|
45
|
+
}
|
46
|
+
|
33
47
|
// -----------------------------------------------------------------------------
|
34
48
|
// Parsing.
|
35
49
|
// -----------------------------------------------------------------------------
|
@@ -164,7 +178,7 @@ static size_t stringdata_handler(void* closure, const void* hd,
|
|
164
178
|
const char* str, size_t len,
|
165
179
|
const upb_bufhandle* handle) {
|
166
180
|
VALUE rb_str = (VALUE)closure;
|
167
|
-
|
181
|
+
noleak_rb_str_cat(rb_str, str, len);
|
168
182
|
return len;
|
169
183
|
}
|
170
184
|
|
@@ -175,11 +189,11 @@ static void *appendsubmsg_handler(void *closure, const void *hd) {
|
|
175
189
|
VALUE subdesc =
|
176
190
|
get_def_obj((void*)submsgdata->md);
|
177
191
|
VALUE subklass = Descriptor_msgclass(subdesc);
|
192
|
+
MessageHeader* submsg;
|
178
193
|
|
179
194
|
VALUE submsg_rb = rb_class_new_instance(0, NULL, subklass);
|
180
195
|
RepeatedField_push(ary, submsg_rb);
|
181
196
|
|
182
|
-
MessageHeader* submsg;
|
183
197
|
TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
|
184
198
|
return submsg;
|
185
199
|
}
|
@@ -191,14 +205,15 @@ static void *submsg_handler(void *closure, const void *hd) {
|
|
191
205
|
VALUE subdesc =
|
192
206
|
get_def_obj((void*)submsgdata->md);
|
193
207
|
VALUE subklass = Descriptor_msgclass(subdesc);
|
208
|
+
VALUE submsg_rb;
|
209
|
+
MessageHeader* submsg;
|
194
210
|
|
195
211
|
if (DEREF(msg, submsgdata->ofs, VALUE) == Qnil) {
|
196
212
|
DEREF(msg, submsgdata->ofs, VALUE) =
|
197
213
|
rb_class_new_instance(0, NULL, subklass);
|
198
214
|
}
|
199
215
|
|
200
|
-
|
201
|
-
MessageHeader* submsg;
|
216
|
+
submsg_rb = DEREF(msg, submsgdata->ofs, VALUE);
|
202
217
|
TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
|
203
218
|
return submsg;
|
204
219
|
}
|
@@ -254,12 +269,14 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
|
|
254
269
|
&frame->key_storage);
|
255
270
|
|
256
271
|
VALUE value_field_typeclass = Qnil;
|
272
|
+
VALUE value;
|
273
|
+
|
257
274
|
if (mapdata->value_field_type == UPB_TYPE_MESSAGE ||
|
258
275
|
mapdata->value_field_type == UPB_TYPE_ENUM) {
|
259
276
|
value_field_typeclass = get_def_obj(mapdata->value_field_subdef);
|
260
277
|
}
|
261
278
|
|
262
|
-
|
279
|
+
value = native_slot_get(
|
263
280
|
mapdata->value_field_type, value_field_typeclass,
|
264
281
|
&frame->value_storage);
|
265
282
|
|
@@ -280,15 +297,14 @@ static map_handlerdata_t* new_map_handlerdata(
|
|
280
297
|
size_t ofs,
|
281
298
|
const upb_msgdef* mapentry_def,
|
282
299
|
Descriptor* desc) {
|
283
|
-
|
300
|
+
const upb_fielddef* key_field;
|
301
|
+
const upb_fielddef* value_field;
|
284
302
|
map_handlerdata_t* hd = ALLOC(map_handlerdata_t);
|
285
303
|
hd->ofs = ofs;
|
286
|
-
|
287
|
-
MAP_KEY_FIELD);
|
304
|
+
key_field = upb_msgdef_itof(mapentry_def, MAP_KEY_FIELD);
|
288
305
|
assert(key_field != NULL);
|
289
306
|
hd->key_field_type = upb_fielddef_type(key_field);
|
290
|
-
|
291
|
-
MAP_VALUE_FIELD);
|
307
|
+
value_field = upb_msgdef_itof(mapentry_def, MAP_VALUE_FIELD);
|
292
308
|
assert(value_field != NULL);
|
293
309
|
hd->value_field_type = upb_fielddef_type(value_field);
|
294
310
|
hd->value_field_subdef = upb_fielddef_subdef(value_field);
|
@@ -354,6 +370,8 @@ static void *oneofsubmsg_handler(void *closure,
|
|
354
370
|
VALUE subdesc =
|
355
371
|
get_def_obj((void*)oneofdata->md);
|
356
372
|
VALUE subklass = Descriptor_msgclass(subdesc);
|
373
|
+
VALUE submsg_rb;
|
374
|
+
MessageHeader* submsg;
|
357
375
|
|
358
376
|
if (oldcase != oneofdata->oneof_case_num ||
|
359
377
|
DEREF(msg, oneofdata->ofs, VALUE) == Qnil) {
|
@@ -369,8 +387,7 @@ static void *oneofsubmsg_handler(void *closure,
|
|
369
387
|
DEREF(msg, oneofdata->case_ofs, uint32_t) =
|
370
388
|
oneofdata->oneof_case_num;
|
371
389
|
|
372
|
-
|
373
|
-
MessageHeader* submsg;
|
390
|
+
submsg_rb = DEREF(msg, oneofdata->ofs, VALUE);
|
374
391
|
TypedData_Get_Struct(submsg_rb, MessageHeader, &Message_type, submsg);
|
375
392
|
return submsg;
|
376
393
|
}
|
@@ -465,8 +482,9 @@ static void add_handlers_for_mapfield(upb_handlers* h,
|
|
465
482
|
Descriptor* desc) {
|
466
483
|
const upb_msgdef* map_msgdef = upb_fielddef_msgsubdef(fielddef);
|
467
484
|
map_handlerdata_t* hd = new_map_handlerdata(offset, map_msgdef, desc);
|
468
|
-
upb_handlers_addcleanup(h, hd, free);
|
469
485
|
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
|
486
|
+
|
487
|
+
upb_handlers_addcleanup(h, hd, free);
|
470
488
|
upb_handlerattr_sethandlerdata(&attr, hd);
|
471
489
|
upb_handlers_setstartsubmsg(h, fielddef, startmapentry_handler, &attr);
|
472
490
|
upb_handlerattr_uninit(&attr);
|
@@ -479,8 +497,9 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef,
|
|
479
497
|
const upb_fielddef* key_field = map_entry_key(msgdef);
|
480
498
|
const upb_fielddef* value_field = map_entry_value(msgdef);
|
481
499
|
map_handlerdata_t* hd = new_map_handlerdata(0, msgdef, desc);
|
482
|
-
upb_handlers_addcleanup(h, hd, free);
|
483
500
|
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
|
501
|
+
|
502
|
+
upb_handlers_addcleanup(h, hd, free);
|
484
503
|
upb_handlerattr_sethandlerdata(&attr, hd);
|
485
504
|
upb_handlers_setendmsg(h, endmap_handler, &attr);
|
486
505
|
|
@@ -542,6 +561,7 @@ static void add_handlers_for_oneof_field(upb_handlers *h,
|
|
542
561
|
static void add_handlers_for_message(const void *closure, upb_handlers *h) {
|
543
562
|
const upb_msgdef* msgdef = upb_handlers_msgdef(h);
|
544
563
|
Descriptor* desc = ruby_to_Descriptor(get_def_obj((void*)msgdef));
|
564
|
+
upb_msg_field_iter i;
|
545
565
|
|
546
566
|
// If this is a mapentry message type, set up a special set of handlers and
|
547
567
|
// bail out of the normal (user-defined) message type handling.
|
@@ -558,7 +578,6 @@ static void add_handlers_for_message(const void *closure, upb_handlers *h) {
|
|
558
578
|
desc->layout = create_layout(desc->msgdef);
|
559
579
|
}
|
560
580
|
|
561
|
-
upb_msg_field_iter i;
|
562
581
|
for (upb_msg_field_begin(&i, desc->msgdef);
|
563
582
|
!upb_msg_field_done(&i);
|
564
583
|
upb_msg_field_next(&i)) {
|
@@ -610,8 +629,7 @@ const upb_pbdecodermethod *new_fillmsg_decodermethod(Descriptor* desc,
|
|
610
629
|
upb_pbdecodermethodopts opts;
|
611
630
|
upb_pbdecodermethodopts_init(&opts, handlers);
|
612
631
|
|
613
|
-
|
614
|
-
return ret;
|
632
|
+
return upb_pbdecodermethod_new(&opts, owner);
|
615
633
|
}
|
616
634
|
|
617
635
|
static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
|
@@ -622,6 +640,51 @@ static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
|
|
622
640
|
return desc->fill_method;
|
623
641
|
}
|
624
642
|
|
643
|
+
|
644
|
+
// Stack-allocated context during an encode/decode operation. Contains the upb
|
645
|
+
// environment and its stack-based allocator, an initial buffer for allocations
|
646
|
+
// to avoid malloc() when possible, and a template for Ruby exception messages
|
647
|
+
// if any error occurs.
|
648
|
+
#define STACK_ENV_STACKBYTES 4096
|
649
|
+
typedef struct {
|
650
|
+
upb_env env;
|
651
|
+
upb_seededalloc alloc;
|
652
|
+
const char* ruby_error_template;
|
653
|
+
char allocbuf[STACK_ENV_STACKBYTES];
|
654
|
+
} stackenv;
|
655
|
+
|
656
|
+
static void stackenv_init(stackenv* se, const char* errmsg);
|
657
|
+
static void stackenv_uninit(stackenv* se);
|
658
|
+
|
659
|
+
// Callback invoked by upb if any error occurs during parsing or serialization.
|
660
|
+
static bool env_error_func(void* ud, const upb_status* status) {
|
661
|
+
stackenv* se = ud;
|
662
|
+
// Free the env -- rb_raise will longjmp up the stack past the encode/decode
|
663
|
+
// function so it would not otherwise have been freed.
|
664
|
+
stackenv_uninit(se);
|
665
|
+
|
666
|
+
// TODO(haberman): have a way to verify that this is actually a parse error,
|
667
|
+
// instead of just throwing "parse error" unconditionally.
|
668
|
+
rb_raise(cParseError, se->ruby_error_template, upb_status_errmsg(status));
|
669
|
+
// Never reached: rb_raise() always longjmp()s up the stack, past all of our
|
670
|
+
// code, back to Ruby.
|
671
|
+
return false;
|
672
|
+
}
|
673
|
+
|
674
|
+
static void stackenv_init(stackenv* se, const char* errmsg) {
|
675
|
+
se->ruby_error_template = errmsg;
|
676
|
+
upb_env_init(&se->env);
|
677
|
+
upb_seededalloc_init(&se->alloc, &se->allocbuf, STACK_ENV_STACKBYTES);
|
678
|
+
upb_env_setallocfunc(
|
679
|
+
&se->env, upb_seededalloc_getallocfunc(&se->alloc), &se->alloc);
|
680
|
+
upb_env_seterrorfunc(&se->env, env_error_func, se);
|
681
|
+
}
|
682
|
+
|
683
|
+
static void stackenv_uninit(stackenv* se) {
|
684
|
+
upb_env_uninit(&se->env);
|
685
|
+
upb_seededalloc_uninit(&se->alloc);
|
686
|
+
}
|
687
|
+
|
625
688
|
/*
|
626
689
|
* call-seq:
|
627
690
|
* MessageClass.decode(data) => message
|
@@ -631,34 +694,33 @@ static const upb_pbdecodermethod *msgdef_decodermethod(Descriptor* desc) {
|
|
631
694
|
* and returns a message object with the corresponding field values.
|
632
695
|
*/
|
633
696
|
VALUE Message_decode(VALUE klass, VALUE data) {
|
634
|
-
VALUE descriptor =
|
697
|
+
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
|
635
698
|
Descriptor* desc = ruby_to_Descriptor(descriptor);
|
636
699
|
VALUE msgklass = Descriptor_msgclass(descriptor);
|
700
|
+
VALUE msg_rb;
|
701
|
+
MessageHeader* msg;
|
637
702
|
|
638
703
|
if (TYPE(data) != T_STRING) {
|
639
704
|
rb_raise(rb_eArgError, "Expected string for binary protobuf data.");
|
640
705
|
}
|
641
706
|
|
642
|
-
|
643
|
-
MessageHeader* msg;
|
707
|
+
msg_rb = rb_class_new_instance(0, NULL, msgklass);
|
644
708
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
|
645
709
|
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
rb_raise(rb_eRuntimeError, "Error occurred during parsing: %s.",
|
661
|
-
upb_status_errmsg(&status));
|
710
|
+
{
|
711
|
+
const upb_pbdecodermethod* method = msgdef_decodermethod(desc);
|
712
|
+
const upb_handlers* h = upb_pbdecodermethod_desthandlers(method);
|
713
|
+
stackenv se;
|
714
|
+
upb_sink sink;
|
715
|
+
upb_pbdecoder* decoder;
|
716
|
+
stackenv_init(&se, "Error occurred during parsing: %s");
|
717
|
+
|
718
|
+
upb_sink_reset(&sink, h, msg);
|
719
|
+
decoder = upb_pbdecoder_create(&se.env, method, &sink);
|
720
|
+
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
|
721
|
+
upb_pbdecoder_input(decoder));
|
722
|
+
|
723
|
+
stackenv_uninit(&se);
|
662
724
|
}
|
663
725
|
|
664
726
|
return msg_rb;
|
@@ -673,9 +735,11 @@ VALUE Message_decode(VALUE klass, VALUE data) {
|
|
673
735
|
* and returns a message object with the corresponding field values.
|
674
736
|
*/
|
675
737
|
VALUE Message_decode_json(VALUE klass, VALUE data) {
|
676
|
-
VALUE descriptor =
|
738
|
+
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
|
677
739
|
Descriptor* desc = ruby_to_Descriptor(descriptor);
|
678
740
|
VALUE msgklass = Descriptor_msgclass(descriptor);
|
741
|
+
VALUE msg_rb;
|
742
|
+
MessageHeader* msg;
|
679
743
|
|
680
744
|
if (TYPE(data) != T_STRING) {
|
681
745
|
rb_raise(rb_eArgError, "Expected string for JSON data.");
|
@@ -684,24 +748,21 @@ VALUE Message_decode_json(VALUE klass, VALUE data) {
|
|
684
748
|
// convert, because string handlers pass data directly to message string
|
685
749
|
// fields.
|
686
750
|
|
687
|
-
|
688
|
-
MessageHeader* msg;
|
751
|
+
msg_rb = rb_class_new_instance(0, NULL, msgklass);
|
689
752
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
|
690
753
|
|
691
|
-
|
692
|
-
|
693
|
-
|
754
|
+
{
|
755
|
+
stackenv se;
|
756
|
+
upb_sink sink;
|
757
|
+
upb_json_parser* parser;
|
758
|
+
stackenv_init(&se, "Error occurred during parsing: %s");
|
694
759
|
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
upb_json_parser_input(&parser));
|
760
|
+
upb_sink_reset(&sink, get_fill_handlers(desc), msg);
|
761
|
+
parser = upb_json_parser_create(&se.env, &sink);
|
762
|
+
upb_bufsrc_putbuf(RSTRING_PTR(data), RSTRING_LEN(data),
|
763
|
+
upb_json_parser_input(parser));
|
700
764
|
|
701
|
-
|
702
|
-
if (!upb_ok(&status)) {
|
703
|
-
rb_raise(rb_eRuntimeError, "Error occurred during parsing: %s.",
|
704
|
-
upb_status_errmsg(&status));
|
765
|
+
stackenv_uninit(&se);
|
705
766
|
}
|
706
767
|
|
707
768
|
return msg_rb;
|
@@ -733,12 +794,12 @@ static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
|
|
733
794
|
|
734
795
|
static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
|
735
796
|
size_t len, const upb_bufhandle *handle) {
|
736
|
-
UPB_UNUSED(hd);
|
737
|
-
UPB_UNUSED(handle);
|
738
|
-
|
739
797
|
stringsink *sink = _sink;
|
740
798
|
size_t new_size = sink->size;
|
741
799
|
|
800
|
+
UPB_UNUSED(hd);
|
801
|
+
UPB_UNUSED(handle);
|
802
|
+
|
742
803
|
while (sink->len + len > new_size) {
|
743
804
|
new_size *= 2;
|
744
805
|
}
|
@@ -792,10 +853,11 @@ static upb_selector_t getsel(const upb_fielddef *f, upb_handlertype_t type) {
|
|
792
853
|
}
|
793
854
|
|
794
855
|
static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
|
856
|
+
upb_sink subsink;
|
857
|
+
|
795
858
|
if (str == Qnil) return;
|
796
859
|
|
797
860
|
assert(BUILTIN_TYPE(str) == RUBY_T_STRING);
|
798
|
-
upb_sink subsink;
|
799
861
|
|
800
862
|
// Ensure that the string has the correct encoding. We also check at field-set
|
801
863
|
// time, but the user may have mutated the string object since then.
|
@@ -810,11 +872,14 @@ static void putstr(VALUE str, const upb_fielddef *f, upb_sink *sink) {
|
|
810
872
|
|
811
873
|
static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
|
812
874
|
int depth) {
|
875
|
+
upb_sink subsink;
|
876
|
+
VALUE descriptor;
|
877
|
+
Descriptor* subdesc;
|
878
|
+
|
813
879
|
if (submsg == Qnil) return;
|
814
880
|
|
815
|
-
|
816
|
-
|
817
|
-
Descriptor* subdesc = ruby_to_Descriptor(descriptor);
|
881
|
+
descriptor = rb_ivar_get(submsg, descriptor_instancevar_interned);
|
882
|
+
subdesc = ruby_to_Descriptor(descriptor);
|
818
883
|
|
819
884
|
upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink);
|
820
885
|
putmsg(submsg, subdesc, &subsink, depth + 1);
|
@@ -823,19 +888,20 @@ static void putsubmsg(VALUE submsg, const upb_fielddef *f, upb_sink *sink,
|
|
823
888
|
|
824
889
|
static void putary(VALUE ary, const upb_fielddef *f, upb_sink *sink,
|
825
890
|
int depth) {
|
826
|
-
if (ary == Qnil) return;
|
827
|
-
|
828
891
|
upb_sink subsink;
|
892
|
+
upb_fieldtype_t type = upb_fielddef_type(f);
|
893
|
+
upb_selector_t sel = 0;
|
894
|
+
int size;
|
895
|
+
|
896
|
+
if (ary == Qnil) return;
|
829
897
|
|
830
898
|
upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
|
831
899
|
|
832
|
-
upb_fieldtype_t type = upb_fielddef_type(f);
|
833
|
-
upb_selector_t sel = 0;
|
834
900
|
if (upb_fielddef_isprimitive(f)) {
|
835
901
|
sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
|
836
902
|
}
|
837
903
|
|
838
|
-
|
904
|
+
size = NUM2INT(RepeatedField_length(ary));
|
839
905
|
for (int i = 0; i < size; i++) {
|
840
906
|
void* memory = RepeatedField_index_native(ary, i);
|
841
907
|
switch (type) {
|
@@ -918,31 +984,35 @@ static void put_ruby_value(VALUE value,
|
|
918
984
|
|
919
985
|
static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
|
920
986
|
int depth) {
|
921
|
-
|
922
|
-
Map* self = ruby_to_Map(map);
|
923
|
-
|
987
|
+
Map* self;
|
924
988
|
upb_sink subsink;
|
989
|
+
const upb_fielddef* key_field;
|
990
|
+
const upb_fielddef* value_field;
|
991
|
+
Map_iter it;
|
992
|
+
|
993
|
+
if (map == Qnil) return;
|
994
|
+
self = ruby_to_Map(map);
|
925
995
|
|
926
996
|
upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink);
|
927
997
|
|
928
998
|
assert(upb_fielddef_type(f) == UPB_TYPE_MESSAGE);
|
929
|
-
|
930
|
-
|
999
|
+
key_field = map_field_key(f);
|
1000
|
+
value_field = map_field_value(f);
|
931
1001
|
|
932
|
-
Map_iter it;
|
933
1002
|
for (Map_begin(map, &it); !Map_done(&it); Map_next(&it)) {
|
934
1003
|
VALUE key = Map_iter_key(&it);
|
935
1004
|
VALUE value = Map_iter_value(&it);
|
1005
|
+
upb_status status;
|
936
1006
|
|
937
1007
|
upb_sink entry_sink;
|
938
|
-
upb_sink_startsubmsg(&subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
|
1008
|
+
upb_sink_startsubmsg(&subsink, getsel(f, UPB_HANDLER_STARTSUBMSG),
|
1009
|
+
&entry_sink);
|
939
1010
|
upb_sink_startmsg(&entry_sink);
|
940
1011
|
|
941
1012
|
put_ruby_value(key, key_field, Qnil, depth + 1, &entry_sink);
|
942
1013
|
put_ruby_value(value, value_field, self->value_type_class, depth + 1,
|
943
1014
|
&entry_sink);
|
944
1015
|
|
945
|
-
upb_status status;
|
946
1016
|
upb_sink_endmsg(&entry_sink, &status);
|
947
1017
|
upb_sink_endsubmsg(&subsink, getsel(f, UPB_HANDLER_ENDSUBMSG));
|
948
1018
|
}
|
@@ -952,19 +1022,21 @@ static void putmap(VALUE map, const upb_fielddef *f, upb_sink *sink,
|
|
952
1022
|
|
953
1023
|
static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
954
1024
|
upb_sink *sink, int depth) {
|
1025
|
+
MessageHeader* msg;
|
1026
|
+
upb_msg_field_iter i;
|
1027
|
+
upb_status status;
|
1028
|
+
|
955
1029
|
upb_sink_startmsg(sink);
|
956
1030
|
|
957
1031
|
// Protect against cycles (possible because users may freely reassign message
|
958
1032
|
// and repeated fields) by imposing a maximum recursion depth.
|
959
|
-
if (depth >
|
1033
|
+
if (depth > ENCODE_MAX_NESTING) {
|
960
1034
|
rb_raise(rb_eRuntimeError,
|
961
1035
|
"Maximum recursion depth exceeded during encoding.");
|
962
1036
|
}
|
963
1037
|
|
964
|
-
MessageHeader* msg;
|
965
1038
|
TypedData_Get_Struct(msg_rb, MessageHeader, &Message_type, msg);
|
966
1039
|
|
967
|
-
upb_msg_field_iter i;
|
968
1040
|
for (upb_msg_field_begin(&i, desc->msgdef);
|
969
1041
|
!upb_msg_field_done(&i);
|
970
1042
|
upb_msg_field_next(&i)) {
|
@@ -1036,7 +1108,6 @@ static void putmsg(VALUE msg_rb, const Descriptor* desc,
|
|
1036
1108
|
}
|
1037
1109
|
}
|
1038
1110
|
|
1039
|
-
upb_status status;
|
1040
1111
|
upb_sink_endmsg(sink, &status);
|
1041
1112
|
}
|
1042
1113
|
|
@@ -1065,27 +1136,32 @@ static const upb_handlers* msgdef_json_serialize_handlers(Descriptor* desc) {
|
|
1065
1136
|
* wire format.
|
1066
1137
|
*/
|
1067
1138
|
VALUE Message_encode(VALUE klass, VALUE msg_rb) {
|
1068
|
-
VALUE descriptor =
|
1139
|
+
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
|
1069
1140
|
Descriptor* desc = ruby_to_Descriptor(descriptor);
|
1070
1141
|
|
1071
1142
|
stringsink sink;
|
1072
1143
|
stringsink_init(&sink);
|
1073
1144
|
|
1074
|
-
|
1075
|
-
|
1145
|
+
{
|
1146
|
+
const upb_handlers* serialize_handlers =
|
1147
|
+
msgdef_pb_serialize_handlers(desc);
|
1076
1148
|
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1149
|
+
stackenv se;
|
1150
|
+
upb_pb_encoder* encoder;
|
1151
|
+
VALUE ret;
|
1080
1152
|
|
1081
|
-
|
1153
|
+
stackenv_init(&se, "Error occurred during encoding: %s");
|
1154
|
+
encoder = upb_pb_encoder_create(&se.env, serialize_handlers, &sink.sink);
|
1082
1155
|
|
1083
|
-
|
1156
|
+
putmsg(msg_rb, desc, upb_pb_encoder_input(encoder), 0);
|
1084
1157
|
|
1085
|
-
|
1086
|
-
stringsink_uninit(&sink);
|
1158
|
+
ret = rb_str_new(sink.ptr, sink.len);
|
1087
1159
|
|
1088
|
-
|
1160
|
+
stackenv_uninit(&se);
|
1161
|
+
stringsink_uninit(&sink);
|
1162
|
+
|
1163
|
+
return ret;
|
1164
|
+
}
|
1089
1165
|
}
|
1090
1166
|
|
1091
1167
|
/*
|
@@ -1095,73 +1171,30 @@ VALUE Message_encode(VALUE klass, VALUE msg_rb) {
|
|
1095
1171
|
* Encodes the given message object into its serialized JSON representation.
|
1096
1172
|
*/
|
1097
1173
|
VALUE Message_encode_json(VALUE klass, VALUE msg_rb) {
|
1098
|
-
VALUE descriptor =
|
1174
|
+
VALUE descriptor = rb_ivar_get(klass, descriptor_instancevar_interned);
|
1099
1175
|
Descriptor* desc = ruby_to_Descriptor(descriptor);
|
1100
1176
|
|
1101
1177
|
stringsink sink;
|
1102
1178
|
stringsink_init(&sink);
|
1103
1179
|
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1180
|
+
{
|
1181
|
+
const upb_handlers* serialize_handlers =
|
1182
|
+
msgdef_json_serialize_handlers(desc);
|
1183
|
+
upb_json_printer* printer;
|
1184
|
+
stackenv se;
|
1185
|
+
VALUE ret;
|
1110
1186
|
|
1111
|
-
|
1187
|
+
stackenv_init(&se, "Error occurred during encoding: %s");
|
1188
|
+
printer = upb_json_printer_create(&se.env, serialize_handlers, &sink.sink);
|
1112
1189
|
|
1113
|
-
|
1190
|
+
putmsg(msg_rb, desc, upb_json_printer_input(printer), 0);
|
1114
1191
|
|
1115
|
-
|
1116
|
-
stringsink_uninit(&sink);
|
1192
|
+
ret = rb_str_new(sink.ptr, sink.len);
|
1117
1193
|
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
/*
|
1122
|
-
* call-seq:
|
1123
|
-
* Google::Protobuf.encode(msg) => bytes
|
1124
|
-
*
|
1125
|
-
* Encodes the given message object to protocol buffers wire format. This is an
|
1126
|
-
* alternative to the #encode method on msg's class.
|
1127
|
-
*/
|
1128
|
-
VALUE Google_Protobuf_encode(VALUE self, VALUE msg_rb) {
|
1129
|
-
VALUE klass = CLASS_OF(msg_rb);
|
1130
|
-
return Message_encode(klass, msg_rb);
|
1131
|
-
}
|
1132
|
-
|
1133
|
-
/*
|
1134
|
-
* call-seq:
|
1135
|
-
* Google::Protobuf.encode_json(msg) => json_string
|
1136
|
-
*
|
1137
|
-
* Encodes the given message object to its JSON representation. This is an
|
1138
|
-
* alternative to the #encode_json method on msg's class.
|
1139
|
-
*/
|
1140
|
-
VALUE Google_Protobuf_encode_json(VALUE self, VALUE msg_rb) {
|
1141
|
-
VALUE klass = CLASS_OF(msg_rb);
|
1142
|
-
return Message_encode_json(klass, msg_rb);
|
1143
|
-
}
|
1194
|
+
stackenv_uninit(&se);
|
1195
|
+
stringsink_uninit(&sink);
|
1144
1196
|
|
1145
|
-
|
1146
|
-
|
1147
|
-
* Google::Protobuf.decode(class, bytes) => msg
|
1148
|
-
*
|
1149
|
-
* Decodes the given bytes as protocol buffers wire format under the
|
1150
|
-
* interpretation given by the given class's message definition. This is an
|
1151
|
-
* alternative to the #decode method on the given class.
|
1152
|
-
*/
|
1153
|
-
VALUE Google_Protobuf_decode(VALUE self, VALUE klass, VALUE msg_rb) {
|
1154
|
-
return Message_decode(klass, msg_rb);
|
1197
|
+
return ret;
|
1198
|
+
}
|
1155
1199
|
}
|
1156
1200
|
|
1157
|
-
/*
|
1158
|
-
* call-seq:
|
1159
|
-
* Google::Protobuf.decode_json(class, json_string) => msg
|
1160
|
-
*
|
1161
|
-
* Decodes the given JSON string under the interpretation given by the given
|
1162
|
-
* class's message definition. This is an alternative to the #decode_json method
|
1163
|
-
* on the given class.
|
1164
|
-
*/
|
1165
|
-
VALUE Google_Protobuf_decode_json(VALUE self, VALUE klass, VALUE msg_rb) {
|
1166
|
-
return Message_decode_json(klass, msg_rb);
|
1167
|
-
}
|