From ec67ab630b31a89b698ad72ef4407828c01ae1b0 Mon Sep 17 00:00:00 2001 From: Erik Boasson Date: Thu, 22 Feb 2024 16:57:17 +0100 Subject: [PATCH] Add support for optional members in dynsub Signed-off-by: Erik Boasson --- examples/dynsub/print_sample.c | 16 ++++++++++++++-- examples/dynsub/type_cache.c | 3 +++ examples/dynsub/variouspub.c | 16 ++++++++++++++-- examples/dynsub/variouspub_types.idl | 7 +++++++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/examples/dynsub/print_sample.c b/examples/dynsub/print_sample.c index 2a5ab79228..8b0600d75c 100644 --- a/examples/dynsub/print_sample.c +++ b/examples/dynsub/print_sample.c @@ -180,8 +180,20 @@ static void print_sample1_to (const unsigned char *sample, const DDS_XTypes_Comp for (uint32_t i = 0; i < t->member_seq._length; i++) { const DDS_XTypes_CompleteStructMember *m = &t->member_seq._buffer[i]; - c1.key = c->key && m->common.member_flags & DDS_XTypes_IS_KEY; - print_sample1_ti (p, &m->common.member_type_id, &c1, sep, *m->detail.name ? m->detail.name : NULL, false); + if (m->common.member_flags & DDS_XTypes_IS_OPTIONAL) { + void const * const *p1 = (const void *) align (p, &c1, _Alignof (void *), sizeof (void *)); + if (*p1 == NULL) { + printf ("%s", sep); + if (*m->detail.name) printf ("\"%s\":", m->detail.name); + printf ("(nothing)"); + } else { + struct context c2 = { .valid_data = c->valid_data, .key = false, .offset = 0, .maxalign = 1 }; + print_sample1_ti (*p1, &m->common.member_type_id, &c2, sep, *m->detail.name ? m->detail.name : NULL, false); + } + } else { + c1.key = c->key && m->common.member_flags & DDS_XTypes_IS_KEY; + print_sample1_ti (p, &m->common.member_type_id, &c1, sep, *m->detail.name ? m->detail.name : NULL, false); + } sep = ","; } if (!is_base_type) printf ("}"); diff --git a/examples/dynsub/type_cache.c b/examples/dynsub/type_cache.c index da845709d0..57cb9e9ba4 100644 --- a/examples/dynsub/type_cache.c +++ b/examples/dynsub/type_cache.c @@ -345,6 +345,9 @@ void build_typecache_to (const DDS_XTypes_CompleteTypeObject *typeobj, size_t *a const DDS_XTypes_CompleteStructMember *m = &t->member_seq._buffer[i]; size_t a, s; build_typecache_ti (&m->common.member_type_id, &a, &s); + if (m->common.member_flags & DDS_XTypes_IS_OPTIONAL) { + a = _Alignof (void *); s = sizeof (void *); + } if (a > *align) *align = a; if (*size % a) diff --git a/examples/dynsub/variouspub.c b/examples/dynsub/variouspub.c index d5398d6b5e..e1773bcf31 100644 --- a/examples/dynsub/variouspub.c +++ b/examples/dynsub/variouspub.c @@ -85,6 +85,13 @@ static void *samples_c[] = { NULL }; +static int32_t long_4 = 4; +static void *samples_M1_O[] = { + &(M1_O){ .x = NULL }, + &(M1_O){ .x = &long_4 }, + NULL +}; + static struct tpentry { const char *name; const dds_topic_descriptor_t *descr; @@ -94,6 +101,7 @@ static struct tpentry { { "A", &A_desc, samples_a, offsetof (A, count) }, { "B", &B_desc, samples_b, offsetof (B, a.count) }, { "C", &C_desc, samples_c, offsetof (C, b.a.count) }, + { "M1::O", &M1_O_desc, samples_M1_O, SIZE_MAX }, { NULL, NULL, NULL, 0 } }; @@ -145,8 +153,12 @@ int main (int argc, char **argv) { dds_return_t ret = 0; void *sample = tpentry->samples[sample_idx]; - uint32_t *countp = (uint32_t *) ((unsigned char *) sample + tpentry->count_offset); - *countp = count++; + uint32_t * const countp = + (tpentry->count_offset != SIZE_MAX) + ? (uint32_t *) ((unsigned char *) sample + tpentry->count_offset) + : 0; + if (countp) + *countp = count++; if ((ret = dds_write (writer, sample)) < 0) { fprintf (stderr, "dds_write: %s\n", dds_strretcode (ret)); diff --git a/examples/dynsub/variouspub_types.idl b/examples/dynsub/variouspub_types.idl index 1cf5baba74..b9f79c4c16 100644 --- a/examples/dynsub/variouspub_types.idl +++ b/examples/dynsub/variouspub_types.idl @@ -20,3 +20,10 @@ struct C { @key short k; }; + +module M1 { + @appendable + struct O { + @optional long x; + }; +};