Skip to content

Commit

Permalink
Fix for using string types in dynamic type API
Browse files Browse the repository at this point in the history
Fixes a bug in the XTypes wrapper that prevented creating dynamic
aggregated types with string members. This also adds support for
string bounds, and includes some minor code improvements.

Signed-off-by: Dennis Potman <[email protected]>
  • Loading branch information
dpotman authored and eboasson committed Mar 27, 2023
1 parent 11b923a commit 70dcacf
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 17 deletions.
10 changes: 10 additions & 0 deletions examples/dyntype/dyntype.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ int main (int argc, char ** argv)
.name = "dynamic_alias"
});

// String types
dds_dynamic_type_t dstring = dds_dynamic_type_create (participant, (dds_dynamic_type_descriptor_t) { .kind = DDS_DYNAMIC_STRING8 });
dds_dynamic_type_t dstring_bounded = dds_dynamic_type_create (participant, (dds_dynamic_type_descriptor_t) {
.kind = DDS_DYNAMIC_STRING8,
.bounds = (uint32_t[]) { 100 },
.num_bounds = 1
});

dds_dynamic_type_t dstruct = dds_dynamic_type_create (participant, (dds_dynamic_type_descriptor_t) { .kind = DDS_DYNAMIC_STRUCTURE, .name = "dynamic_struct" });
dds_dynamic_type_add_member (&dstruct, DDS_DYNAMIC_MEMBER_PRIM(DDS_DYNAMIC_INT32, "member_int32"));
dds_dynamic_type_add_member (&dstruct, DDS_DYNAMIC_MEMBER_ID_PRIM(DDS_DYNAMIC_FLOAT64, "member_float64", 10 /* has specific member id */));
Expand All @@ -103,6 +111,8 @@ int main (int argc, char ** argv)
dds_dynamic_type_add_member (&dstruct, DDS_DYNAMIC_MEMBER(denum, "member_enum"));
dds_dynamic_type_add_member (&dstruct, DDS_DYNAMIC_MEMBER(dbitmask, "member_bitmask"));
dds_dynamic_type_add_member (&dstruct, DDS_DYNAMIC_MEMBER(dalias, "member_alias"));
dds_dynamic_type_add_member (&dstruct, DDS_DYNAMIC_MEMBER(dstring, "member_string8"));
dds_dynamic_type_add_member (&dstruct, DDS_DYNAMIC_MEMBER(dstring_bounded, "member_string8_bounded"));

