identifier = '%s_%s_tag' % (self.struct_name, self.name)
return '#define %-40s %d\n' % (identifier, self.tag)
- def pb_field_t(self, prev_field_name):
+ def pb_field_t(self, prev_field_name, union_index = None):
'''Return the pb_field_t initializer to use in the constant array.
- prev_field_name is the name of the previous field or None.
+ prev_field_name is the name of the previous field or None. For OneOf
+ unions, union_index is the index of this field inside the OneOf.
'''
if self.rules == 'ONEOF':
result += '%-8s, ' % self.pbtype
result += '%s, ' % self.rules
result += '%-8s, ' % (self.allocation if not self.inline else "INLINE")
- result += '%s, ' % ("FIRST" if not prev_field_name else "OTHER")
+
+ if union_index is not None and union_index > 0:
+ result += 'UNION, '
+ elif prev_field_name is None:
+ result += 'FIRST, '
+ else:
+ result += 'OTHER, '
+
result += '%s, ' % self.struct_name
result += '%s, ' % self.name
result += '%s, ' % (prev_field_name or self.name)
return ''.join([f.tags() for f in self.fields])
def pb_field_t(self, prev_field_name):
- result = ',\n'.join([f.pb_field_t(prev_field_name) for f in self.fields])
- return result
+ parts = []
+ for union_index, field in enumerate(self.fields):
+ parts.append(field.pb_field_t(prev_field_name, union_index))
+ return ',\n'.join(parts)
def get_last_field_name(self):
if self.anonymous:
#define PB_DATAOFFSET_FIRST(st, m1, m2) (offsetof(st, m1))
/* data_offset for subsequent fields */
#define PB_DATAOFFSET_OTHER(st, m1, m2) (offsetof(st, m1) - offsetof(st, m2) - pb_membersize(st, m2))
+/* data offset for subsequent fields inside an union (oneof) */
+#define PB_DATAOFFSET_UNION(st, m1, m2) (PB_SIZE_MAX)
/* Choose first/other based on m1 == m2 (deprecated, remains for backwards compatibility) */
#define PB_DATAOFFSET_CHOOSE(st, m1, m2) (int)(offsetof(st, m1) == offsetof(st, m2) \
? PB_DATAOFFSET_FIRST(st, m1, m2) \
size_t prev_size = prev_field->data_size;
if (PB_HTYPE(prev_field->type) == PB_HTYPE_ONEOF &&
- PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF)
+ PB_HTYPE(iter->pos->type) == PB_HTYPE_ONEOF &&
+ iter->pos->data_offset == PB_SIZE_MAX)
{
/* Don't advance pointers inside unions */
- prev_size = 0;
- iter->pData = (char*)iter->pData - prev_field->data_offset;
+ return true;
}
else if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC &&
PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED)