google-protobuf 3.6.1-x64-mingw32 → 3.7.0.rc.2-x64-mingw32
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 +554 -71
- data/ext/google/protobuf_c/encode_decode.c +238 -66
- data/ext/google/protobuf_c/extconf.rb +5 -1
- data/ext/google/protobuf_c/message.c +135 -69
- data/ext/google/protobuf_c/protobuf.c +4 -0
- data/ext/google/protobuf_c/protobuf.h +62 -2
- data/ext/google/protobuf_c/storage.c +211 -104
- data/ext/google/protobuf_c/upb.c +4126 -1721
- data/ext/google/protobuf_c/upb.h +1125 -339
- data/ext/google/protobuf_c/wrap_memcpy.c +1 -1
- data/lib/google/2.3/protobuf_c.so +0 -0
- data/lib/google/2.4/protobuf_c.so +0 -0
- data/lib/google/2.5/protobuf_c.so +0 -0
- data/lib/google/2.6/protobuf_c.so +0 -0
- data/lib/google/protobuf.rb +3 -2
- data/lib/google/protobuf/any_pb.rb +5 -3
- data/lib/google/protobuf/api_pb.rb +23 -21
- data/lib/google/protobuf/duration_pb.rb +5 -3
- data/lib/google/protobuf/empty_pb.rb +3 -1
- data/lib/google/protobuf/field_mask_pb.rb +4 -2
- data/lib/google/protobuf/repeated_field.rb +1 -1
- data/lib/google/protobuf/source_context_pb.rb +4 -2
- data/lib/google/protobuf/struct_pb.rb +19 -17
- data/lib/google/protobuf/timestamp_pb.rb +5 -3
- data/lib/google/protobuf/type_pb.rb +68 -66
- data/lib/google/protobuf/well_known_types.rb +12 -0
- data/lib/google/protobuf/wrappers_pb.rb +28 -26
- data/tests/basic.rb +137 -1181
- data/tests/generated_code_test.rb +5 -3
- metadata +6 -8
- data/lib/google/2.0/protobuf_c.so +0 -0
- data/lib/google/2.1/protobuf_c.so +0 -0
- data/lib/google/2.2/protobuf_c.so +0 -0
@@ -38,6 +38,8 @@
|
|
38
38
|
// Ruby <-> native slot management.
|
39
39
|
// -----------------------------------------------------------------------------
|
40
40
|
|
41
|
+
#define CHARPTR_AT(msg, ofs) ((char*)msg + ofs)
|
42
|
+
#define DEREF_OFFSET(msg, ofs, type) *(type*)CHARPTR_AT(msg, ofs)
|
41
43
|
#define DEREF(memory, type) *(type*)(memory)
|
42
44
|
|
43
45
|
size_t native_slot_size(upb_fieldtype_t type) {
|
@@ -57,37 +59,6 @@ size_t native_slot_size(upb_fieldtype_t type) {
|
|
57
59
|
}
|
58
60
|
}
|
59
61
|
|
60
|
-
static VALUE value_from_default(const upb_fielddef *field) {
|
61
|
-
switch (upb_fielddef_type(field)) {
|
62
|
-
case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
|
63
|
-
case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
|
64
|
-
case UPB_TYPE_BOOL:
|
65
|
-
return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
|
66
|
-
case UPB_TYPE_MESSAGE: return Qnil;
|
67
|
-
case UPB_TYPE_ENUM: {
|
68
|
-
const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
|
69
|
-
int32_t num = upb_fielddef_defaultint32(field);
|
70
|
-
const char *label = upb_enumdef_iton(enumdef, num);
|
71
|
-
if (label) {
|
72
|
-
return ID2SYM(rb_intern(label));
|
73
|
-
} else {
|
74
|
-
return INT2NUM(num);
|
75
|
-
}
|
76
|
-
}
|
77
|
-
case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
|
78
|
-
case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
|
79
|
-
case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
|
80
|
-
case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
|
81
|
-
case UPB_TYPE_STRING:
|
82
|
-
case UPB_TYPE_BYTES: {
|
83
|
-
size_t size;
|
84
|
-
const char *str = upb_fielddef_defaultstr(field, &size);
|
85
|
-
return rb_str_new(str, size);
|
86
|
-
}
|
87
|
-
default: return Qnil;
|
88
|
-
}
|
89
|
-
}
|
90
|
-
|
91
62
|
static bool is_ruby_num(VALUE value) {
|
92
63
|
return (TYPE(value) == T_FLOAT ||
|
93
64
|
TYPE(value) == T_FIXNUM ||
|
@@ -96,7 +67,7 @@ static bool is_ruby_num(VALUE value) {
|
|
96
67
|
|
97
68
|
void native_slot_check_int_range_precision(upb_fieldtype_t type, VALUE val) {
|
98
69
|
if (!is_ruby_num(val)) {
|
99
|
-
rb_raise(
|
70
|
+
rb_raise(cTypeError, "Expected number type for integral field.");
|
100
71
|
}
|
101
72
|
|
102
73
|
// NUM2{INT,UINT,LL,ULL} macros do the appropriate range checks on upper
|
@@ -153,13 +124,13 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
153
124
|
switch (type) {
|
154
125
|
case UPB_TYPE_FLOAT:
|
155
126
|
if (!is_ruby_num(value)) {
|
156
|
-
rb_raise(
|
127
|
+
rb_raise(cTypeError, "Expected number type for float field.");
|
157
128
|
}
|
158
129
|
DEREF(memory, float) = NUM2DBL(value);
|
159
130
|
break;
|
160
131
|
case UPB_TYPE_DOUBLE:
|
161
132
|
if (!is_ruby_num(value)) {
|
162
|
-
rb_raise(
|
133
|
+
rb_raise(cTypeError, "Expected number type for double field.");
|
163
134
|
}
|
164
135
|
DEREF(memory, double) = NUM2DBL(value);
|
165
136
|
break;
|
@@ -170,7 +141,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
170
141
|
} else if (value == Qfalse) {
|
171
142
|
val = 0;
|
172
143
|
} else {
|
173
|
-
rb_raise(
|
144
|
+
rb_raise(cTypeError, "Invalid argument for boolean field.");
|
174
145
|
}
|
175
146
|
DEREF(memory, int8_t) = val;
|
176
147
|
break;
|
@@ -179,7 +150,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
179
150
|
if (CLASS_OF(value) == rb_cSymbol) {
|
180
151
|
value = rb_funcall(value, rb_intern("to_s"), 0);
|
181
152
|
} else if (CLASS_OF(value) != rb_cString) {
|
182
|
-
rb_raise(
|
153
|
+
rb_raise(cTypeError, "Invalid argument for string field.");
|
183
154
|
}
|
184
155
|
|
185
156
|
DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
|
@@ -187,7 +158,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
187
158
|
|
188
159
|
case UPB_TYPE_BYTES: {
|
189
160
|
if (CLASS_OF(value) != rb_cString) {
|
190
|
-
rb_raise(
|
161
|
+
rb_raise(cTypeError, "Invalid argument for string field.");
|
191
162
|
}
|
192
163
|
|
193
164
|
DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
|
@@ -197,7 +168,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
197
168
|
if (CLASS_OF(value) == CLASS_OF(Qnil)) {
|
198
169
|
value = Qnil;
|
199
170
|
} else if (CLASS_OF(value) != type_class) {
|
200
|
-
rb_raise(
|
171
|
+
rb_raise(cTypeError,
|
201
172
|
"Invalid type %s to assign to submessage field.",
|
202
173
|
rb_class2name(CLASS_OF(value)));
|
203
174
|
}
|
@@ -209,7 +180,7 @@ void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
|
|
209
180
|
if (TYPE(value) == T_STRING) {
|
210
181
|
value = rb_funcall(value, rb_intern("to_sym"), 0);
|
211
182
|
} else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
|
212
|
-
rb_raise(
|
183
|
+
rb_raise(cTypeError,
|
213
184
|
"Expected number or symbol type for enum field.");
|
214
185
|
}
|
215
186
|
if (TYPE(value) == T_SYMBOL) {
|
@@ -404,7 +375,12 @@ const upb_msgdef *map_entry_msgdef(const upb_fielddef* field) {
|
|
404
375
|
}
|
405
376
|
|
406
377
|
bool is_map_field(const upb_fielddef *field) {
|
407
|
-
|
378
|
+
const upb_msgdef* subdef = tryget_map_entry_msgdef(field);
|
379
|
+
if (subdef == NULL) return false;
|
380
|
+
|
381
|
+
// Map fields are a proto3 feature.
|
382
|
+
// If we're using proto2 syntax we need to fallback to the repeated field.
|
383
|
+
return upb_msgdef_syntax(subdef) == UPB_SYNTAX_PROTO3;
|
408
384
|
}
|
409
385
|
|
410
386
|
const upb_fielddef* map_field_key(const upb_fielddef* field) {
|
@@ -433,6 +409,12 @@ const upb_fielddef* map_entry_value(const upb_msgdef* msgdef) {
|
|
433
409
|
// Memory layout management.
|
434
410
|
// -----------------------------------------------------------------------------
|
435
411
|
|
412
|
+
bool field_contains_hasbit(MessageLayout* layout,
|
413
|
+
const upb_fielddef* field) {
|
414
|
+
return layout->fields[upb_fielddef_index(field)].hasbit !=
|
415
|
+
MESSAGE_FIELD_NO_HASBIT;
|
416
|
+
}
|
417
|
+
|
436
418
|
static size_t align_up_to(size_t offset, size_t granularity) {
|
437
419
|
// Granularity must be a power of two.
|
438
420
|
return (offset + granularity - 1) & ~(granularity - 1);
|
@@ -447,6 +429,23 @@ MessageLayout* create_layout(const upb_msgdef* msgdef) {
|
|
447
429
|
|
448
430
|
layout->fields = ALLOC_N(MessageField, nfields);
|
449
431
|
|
432
|
+
size_t hasbit = 0;
|
433
|
+
for (upb_msg_field_begin(&it, msgdef);
|
434
|
+
!upb_msg_field_done(&it);
|
435
|
+
upb_msg_field_next(&it)) {
|
436
|
+
const upb_fielddef* field = upb_msg_iter_field(&it);
|
437
|
+
if (upb_fielddef_haspresence(field)) {
|
438
|
+
layout->fields[upb_fielddef_index(field)].hasbit = hasbit++;
|
439
|
+
} else {
|
440
|
+
layout->fields[upb_fielddef_index(field)].hasbit =
|
441
|
+
MESSAGE_FIELD_NO_HASBIT;
|
442
|
+
}
|
443
|
+
}
|
444
|
+
|
445
|
+
if (hasbit != 0) {
|
446
|
+
off += (hasbit + 8 - 1) / 8;
|
447
|
+
}
|
448
|
+
|
450
449
|
for (upb_msg_field_begin(&it, msgdef);
|
451
450
|
!upb_msg_field_done(&it);
|
452
451
|
upb_msg_field_next(&it)) {
|
@@ -569,6 +568,136 @@ static uint32_t* slot_oneof_case(MessageLayout* layout,
|
|
569
568
|
layout->fields[upb_fielddef_index(field)].case_offset);
|
570
569
|
}
|
571
570
|
|
571
|
+
static void slot_set_hasbit(MessageLayout* layout,
|
572
|
+
const void* storage,
|
573
|
+
const upb_fielddef* field) {
|
574
|
+
size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
|
575
|
+
assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
|
576
|
+
|
577
|
+
((uint8_t*)storage)[hasbit / 8] |= 1 << (hasbit % 8);
|
578
|
+
}
|
579
|
+
|
580
|
+
static void slot_clear_hasbit(MessageLayout* layout,
|
581
|
+
const void* storage,
|
582
|
+
const upb_fielddef* field) {
|
583
|
+
size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
|
584
|
+
assert(hasbit != MESSAGE_FIELD_NO_HASBIT);
|
585
|
+
((uint8_t*)storage)[hasbit / 8] &= ~(1 << (hasbit % 8));
|
586
|
+
}
|
587
|
+
|
588
|
+
static bool slot_is_hasbit_set(MessageLayout* layout,
|
589
|
+
const void* storage,
|
590
|
+
const upb_fielddef* field) {
|
591
|
+
size_t hasbit = layout->fields[upb_fielddef_index(field)].hasbit;
|
592
|
+
if (hasbit == MESSAGE_FIELD_NO_HASBIT) {
|
593
|
+
return false;
|
594
|
+
}
|
595
|
+
|
596
|
+
return DEREF_OFFSET(
|
597
|
+
(uint8_t*)storage, hasbit / 8, char) & (1 << (hasbit % 8));
|
598
|
+
}
|
599
|
+
|
600
|
+
VALUE layout_has(MessageLayout* layout,
|
601
|
+
const void* storage,
|
602
|
+
const upb_fielddef* field) {
|
603
|
+
assert(field_contains_hasbit(layout, field));
|
604
|
+
return slot_is_hasbit_set(layout, storage, field) ? Qtrue : Qfalse;
|
605
|
+
}
|
606
|
+
|
607
|
+
void layout_clear(MessageLayout* layout,
|
608
|
+
const void* storage,
|
609
|
+
const upb_fielddef* field) {
|
610
|
+
void* memory = slot_memory(layout, storage, field);
|
611
|
+
uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
|
612
|
+
|
613
|
+
if (field_contains_hasbit(layout, field)) {
|
614
|
+
slot_clear_hasbit(layout, storage, field);
|
615
|
+
}
|
616
|
+
|
617
|
+
if (upb_fielddef_containingoneof(field)) {
|
618
|
+
memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
|
619
|
+
*oneof_case = ONEOF_CASE_NONE;
|
620
|
+
} else if (is_map_field(field)) {
|
621
|
+
VALUE map = Qnil;
|
622
|
+
|
623
|
+
const upb_fielddef* key_field = map_field_key(field);
|
624
|
+
const upb_fielddef* value_field = map_field_value(field);
|
625
|
+
VALUE type_class = field_type_class(value_field);
|
626
|
+
|
627
|
+
if (type_class != Qnil) {
|
628
|
+
VALUE args[3] = {
|
629
|
+
fieldtype_to_ruby(upb_fielddef_type(key_field)),
|
630
|
+
fieldtype_to_ruby(upb_fielddef_type(value_field)),
|
631
|
+
type_class,
|
632
|
+
};
|
633
|
+
map = rb_class_new_instance(3, args, cMap);
|
634
|
+
} else {
|
635
|
+
VALUE args[2] = {
|
636
|
+
fieldtype_to_ruby(upb_fielddef_type(key_field)),
|
637
|
+
fieldtype_to_ruby(upb_fielddef_type(value_field)),
|
638
|
+
};
|
639
|
+
map = rb_class_new_instance(2, args, cMap);
|
640
|
+
}
|
641
|
+
|
642
|
+
DEREF(memory, VALUE) = map;
|
643
|
+
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
644
|
+
VALUE ary = Qnil;
|
645
|
+
|
646
|
+
VALUE type_class = field_type_class(field);
|
647
|
+
|
648
|
+
if (type_class != Qnil) {
|
649
|
+
VALUE args[2] = {
|
650
|
+
fieldtype_to_ruby(upb_fielddef_type(field)),
|
651
|
+
type_class,
|
652
|
+
};
|
653
|
+
ary = rb_class_new_instance(2, args, cRepeatedField);
|
654
|
+
} else {
|
655
|
+
VALUE args[1] = { fieldtype_to_ruby(upb_fielddef_type(field)) };
|
656
|
+
ary = rb_class_new_instance(1, args, cRepeatedField);
|
657
|
+
}
|
658
|
+
|
659
|
+
DEREF(memory, VALUE) = ary;
|
660
|
+
} else {
|
661
|
+
native_slot_set(upb_fielddef_type(field), field_type_class(field),
|
662
|
+
memory, layout_get_default(field));
|
663
|
+
}
|
664
|
+
}
|
665
|
+
|
666
|
+
VALUE layout_get_default(const upb_fielddef *field) {
|
667
|
+
switch (upb_fielddef_type(field)) {
|
668
|
+
case UPB_TYPE_FLOAT: return DBL2NUM(upb_fielddef_defaultfloat(field));
|
669
|
+
case UPB_TYPE_DOUBLE: return DBL2NUM(upb_fielddef_defaultdouble(field));
|
670
|
+
case UPB_TYPE_BOOL:
|
671
|
+
return upb_fielddef_defaultbool(field) ? Qtrue : Qfalse;
|
672
|
+
case UPB_TYPE_MESSAGE: return Qnil;
|
673
|
+
case UPB_TYPE_ENUM: {
|
674
|
+
const upb_enumdef *enumdef = upb_fielddef_enumsubdef(field);
|
675
|
+
int32_t num = upb_fielddef_defaultint32(field);
|
676
|
+
const char *label = upb_enumdef_iton(enumdef, num);
|
677
|
+
if (label) {
|
678
|
+
return ID2SYM(rb_intern(label));
|
679
|
+
} else {
|
680
|
+
return INT2NUM(num);
|
681
|
+
}
|
682
|
+
}
|
683
|
+
case UPB_TYPE_INT32: return INT2NUM(upb_fielddef_defaultint32(field));
|
684
|
+
case UPB_TYPE_INT64: return LL2NUM(upb_fielddef_defaultint64(field));;
|
685
|
+
case UPB_TYPE_UINT32: return UINT2NUM(upb_fielddef_defaultuint32(field));
|
686
|
+
case UPB_TYPE_UINT64: return ULL2NUM(upb_fielddef_defaultuint64(field));
|
687
|
+
case UPB_TYPE_STRING:
|
688
|
+
case UPB_TYPE_BYTES: {
|
689
|
+
size_t size;
|
690
|
+
const char *str = upb_fielddef_defaultstr(field, &size);
|
691
|
+
VALUE str_rb = rb_str_new(str, size);
|
692
|
+
|
693
|
+
rb_enc_associate(str_rb, (upb_fielddef_type(field) == UPB_TYPE_BYTES) ?
|
694
|
+
kRubyString8bitEncoding : kRubyStringUtf8Encoding);
|
695
|
+
rb_obj_freeze(str_rb);
|
696
|
+
return str_rb;
|
697
|
+
}
|
698
|
+
default: return Qnil;
|
699
|
+
}
|
700
|
+
}
|
572
701
|
|
573
702
|
VALUE layout_get(MessageLayout* layout,
|
574
703
|
const void* storage,
|
@@ -576,15 +705,24 @@ VALUE layout_get(MessageLayout* layout,
|
|
576
705
|
void* memory = slot_memory(layout, storage, field);
|
577
706
|
uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
|
578
707
|
|
708
|
+
bool field_set;
|
709
|
+
if (field_contains_hasbit(layout, field)) {
|
710
|
+
field_set = slot_is_hasbit_set(layout, storage, field);
|
711
|
+
} else {
|
712
|
+
field_set = true;
|
713
|
+
}
|
714
|
+
|
579
715
|
if (upb_fielddef_containingoneof(field)) {
|
580
716
|
if (*oneof_case != upb_fielddef_number(field)) {
|
581
|
-
return
|
717
|
+
return layout_get_default(field);
|
582
718
|
}
|
583
719
|
return native_slot_get(upb_fielddef_type(field),
|
584
720
|
field_type_class(field),
|
585
721
|
memory);
|
586
722
|
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
587
723
|
return *((VALUE *)memory);
|
724
|
+
} else if (!field_set) {
|
725
|
+
return layout_get_default(field);
|
588
726
|
} else {
|
589
727
|
return native_slot_get(upb_fielddef_type(field),
|
590
728
|
field_type_class(field),
|
@@ -598,18 +736,18 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
|
|
598
736
|
|
599
737
|
if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
|
600
738
|
RTYPEDDATA_TYPE(val) != &RepeatedField_type) {
|
601
|
-
rb_raise(
|
739
|
+
rb_raise(cTypeError, "Expected repeated field array");
|
602
740
|
}
|
603
741
|
|
604
742
|
self = ruby_to_RepeatedField(val);
|
605
743
|
if (self->field_type != upb_fielddef_type(field)) {
|
606
|
-
rb_raise(
|
744
|
+
rb_raise(cTypeError, "Repeated field array has wrong element type");
|
607
745
|
}
|
608
746
|
|
609
|
-
if (self->field_type == UPB_TYPE_MESSAGE) {
|
747
|
+
if (self->field_type == UPB_TYPE_MESSAGE) {
|
610
748
|
if (self->field_type_class !=
|
611
749
|
Descriptor_msgclass(get_def_obj(upb_fielddef_subdef(field)))) {
|
612
|
-
rb_raise(
|
750
|
+
rb_raise(cTypeError,
|
613
751
|
"Repeated field array has wrong message class");
|
614
752
|
}
|
615
753
|
}
|
@@ -618,7 +756,7 @@ static void check_repeated_field_type(VALUE val, const upb_fielddef* field) {
|
|
618
756
|
if (self->field_type == UPB_TYPE_ENUM) {
|
619
757
|
if (self->field_type_class !=
|
620
758
|
EnumDescriptor_enummodule(get_def_obj(upb_fielddef_subdef(field)))) {
|
621
|
-
rb_raise(
|
759
|
+
rb_raise(cTypeError,
|
622
760
|
"Repeated field array has wrong enum class");
|
623
761
|
}
|
624
762
|
}
|
@@ -631,21 +769,21 @@ static void check_map_field_type(VALUE val, const upb_fielddef* field) {
|
|
631
769
|
|
632
770
|
if (!RB_TYPE_P(val, T_DATA) || !RTYPEDDATA_P(val) ||
|
633
771
|
RTYPEDDATA_TYPE(val) != &Map_type) {
|
634
|
-
rb_raise(
|
772
|
+
rb_raise(cTypeError, "Expected Map instance");
|
635
773
|
}
|
636
774
|
|
637
775
|
self = ruby_to_Map(val);
|
638
776
|
if (self->key_type != upb_fielddef_type(key_field)) {
|
639
|
-
rb_raise(
|
777
|
+
rb_raise(cTypeError, "Map key type does not match field's key type");
|
640
778
|
}
|
641
779
|
if (self->value_type != upb_fielddef_type(value_field)) {
|
642
|
-
rb_raise(
|
780
|
+
rb_raise(cTypeError, "Map value type does not match field's value type");
|
643
781
|
}
|
644
782
|
if (upb_fielddef_type(value_field) == UPB_TYPE_MESSAGE ||
|
645
783
|
upb_fielddef_type(value_field) == UPB_TYPE_ENUM) {
|
646
784
|
if (self->value_type_class !=
|
647
785
|
get_def_obj(upb_fielddef_subdef(value_field))) {
|
648
|
-
rb_raise(
|
786
|
+
rb_raise(cTypeError,
|
649
787
|
"Map value type has wrong message/enum class");
|
650
788
|
}
|
651
789
|
}
|
@@ -689,67 +827,24 @@ void layout_set(MessageLayout* layout,
|
|
689
827
|
check_repeated_field_type(val, field);
|
690
828
|
DEREF(memory, VALUE) = val;
|
691
829
|
} else {
|
692
|
-
native_slot_set(upb_fielddef_type(field), field_type_class(field),
|
693
|
-
|
830
|
+
native_slot_set(upb_fielddef_type(field), field_type_class(field), memory,
|
831
|
+
val);
|
832
|
+
}
|
833
|
+
|
834
|
+
if (layout->fields[upb_fielddef_index(field)].hasbit !=
|
835
|
+
MESSAGE_FIELD_NO_HASBIT) {
|
836
|
+
slot_set_hasbit(layout, storage, field);
|
694
837
|
}
|
695
838
|
}
|
696
839
|
|
697
840
|
void layout_init(MessageLayout* layout,
|
698
841
|
void* storage) {
|
842
|
+
|
699
843
|
upb_msg_field_iter it;
|
700
844
|
for (upb_msg_field_begin(&it, layout->msgdef);
|
701
845
|
!upb_msg_field_done(&it);
|
702
846
|
upb_msg_field_next(&it)) {
|
703
|
-
|
704
|
-
void* memory = slot_memory(layout, storage, field);
|
705
|
-
uint32_t* oneof_case = slot_oneof_case(layout, storage, field);
|
706
|
-
|
707
|
-
if (upb_fielddef_containingoneof(field)) {
|
708
|
-
memset(memory, 0, NATIVE_SLOT_MAX_SIZE);
|
709
|
-
*oneof_case = ONEOF_CASE_NONE;
|
710
|
-
} else if (is_map_field(field)) {
|
711
|
-
VALUE map = Qnil;
|
712
|
-
|
713
|
-
const upb_fielddef* key_field = map_field_key(field);
|
714
|
-
const upb_fielddef* value_field = map_field_value(field);
|
715
|
-
VALUE type_class = field_type_class(value_field);
|
716
|
-
|
717
|
-
if (type_class != Qnil) {
|
718
|
-
VALUE args[3] = {
|
719
|
-
fieldtype_to_ruby(upb_fielddef_type(key_field)),
|
720
|
-
fieldtype_to_ruby(upb_fielddef_type(value_field)),
|
721
|
-
type_class,
|
722
|
-
};
|
723
|
-
map = rb_class_new_instance(3, args, cMap);
|
724
|
-
} else {
|
725
|
-
VALUE args[2] = {
|
726
|
-
fieldtype_to_ruby(upb_fielddef_type(key_field)),
|
727
|
-
fieldtype_to_ruby(upb_fielddef_type(value_field)),
|
728
|
-
};
|
729
|
-
map = rb_class_new_instance(2, args, cMap);
|
730
|
-
}
|
731
|
-
|
732
|
-
DEREF(memory, VALUE) = map;
|
733
|
-
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
734
|
-
VALUE ary = Qnil;
|
735
|
-
|
736
|
-
VALUE type_class = field_type_class(field);
|
737
|
-
|
738
|
-
if (type_class != Qnil) {
|
739
|
-
VALUE args[2] = {
|
740
|
-
fieldtype_to_ruby(upb_fielddef_type(field)),
|
741
|
-
type_class,
|
742
|
-
};
|
743
|
-
ary = rb_class_new_instance(2, args, cRepeatedField);
|
744
|
-
} else {
|
745
|
-
VALUE args[1] = { fieldtype_to_ruby(upb_fielddef_type(field)) };
|
746
|
-
ary = rb_class_new_instance(1, args, cRepeatedField);
|
747
|
-
}
|
748
|
-
|
749
|
-
DEREF(memory, VALUE) = ary;
|
750
|
-
} else {
|
751
|
-
native_slot_init(upb_fielddef_type(field), memory);
|
752
|
-
}
|
847
|
+
layout_clear(layout, storage, upb_msg_iter_field(&it));
|
753
848
|
}
|
754
849
|
}
|
755
850
|
|
@@ -796,6 +891,11 @@ void layout_dup(MessageLayout* layout, void* to, void* from) {
|
|
796
891
|
} else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) {
|
797
892
|
DEREF(to_memory, VALUE) = RepeatedField_dup(DEREF(from_memory, VALUE));
|
798
893
|
} else {
|
894
|
+
if (field_contains_hasbit(layout, field)) {
|
895
|
+
if (!slot_is_hasbit_set(layout, from, field)) continue;
|
896
|
+
slot_set_hasbit(layout, to, field);
|
897
|
+
}
|
898
|
+
|
799
899
|
native_slot_dup(upb_fielddef_type(field), to_memory, from_memory);
|
800
900
|
}
|
801
901
|
}
|
@@ -825,6 +925,11 @@ void layout_deep_copy(MessageLayout* layout, void* to, void* from) {
|
|
825
925
|
DEREF(to_memory, VALUE) =
|
826
926
|
RepeatedField_deep_copy(DEREF(from_memory, VALUE));
|
827
927
|
} else {
|
928
|
+
if (field_contains_hasbit(layout, field)) {
|
929
|
+
if (!slot_is_hasbit_set(layout, from, field)) continue;
|
930
|
+
slot_set_hasbit(layout, to, field);
|
931
|
+
}
|
932
|
+
|
828
933
|
native_slot_deep_copy(upb_fielddef_type(field), to_memory, from_memory);
|
829
934
|
}
|
830
935
|
}
|
@@ -861,8 +966,10 @@ VALUE layout_eq(MessageLayout* layout, void* msg1, void* msg2) {
|
|
861
966
|
return Qfalse;
|
862
967
|
}
|
863
968
|
} else {
|
864
|
-
if (
|
865
|
-
|
969
|
+
if (slot_is_hasbit_set(layout, msg1, field) !=
|
970
|
+
slot_is_hasbit_set(layout, msg2, field) ||
|
971
|
+
!native_slot_eq(upb_fielddef_type(field),
|
972
|
+
msg1_memory, msg2_memory)) {
|
866
973
|
return Qfalse;
|
867
974
|
}
|
868
975
|
}
|