// Add members at specific index
dds_dynamic_type_add_member (&dstruct, (dds_dynamic_member_descriptor_t) {
Expand Down
26 changes: 15 additions & 11 deletions src/core/ddsc/src/dds_dynamic_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,7 @@ dds_dynamic_type_t dds_dynamic_type_create (dds_entity_t entity, dds_dynamic_typ
switch (descriptor.kind)
{
case DDS_DYNAMIC_NONE:
type.ret = DDS_RETCODE_BAD_PARAMETER;
break;
goto err_bad_param;

case DDS_DYNAMIC_BOOLEAN:
case DDS_DYNAMIC_BYTE:
Expand All @@ -194,52 +193,54 @@ dds_dynamic_type_t dds_dynamic_type_create (dds_entity_t entity, dds_dynamic_typ
type.ret = ddsi_dynamic_type_create_primitive (gv, (struct ddsi_type **) &type.x, descriptor.kind);
break;
case DDS_DYNAMIC_STRING8:
type.ret = ddsi_dynamic_type_create_string (gv, (struct ddsi_type **) &type.x);
if (descriptor.num_bounds > 1)
goto err_bad_param;
type.ret = ddsi_dynamic_type_create_string8 (gv, (struct ddsi_type **) &type.x, descriptor.num_bounds ? descriptor.bounds[0] : 0);
break;
case DDS_DYNAMIC_ALIAS: {
if (!typespec_valid (descriptor.base_type, false) || !typename_valid (descriptor.name))
goto err;
goto err_bad_param;
dds_dynamic_type_t aliased_type = dyntype_from_typespec (gv, descriptor.base_type);
type.ret = ddsi_dynamic_type_create_alias (gv, (struct ddsi_type **) &type.x, descriptor.name, (struct ddsi_type **) &aliased_type.x);
break;
}
case DDS_DYNAMIC_ENUMERATION:
if (!typename_valid (descriptor.name))
goto err;
goto err_bad_param;
type.ret = ddsi_dynamic_type_create_enum (gv, (struct ddsi_type **) &type.x, descriptor.name);
break;
case DDS_DYNAMIC_BITMASK:
if (!typename_valid (descriptor.name))
goto err;
goto err_bad_param;
type.ret = ddsi_dynamic_type_create_bitmask (gv, (struct ddsi_type **) &type.x, descriptor.name);
break;
case DDS_DYNAMIC_ARRAY: {
if (!typespec_valid (descriptor.element_type, false) || !typename_valid (descriptor.name) || descriptor.num_bounds == 0 || descriptor.bounds == NULL)
goto err;
goto err_bad_param;
for (uint32_t n = 0; n < descriptor.num_bounds; n++)
if (descriptor.bounds[n] == 0)
goto err;
goto err_bad_param;
dds_dynamic_type_t element_type = dyntype_from_typespec (gv, descriptor.element_type);
type.ret = ddsi_dynamic_type_create_array (gv, (struct ddsi_type **) &type.x, descriptor.name, (struct ddsi_type **) &element_type.x, descriptor.num_bounds, descriptor.bounds);
break;
}
case DDS_DYNAMIC_SEQUENCE: {
if (!typespec_valid (descriptor.element_type, false) || !typename_valid (descriptor.name) || descriptor.num_bounds > 1 || (descriptor.num_bounds == 1 && descriptor.bounds == NULL))
goto err;
goto err_bad_param;
dds_dynamic_type_t element_type = dyntype_from_typespec (gv, descriptor.element_type);
type.ret = ddsi_dynamic_type_create_sequence (gv, (struct ddsi_type **) &type.x, descriptor.name, (struct ddsi_type **) &element_type.x, descriptor.num_bounds > 0 ? descriptor.bounds[0] : 0);
break;
}
case DDS_DYNAMIC_STRUCTURE: {
if (!typespec_valid (descriptor.base_type, true) || !typename_valid (descriptor.name))
goto err;
goto err_bad_param;
dds_dynamic_type_t base_type = dyntype_from_typespec (gv, descriptor.base_type);
type.ret = ddsi_dynamic_type_create_struct (gv, (struct ddsi_type **) &type.x, descriptor.name, (struct ddsi_type **) &base_type.x);
break;
}
case DDS_DYNAMIC_UNION: {
if (!typespec_valid (descriptor.discriminator_type, false) || !union_disc_valid (descriptor.discriminator_type) || !typename_valid (descriptor.name))
goto err;
goto err_bad_param;
dds_dynamic_type_t discriminator_type = dyntype_from_typespec (gv, descriptor.discriminator_type);
type.ret = ddsi_dynamic_type_create_union (gv, (struct ddsi_type **) &type.x, descriptor.name, (struct ddsi_type **) &discriminator_type.x);
break;
Expand All @@ -252,7 +253,10 @@ dds_dynamic_type_t dds_dynamic_type_create (dds_entity_t entity, dds_dynamic_typ
type.ret = DDS_RETCODE_UNSUPPORTED;
break;
}
return type;

err_bad_param:
type.ret = DDS_RETCODE_BAD_PARAMETER;
err:
return type;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/ddsi/include/dds/ddsi/ddsi_dynamic_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ dds_return_t ddsi_dynamic_type_create_bitmask (struct ddsi_domaingv *gv, struct
dds_return_t ddsi_dynamic_type_create_alias (struct ddsi_domaingv *gv, struct ddsi_type **type, const char *type_name, struct ddsi_type **aliased_type);

/** @component dynamic_type_support */
dds_return_t ddsi_dynamic_type_create_string (struct ddsi_domaingv *gv, struct ddsi_type **type);
dds_return_t ddsi_dynamic_type_create_string8 (struct ddsi_domaingv *gv, struct ddsi_type **type, uint32_t bound);

/** @component dynamic_type_support */
dds_return_t ddsi_dynamic_type_create_primitive (struct ddsi_domaingv *gv, struct ddsi_type **type, dds_dynamic_type_kind_t kind);
Expand Down
8 changes: 5 additions & 3 deletions src/core/ddsi/src/ddsi_dynamic_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ static dds_return_t dynamic_type_ref_deps (struct ddsi_type *type)
dds_return_t ret = DDS_RETCODE_OK;
switch (type->xt._d)
{
case DDS_XTypes_TK_STRING8:
break;
case DDS_XTypes_TK_SEQUENCE:
if ((ret = ddsi_type_register_dep (type->gv, &type->xt.id, &type->xt._u.seq.c.element_type, &type->xt._u.seq.c.element_type->xt.id.x)) != DDS_RETCODE_OK)
goto err;
Expand Down Expand Up @@ -63,6 +61,9 @@ static dds_return_t dynamic_type_ref_deps (struct ddsi_type *type)
ddsi_type_unref_locked (type->gv, type->xt._u.union_type.members.seq[m].type);
}
break;
default:
// other types don't have dependencies
break;
}
err:
return ret;
Expand Down Expand Up @@ -241,11 +242,12 @@ dds_return_t ddsi_dynamic_type_create_alias (struct ddsi_domaingv *gv, struct dd
return DDS_RETCODE_OK;
}

dds_return_t ddsi_dynamic_type_create_string (struct ddsi_domaingv *gv, struct ddsi_type **type)
dds_return_t ddsi_dynamic_type_create_string8 (struct ddsi_domaingv *gv, struct ddsi_type **type, uint32_t bound)
{
if ((*type = ddsrt_calloc (1, sizeof (**type))) == NULL)
return DDS_RETCODE_OUT_OF_RESOURCES;
dynamic_type_init (gv, *type, DDS_XTypes_TK_STRING8, DDSI_TYPEID_KIND_FULLY_DESCRIPTIVE);
(*type)->xt._u.str8.bound = bound;
return DDS_RETCODE_OK;
}

Expand Down
23 changes: 21 additions & 2 deletions src/core/ddsi/src/ddsi_typewrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2742,10 +2742,29 @@ static void ddsi_xt_get_non_hash_id (const struct xt_type *xt, struct DDS_XTypes
switch (xt->_d)
{
case DDS_XTypes_TK_STRING8:
if (xt->_u.str8.bound <= 255)
{
ti->_d = DDS_XTypes_TI_STRING8_SMALL;
ti->_u.string_sdefn.bound = (DDS_XTypes_SBound) xt->_u.str8.bound;
}
else
{
ti->_d = DDS_XTypes_TI_STRING8_LARGE;
ti->_u.string_ldefn.bound = xt->_u.str8.bound;
}
break;
case DDS_XTypes_TK_STRING16:
ddsi_typeid_copy_to_impl (ti, &xt->id);
if (xt->_u.str16.bound <= 255)
{
ti->_d = DDS_XTypes_TI_STRING16_SMALL;
ti->_u.string_sdefn.bound = (DDS_XTypes_SBound) xt->_u.str16.bound;
}
else
{
ti->_d = DDS_XTypes_TI_STRING16_LARGE;
ti->_u.string_ldefn.bound = xt->_u.str16.bound;
}
break;

case DDS_XTypes_TK_SEQUENCE:
if (xt->_u.seq.bound <= 255)
{
Expand Down

0 comments on commit 70dcacf

Please sign in to comment.