Commit 80722b03 authored by Kenton Varda's avatar Kenton Varda

Revamp dynamic struct getters/setters to not distinguish unions. Add…

Revamp dynamic struct getters/setters to not distinguish unions.  Add converience versions that take string names.
parent 449f4b23
......@@ -39,7 +39,7 @@ TEST(Blob, Text) {
EXPECT_STREQ("foo", text.data());
EXPECT_EQ(3u, text.size());
std::string str2 = text;
std::string str2 = text.as<std::string>();
EXPECT_EQ("foo", str2);
Text::Reader text2 = "bar";
......@@ -62,7 +62,7 @@ TEST(Blob, Data) {
EXPECT_EQ("foo", data);
EXPECT_EQ(3u, data.size());
std::string str2 = data;
std::string str2 = data.as<std::string>();
EXPECT_EQ("foo", str2);
Data::Reader data2 = "bar";
......
......@@ -66,10 +66,6 @@ public:
inline Reader(const T& other): bytes(other.data()), size_(other.size()) {}
// Primarily intended for converting from std::string.
template <typename T>
inline operator T() const { return T(bytes, size_); }
// Primarily intended for converting to std::string.
template <typename T>
inline T as() const { return T(bytes, size_); }
// Explicitly converts to the desired type, which must have a (const char*, size) constructor.
......
......@@ -339,9 +339,17 @@ DynamicList::Builder DynamicObject::Builder::asList(internal::ListSchema schema)
// =======================================================================================
schema::StructNode::Union::Reader DynamicUnion::Reader::getSchema() {
return schema.getBody().getUnionMember();
}
schema::StructNode::Union::Reader DynamicUnion::Builder::getSchema() {
return schema.getBody().getUnionMember();
}
Maybe<schema::StructNode::Member::Reader> DynamicUnion::Reader::which() {
auto members = schema.getMembers();
uint16_t discrim = reader.getDataField<uint32_t>(schema.getDiscriminantOffset() * ELEMENTS);
auto uschema = getSchema();
auto members = uschema.getMembers();
uint16_t discrim = reader.getDataField<uint32_t>(uschema.getDiscriminantOffset() * ELEMENTS);
if (discrim < members.size()) {
return members[discrim];
......@@ -350,8 +358,9 @@ Maybe<schema::StructNode::Member::Reader> DynamicUnion::Reader::which() {
}
}
Maybe<schema::StructNode::Member::Reader> DynamicUnion::Builder::which() {
auto members = schema.getMembers();
uint16_t discrim = builder.getDataField<uint32_t>(schema.getDiscriminantOffset() * ELEMENTS);
auto uschema = getSchema();
auto members = uschema.getMembers();
uint16_t discrim = builder.getDataField<uint32_t>(uschema.getDiscriminantOffset() * ELEMENTS);
if (discrim < members.size()) {
return members[discrim];
......@@ -365,11 +374,9 @@ DynamicValue::Reader DynamicUnion::Reader::get() {
RECOVERABLE_PRECOND(w != nullptr, "Can't get() unknown union value.") {
return DynamicValue::Reader();
}
auto body = w->getBody();
CHECK(body.which() == schema::StructNode::Member::Body::FIELD_MEMBER,
CHECK(w->getBody().which() == schema::StructNode::Member::Body::FIELD_MEMBER,
"Unsupported union member type.");
return DynamicValue::Reader(DynamicStruct::Reader::getFieldImpl(
pool, reader, body.getFieldMember()));
return DynamicValue::Reader(DynamicStruct::Reader::getImpl(pool, reader, *w));
}
DynamicValue::Builder DynamicUnion::Builder::get() {
......@@ -377,28 +384,26 @@ DynamicValue::Builder DynamicUnion::Builder::get() {
RECOVERABLE_PRECOND(w != nullptr, "Can't get() unknown union value.") {
return DynamicValue::Builder();
}
auto body = w->getBody();
CHECK(body.which() == schema::StructNode::Member::Body::FIELD_MEMBER,
CHECK(w->getBody().which() == schema::StructNode::Member::Body::FIELD_MEMBER,
"Unsupported union member type.");
return DynamicValue::Builder(DynamicStruct::Builder::getFieldImpl(
pool, builder, body.getFieldMember()));
return DynamicValue::Builder(DynamicStruct::Builder::getImpl(pool, builder, *w));
}
void DynamicUnion::Builder::set(
schema::StructNode::Field::Reader field, DynamicValue::Reader value) {
builder.setDataField<uint16_t>(schema.getDiscriminantOffset() * ELEMENTS, field.getIndex());
DynamicStruct::Builder::setFieldImpl(pool, builder, field, value);
schema::StructNode::Member::Reader member, DynamicValue::Reader value) {
builder.setDataField<uint16_t>(getSchema().getDiscriminantOffset() * ELEMENTS, member.getIndex());
DynamicStruct::Builder::setImpl(pool, builder, member, value);
}
DynamicValue::Builder DynamicUnion::Builder::init(schema::StructNode::Field::Reader field) {
builder.setDataField<uint16_t>(schema.getDiscriminantOffset() * ELEMENTS, field.getIndex());
return DynamicStruct::Builder::initFieldImpl(pool, builder, field);
DynamicValue::Builder DynamicUnion::Builder::init(schema::StructNode::Member::Reader member) {
builder.setDataField<uint16_t>(getSchema().getDiscriminantOffset() * ELEMENTS, member.getIndex());
return DynamicStruct::Builder::initImpl(pool, builder, member);
}
DynamicValue::Builder DynamicUnion::Builder::init(schema::StructNode::Field::Reader field,
DynamicValue::Builder DynamicUnion::Builder::init(schema::StructNode::Member::Reader member,
uint size) {
builder.setDataField<uint16_t>(schema.getDiscriminantOffset() * ELEMENTS, field.getIndex());
return DynamicStruct::Builder::initFieldImpl(pool, builder, field, size);
builder.setDataField<uint16_t>(getSchema().getDiscriminantOffset() * ELEMENTS, member.getIndex());
return DynamicStruct::Builder::initImpl(pool, builder, member, size);
}
// =======================================================================================
......@@ -442,30 +447,105 @@ Maybe<schema::StructNode::Member::Reader> DynamicStruct::Builder::findMemberByNa
}
}
DynamicValue::Builder DynamicStruct::Builder::initObjectField(
schema::StructNode::Field::Reader field, schema::Type::Reader type) {
VALIDATE_INPUT(field.getType().getBody().which() == schema::Type::Body::OBJECT_TYPE,
"Expected an Object. (To dynamically initialize a non-Object field, do not "
"pass an element type to initObjectField().)") {
return initFieldImpl(pool, builder, field);
DynamicValue::Builder DynamicStruct::Builder::initObject(
schema::StructNode::Member::Reader member, schema::Type::Reader type) {
switch (member.getBody().which()) {
case schema::StructNode::Member::Body::UNION_MEMBER:
FAIL_VALIDATE_INPUT(
"Can't init() a union. get() it first and then init() one of its members.");
return getImpl(pool, builder, member);
case schema::StructNode::Member::Body::FIELD_MEMBER: {
auto field = member.getBody().getFieldMember();
VALIDATE_INPUT(field.getType().getBody().which() == schema::Type::Body::OBJECT_TYPE,
"Expected an Object. (To dynamically initialize a non-Object field, do not "
"pass an element type to initObjectField().)") {
return initImpl(pool, builder, member);
}
return initFieldImpl(pool, builder, field, type);
}
}
return initFieldImpl(pool, builder, field, type);
}
DynamicValue::Builder DynamicStruct::Builder::initObjectField(
schema::StructNode::Field::Reader field, schema::Type::Reader type, uint size) {
VALIDATE_INPUT(field.getType().getBody().which() == schema::Type::Body::OBJECT_TYPE,
"Expected an Object. (To dynamically initialize a non-Object field, do not "
"pass a struct schema to initObjectField().)") {
return initFieldImpl(pool, builder, field, size);
FAIL_CHECK("switch() missing case.", member.getBody().which());
return getImpl(pool, builder, member);
}
DynamicValue::Builder DynamicStruct::Builder::initObject(
schema::StructNode::Member::Reader member, schema::Type::Reader type, uint size) {
switch (member.getBody().which()) {
case schema::StructNode::Member::Body::UNION_MEMBER:
FAIL_VALIDATE_INPUT(
"Can't init() a union. get() it first and then init() one of its members.");
return getImpl(pool, builder, member);
case schema::StructNode::Member::Body::FIELD_MEMBER: {
auto field = member.getBody().getFieldMember();
VALIDATE_INPUT(field.getType().getBody().which() == schema::Type::Body::OBJECT_TYPE,
"Expected an Object. (To dynamically initialize a non-Object field, do not "
"pass a struct schema to initObjectField().)") {
return initImpl(pool, builder, member, size);
}
return initFieldImpl(pool, builder, field, type, size);
}
}
return initFieldImpl(pool, builder, field, type, size);
FAIL_CHECK("switch() missing case.", member.getBody().which());
return getImpl(pool, builder, member);
}
DynamicUnion::Reader DynamicStruct::Reader::getUnion(schema::StructNode::Union::Reader un) {
return DynamicUnion::Reader(pool, un, reader);
DynamicValue::Reader DynamicStruct::Reader::get(Text::Reader name) {
auto member = findMemberByName(name);
RECOVERABLE_PRECOND(member != nullptr, "struct has no such member", name) {
return DynamicValue::Reader();
}
return get(*member);
}
DynamicValue::Builder DynamicStruct::Builder::get(Text::Reader name) {
auto member = findMemberByName(name);
RECOVERABLE_PRECOND(member != nullptr, "struct has no such member", name) {
return DynamicValue::Builder();
}
return get(*member);
}
void DynamicStruct::Builder::set(Text::Reader name, DynamicValue::Reader value) {
auto member = findMemberByName(name);
RECOVERABLE_PRECOND(member != nullptr, "struct has no such member", name) {
return;
}
return set(*member, value);
}
DynamicUnion::Builder DynamicStruct::Builder::getUnion(schema::StructNode::Union::Reader un) {
return DynamicUnion::Builder(pool, un, builder);
void DynamicStruct::Builder::set(Text::Reader name,
std::initializer_list<DynamicValue::Reader> value) {
init(name, value.size()).as<DynamicList>().copyFrom(value);
}
DynamicValue::Builder DynamicStruct::Builder::init(Text::Reader name) {
auto member = findMemberByName(name);
RECOVERABLE_PRECOND(member != nullptr, "struct has no such member", name) {
return DynamicValue::Builder();
}
return init(*member);
}
DynamicValue::Builder DynamicStruct::Builder::init(Text::Reader name, uint size) {
auto member = findMemberByName(name);
RECOVERABLE_PRECOND(member != nullptr, "struct has no such member", name) {
return DynamicValue::Builder();
}
return init(*member, size);
}
DynamicValue::Builder DynamicStruct::Builder::initObject(
Text::Reader name, schema::Type::Reader type) {
auto member = findMemberByName(name);
RECOVERABLE_PRECOND(member != nullptr, "struct has no such member", name) {
return DynamicValue::Builder();
}
return initObject(*member, type);
}
DynamicValue::Builder DynamicStruct::Builder::initObject(
Text::Reader name, schema::Type::Reader type, uint size) {
auto member = findMemberByName(name);
RECOVERABLE_PRECOND(member != nullptr, "struct has no such member", name) {
return DynamicValue::Builder();
}
return initObject(*member, type, size);
}
void DynamicStruct::Builder::copyFrom(Reader other) {
......@@ -474,261 +554,333 @@ void DynamicStruct::Builder::copyFrom(Reader other) {
FAIL_CHECK("Unimplemented: copyFrom()");
}
DynamicValue::Reader DynamicStruct::Reader::getFieldImpl(
DynamicValue::Reader DynamicStruct::Reader::getImpl(
const SchemaPool* pool, internal::StructReader reader,
schema::StructNode::Field::Reader field) {
auto type = field.getType().getBody();
auto dval = field.getDefaultValue().getBody();
schema::StructNode::Member::Reader member) {
switch (member.getBody().which()) {
case schema::StructNode::Member::Body::UNION_MEMBER:
return DynamicUnion::Reader(pool, member, reader);
switch (type.which()) {
case schema::Type::Body::VOID_TYPE:
return DynamicValue::Reader(reader.getDataField<Void>(field.getOffset() * ELEMENTS));
case schema::StructNode::Member::Body::FIELD_MEMBER: {
auto field = member.getBody().getFieldMember();
auto type = field.getType().getBody();
auto dval = field.getDefaultValue().getBody();
switch (type.which()) {
case schema::Type::Body::VOID_TYPE:
return DynamicValue::Reader(reader.getDataField<Void>(field.getOffset() * ELEMENTS));
#define HANDLE_TYPE(discrim, titleCase, type) \
case schema::Type::Body::discrim##_TYPE: \
return DynamicValue::Reader(reader.getDataField<type>( \
field.getOffset() * ELEMENTS, \
bitCast<typename internal::MaskType<type>::Type>(dval.get##titleCase##Value())));
HANDLE_TYPE(BOOL, Bool, bool)
HANDLE_TYPE(INT8, Int8, int8_t)
HANDLE_TYPE(INT16, Int16, int16_t)
HANDLE_TYPE(INT32, Int32, int32_t)
HANDLE_TYPE(INT64, Int64, int64_t)
HANDLE_TYPE(UINT8, Uint8, uint8_t)
HANDLE_TYPE(UINT16, Uint16, uint16_t)
HANDLE_TYPE(UINT32, Uint32, uint32_t)
HANDLE_TYPE(UINT64, Uint64, uint64_t)
HANDLE_TYPE(FLOAT32, Float32, float)
HANDLE_TYPE(FLOAT64, Float64, double)
case schema::Type::Body::discrim##_TYPE: \
return DynamicValue::Reader(reader.getDataField<type>( \
field.getOffset() * ELEMENTS, \
bitCast<typename internal::MaskType<type>::Type>(dval.get##titleCase##Value())));
HANDLE_TYPE(BOOL, Bool, bool)
HANDLE_TYPE(INT8, Int8, int8_t)
HANDLE_TYPE(INT16, Int16, int16_t)
HANDLE_TYPE(INT32, Int32, int32_t)
HANDLE_TYPE(INT64, Int64, int64_t)
HANDLE_TYPE(UINT8, Uint8, uint8_t)
HANDLE_TYPE(UINT16, Uint16, uint16_t)
HANDLE_TYPE(UINT32, Uint32, uint32_t)
HANDLE_TYPE(UINT64, Uint64, uint64_t)
HANDLE_TYPE(FLOAT32, Float32, float)
HANDLE_TYPE(FLOAT64, Float64, double)
#undef HANDLE_TYPE
case schema::Type::Body::ENUM_TYPE: {
uint16_t typedDval;
typedDval = dval.getEnumValue();
return DynamicValue::Reader(DynamicEnum(
pool, pool->getEnum(type.getEnumType()),
reader.getDataField<uint16_t>(field.getOffset() * ELEMENTS, typedDval)));
}
case schema::Type::Body::TEXT_TYPE: {
Text::Reader typedDval = dval.getTextValue();
return DynamicValue::Reader(
reader.getBlobField<Text>(field.getOffset() * REFERENCES,
typedDval.data(), typedDval.size() * BYTES));
}
case schema::Type::Body::DATA_TYPE: {
Data::Reader typedDval = dval.getDataValue();
return DynamicValue::Reader(
reader.getBlobField<Data>(field.getOffset() * REFERENCES,
typedDval.data(), typedDval.size() * BYTES));
}
case schema::Type::Body::ENUM_TYPE: {
uint16_t typedDval;
typedDval = dval.getEnumValue();
return DynamicValue::Reader(DynamicEnum(
pool, pool->getEnum(type.getEnumType()),
reader.getDataField<uint16_t>(field.getOffset() * ELEMENTS, typedDval)));
}
case schema::Type::Body::TEXT_TYPE: {
Text::Reader typedDval = dval.getTextValue();
return DynamicValue::Reader(
reader.getBlobField<Text>(field.getOffset() * REFERENCES,
typedDval.data(), typedDval.size() * BYTES));
}
case schema::Type::Body::DATA_TYPE: {
Data::Reader typedDval = dval.getDataValue();
return DynamicValue::Reader(
reader.getBlobField<Data>(field.getOffset() * REFERENCES,
typedDval.data(), typedDval.size() * BYTES));
}
case schema::Type::Body::LIST_TYPE: {
auto elementType = type.getListType();
return DynamicValue::Reader(DynamicList::Reader(
pool, elementType,
reader.getListField(field.getOffset() * REFERENCES,
elementSizeFor(elementType.getBody().which()),
dval.getListValue<internal::TrustedMessage>())));
}
case schema::Type::Body::STRUCT_TYPE: {
return DynamicValue::Reader(DynamicStruct::Reader(
pool, pool->getStruct(type.getStructType()),
reader.getStructField(field.getOffset() * REFERENCES,
dval.getStructValue<internal::TrustedMessage>())));
}
case schema::Type::Body::OBJECT_TYPE: {
return DynamicValue::Reader(DynamicObject::Reader(
pool, reader.getObjectField(field.getOffset() * REFERENCES,
dval.getObjectValue<internal::TrustedMessage>())));
}
case schema::Type::Body::INTERFACE_TYPE:
FAIL_CHECK("Interfaces not yet implemented.");
break;
}
case schema::Type::Body::LIST_TYPE: {
auto elementType = type.getListType();
return DynamicValue::Reader(DynamicList::Reader(
pool, elementType,
reader.getListField(field.getOffset() * REFERENCES,
elementSizeFor(elementType.getBody().which()),
dval.getListValue<internal::TrustedMessage>())));
FAIL_CHECK("switch() missing case.", type.which());
return DynamicValue::Reader();
}
case schema::Type::Body::STRUCT_TYPE: {
return DynamicValue::Reader(DynamicStruct::Reader(
pool, pool->getStruct(type.getStructType()),
reader.getStructField(field.getOffset() * REFERENCES,
dval.getStructValue<internal::TrustedMessage>())));
}
case schema::Type::Body::OBJECT_TYPE: {
return DynamicValue::Reader(DynamicObject::Reader(
pool, reader.getObjectField(field.getOffset() * REFERENCES,
dval.getObjectValue<internal::TrustedMessage>())));
}
case schema::Type::Body::INTERFACE_TYPE:
FAIL_CHECK("Interfaces not yet implemented.");
break;
}
FAIL_CHECK("switch() missing case.", type.which());
FAIL_CHECK("switch() missing case.", member.getBody().which());
return DynamicValue::Reader();
}
DynamicValue::Builder DynamicStruct::Builder::getFieldImpl(
DynamicValue::Builder DynamicStruct::Builder::getImpl(
const SchemaPool* pool, internal::StructBuilder builder,
schema::StructNode::Field::Reader field) {
auto type = field.getType().getBody();
auto dval = field.getDefaultValue().getBody();
schema::StructNode::Member::Reader member) {
switch (member.getBody().which()) {
case schema::StructNode::Member::Body::UNION_MEMBER:
return DynamicUnion::Builder(pool, member, builder);
switch (type.which()) {
case schema::Type::Body::VOID_TYPE:
return DynamicValue::Builder(builder.getDataField<Void>(field.getOffset() * ELEMENTS));
case schema::StructNode::Member::Body::FIELD_MEMBER: {
auto field = member.getBody().getFieldMember();
auto type = field.getType().getBody();
auto dval = field.getDefaultValue().getBody();
switch (type.which()) {
case schema::Type::Body::VOID_TYPE:
return DynamicValue::Builder(builder.getDataField<Void>(field.getOffset() * ELEMENTS));
#define HANDLE_TYPE(discrim, titleCase, type) \
case schema::Type::Body::discrim##_TYPE: \
return DynamicValue::Builder(builder.getDataField<type>( \
field.getOffset() * ELEMENTS, \
bitCast<typename internal::MaskType<type>::Type>(dval.get##titleCase##Value())));
HANDLE_TYPE(BOOL, Bool, bool)
HANDLE_TYPE(INT8, Int8, int8_t)
HANDLE_TYPE(INT16, Int16, int16_t)
HANDLE_TYPE(INT32, Int32, int32_t)
HANDLE_TYPE(INT64, Int64, int64_t)
HANDLE_TYPE(UINT8, Uint8, uint8_t)
HANDLE_TYPE(UINT16, Uint16, uint16_t)
HANDLE_TYPE(UINT32, Uint32, uint32_t)
HANDLE_TYPE(UINT64, Uint64, uint64_t)
HANDLE_TYPE(FLOAT32, Float32, float)
HANDLE_TYPE(FLOAT64, Float64, double)
case schema::Type::Body::discrim##_TYPE: \
return DynamicValue::Builder(builder.getDataField<type>( \
field.getOffset() * ELEMENTS, \
bitCast<typename internal::MaskType<type>::Type>(dval.get##titleCase##Value())));
HANDLE_TYPE(BOOL, Bool, bool)
HANDLE_TYPE(INT8, Int8, int8_t)
HANDLE_TYPE(INT16, Int16, int16_t)
HANDLE_TYPE(INT32, Int32, int32_t)
HANDLE_TYPE(INT64, Int64, int64_t)
HANDLE_TYPE(UINT8, Uint8, uint8_t)
HANDLE_TYPE(UINT16, Uint16, uint16_t)
HANDLE_TYPE(UINT32, Uint32, uint32_t)
HANDLE_TYPE(UINT64, Uint64, uint64_t)
HANDLE_TYPE(FLOAT32, Float32, float)
HANDLE_TYPE(FLOAT64, Float64, double)
#undef HANDLE_TYPE
case schema::Type::Body::ENUM_TYPE: {
uint16_t typedDval;
typedDval = dval.getEnumValue();
return DynamicValue::Builder(DynamicEnum(
pool, pool->getEnum(type.getEnumType()),
builder.getDataField<uint16_t>(field.getOffset() * ELEMENTS, typedDval)));
}
case schema::Type::Body::TEXT_TYPE: {
Text::Reader typedDval = dval.getTextValue();
return DynamicValue::Builder(
builder.getBlobField<Text>(field.getOffset() * REFERENCES,
typedDval.data(), typedDval.size() * BYTES));
}
case schema::Type::Body::DATA_TYPE: {
Data::Reader typedDval = dval.getDataValue();
return DynamicValue::Builder(
builder.getBlobField<Data>(field.getOffset() * REFERENCES,
typedDval.data(), typedDval.size() * BYTES));
}
case schema::Type::Body::LIST_TYPE: {
auto elementType = type.getListType();
return DynamicValue::Builder(DynamicList::Builder(
pool, elementType,
builder.getListField(field.getOffset() * REFERENCES,
dval.getListValue<internal::TrustedMessage>())));
}
case schema::Type::Body::STRUCT_TYPE: {
auto structNode = pool->getStruct(type.getStructType());
auto structSchema = structNode.getBody().getStructNode();
return DynamicValue::Builder(DynamicStruct::Builder(
pool, structNode,
builder.getStructField(
field.getOffset() * REFERENCES,
internal::StructSize(
structSchema.getDataSectionWordSize() * WORDS,
structSchema.getPointerSectionSize() * REFERENCES,
static_cast<internal::FieldSize>(structSchema.getPreferredListEncoding())),
dval.getStructValue<internal::TrustedMessage>())));
}
case schema::Type::Body::ENUM_TYPE: {
uint16_t typedDval;
typedDval = dval.getEnumValue();
return DynamicValue::Builder(DynamicEnum(
pool, pool->getEnum(type.getEnumType()),
builder.getDataField<uint16_t>(field.getOffset() * ELEMENTS, typedDval)));
}
case schema::Type::Body::TEXT_TYPE: {
Text::Reader typedDval = dval.getTextValue();
return DynamicValue::Builder(
builder.getBlobField<Text>(field.getOffset() * REFERENCES,
typedDval.data(), typedDval.size() * BYTES));
}
case schema::Type::Body::DATA_TYPE: {
Data::Reader typedDval = dval.getDataValue();
return DynamicValue::Builder(
builder.getBlobField<Data>(field.getOffset() * REFERENCES,
typedDval.data(), typedDval.size() * BYTES));
}
case schema::Type::Body::LIST_TYPE: {
auto elementType = type.getListType();
return DynamicValue::Builder(DynamicList::Builder(
pool, elementType,
builder.getListField(field.getOffset() * REFERENCES,
dval.getListValue<internal::TrustedMessage>())));
}
case schema::Type::Body::STRUCT_TYPE: {
auto structNode = pool->getStruct(type.getStructType());
auto structSchema = structNode.getBody().getStructNode();
return DynamicValue::Builder(DynamicStruct::Builder(
pool, structNode,
builder.getStructField(
field.getOffset() * REFERENCES,
internal::StructSize(
structSchema.getDataSectionWordSize() * WORDS,
structSchema.getPointerSectionSize() * REFERENCES,
static_cast<internal::FieldSize>(structSchema.getPreferredListEncoding())),
dval.getStructValue<internal::TrustedMessage>())));
}
case schema::Type::Body::OBJECT_TYPE: {
return DynamicValue::Builder(DynamicObject::Builder(
pool, builder.getObjectField(field.getOffset() * REFERENCES,
dval.getObjectValue<internal::TrustedMessage>())));
}
case schema::Type::Body::INTERFACE_TYPE:
FAIL_CHECK("Interfaces not yet implemented.");
break;
}
case schema::Type::Body::OBJECT_TYPE: {
return DynamicValue::Builder(DynamicObject::Builder(
pool, builder.getObjectField(field.getOffset() * REFERENCES,
dval.getObjectValue<internal::TrustedMessage>())));
FAIL_CHECK("switch() missing case.", type.which());
return DynamicValue::Builder();
}
case schema::Type::Body::INTERFACE_TYPE:
FAIL_CHECK("Interfaces not yet implemented.");
break;
}
FAIL_CHECK("switch() missing case.", type.which());
FAIL_CHECK("switch() missing case.", member.getBody().which());
return DynamicValue::Builder();
}
void DynamicStruct::Builder::setFieldImpl(
void DynamicStruct::Builder::setImpl(
const SchemaPool* pool, internal::StructBuilder builder,
schema::StructNode::Field::Reader field, DynamicValue::Reader value) {
auto type = field.getType().getBody();
auto dval = field.getDefaultValue().getBody();
schema::StructNode::Member::Reader member, DynamicValue::Reader value) {
switch (member.getBody().which()) {
case schema::StructNode::Member::Body::UNION_MEMBER: {
auto src = value.as<DynamicUnion>();
auto which = src.which();
VALIDATE_INPUT(which != nullptr,
"Trying to copy a union value, but the union's discriminant is not recognized. It "
"was probably constructed using a newer version of the schema.") {
return;
}
setImpl(pool, builder, *which, src.get());
return;
}
switch (type.which()) {
case schema::Type::Body::VOID_TYPE:
builder.setDataField<Void>(field.getOffset() * ELEMENTS, value.as<Void>());
break;
case schema::StructNode::Member::Body::FIELD_MEMBER: {
auto field = member.getBody().getFieldMember();
auto type = field.getType().getBody();
auto dval = field.getDefaultValue().getBody();
#define HANDLE_TYPE(discrim, titleCase, type) \
case schema::Type::Body::discrim##_TYPE: \
builder.setDataField<type>( \
field.getOffset() * ELEMENTS, value.as<type>(), \
bitCast<internal::Mask<type> >(dval.get##titleCase##Value())); \
break;
switch (type.which()) {
case schema::Type::Body::VOID_TYPE:
builder.setDataField<Void>(field.getOffset() * ELEMENTS, value.as<Void>());
return;
HANDLE_TYPE(BOOL, Bool, bool)
HANDLE_TYPE(INT8, Int8, int8_t)
HANDLE_TYPE(INT16, Int16, int16_t)
HANDLE_TYPE(INT32, Int32, int32_t)
HANDLE_TYPE(INT64, Int64, int64_t)
HANDLE_TYPE(UINT8, Uint8, uint8_t)
HANDLE_TYPE(UINT16, Uint16, uint16_t)
HANDLE_TYPE(UINT32, Uint32, uint32_t)
HANDLE_TYPE(UINT64, Uint64, uint64_t)
HANDLE_TYPE(FLOAT32, Float32, float)
HANDLE_TYPE(FLOAT64, Float64, double)
#define HANDLE_TYPE(discrim, titleCase, type) \
case schema::Type::Body::discrim##_TYPE: \
builder.setDataField<type>( \
field.getOffset() * ELEMENTS, value.as<type>(), \
bitCast<internal::Mask<type> >(dval.get##titleCase##Value())); \
return;
HANDLE_TYPE(BOOL, Bool, bool)
HANDLE_TYPE(INT8, Int8, int8_t)
HANDLE_TYPE(INT16, Int16, int16_t)
HANDLE_TYPE(INT32, Int32, int32_t)
HANDLE_TYPE(INT64, Int64, int64_t)
HANDLE_TYPE(UINT8, Uint8, uint8_t)
HANDLE_TYPE(UINT16, Uint16, uint16_t)
HANDLE_TYPE(UINT32, Uint32, uint32_t)
HANDLE_TYPE(UINT64, Uint64, uint64_t)
HANDLE_TYPE(FLOAT32, Float32, float)
HANDLE_TYPE(FLOAT64, Float64, double)
#undef HANDLE_TYPE
case schema::Type::Body::ENUM_TYPE:
builder.setDataField<uint16_t>(
field.getOffset() * ELEMENTS, value.as<DynamicEnum>().getRaw(),
dval.getEnumValue());
break;
case schema::Type::Body::TEXT_TYPE:
builder.setBlobField<Text>(field.getOffset() * REFERENCES, value.as<Text>());
break;
case schema::Type::Body::DATA_TYPE:
builder.setBlobField<Data>(field.getOffset() * REFERENCES, value.as<Data>());
break;
case schema::Type::Body::ENUM_TYPE:
builder.setDataField<uint16_t>(
field.getOffset() * ELEMENTS, value.as<DynamicEnum>().getRaw(),
dval.getEnumValue());
return;
case schema::Type::Body::TEXT_TYPE:
builder.setBlobField<Text>(field.getOffset() * REFERENCES, value.as<Text>());
return;
case schema::Type::Body::DATA_TYPE:
builder.setBlobField<Data>(field.getOffset() * REFERENCES, value.as<Data>());
return;
case schema::Type::Body::LIST_TYPE: {
// TODO(now): We need to do a schemaless copy to avoid losing information if the values
// are larger than what the schema defines.
auto listValue = value.as<DynamicList>();
initImpl(pool, builder, member, listValue.size())
.as<DynamicList>().copyFrom(listValue);
return;
}
case schema::Type::Body::STRUCT_TYPE: {
// TODO(now): We need to do a schemaless copy to avoid losing information if the values
// are larger than what the schema defines.
initImpl(pool, builder, member).as<DynamicStruct>()
.copyFrom(value.as<DynamicStruct>());
return;
}
case schema::Type::Body::OBJECT_TYPE: {
// TODO(now): Perform schemaless copy.
FAIL_CHECK("TODO");
return;
}
case schema::Type::Body::INTERFACE_TYPE:
FAIL_CHECK("Interfaces not yet implemented.");
return;
}
case schema::Type::Body::LIST_TYPE: {
// TODO(now): We need to do a schemaless copy to avoid losing information if the values are
// larger than what the schema defines.
auto listValue = value.as<DynamicList>();
initFieldImpl(pool, builder, field, listValue.size()).as<DynamicList>().copyFrom(listValue);
break;
FAIL_CHECK("switch() missing case.", type.which());
return;
}
}
case schema::Type::Body::STRUCT_TYPE: {
// TODO(now): We need to do a schemaless copy to avoid losing information if the values are
// larger than what the schema defines.
initFieldImpl(pool, builder, field).as<DynamicStruct>().copyFrom(value.as<DynamicStruct>());
break;
}
FAIL_CHECK("switch() missing case.", member.getBody().which());
}
case schema::Type::Body::OBJECT_TYPE: {
// TODO(now): Perform schemaless copy.
FAIL_CHECK("TODO");
break;
}
DynamicValue::Builder DynamicStruct::Builder::initImpl(
const SchemaPool* pool, internal::StructBuilder builder,
schema::StructNode::Member::Reader member, uint size) {
switch (member.getBody().which()) {
case schema::StructNode::Member::Body::UNION_MEMBER:
FAIL_VALIDATE_INPUT(
"Can't init() a union. get() it first and then init() one of its members.");
return getImpl(pool, builder, member);
case schema::Type::Body::INTERFACE_TYPE:
FAIL_CHECK("Interfaces not yet implemented.");
break;
case schema::StructNode::Member::Body::FIELD_MEMBER: {
auto field = member.getBody().getFieldMember();
return initFieldImpl(pool, builder, field, field.getType(), size);
}
}
}
DynamicValue::Builder DynamicStruct::Builder::initFieldImpl(
const SchemaPool* pool, internal::StructBuilder builder,
schema::StructNode::Field::Reader field, uint size) {
return initFieldImpl(pool, builder, field, field.getType(), size);
FAIL_CHECK("switch() missing case.", member.getBody().which());
return getImpl(pool, builder, member);
}
DynamicValue::Builder DynamicStruct::Builder::initFieldImpl(
DynamicValue::Builder DynamicStruct::Builder::initImpl(
const SchemaPool* pool, internal::StructBuilder builder,
schema::StructNode::Field::Reader field) {
return initFieldImpl(pool, builder, field, field.getType());
schema::StructNode::Member::Reader member) {
switch (member.getBody().which()) {
case schema::StructNode::Member::Body::UNION_MEMBER:
FAIL_VALIDATE_INPUT(
"Can't init() a union. get() it first and then init() one of its members.");
return getImpl(pool, builder, member);
case schema::StructNode::Member::Body::FIELD_MEMBER: {
auto field = member.getBody().getFieldMember();
return initFieldImpl(pool, builder, field, field.getType());
}
}
FAIL_CHECK("switch() missing case.", member.getBody().which());
return getImpl(pool, builder, member);
}
DynamicValue::Builder DynamicStruct::Builder::initFieldImpl(
......@@ -752,7 +904,7 @@ DynamicValue::Builder DynamicStruct::Builder::initFieldImpl(
case schema::Type::Body::STRUCT_TYPE:
case schema::Type::Body::INTERFACE_TYPE:
FAIL_VALIDATE_INPUT("Expected a list or blob.");
return getFieldImpl(pool, builder, field);
return DynamicValue::Builder();
case schema::Type::Body::TEXT_TYPE:
return DynamicValue::Builder(
......@@ -813,7 +965,7 @@ DynamicValue::Builder DynamicStruct::Builder::initFieldImpl(
case schema::Type::Body::LIST_TYPE:
case schema::Type::Body::INTERFACE_TYPE:
FAIL_VALIDATE_INPUT("Expected a list or blob.");
return getFieldImpl(pool, builder, field);
return DynamicValue::Builder();
case schema::Type::Body::STRUCT_TYPE: {
auto structType = pool->getStruct(type.getBody().getStructType());
......@@ -1086,6 +1238,14 @@ void DynamicList::Builder::copyFrom(Reader other) {
FAIL_CHECK("Unimplemented: copyFrom()");
}
void DynamicList::Builder::copyFrom(std::initializer_list<DynamicValue::Reader> value) {
PRECOND(value.size() == size(), "DynamicList::copyFrom() argument had different size.");
uint i = 0;
for (auto element: value) {
set(i++, element);
}
}
DynamicList::Reader DynamicList::Builder::asReader() {
return DynamicList::Reader(pool, elementType, depth, elementSchema, builder.asReader());
}
......
......@@ -131,16 +131,13 @@ public:
ReaderFor<DynamicTypeFor<FromReader<T>>> toDynamic(T&& value) const;
template <typename T>
BuilderFor<DynamicTypeFor<FromBuilder<T>>> toDynamic(T&& value) const;
// Convert an arbitrary struct or list reader or builder type into the equivalent dynamic type.
template <typename T>
DynamicTypeFor<TypeIfEnum<T>> toDynamic(T&& value) const;
// Convert an arbitrary struct or list reader or builder type, or an enum type, into the
// equivalent dynamic type.
// Example:
// DynamicStruct::Reader foo = pool.toDynamic(myType.getFoo());
template <typename T> DynamicEnum fromEnum(T&& value) const;
template <typename T> DynamicStruct::Reader fromStructReader(T&& reader) const;
template <typename T> DynamicStruct::Builder fromStructBuilder(T&& builder) const;
template <typename T> DynamicList::Reader fromListReader(T&& reader) const;
template <typename T> DynamicList::Builder fromListBuilder(T&& builder) const;
// Convert native types to dynamic types.
// // myStruct has a field named foo that has struct type.
// DynamicStruct::Reader foo = pool.toDynamic(myStruct.getFoo());
private:
struct Impl;
......@@ -276,6 +273,7 @@ private:
friend struct DynamicStruct;
friend struct DynamicList;
friend class SchemaPool;
};
// -------------------------------------------------------------------
......@@ -344,7 +342,8 @@ class DynamicUnion::Reader {
public:
Reader() = default;
schema::StructNode::Union::Reader getSchema() { return schema; }
schema::StructNode::Member::Reader getMemberSchema() { return schema; }
schema::StructNode::Union::Reader getSchema();
Maybe<schema::StructNode::Member::Reader> which();
// Returns which field is set, or nullptr if an unknown field is set (i.e. the schema is old, and
......@@ -355,10 +354,10 @@ public:
private:
const SchemaPool* pool;
schema::StructNode::Union::Reader schema;
schema::StructNode::Member::Reader schema;
internal::StructReader reader;
inline Reader(const SchemaPool* pool, schema::StructNode::Union::Reader schema,
inline Reader(const SchemaPool* pool, schema::StructNode::Member::Reader schema,
internal::StructReader reader)
: pool(pool), schema(schema), reader(reader) {}
......@@ -369,23 +368,24 @@ class DynamicUnion::Builder {
public:
Builder() = default;
schema::StructNode::Union::Reader getSchema() { return schema; }
schema::StructNode::Member::Reader getMemberSchema() { return schema; }
schema::StructNode::Union::Reader getSchema();
Maybe<schema::StructNode::Member::Reader> which();
// Returns which field is set, or nullptr if an unknown field is set (i.e. the schema is old, and
// the underlying data has the union set to a member we don't know about).
DynamicValue::Builder get();
void set(schema::StructNode::Field::Reader field, DynamicValue::Reader value);
DynamicValue::Builder init(schema::StructNode::Field::Reader field);
DynamicValue::Builder init(schema::StructNode::Field::Reader field, uint size);
void set(schema::StructNode::Member::Reader member, DynamicValue::Reader value);
DynamicValue::Builder init(schema::StructNode::Member::Reader member);
DynamicValue::Builder init(schema::StructNode::Member::Reader member, uint size);
private:
const SchemaPool* pool;
schema::StructNode::Union::Reader schema;
schema::StructNode::Member::Reader schema;
internal::StructBuilder builder;
inline Builder(const SchemaPool* pool, schema::StructNode::Union::Reader schema,
inline Builder(const SchemaPool* pool, schema::StructNode::Member::Reader schema,
internal::StructBuilder builder)
: pool(pool), schema(schema), builder(builder) {}
......@@ -408,11 +408,11 @@ public:
Maybe<schema::StructNode::Member::Reader> findMemberByName(Text::Reader name);
// Looks up the member with the given name, or returns nullptr if no such member exists.
DynamicValue::Reader getField(schema::StructNode::Field::Reader field);
// Returns the value of the given field.
DynamicValue::Reader get(schema::StructNode::Member::Reader member);
// Read the given member value.
DynamicUnion::Reader getUnion(schema::StructNode::Union::Reader un);
// Returns the value of the given union.
DynamicValue::Reader get(Text::Reader name);
// Shortcut to read a member by name. Throws an exception if no such member exists.
private:
const SchemaPool* pool;
......@@ -424,9 +424,9 @@ private:
void verifyTypeId(uint64_t id);
static DynamicValue::Reader getFieldImpl(
static DynamicValue::Reader getImpl(
const SchemaPool* pool, internal::StructReader reader,
schema::StructNode::Field::Reader field);
schema::StructNode::Member::Reader member);
template <typename T>
friend struct internal::PointerHelpers;
......@@ -453,24 +453,32 @@ public:
Maybe<schema::StructNode::Member::Reader> findMemberByName(Text::Reader name);
// Looks up the member with the given name, or returns nullptr if no such member exists.
DynamicValue::Builder getField(schema::StructNode::Field::Reader field);
// Returns the value of the given field.
void setField(schema::StructNode::Field::Reader field, DynamicValue::Reader value);
// Sets the value of the given field.
DynamicValue::Builder initField(schema::StructNode::Field::Reader field);
DynamicValue::Builder initField(schema::StructNode::Field::Reader field, uint size);
// Initialize a struct or list field by field schema.
DynamicValue::Builder initObjectField(schema::StructNode::Field::Reader field,
schema::Type::Reader type);
DynamicValue::Builder initObjectField(schema::StructNode::Field::Reader field,
schema::Type::Reader type, uint size);
// Initialize an Object-typed field. You must specify the type to initialize as.
DynamicUnion::Builder getUnion(schema::StructNode::Union::Reader un);
// Returns the value of the given union.
DynamicValue::Builder get(schema::StructNode::Member::Reader member);
// Read the given member value.
void set(schema::StructNode::Member::Reader member, DynamicValue::Reader value);
// Set the given member value.
DynamicValue::Builder init(schema::StructNode::Member::Reader member);
DynamicValue::Builder init(schema::StructNode::Member::Reader member, uint size);
// Init a struct, list, or blob field.
DynamicValue::Builder initObject(schema::StructNode::Member::Reader member,
schema::Type::Reader type);
DynamicValue::Builder initObject(schema::StructNode::Member::Reader member,
schema::Type::Reader type, uint size);
// Init an object field. You must specify the type. The provided Type::Reader can point to a
// temporary message; it will not be accessed again after the method returns. Of course, if it
// refers to any other types by ID, those types must be present in the SchemaPool.
DynamicValue::Builder get(Text::Reader name);
void set(Text::Reader name, DynamicValue::Reader value);
void set(Text::Reader name, std::initializer_list<DynamicValue::Reader> value);
DynamicValue::Builder init(Text::Reader name);
DynamicValue::Builder init(Text::Reader name, uint size);
DynamicValue::Builder initObject(Text::Reader name, schema::Type::Reader type);
DynamicValue::Builder initObject(Text::Reader name, schema::Type::Reader type, uint size);
// Shortcuts to access members by name. These throw exceptions if no such field exists.
void copyFrom(Reader other);
......@@ -487,18 +495,18 @@ private:
void verifyTypeId(uint64_t id);
static DynamicValue::Builder getFieldImpl(
static DynamicValue::Builder getImpl(
const SchemaPool* pool, internal::StructBuilder builder,
schema::StructNode::Field::Reader field);
static void setFieldImpl(
schema::StructNode::Member::Reader member);
static void setImpl(
const SchemaPool* pool, internal::StructBuilder builder,
schema::StructNode::Field::Reader field, DynamicValue::Reader value);
static DynamicValue::Builder initFieldImpl(
schema::StructNode::Member::Reader member, DynamicValue::Reader value);
static DynamicValue::Builder initImpl(
const SchemaPool* pool, internal::StructBuilder builder,
schema::StructNode::Field::Reader field, uint size);
static DynamicValue::Builder initFieldImpl(
schema::StructNode::Member::Reader member, uint size);
static DynamicValue::Builder initImpl(
const SchemaPool* pool, internal::StructBuilder builder,
schema::StructNode::Field::Reader field);
schema::StructNode::Member::Reader member);
static DynamicValue::Builder initFieldImpl(
const SchemaPool* pool, internal::StructBuilder builder,
schema::StructNode::Field::Reader field,
......@@ -590,6 +598,7 @@ public:
inline iterator end() { return iterator(this, size()); }
void copyFrom(Reader other);
void copyFrom(std::initializer_list<DynamicValue::Reader> value);
Reader asReader();
......@@ -849,6 +858,10 @@ template <typename T>
BuilderFor<DynamicTypeFor<FromBuilder<T>>> SchemaPool::toDynamic(T&& value) const {
return ToDynamicImpl<FromBuilder<T>>::apply(this, value);
}
template <typename T>
DynamicTypeFor<TypeIfEnum<T>> SchemaPool::toDynamic(T&& value) const {
return DynamicEnum(this, getEnum(typeId<T>()), static_cast<uint16_t>(value));
}
#define CAPNPROTO_DECLARE_DYNAMIC_VALUE_CONSTRUCTOR(cppType, typeTag, fieldName) \
inline DynamicValue::Reader::Reader(cppType value) \
......@@ -1016,25 +1029,25 @@ typename T::Builder DynamicStruct::Builder::as() {
return typename T::Builder(builder);
}
inline DynamicValue::Reader DynamicStruct::Reader::getField(
schema::StructNode::Field::Reader field) {
return getFieldImpl(pool, reader, field);
inline DynamicValue::Reader DynamicStruct::Reader::get(
schema::StructNode::Member::Reader member) {
return getImpl(pool, reader, member);
}
inline DynamicValue::Builder DynamicStruct::Builder::getField(
schema::StructNode::Field::Reader field) {
return getFieldImpl(pool, builder, field);
inline DynamicValue::Builder DynamicStruct::Builder::get(
schema::StructNode::Member::Reader member) {
return getImpl(pool, builder, member);
}
inline void DynamicStruct::Builder::setField(
schema::StructNode::Field::Reader field, DynamicValue::Reader value) {
return setFieldImpl(pool, builder, field, value);
inline void DynamicStruct::Builder::set(
schema::StructNode::Member::Reader member, DynamicValue::Reader value) {
return setImpl(pool, builder, member, value);
}
inline DynamicValue::Builder DynamicStruct::Builder::initField(
schema::StructNode::Field::Reader field) {
return initFieldImpl(pool, builder, field);
inline DynamicValue::Builder DynamicStruct::Builder::init(
schema::StructNode::Member::Reader member) {
return initImpl(pool, builder, member);
}
inline DynamicValue::Builder DynamicStruct::Builder::initField(
schema::StructNode::Field::Reader field, uint size) {
return initFieldImpl(pool, builder, field, size);
inline DynamicValue::Builder DynamicStruct::Builder::init(
schema::StructNode::Member::Reader member, uint size) {
return initImpl(pool, builder, member, size);
}
inline DynamicStruct::Reader DynamicStruct::Builder::asReader() {
......
......@@ -70,6 +70,12 @@ template <typename T>
using FromBuilder = typename RemoveReference<T>::Builds;
// FromBuilder<MyType::Builder> = MyType (for any Cap'n Proto type).
template <typename T, Kind k = kind<T>()> struct TypeIfEnum_;
template <typename T> struct TypeIfEnum_<T, Kind::ENUM> { typedef T Type; };
template <typename T>
using TypeIfEnum = typename TypeIfEnum_<RemoveReference<T>>::Type;
namespace internal {
template <typename T, Kind k> struct KindOf<List<T, k>> { static constexpr Kind kind = Kind::LIST; };
......@@ -229,11 +235,11 @@ struct List<T, Kind::PRIMITIVE> {
set(pos, *i);
}
CAPNPROTO_INLINE_DPRECOND(pos == size() && i == end,
"List::copyFrom() argument had different size.");
"List::copyFrom() argument had different size.");
}
void copyFrom(std::initializer_list<T> other) {
CAPNPROTO_INLINE_DPRECOND(other.size() == size(),
"List::copyFrom() argument had different size.");
"List::copyFrom() argument had different size.");
for (uint i = 0; i < other.size(); i++) {
set(i, other.begin()[i]);
}
......
......@@ -198,6 +198,11 @@ struct StructNode {
ordinal @1 :UInt16;
index @7 :UInt16;
# The index of this member within the containing struct or union's member list. This is
# redundant information, but it can be useful for the dynamic API which has methods that take
# a Member pointer to specify on which member to act.
codeOrder @2 :UInt16;
# Indicates where this member appeared in the code, relative to other members.
# Code ordering may have semantic relevance -- programmers tend to place related fields
......@@ -219,11 +224,6 @@ struct StructNode {
}
struct Field {
index @3 :UInt16;
# The index of this field within the containing struct or union's member list. This is
# redundant information, but it can be useful for the dynamic API which uses Field pointers as
# identifiers.
offset @0 :UInt32;
# Offset, in units of the field's size, from the beginning of the section in which the field
# resides. E.g. for a UInt32 field, multiply this by 4 to get the byte offset from the
......
......@@ -617,15 +617,15 @@ encodeSchema requestedFiles allFiles = (encRoot, nodesForEmbedding) where
dataValues2 = [ (0, encUInt16 $ fieldNumber field)
, (16, encUInt16 codeOrder)
, (32, encUInt16 (0::Word16)) -- discriminant
, (48, encUInt16 index)
]
ptrValues2 = [ (0, encText $ fieldName field)
, (1, encAnnotationList $ fieldAnnotations field)
, (2, encStruct (DataSectionWords 1, 2) (dataValues3, ptrValues3))
, (2, encStruct (DataSection32, 2) (dataValues3, ptrValues3))
]
-- StructNode.Field
dataValues3 = [ (0, encUInt32 $ offsetToInt $ fieldOffset field)
, (32, encUInt16 index) ]
dataValues3 = [ (0, encUInt32 $ offsetToInt $ fieldOffset field) ]
ptrValues3 = [ (0, encStruct typeSize $ encType $ fieldType field)
, (1, encStruct valueSize $ encValue (fieldType field) $
fieldDefaultValue field)
......@@ -637,10 +637,11 @@ encodeSchema requestedFiles allFiles = (encRoot, nodesForEmbedding) where
offsetToInt (InlineCompositeOffset {}) =
error "Inline types not currently supported by codegen plugins."
encMember _ (codeOrder, (_, DescUnion union)) = (dataValues2, ptrValues2) where
encMember index (codeOrder, (_, DescUnion union)) = (dataValues2, ptrValues2) where
dataValues2 = [ (0, encUInt16 $ unionNumber union)
, (16, encUInt16 codeOrder)
, (32, encUInt16 (1::Word16)) -- discriminant
, (48, encUInt16 index)
]
ptrValues2 = [ (0, encText $ unionName union)
, (1, encAnnotationList $ unionAnnotations union)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment