google-protobuf 3.0.0.alpha.3.1.pre → 3.0.0.alpha.4.0
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.
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
|
-
}
|